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

package com.postgres.replic.tools;

import java.sql.*;
import java.util.*;

public class DBMetaHelper {

    private Connection m_connection;
    private DatabaseMetaData m_dbmd;
    private ResultSetMetaData m_rsmd;
    private boolean debug = false;

    public void setDebug(boolean debug) {
        this.debug = debug;
    }

    public DBMetaHelper (Connection conn) throws Exception {
        if (conn == null) {
            throw new Exception ("DBMetaHelper:: connection may not be null!");
        }
        m_connection = conn;
    }


    /** <p> create a new DatabaseMetaData object */
    public DatabaseMetaData getDatabaseMetaData() throws Exception {
        java.sql.DatabaseMetaData md = null;
        if (m_dbmd != null) {
            md = m_dbmd;
        } else {
            // No data cache yet; create a new DatabaseMetaData object
            md = m_connection.getMetaData();
        }
        return md;
    }


    /**
     * <p>Get all Columns information.
     * @return The ResultSet information
     */
    public ResultSet getColumns(String schemaPattern)
    throws Exception {
        java.sql.ResultSet rs = getColumns(schemaPattern, "%");
        return rs;
    }

    /**
     * <p>Get all Columns information.
     * @return <{ResultSet}>
     */
    public ResultSet getColumns(String schemaPattern,
    String tablenamePattern) throws Exception {
        java.sql.ResultSet rs =
        getDatabaseMetaData().getColumns("%", schemaPattern, tablenamePattern, "%");
        return rs;
    }

    /**
     *  Get a description of tables available in a catalog. Only table
     * descriptions matching the catalog, schema, table
     * name and type criteria are returned.  They are ordered by TABLE_TYPE,
     * TABLE_SCHEM and TABLE_NAME.
     * @param schemaPattern Schema name or null for all
     * @return ResultSet handle
     */
    public ResultSet getTables(String schemaPattern)
    throws Exception {
        String types[] = new String[1];
        types[0] = "TABLE";
        java.sql.ResultSet rs =
        getDatabaseMetaData().getTables("%", schemaPattern, "%", types);
        java.sql.ResultSetMetaData rsmd = rs.getMetaData();
        // int columnCount = rsmd.getColumnCount();
        return rs;
    }

    /**
     *  Get a description of tables available in a catalog. Only table
     * descriptions matching the catalog, schema, table
     * name and type criteria are returned.  They are ordered by TABLE_TYPE,
     * TABLE_SCHEM and TABLE_NAME.
     * @param schemaPattern Schema name or null for all
     * @return ResultSet handle
     */
    public ResultSet getProcedures(String schemaPattern)
    throws Exception {
        java.sql.ResultSet rs =
        getDatabaseMetaData().getProcedures("%", schemaPattern, "%");
        java.sql.ResultSetMetaData rsmd = rs.getMetaData();
        // int columnCount = rsmd.getColumnCount();
        return rs;
    }

    public boolean columnExists(String schema,
    String table, String column) throws Exception {

        if (schema == null || table == null || column == null) {
            throw new Exception("DBMetaHelper::columnExists schema, table, column may not be null");
        } else if (schema.trim().equals("") ||
        table.trim().equals("") ||
        column.trim().equals("")) {
            ;
            throw new Exception("DBMetaHelper::columnExists schema, table, column may not be empty");
        }

        boolean rc = false;
        java.sql.ResultSet rs =  getColumns(schema, table);


        while (rs.next()) {
            String columnName = rs.getString("COLUMN_NAME");
            if (debug)  System.out.println("          columnExists: " +
                columnName);
            if (columnName.equals(column)) {
                rc = true;
            }
        }

        return rc;

    }

    public String [] getColumns (String schema,
    String table,
    String exceptColumn) throws Exception {
        String [] exceptColumns = new String[1];
        exceptColumns[0] = exceptColumn;
        return getColumns(schema, table, exceptColumn);

    }

    public String [] getColumns (String schema,
    String table,
    String [] exceptColumns) throws Exception {

        if (schema == null || table == null) {
            throw new Exception("DBMetaHelper::getColumns schema, table may not be null");
        } else if (schema.trim().equals("") ||
        table.trim().equals("")  ) {
            throw new Exception("DBMetaHelper::getColumns schema, table may not be empty");
        }

        int len = 0;
        if (exceptColumns != null) {
            len = exceptColumns.length;
        }

        java.sql.ResultSet rs =  getColumns(schema, table);

        int count = 0;
        int index = 0;
        int columnCount = rs.getMetaData().getColumnCount();
        String [] rsArray = new String[columnCount];

        while (rs.next()) {

            String columnName = rs.getString("COLUMN_NAME");
            if (debug)  System.out.println("DBMetaHelper::getColumns: columnName=" +
                columnName);

            boolean except = false;
            for (int i = 0; i < len; i++) {
                if (columnName.equals(exceptColumns[i])) {
                    except = true;
                    break;
                }
            }

            if (!except) {
                rsArray[count++] = columnName;
            }
        }

        if (debug)  System.out.println("DBMetaHelper::getColumns: count=" + count);

        String [] resArray = new String[count];
        for (int i = 0; i < count; i++) {
            resArray[i] = rsArray[i];
        }

        return resArray;
    }

    /**
     * <p>Get all  Primary Keys
     * @param schemaPattern - schema pattern
     * @param - tablenamePattern - table name Pattern (%, ...)
     * @return The ResultSet
     */
    public ResultSet getPrimaryKeysRS(String schemaPattern,
        String tablenamePattern) throws Exception {
            java.sql.ResultSet rs =
                getDatabaseMetaData().getPrimaryKeys(null, schemaPattern, tablenamePattern);
            return rs;
    }

    public String [] getPrimaryKeys(String schema,
    String table) throws Exception {

        if (schema == null || table == null) {
            throw new Exception("DBMetaHelper::getPrimaryKeys schema, table may not be null");
        } else if (schema.trim().equals("") ||
        table.trim().equals("")  ) {
            throw new Exception("DBMetaHelper::getPrimaryKeys schema, table may not be empty");
        }

        String [] rsArray = null;
        java.sql.ResultSet rs = null;

        try {
            rs = getPrimaryKeysRS(schema, table);
            ArrayList rsArrayList = new ArrayList();

            while (rs.next()) {
                String columnName = rs.getString("COLUMN_NAME");
                if (debug)  System.out.println("DBMetaHelper::getPrimaryKeys: columnName=" +
                    columnName);

                rsArrayList.add(columnName);
            }

            int len = rsArrayList.size();
            if (len <= 0) {
                System.out.println("-- Table " + table + " does not have primary key!");
                return null;
            }

            rsArray = new String[len];
            for (int i = 0; i < len; i++) {
                rsArray[i] = (String) rsArrayList.get(i);
            }

        } catch (Exception e) {
            System.out.println("DBMetaHelper::getPrimaryKeys: " + e.toString());
            throw new Exception("CAnnot get primary keys for " + table);
        } finally {
            try {
               if (rs != null) {
                    rs.close();
               }
            } catch (Exception e) {}
        }


        return rsArray;

    }


}
