Example #1
0
  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();
    }
  }
Example #6
0
 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());
 }