/**
  * Create foreign keys from table.
  *
  * @param table
  * @uses schema
  * @throws SQLException
  */
 @Override
 protected void buildForeignKeys(final DatabaseTable table) throws SQLException {
   final ResultSet resultSet =
       dbmd.getImportedKeys(null, getSchemaSpacePattern(), table.getTitle());
   while (resultSet.next()) {
     final ForeignKey foreign = new ForeignKey(resultSet.getString(12));
     foreign.setColumn(resultSet.getString(8));
     foreign.setReferToTable(resultSet.getString(3));
     foreign.setReferToColumn(resultSet.getString(4));
     schema.addForeignKey(foreign);
   }
   resultSet.close();
 }
  /**
   * Create primary keys from table.
   *
   * @param table
   * @uses schema
   * @throws SQLException
   */
  @Override
  protected void buildPrimaryKeys(final DatabaseTable table) throws SQLException {
    PrimaryKey primary = null;

    final ResultSet resultSet =
        dbmd.getPrimaryKeys(null, getSchemaSpacePattern(), table.getTitle());
    while (resultSet.next()) {
      if (primary == null) {
        primary = new PrimaryKey(resultSet.getString(6));
      }
      primary.addColumn(resultSet.getString(4));
    }
    resultSet.close();

    if (primary != null) {
      schema.addPrimaryKey(primary);
    }
  }
  /**
   * Create unique keys keys from table.
   *
   * @param table
   * @uses schema
   * @throws SQLException
   */
  @Override
  protected void buildUniqueKeys(final DatabaseTable table) throws SQLException {

    final List<UniqueKey> uniqueKeys = new ArrayList<UniqueKey>();
    final List<Index> indices = new ArrayList<Index>();

    // For each result, create a key if 9th value (name) is present and not already exists.
    final ResultSet resultSet =
        dbmd.getIndexInfo(null, getSchemaSpacePattern(), table.getTitle(), false, false);
    while (resultSet.next()) {
      if (resultSet.getString(9) != null) {
        if (resultSet.getBoolean(4)) {
          Index index = new Index(resultSet.getString(6));
          if (indices.contains(index)) {
            index = indices.get(indices.indexOf(index));
          } else {
            indices.add(index);
          }
          index.addColumn(resultSet.getString(9));
        } else {
          UniqueKey uniqueKey = new UniqueKey(resultSet.getString(6));
          if (uniqueKeys.contains(uniqueKey)) {
            // If already in the list, get that key instead of the
            // one
            // above.
            uniqueKey = uniqueKeys.get(uniqueKeys.indexOf(uniqueKey));
          } else {
            uniqueKeys.add(uniqueKey);
          }
          uniqueKey.addColumn(resultSet.getString(9));
        }
      }
    }
    resultSet.close();

    // Add them all to the schema.
    for (final UniqueKey uniqueKey : uniqueKeys) {
      schema.addUniqueKey(uniqueKey);
    }
    for (final Index index : indices) {
      schema.addIndex(index);
    }
  }
  @Override
  protected void analyzeTriggers() throws SQLException {
    for (final DatabaseTrigger trigger : triggers) {
      firePropertyChange("analyzingTrigger", trigger.getTitle());

      // Create a new ddlschema object.
      final TriggerSchemaEditable schema = trigger.createTriggerSchemaEditableObject();

      // Get all trigger data.
      final String[] data = triggerData.get(trigger.getTitle());

      // 1 trigger_name, 2 trigger_type, 3 triggering_event, 4 table_owner, 5 base_object_type, 6
      // table_name, 7
      // column_name, 8 referencing_names, 9 when_clause, 10 status, 11 description, 12 action_type,
      // 13
      // trigger_body, 14 crossedition, 15 before_statement, 16 before_row, 17 after_row, 18
      // after_statement, 19
      // instead_of_row
      // 1 trigger_name, 2 event_manipulation, 3 definer, 4 event_object_table, 5 action_statement,
      // 6
      // action_timing

      schema.setName(trimStringOrNull(data[1 - 1]));
      schema.setType(trimStringOrNull(data[6 - 1]));
      schema.setEvents(Arrays.asList(trimStringOrNull(data[2 - 1]).split("(OR)")));
      schema.setTableOwner(trimStringOrNull(data[3 - 1]));
      // schema.setBaseObjectType(trimStringOrNull(data[5 - 1]));
      schema.setTableName(trimStringOrNull(data[4 - 1]));
      // schema.setColumnName(trimStringOrNull(data[7 - 1]));
      // schema.setReferencingNames(trimStringOrNull(data[8 - 1]));
      // schema.setWhenClause(trimStringOrNull(data[9 - 1]));
      schema.setEnabled(true);
      // schema.setDescription(trimStringOrNull(data[11 - 1]));
      // schema.setActionType(trimStringOrNull(data[12 - 1]));

      // MySQL deletes the ending semicolon of the trigger-body, so we added it again
      schema.setBody(trimStringOrNull(data[5 - 1]) + ";");

      // schema.setCrossEdition(!"NO".equalsIgnoreCase(trimStringOrNull(data[14 - 1])));
      // schema.setInsteadOfRow(!"NO".equalsIgnoreCase(trimStringOrNull(data[19 - 1])));

      // This columns are always "NO" and seem not containing the right information. As workaround,
      // we scan the
      // type column's content.
      // schema.setBeforeStatement(!"NO".equalsIgnoreCase(trimStringOrNull(data[15 - 1])));
      // schema.setBeforeRow(!"NO".equalsIgnoreCase(trimStringOrNull(data[16 - 1])));
      // schema.setAfterRow(!"NO".equalsIgnoreCase(trimStringOrNull(data[17 - 1])));
      // schema.setAfterStatement(!"NO".equalsIgnoreCase(trimStringOrNull(data[18 - 1])));
      // schema.setBeforeStatement(compareModeStrings(data[2 - 1], "BEFORE STATEMENT"));
      // schema.setBeforeRow(compareModeStrings(data[6 - 1], "BEFORE"));
      // schema.setAfterRow(compareModeStrings(data[6 - 1], "AFTER"));
      // schema.setAfterStatement(compareModeStrings(data[2 - 1], "AFTER STATEMENT"));
      // schema.setInsteadOfRow(compareModeStrings(data[2 - 1], "INSTEAD OF"));
      // Save the trigger schema.
      trigger.setTriggerSchemaObject(schema);

      // Add the trigger to the corresponding table. Otherwise ignore this trigger
      final DatabaseTable table = schema.getTable();
      if (table != null) {
        final DdlSchemaEditable ddlschema = table.createDdlSchemaEditableObject();
        ddlschema.addTrigger(schema.getName());
        table.setDdlSchemaObject(ddlschema);
      } else {
        trigger.getConnection().removeTrigger(trigger);
        triggers.remove(trigger);
      }
    }
  }