/*
 * $Source: /usr/local/cvsroot/erserver/erserver/java/src/com/postgres/replic/tools/MasterAdd.java,v $
 * $Author: asullivan $ $Revision: 1.1.1.1 $ $Date: 2003/08/26 19:02:25 $
 *
 */

package com.postgres.replic.tools;

import java.sql.*;
import com.postgres.util.cmd.*;

public abstract class MasterAdd implements ToolKitConst {
    private static final String APP_NAME = "java MasterAdd";
    protected boolean debug = false;
    protected boolean verbose = false;
    protected String host;
    protected String port;
    protected String user;
    protected String pass;
    protected String db;
    protected String schema;
    protected String table;
    protected String column;
    protected String trigger;

    protected DBMetaHelper dbMetaHelper;

    private static final String[] labels =
        {"-host", "-port", "-user", "-pass", "-db", "-schema", "-table", "-column", "-trigger"};
    private static final String[] flags =       {"-debug", "-verbose"};

    protected Connection conn;


    public MasterAdd(){
    }

    public MasterAdd(String table, String column)
    throws Exception {
       init(table, column);
    }

    public abstract void run(String[] args);

    public void setConnection(Connection conn){
        this.conn = conn;
    }

    protected DBMetaHelper getDBMetaHelper() throws Exception{
        if (dbMetaHelper == null) {
            dbMetaHelper = new DBMetaHelper(getConnection());
        }
        return dbMetaHelper;
    }

    protected boolean init(String[] args)  {
        debug = false;
        verbose = false;
        boolean rc = false;
        CmdLine cline = null;

        if (args == null || args.length <= 0) {
            //System.out.println("args == null || args.length");
            setDefaults();

            return true;
        } else {
            //System.out.println("!(args == null || args.length)");
        }

        try {
            cline = CmdLine.instance(args, labels, flags);
            // Flags:
            verbose = cline.getFlag("-verbose");
            debug = cline.getFlag("-debug");


            // Params:
            host = cline.getParam("-host");
            port = cline.getParam("-port");
            user = cline.getParam("-user");
            pass = cline.getParam("-pass");
            db = cline.getParam("-db");
            schema = cline.getParam("-schema");
            trigger = cline.getParam("-trigger");
            table = cline.getParam("-table");
            column = cline.getParam("-column");


            setDefaults();

            if (verbose) {
                System.out.println("verbose=" + verbose);
                System.out.println("debug=" + debug);
                System.out.println("host=" + host);
                System.out.println("port=" + port);
                System.out.println("user=" + user);
                System.out.println("pass=" + pass);
                System.out.println("db=" + db);
                System.out.println("schema=" + schema);
                System.out.println("trigger=" + trigger);
            }

            validate();

            getConnection().setAutoCommit(false);

            rc = true;
        } catch (Exception e) {

            System.out.println("JDBCSystem::init: " + e.toString());
            String usage = CmdLine.getUsage(getAppName(), labels, flags);
            System.out.println(usage);

        }
        return rc;
    }

    protected String getAppName(){
        return APP_NAME;
    }

   private void setDefaults() {
        host = (host == null) ? HOST : host;
        port = (port == null) ? PORT : port;
        //user = (user == null) ? USER : user;
        //pass = (pass == null) ? PASS : pass;
        //db = (db == null) ? DB : db;
        schema = (schema == null) ? db : schema;
    }


    private void validate() throws Exception  {
        if (db == null) {
            throw new Exception("MasterAdd:: 150 ERROR: Database name may not be null");
        }

        if (trigger == null) {
            throw new Exception("MasterAdd:: 160 ERROR: trigger name may not be null");
        }

        if (table == null) {
            throw new Exception("MasterAdd:: 170 ERROR: table name may not be null");
        }

        if (column == null) {
            throw new Exception("MasterAdd:: 180 ERROR: column name may not be null");
        }

        //if (conn == null) {
        //    throw new Exception("MasterAdd:: 110 ERROR: No connection to the database!");
        //}

        if (table == null || table.trim().equals("")) {
            throw new Exception("MasterAdd:: 120 ERROR: table may not empty!");
        }

        if (column == null || column.trim().equals("")) {
            throw new Exception("MasterAdd:: 130 ERROR: column may not empty!");
        }

    }

    public void init(String table, String column) throws Exception {
        this.table = table;
        this.column = column;
        validate();
    }

    public abstract ResultSet getTableColumnAttrRS() throws SQLException;

    public abstract boolean createTrigger(String trigger, String table, String columnName)
    throws SQLException ;

    public abstract int insertInto_RSERV_TABLES_(int tableId, String columnName)
    throws SQLException ;

    public void masterAdd(String trigger) {
        ResultSet rs = null;
        Statement stmt = null;


        if (debug) System.out.println("MasterAdd::masterAdd: BEGIN");

        try {
            stmt = getConnection().createStatement();

            rs = getTableColumnAttrRS();
            while (rs.next()) {
            	int tableId = rs.getInt(1);
                String columnNum = rs.getString(2);
                if (debug) System.out.println("MasterAdd::masterAdd: tableId="+table+"; columnName="+columnNum);
                createTrigger(trigger, table, columnNum);
                int i = insertInto_RSERV_TABLES_(tableId, columnNum);
                if (debug) System.out.println("MasterAdd::masterAdd: inserted "+i+"; rows");
            }

            getConnection().commit();

        } catch (Exception e) {
            System.out.println("MasterAdd::masterAdd: ERROR: " + e.toString());

        } finally {
            try {
                if (rs != null) { rs.close(); }
            } catch (Exception e) { }
            try {
                if (stmt != null) { stmt.close(); }
            } catch (Exception e) { }
        }
    }

    public Connection getConnection() throws SQLException {
        Connection conn = null;

        if (this.conn == null) {

            DriverManager.registerDriver(
                new org.postgresql.Driver());

            if (DEBUG ) System.out.println ("AFTER DriverManager.registerDriver");
            // Connect to the database
            // You must put a database name after the @ sign in the connection URL.
            // You can use either the fully specified SQL*net syntax or a short cut
            // syntax as <host>:<port>:<sid>.  The example uses the short cut syntax.
            String connString = DB_TCP + host + ":" + port + "/" + db;
            conn =
            DriverManager.getConnection (connString, user, pass);

            if (DEBUG )
                System.out.println ("SUCESSFULLY CONNECTED TO DATABASE " + connString);
            this.conn = conn;
        }

        return this.conn;

    }
}
