public void connectForeignKeys( Map<String, Table> tables, Database db, Properties properties, Pattern excludeIndirectColumns, Pattern excludeColumns) throws SQLException { ResultSet rs = null; try { rs = db.getMetaData().getImportedKeys(null, getSchema(), getName()); while (rs.next()) { addForeignKey( rs.getString("FK_NAME"), rs.getString("FKCOLUMN_NAME"), rs.getString("PKTABLE_SCHEM"), rs.getString("PKTABLE_NAME"), rs.getString("PKCOLUMN_NAME"), tables, db, properties, excludeIndirectColumns, excludeColumns); } } finally { if (rs != null) rs.close(); } // if we're one of multiples then also find all of the 'remote' tables in other // schemas that point to our primary keys (not necessary in the normal case // as we infer this from the opposite direction) if (getSchema() != null && Config.getInstance().isOneOfMultipleSchemas()) { try { rs = db.getMetaData().getExportedKeys(null, getSchema(), getName()); while (rs.next()) { String otherSchema = rs.getString("FKTABLE_SCHEM"); if (!getSchema().equals(otherSchema)) db.addRemoteTable( otherSchema, rs.getString("FKTABLE_NAME"), getSchema(), properties, excludeIndirectColumns, excludeColumns); } } finally { if (rs != null) rs.close(); } } }
/** * Initialize index information * * @throws SQLException */ private void initIndexes() throws SQLException { if (isView() || isRemote()) return; // first try to initialize using the index query spec'd in the .properties // do this first because some DB's (e.g. Oracle) do 'bad' things with getIndexInfo() // (they try to do a DDL analyze command that has some bad side-effects) if (initIndexes(properties.getProperty("selectIndexesSql"))) return; // couldn't, so try the old fashioned approach ResultSet rs = null; try { rs = db.getMetaData().getIndexInfo(null, getSchema(), getName(), false, true); while (rs.next()) { if (rs.getShort("TYPE") != DatabaseMetaData.tableIndexStatistic) addIndex(rs); } } catch (SQLException exc) { logger.warning( "Unable to extract index info for table '" + getName() + "' in schema '" + getSchema() + "': " + exc); } finally { if (rs != null) rs.close(); } }
/** * @param excludeIndirectColumns * @param excludeColumns * @throws SQLException */ private void initColumns(Pattern excludeIndirectColumns, Pattern excludeColumns) throws SQLException { ResultSet rs = null; synchronized (Table.class) { try { rs = db.getMetaData().getColumns(null, getSchema(), getName(), "%"); while (rs.next()) addColumn(rs, excludeIndirectColumns, excludeColumns); } catch (SQLException exc) { class ColumnInitializationFailure extends SQLException { private static final long serialVersionUID = 1L; public ColumnInitializationFailure(SQLException failure) { super( "Failed to collect column details for " + (isView() ? "view" : "table") + " '" + getName() + "' in schema '" + getSchema() + "'"); initCause(failure); } } throw new ColumnInitializationFailure(exc); } finally { if (rs != null) rs.close(); } } if (!isView() && !isRemote()) initColumnAutoUpdate(false); }
protected int fetchNumRows(String clause, boolean forceQuotes) throws SQLException { PreparedStatement stmt = null; ResultSet rs = null; StringBuilder sql = new StringBuilder("select "); sql.append(clause); sql.append(" from "); if (getSchema() != null) { sql.append(getSchema()); sql.append('.'); } if (forceQuotes) { String quote = db.getMetaData().getIdentifierQuoteString().trim(); sql.append(quote + getName() + quote); } else sql.append(db.getQuotedIdentifier(getName())); try { stmt = db.getConnection().prepareStatement(sql.toString()); rs = stmt.executeQuery(); while (rs.next()) { return rs.getInt(1); } return -1; } catch (SQLException exc) { if (forceQuotes) // we tried with and w/o quotes...fail this attempt throw exc; return fetchNumRows(clause, true); } finally { if (rs != null) rs.close(); if (stmt != null) stmt.close(); } }
/** * @param forceQuotes * @throws SQLException */ private void initColumnAutoUpdate(boolean forceQuotes) throws SQLException { ResultSet rs = null; PreparedStatement stmt = null; // we've got to get a result set with all the columns in it // so we can ask if the columns are auto updated // Ugh!!! Should have been in DatabaseMetaData instead!!! StringBuilder sql = new StringBuilder("select * from "); if (getSchema() != null) { sql.append(getSchema()); sql.append('.'); } if (forceQuotes) { String quote = db.getMetaData().getIdentifierQuoteString().trim(); sql.append(quote + getName() + quote); } else sql.append(db.getQuotedIdentifier(getName())); sql.append(" where 0 = 1"); try { stmt = db.getMetaData().getConnection().prepareStatement(sql.toString()); rs = stmt.executeQuery(); ResultSetMetaData rsMeta = rs.getMetaData(); for (int i = rsMeta.getColumnCount(); i > 0; --i) { TableColumn column = getColumn(rsMeta.getColumnName(i)); column.setIsAutoUpdated(rsMeta.isAutoIncrement(i)); } } catch (SQLException exc) { if (forceQuotes) { // don't completely choke just because we couldn't do this.... logger.warning("Failed to determine auto increment status: " + exc); logger.warning("SQL: " + sql.toString()); } else { initColumnAutoUpdate(true); } } finally { if (rs != null) rs.close(); if (stmt != null) stmt.close(); } }
public Table( Database db, String schema, String name, String comments, Properties properties, Pattern excludeIndirectColumns, Pattern excludeColumns) throws SQLException { this.schema = schema; this.name = name; setComments(comments); initColumns(db, excludeIndirectColumns, excludeColumns); initIndexes(db, properties); initPrimaryKeys(db.getMetaData(), properties); numRows = Config.getInstance().isNumRowsEnabled() ? fetchNumRows(db, properties) : -1; }
/** * Construct a table that knows everything about the database table's metadata * * @param db * @param schema * @param name * @param comments * @param properties * @param excludeIndirectColumns * @param excludeColumns * @throws SQLException */ public Table( Database db, String schema, String name, String comments, Properties properties, Pattern excludeIndirectColumns, Pattern excludeColumns) throws SQLException { this.schema = schema; this.name = name; this.db = db; this.properties = properties; logger.fine( "Creating " + getClass().getSimpleName().toLowerCase() + " " + schema == null ? name : (schema + '.' + name)); setComments(comments); initColumns(excludeIndirectColumns, excludeColumns); initIndexes(); initPrimaryKeys(db.getMetaData()); }