Package henplus

Source Code of henplus.SQLMetaDataBuilder

/*
* This is free software, licensed under the Gnu Public License (GPL) get a copy from <http://www.gnu.org/licenses/gpl.html>
*
* @version $Id: SQLMetaDataBuilder.java,v 1.7 2005-06-18 04:58:13 hzeller Exp $
*
* @author <a href="mailto:martin.grotzke@javakaffee.de">Martin Grotzke</a>
*/
package henplus;

import henplus.sqlmodel.Column;
import henplus.sqlmodel.ColumnFkInfo;
import henplus.sqlmodel.PrimaryKey;
import henplus.sqlmodel.Table;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

public final class SQLMetaDataBuilder {

    // column description
    public static final int TABLE_NAME = 3; // String
    public static final int COLUMN_NAME = 4; // String
    public static final int DATA_TYPE = 5; // int -> java.sql.Types
    public static final int TYPE_NAME = 6; // String
    public static final int COLUMN_SIZE = 7; // int
    public static final int NULLABLE = 11; // int:
    public static final int COLUMN_DEF = 13; // String
    public static final int ORDINAL_POSITION = 17; // int, starting at 1
    /*
     * columnNoNulls - might not allow NULL values columnNullable - definitely
     * allows NULL values columnNullableUnknown - nullability unknown
     */
    public static final int IS_NULLABLE = 17;

    // primary key description
    public static final int PK_DESC_COLUMN_NAME = 4;
    public static final int PK_DESC_KEY_SEQ = 5;
    public static final int PK_DESC_PK_NAME = 6;

    private static final String[] LIST_TABLES = { "TABLE" };
    private static final boolean VERBOSE = false;

    // foreign key description
    private static final int FK_PKTABLE_NAME = 3;
    private static final int FK_PKCOLUMN_NAME = 4;
    private static final int FK_FKCOLUMN_NAME = 8;
    private static final int FK_FK_NAME = 12;

    private boolean _interrupted;

    /*
     * (non-Javadoc)
     *
     * @see henplus.Interruptable#interrupt()
     */
    public void interrupt() {
        _interrupted = true;
    }

    public SQLMetaData getMetaData(final SQLSession session) {
        ResultSet rset = null;
        final List<String> tableList = new ArrayList<String>();
        try {
            final DatabaseMetaData meta = session.getConnection().getMetaData();
            rset = meta.getTables(null, null, null, LIST_TABLES);
            while (rset.next()) {
                tableList.add(rset.getString(3));
            }
        } catch (final Exception e) {
            // ignore.
        } finally {
            if (rset != null) {
                try {
                    rset.close();
                } catch (final Exception e) {
                }
            }
        }
        return getMetaData(session, tableList);
    }

    public SQLMetaData getMetaData(final SQLSession session, final Collection<String> tableNames) {
        return getMetaData(session, tableNames.iterator());
    }

    public SQLMetaData getMetaData(final SQLSession session, final Iterator<String> tableNamesIter) {
        final SQLMetaData result = new SQLMetaData();

        ResultSet rset = null;
        try {
            _interrupted = false;
            final String catalog = session.getConnection().getCatalog();

            if (_interrupted) {
                return null;
            }

            final DatabaseMetaData meta = session.getConnection().getMetaData();

            while (tableNamesIter.hasNext() && !_interrupted) {
                final String tableName = tableNamesIter.next();
                rset = meta.getColumns(catalog, null, tableName, null);
                final Table table = buildTable(catalog, meta, tableName, rset);
                result.addTable(table);
            }
        } catch (final Exception e) {
            if (VERBOSE) {
                e.printStackTrace();
            }
            HenPlus.msg().println("Database problem reading meta data: " + e.getMessage().trim());
        } finally {
            if (rset != null) {
                try {
                    rset.close();
                } catch (final Exception e) {
                }
            }
        }

        return result;
    }

    public Table getTable(final SQLSession session, final String tableName) {
        Table table = null;
        ResultSet rset = null;
        try {
            final String catalog = session.getConnection().getCatalog();
            final DatabaseMetaData meta = session.getConnection().getMetaData();
            rset = meta.getColumns(catalog, null, tableName, null);
            table = buildTable(catalog, meta, tableName, rset);
        } catch (final Exception e) {
            if (VERBOSE) {
                e.printStackTrace();
            }
            HenPlus.msg().println("Database problem reading meta data: " + e.getMessage().trim());
        } finally {
            if (rset != null) {
                try {
                    rset.close();
                } catch (final Exception e) {
                }
            }
        }
        return table;
    }

    private Table buildTable(final String catalog, final DatabaseMetaData meta, final String tableName, final ResultSet rset)
            throws SQLException {

        Table table = null;
        if (rset != null) {
            table = new Table(tableName);
            final PrimaryKey pk = getPrimaryKey(meta, tableName);
            final Map<String, ColumnFkInfo> fks = getForeignKeys(meta, tableName);
            // what about the following duplicate?
            // rset = meta.getColumns(catalog, null, tableName, null);
            while (!_interrupted && rset.next()) {
                final String colname = rset.getString(COLUMN_NAME);
                final Column column = new Column(colname);
                column.setType(rset.getString(TYPE_NAME));
                column.setSize(rset.getInt(COLUMN_SIZE));
                final boolean nullable = rset.getInt(NULLABLE) == DatabaseMetaData.columnNullable ? true : false;
                column.setNullable(nullable);
                final String defaultVal = rset.getString(COLUMN_DEF);
                column.setDefault(defaultVal != null ? defaultVal.trim() : null);
                column.setPosition(rset.getInt(ORDINAL_POSITION));
                column.setPkInfo(pk.getColumnPkInfo(colname));
                column.setFkInfo(fks.get(colname));

                table.addColumn(column);
            }
            rset.close();
        }
        return table;
    }

    private PrimaryKey getPrimaryKey(final DatabaseMetaData meta, final String tabName) throws SQLException {
        PrimaryKey result = null;
        final ResultSet rset = meta.getPrimaryKeys(null, null, tabName);
        if (rset != null) {
            result = new PrimaryKey();
            String pkname = null;
            while (rset.next()) {
                final String col = rset.getString(PK_DESC_COLUMN_NAME);
                pkname = rset.getString(PK_DESC_PK_NAME);
                final int pkseq = rset.getInt(PK_DESC_KEY_SEQ);
                result.addColumn(col, pkname, pkseq);
            }
            rset.close();
        }
        return result;
    }

    private Map<String,ColumnFkInfo> getForeignKeys(final DatabaseMetaData meta, final String tabName) throws SQLException {
        final Map<String,ColumnFkInfo> fks = new HashMap<String,ColumnFkInfo>();

        ResultSet rset = null;
        // some jdbc version 2 drivers (connector/j) have problems with foreign
        // keys...
        try {
            rset = meta.getImportedKeys(null, null, tabName);
        } catch (final NoSuchElementException e) {
            if (VERBOSE) {
                HenPlus.msg().println("Database problem reading meta data: " + e);
            }
        }

        if (rset != null) {
            while (rset.next()) {
                final ColumnFkInfo fk = new ColumnFkInfo(rset.getString(FK_FK_NAME), rset.getString(FK_PKTABLE_NAME),
                        rset.getString(FK_PKCOLUMN_NAME));
                final String col = rset.getString(FK_FKCOLUMN_NAME);
                fks.put(col, fk);
            }
            rset.close();
        }
        return fks;
    }

}
TOP

Related Classes of henplus.SQLMetaDataBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.