Search in sources :

Example 1 with ForeignKey

use of org.jumpmind.db.model.ForeignKey in project symmetric-ds by JumpMind.

the class AddForeignKeyChange method apply.

/**
     * {@inheritDoc}
     */
public void apply(Database database, boolean caseSensitive) {
    ForeignKey newFK = null;
    try {
        newFK = (ForeignKey) _newForeignKey.clone();
        newFK.setForeignTable(database.findTable(_newForeignKey.getForeignTableName(), caseSensitive));
    } catch (CloneNotSupportedException ex) {
        throw new DdlException(ex);
    }
    database.findTable(getChangedTable().getName()).addForeignKey(newFK);
}
Also used : DdlException(org.jumpmind.db.platform.DdlException) ForeignKey(org.jumpmind.db.model.ForeignKey)

Example 2 with ForeignKey

use of org.jumpmind.db.model.ForeignKey in project symmetric-ds by JumpMind.

the class AseDdlReader method readForeignKeys.

@Override
protected Collection<ForeignKey> readForeignKeys(Connection connection, DatabaseMetaDataWrapper metaData, String tableName) throws SQLException {
    // Sybase (or jConnect) does not return the foreign key names, thus we
    // have to
    // read the foreign keys manually from the system tables
    StringBuffer query = new StringBuffer();
    query.append("SELECT refobjs.name, localtables.id, remotetables.name, remotetables.id");
    for (int idx = 1; idx <= 16; idx++) {
        query.append(", refs.fokey");
        query.append(idx);
        query.append(", refs.refkey");
        query.append(idx);
    }
    query.append(" FROM dbo.sysreferences refs, dbo.sysobjects refobjs, dbo.sysobjects localtables, dbo.sysobjects remotetables");
    query.append(" WHERE refobjs.type = 'RI' AND refs.constrid = refobjs.id AND");
    query.append(" localtables.type = 'U' AND refs.tableid = localtables.id AND localtables.name = '");
    query.append(tableName);
    query.append("' AND remotetables.type = 'U' AND refs.reftabid = remotetables.id");
    Statement stmt = connection.createStatement();
    PreparedStatement prepStmt = connection.prepareStatement("SELECT name FROM dbo.syscolumns WHERE id = ? AND colid = ?");
    ArrayList<ForeignKey> result = new ArrayList<ForeignKey>();
    try {
        ResultSet fkRs = stmt.executeQuery(query.toString());
        while (fkRs.next()) {
            ForeignKey fk = new ForeignKey(fkRs.getString(1));
            int localTableId = fkRs.getInt(2);
            int remoteTableId = fkRs.getInt(4);
            fk.setForeignTableName(fkRs.getString(3));
            for (int idx = 0; idx < 16; idx++) {
                short fkColIdx = fkRs.getShort(5 + idx + idx);
                short pkColIdx = fkRs.getShort(6 + idx + idx);
                Reference ref = new Reference();
                if (fkColIdx == 0) {
                    break;
                }
                prepStmt.setInt(1, localTableId);
                prepStmt.setShort(2, fkColIdx);
                ResultSet colRs = prepStmt.executeQuery();
                if (colRs.next()) {
                    ref.setLocalColumnName(colRs.getString(1));
                }
                colRs.close();
                prepStmt.setInt(1, remoteTableId);
                prepStmt.setShort(2, pkColIdx);
                colRs = prepStmt.executeQuery();
                if (colRs.next()) {
                    ref.setForeignColumnName(colRs.getString(1));
                }
                colRs.close();
                fk.addReference(ref);
            }
            result.add(fk);
        }
        fkRs.close();
    } finally {
        stmt.close();
        prepStmt.close();
    }
    return result;
}
Also used : PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) Reference(org.jumpmind.db.model.Reference) ArrayList(java.util.ArrayList) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) ForeignKey(org.jumpmind.db.model.ForeignKey)

Example 3 with ForeignKey

use of org.jumpmind.db.model.ForeignKey in project symmetric-ds by JumpMind.

the class AbstractDdlBuilder method processTableStructureChanges.

/**
     * Processes the changes to the structure of tables.
     *
     * @param currentModel
     *            The current database schema
     * @param desiredModel
     *            The desired database schema
     * @param changes
     *            The change objects
     */
protected void processTableStructureChanges(Database currentModel, Database desiredModel, Collection<TableChange> changes, StringBuilder ddl) {
    filterChanges(changes);
    LinkedHashMap<String, List<TableChange>> changesPerTable = new LinkedHashMap<String, List<TableChange>>();
    LinkedHashMap<String, List<ForeignKey>> unchangedFKs = new LinkedHashMap<String, List<ForeignKey>>();
    boolean caseSensitive = delimitedIdentifierModeOn;
    // we use the names rather than the table objects
    for (Iterator<TableChange> changeIt = changes.iterator(); changeIt.hasNext(); ) {
        TableChange change = changeIt.next();
        String name = change.getChangedTable().getName();
        if (!caseSensitive) {
            name = name.toUpperCase();
        }
        List<TableChange> changesForTable = (List<TableChange>) changesPerTable.get(name);
        if (changesForTable == null) {
            changesForTable = new ArrayList<TableChange>();
            changesPerTable.put(name, changesForTable);
            unchangedFKs.put(name, getUnchangedForeignKeys(currentModel, desiredModel, name));
        }
        changesForTable.add(change);
    }
    // we also need to drop the foreign keys of the unchanged tables
    // referencing the changed tables
    addRelevantFKsFromUnchangedTables(currentModel, desiredModel, changesPerTable.keySet(), unchangedFKs);
    // we're dropping the unchanged foreign keys
    for (Iterator<Map.Entry<String, List<ForeignKey>>> tableFKIt = unchangedFKs.entrySet().iterator(); tableFKIt.hasNext(); ) {
        Map.Entry<String, List<ForeignKey>> entry = tableFKIt.next();
        Table targetTable = findTable(desiredModel, (String) entry.getKey());
        for (Iterator<ForeignKey> fkIt = entry.getValue().iterator(); fkIt.hasNext(); ) {
            writeExternalForeignKeyDropStmt(targetTable, fkIt.next(), ddl);
        }
    }
    // We're using a copy of the current model so that the table structure
    // changes can modify it
    Database copyOfCurrentModel = copy(currentModel);
    for (Iterator<Map.Entry<String, List<TableChange>>> tableChangeIt = changesPerTable.entrySet().iterator(); tableChangeIt.hasNext(); ) {
        Map.Entry<String, List<TableChange>> entry = tableChangeIt.next();
        processTableStructureChanges(copyOfCurrentModel, desiredModel, entry.getKey(), entry.getValue(), ddl);
    }
    // and finally we're re-creating the unchanged foreign keys
    for (Iterator<Map.Entry<String, List<ForeignKey>>> tableFKIt = unchangedFKs.entrySet().iterator(); tableFKIt.hasNext(); ) {
        Map.Entry<String, List<ForeignKey>> entry = tableFKIt.next();
        Table targetTable = findTable(desiredModel, (String) entry.getKey());
        for (Iterator<ForeignKey> fkIt = entry.getValue().iterator(); fkIt.hasNext(); ) {
            writeExternalForeignKeyCreateStmt(desiredModel, targetTable, fkIt.next(), ddl);
        }
    }
}
Also used : Table(org.jumpmind.db.model.Table) ForeignKey(org.jumpmind.db.model.ForeignKey) LinkedHashMap(java.util.LinkedHashMap) Database(org.jumpmind.db.model.Database) List(java.util.List) ArrayList(java.util.ArrayList) TypeMap(org.jumpmind.db.model.TypeMap) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) RemoveTableChange(org.jumpmind.db.alter.RemoveTableChange) TableChange(org.jumpmind.db.alter.TableChange) AddTableChange(org.jumpmind.db.alter.AddTableChange)

Example 4 with ForeignKey

use of org.jumpmind.db.model.ForeignKey in project symmetric-ds by JumpMind.

the class AbstractDdlBuilder method addRelevantFKsFromUnchangedTables.

/**
     * Adds the foreign keys of the unchanged tables that reference changed
     * tables to the given map.
     *
     * @param currentModel
     *            The current model
     * @param desiredModel
     *            The desired model
     * @param namesOfKnownChangedTables
     *            The known names of changed tables
     * @param fksPerTable
     *            The map table name -> foreign keys to which found foreign keys
     *            will be added to
     */
private void addRelevantFKsFromUnchangedTables(Database currentModel, Database desiredModel, Set<String> namesOfKnownChangedTables, Map<String, List<ForeignKey>> fksPerTable) {
    for (int tableIdx = 0; tableIdx < desiredModel.getTableCount(); tableIdx++) {
        Table targetTable = desiredModel.getTable(tableIdx);
        String name = targetTable.getName();
        Table sourceTable = findTable(currentModel, name);
        List<ForeignKey> relevantFks = null;
        if (!caseSensitive) {
            name = name.toUpperCase();
        }
        if ((sourceTable != null) && !namesOfKnownChangedTables.contains(name)) {
            for (int fkIdx = 0; fkIdx < targetTable.getForeignKeyCount(); fkIdx++) {
                ForeignKey targetFk = targetTable.getForeignKey(fkIdx);
                ForeignKey sourceFk = sourceTable.findForeignKey(targetFk, caseSensitive);
                String refName = targetFk.getForeignTableName();
                if (!caseSensitive) {
                    refName = refName.toUpperCase();
                }
                if ((sourceFk != null) && namesOfKnownChangedTables.contains(refName)) {
                    if (relevantFks == null) {
                        relevantFks = new ArrayList<ForeignKey>();
                        fksPerTable.put(name, relevantFks);
                    }
                    relevantFks.add(targetFk);
                }
            }
        }
    }
}
Also used : Table(org.jumpmind.db.model.Table) ForeignKey(org.jumpmind.db.model.ForeignKey)

Example 5 with ForeignKey

use of org.jumpmind.db.model.ForeignKey in project symmetric-ds by JumpMind.

the class AbstractDdlBuilder method dropTable.

/**
     * Outputs the DDL required to drop the given table. This method also drops
     * foreign keys to the table.
     */
public void dropTable(Database database, Table table, StringBuilder ddl) {
    // we're dropping the foreignkeys to the table first
    for (int idx = database.getTableCount() - 1; idx >= 0; idx--) {
        Table otherTable = database.getTable(idx);
        ForeignKey[] fks = otherTable.getForeignKeys();
        for (int fkIdx = 0; (fks != null) && (fkIdx < fks.length); fkIdx++) {
            if (fks[fkIdx].getForeignTable().equals(table)) {
                writeExternalForeignKeyDropStmt(otherTable, fks[fkIdx], ddl);
            }
        }
    }
    // and the foreign keys from the table
    dropExternalForeignKeys(table, ddl);
    writeTableComment(table, ddl);
    dropTable(table, ddl, false, false);
}
Also used : Table(org.jumpmind.db.model.Table) ForeignKey(org.jumpmind.db.model.ForeignKey)

Aggregations

ForeignKey (org.jumpmind.db.model.ForeignKey)24 Reference (org.jumpmind.db.model.Reference)13 Table (org.jumpmind.db.model.Table)12 ArrayList (java.util.ArrayList)9 Column (org.jumpmind.db.model.Column)8 IIndex (org.jumpmind.db.model.IIndex)6 ResultSet (java.sql.ResultSet)4 HashMap (java.util.HashMap)4 IndexColumn (org.jumpmind.db.model.IndexColumn)4 LinkedHashMap (java.util.LinkedHashMap)3 IOException (java.io.IOException)2 HashSet (java.util.HashSet)2 List (java.util.List)2 TableChange (org.jumpmind.db.alter.TableChange)2 Database (org.jumpmind.db.model.Database)2 PlatformColumn (org.jumpmind.db.model.PlatformColumn)2 Row (org.jumpmind.db.sql.Row)2 IoException (org.jumpmind.exception.IoException)2 File (java.io.File)1 FileWriter (java.io.FileWriter)1