protected void initKeys(ConnectionProvider cp, int id, String tbl) {
    // id == 1 ... capture PK only
    // id == 2 ... capture FKs only
    // id == 3 ... capture FKs (and PKs), but don't expect that all related tables are provided. In
    // other words,
    // tries to initializes all FKs, but doesn't fail if some table is missing.

    if (cp != null)
      try {
        String shortTableName;
        if (tbl == null) shortTableName = getName().getName();
        else shortTableName = tbl;

        boolean relatedTablesProvided = id != 3;
        if (id != 1) initFKs(cp, shortTableName, relatedTablesProvided);
        if (id != 2) initPK(cp, shortTableName);
      } catch (Exception exc) {
        if (Boolean.getBoolean("netbeans.debug.exceptions")) // NOI18N
        exc.printStackTrace();
      }
  }
  protected void initIndexes(ConnectionProvider cp, String tbl) {
    if (cp != null)
      try {
        boolean unique;
        DatabaseMetaData dmd = cp.getDatabaseMetaData();
        String shortTableName;
        if (tbl == null) shortTableName = getName().getName();
        else shortTableName = tbl;

        ResultSet rs;
        //                    rs = dmd.getIndexInfo(cp.getConnection().getCatalog(),
        // dmd.getUserName().trim(), shortTableName, false, true);
        rs =
            dmd.getIndexInfo(
                cp.getConnection().getCatalog(), cp.getSchema(), shortTableName, false, true);

        String name, columnName;
        boolean unq;
        LinkedList idxs = new LinkedList();
        if (rs != null) {
          HashMap rset = new HashMap();
          String uniqueStr;
          while (rs.next()) {
            name = rs.getString("INDEX_NAME"); // NOI18N
            columnName = rs.getString("COLUMN_NAME"); // NOI18N
            if (columnName != null) columnName = columnName.trim();
            unq = rs.getBoolean("NON_UNIQUE"); // NOI18N
            // hack for PostgreSQL bug 3480: the driver returns quotes around quoted column names
            if (columnName != null
                && columnName.length() >= 2
                && columnName.startsWith("\"")
                && columnName.endsWith("\"")) { // NOI18N
              columnName = columnName.substring(1, columnName.length() - 1);
            }

            if (name == null) continue;
            else name = name.trim();

            if (unq) idxs.add(name + "." + columnName + ".false"); // NOI18N
            else idxs.add(name + "." + columnName + ".true"); // NOI18N
          }
          rs.close();
        }

        String info;
        int start, end;
        for (int i = 0; i < idxs.size(); i++) {
          info = idxs.get(i).toString();
          start = info.indexOf('.'); // NOI18N
          end = info.lastIndexOf('.'); // NOI18N
          name = info.substring(0, start);
          if ((info.substring(end + 1)).equals("true")) // NOI18N
          unique = true;
          else unique = false;

          if (indexes.find(DBIdentifier.create(name)) != null) continue;

          IndexElementImpl iei = new IndexElementImpl(this, name, unique);
          IndexElement[] ie = {new IndexElement(iei, (TableElement) element)};
          iei.initColumns(idxs);
          changeIndexes(ie, DBElement.Impl.ADD);
        }
      } catch (Exception exc) {
        if (Boolean.getBoolean("netbeans.debug.exceptions")) // NOI18N
        exc.printStackTrace();
      }
  }
  protected void initColumns(ConnectionProvider cp) {
    if (cp != null)
      try {
        DatabaseMetaData dmd = cp.getDatabaseMetaData();
        String shortTableName = getName().getName();

        ResultSet rs;
        //                 rs = dmd.getColumns(cp.getConnection().getCatalog(),
        // dmd.getUserName().trim(), shortTableName, "%");
        rs = dmd.getColumns(cp.getConnection().getCatalog(), cp.getSchema(), shortTableName, "%");

        int sqlType;
        String sqlTypeName;
        String colName, colNull, colSize, colDec;
        if (rs != null) {
          HashMap rset = new HashMap();
          while (rs.next()) {
            sqlType = rs.getInt("DATA_TYPE"); // NOI18N
            sqlTypeName = rs.getString("TYPE_NAME").trim(); // NOI18N
            colName = rs.getString("COLUMN_NAME").trim(); // NOI18N
            colNull = Integer.toString(rs.getInt("NULLABLE")); // NOI18N
            colSize = rs.getString("COLUMN_SIZE"); // NOI18N
            colDec = rs.getString("DECIMAL_DIGITS"); // NOI18N

            String dbProductName = dmd.getDatabaseProductName().trim();
            // Oracle driver hacks
            if (dbProductName.indexOf("Oracle") != -1) { // NOI18N
              if (sqlType == 11 || ((sqlType == 1111) && sqlTypeName.startsWith("TIMESTAMP")))
                sqlType = Types.TIMESTAMP;
              if ((sqlType == 1111) && sqlTypeName.equals("FLOAT")) // NOI18N
              sqlType = Types.DOUBLE;
              if ((sqlType == 1111) && sqlTypeName.equals("BLOB")) // NOI18N
              sqlType = Types.BLOB;
              if ((sqlType == 1111) && sqlTypeName.equals("CLOB")) // NOI18N
              sqlType = Types.CLOB;
              if ((sqlType == 1111) && sqlTypeName.equals("NVARCHAR2")) // NOI18N
              sqlType = Types.CHAR;
            }
            // MySQL driver hacks
            if (dbProductName.indexOf("MySQL") != -1) { // NOI18N
              if ((sqlType == 1111) && sqlTypeName.equalsIgnoreCase("BIT")) // NOI18N
              sqlType = Types.BIT;
            }

            // workaround for i-net Oranxo driver
            // value in int range is expected by JDBC API but 4294967296 is returned
            try {
              new Integer(colSize);
            } catch (NumberFormatException exc) {
              colSize = Integer.toString(Integer.MAX_VALUE);
            }

            ColumnElementImpl cei =
                new ColumnElementImpl(colName, Integer.toString(sqlType), colNull, colSize, colDec);
            ColumnElement ce = new ColumnElement(cei, (TableElement) element);
            ColumnElement[] c = {ce};
            changeColumns(c, DBElement.Impl.ADD);
          }
          rs.close();
        }
      } catch (Exception exc) {
        if (Boolean.getBoolean("netbeans.debug.exceptions")) // NOI18N
        exc.printStackTrace();
      }
  }