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);
}
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;
}
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);
}
}
}
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);
}
}
}
}
}
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);
}
Aggregations