List changes) throws IOException
{
// First we drop primary keys as necessary
for (Iterator changeIt = changes.iterator(); changeIt.hasNext();)
{
TableChange change = (TableChange)changeIt.next();
if (change instanceof RemovePrimaryKeyChange)
{
processChange(currentModel, desiredModel, (RemovePrimaryKeyChange)change);
changeIt.remove();
}
else if (change instanceof PrimaryKeyChange)
{
PrimaryKeyChange pkChange = (PrimaryKeyChange)change;
RemovePrimaryKeyChange removePkChange = new RemovePrimaryKeyChange(pkChange.getChangedTable(),
pkChange.getOldPrimaryKeyColumns());
processChange(currentModel, desiredModel, removePkChange);
}
}
HashMap columnChanges = new HashMap();
// Next we add/remove columns
for (Iterator changeIt = changes.iterator(); changeIt.hasNext();)
{
TableChange change = (TableChange)changeIt.next();
if (change instanceof AddColumnChange)
{
AddColumnChange addColumnChange = (AddColumnChange)change;
// Sybase can only add not insert columns
if (addColumnChange.isAtEnd())
{
processChange(currentModel, desiredModel, addColumnChange);
changeIt.remove();
}
}
else if (change instanceof RemoveColumnChange)
{
processChange(currentModel, desiredModel, (RemoveColumnChange)change);
changeIt.remove();
}
else if (change instanceof ColumnAutoIncrementChange)
{
// Sybase has no way of adding or removing an IDENTITY constraint
// Thus we have to rebuild the table anyway and can ignore all the other
// column changes
columnChanges = null;
}
else if ((change instanceof ColumnChange) && (columnChanges != null))
{
// we gather all changed columns because we can use the ALTER TABLE ALTER COLUMN
// statement for them
ColumnChange columnChange = (ColumnChange)change;
ArrayList changesPerColumn = (ArrayList)columnChanges.get(columnChange.getChangedColumn());
if (changesPerColumn == null)
{
changesPerColumn = new ArrayList();
columnChanges.put(columnChange.getChangedColumn(), changesPerColumn);
}
changesPerColumn.add(change);
}
}
if (columnChanges != null)
{
for (Iterator changesPerColumnIt = columnChanges.entrySet().iterator(); changesPerColumnIt.hasNext();)
{
Map.Entry entry = (Map.Entry)changesPerColumnIt.next();
Column sourceColumn = (Column)entry.getKey();
ArrayList changesPerColumn = (ArrayList)entry.getValue();
// Sybase does not like us to use the ALTER TABLE ALTER statement if we don't actually
// change the datatype or the required constraint but only the default value
// Thus, if we only have to change the default, we use a different handler
if ((changesPerColumn.size() == 1) && (changesPerColumn.get(0) instanceof ColumnDefaultValueChange))
{
processChange(currentModel,
desiredModel,
(ColumnDefaultValueChange)changesPerColumn.get(0));
}
else
{
Column targetColumn = targetTable.findColumn(sourceColumn.getName(),
getPlatform().isDelimitedIdentifierModeOn());
processColumnChange(sourceTable, targetTable, sourceColumn, targetColumn);
}
for (Iterator changeIt = changesPerColumn.iterator(); changeIt.hasNext();)
{
((ColumnChange)changeIt.next()).apply(currentModel, getPlatform().isDelimitedIdentifierModeOn());
}
}
}
// Finally we add primary keys
for (Iterator changeIt = changes.iterator(); changeIt.hasNext();)
{
TableChange change = (TableChange)changeIt.next();
if (change instanceof AddPrimaryKeyChange)
{
processChange(currentModel, desiredModel, (AddPrimaryKeyChange)change);
changeIt.remove();