
/**
 * ATKIS-EDBS-Reader to read EDBS-File, convert and write it to an Oracle database
 * Copyright (C) 2000  Stephan Falke, Carsten Kleiner, University of Hannover
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package parser;

import java.sql.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * Diese Klasse ist zur Erzeugung der tempor&auml;ren Tabellen und Starten
 * des Datenaufbereitungsprogramm des <TT>PL/SQL</TT>-Paketes <TT>fad</TT>.
 * @author <A href="mailto:fad@gmx.ch">Stephan Falke</A>
 */
class TempTables { 
	
	/**
	 * der Benutzername bei der Datenbank
	 */
	protected static String name;
	
	/**
	 * das Pa&szlig;wort f&uuml; die Datenbank
	 */
	protected static String pass;
	
	/**
	 * die Verbindung zur Datenbank
	 */
	private static Connection conn;
	
	/**
	 * Liest einen String ein.
	 * @param str die Anfrage
	 * @return der eingelesene String
	 */
	private static String askFor (String str) {
		return(JOptionPane.showInputDialog(new Container(), new JLabel(str)));
	}
	
	/**
	 * Liest einen String ein. Die Eingabe wird dabei nicht im Klartext sichtbar.
	 * @param str die Anfrage
	 * @return der eingelesene String
	 */
	private static final String askForSecret (String str) {
		JPasswordField field = new JPasswordField(20);
		Object things[] = {str ,field};
		JOptionPane.showOptionDialog(new Container(), things, null, JOptionPane.OK_CANCEL_OPTION , JOptionPane.QUESTION_MESSAGE, null, null, null);//options , init);
		String pass = new String(field.getPassword());
		return(pass);
	}
	
	/**
	 * zur Erzeugung von Tabellenbeschreibungen. Da die Schl&uuml;ssel der Tabellen 
	 * <tt>CONSTRAINT</tt> sind, werden deren Namen um den &uuml;bergebenen Index 
	 * verl&auml;ngert.
	 * @param str die Teilst&uuml;cke der Tabellenbeschreibung
	 * @param i der anzuh&auml;ngende Index
	 * @return einen Deklarationsteil f&uuml;r die Tabelle, bei der die <tt>CONSTRAINT</tt>
	 * definierten Schl&uuml;ssel mit einem zus&auml;tzlichen Index im Namen versehen sind, 
	 * bei einem negativen Index werden die Namen nicht erweitert.
	 */
	private static String makeString (String[] str, int i) {
		String s = str[0];
		for (int j = 1; j < str.length; j++) {
			if (i < 0) {
				s = s.concat(str[j]);
			}
			else {
				s = s.concat(i + str[j]);
			}
		}
		return(s);
	}
	
	/**
	 * versucht tempor&auml;re Tabellen zu l&ouml;schen
	 * @param no der Index der tempor&auml;ren Tabellen, der im Namen eingetragen wurde
	 * @param count die Anzahl der Tabellen die gel&ouml;scht werden sollen, wenn etwa nicht
	 * ein kompletter Satz der Tabellen erzeugt wurde.
	 */
	private static void dropTempTables (int no, int count) throws Exception {
		Statement stmt;
		try {
			stmt = conn.createStatement();
		}
		catch (SQLException s) {
			throw new Exception(Constants.CANNOT_CONNECT + s.getMessage());
		}
		for (int c = count - 1; c >= 0; c--) {
			try {
				if (no >= 0) {
					stmt.executeUpdate("DROP TABLE " + Constants.TABLE_NAMES[c] + no);
				}
				else {
					stmt.executeUpdate("DROP TABLE " + Constants.TABLE_NAMES[c]);
				}
			}
			catch (SQLException s) {
				if (Constants.LOG) {
					if (no >= 0) {
						System.out.println(Constants.COULDNOT_DROP + Constants.TABLE_NAMES[c] + no + s.getMessage());
					}
					else {
						System.out.println(Constants.COULDNOT_DROP + Constants.TABLE_NAMES[c] + s.getMessage());
					}
				}
			}
		}	
	}
	
	
	/**
	 * erstellt eine tempor&auml;re Datenbank. Zun&auml;chst wird versucht diese ohne
	 * Index zu erstellen. Gelingt dies nicht, so werden alle Indizes von <tt>0</tt>
	 * bis zu einem maximalen Index probiert. Sind Benutzername und bzw. oder
	 * Pa&szlig;wort nicht angegeben, so werden diese abgefragt.
	 * @param args an erster Stelle kann der Benutzername beim Datenbaksystem, an 
	 * zweiter dessen Pa&szlig;wort angegeben werden.
	 * @return der Index der tempor&auml;ren Datenbank; <tt>-1</tt> falls dieser leer 
	 * ist
	 */
	public static int createTempTables (String[] args) throws Exception {
		DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
		try {
			name = args[0];
		}
		catch (Exception e) {
			name = askFor(Constants.USER_NAME_PLEASE);
		}
		try {
			pass = args[1];
		}
		catch (Exception e) {
			pass = askForSecret(Constants.PASS_WORD_PLEASE);
		}
		conn = DriverManager.getConnection(Constants.DATA_BASE, name, pass);
		Statement stmt;
		try {
			stmt = conn.createStatement();
		}
		catch (SQLException s) {
			throw new Exception(Constants.CANNOT_CONNECT); 
		}		
		for (int i = -1; i < Constants.MAX_TRY_CREATE; i++) {
			try {
				dropTempTables(i,Constants.TEMP_TABLE_COUNT);
			}
			catch (Exception e) {
			}
			int j = -1;
			try {
				for (j = 0; j < Constants.TEMP_TABLE_COUNT; j++) {
					if (i >= 0) {
						stmt.executeUpdate("CREATE TABLE " + Constants.TABLE_NAMES[j] + i + makeString(Constants.TABLE_COLUMS[j], i));
					}
					else {
						stmt.executeUpdate("CREATE TABLE " + Constants.TABLE_NAMES[j] + makeString(Constants.TABLE_COLUMS[j], i));
					}
				}
				return(i);
			}	
			catch (SQLException s) {
			}
		}
		throw new Exception(Constants.COULDNOT_CREATE_TEMP_TABLES);
	}
}
