Database desiredModel,
String tableName,
Map parameters,
List changes) throws IOException
{
Table sourceTable = currentModel.findTable(tableName, getPlatform().isDelimitedIdentifierModeOn());
Table targetTable = desiredModel.findTable(tableName, getPlatform().isDelimitedIdentifierModeOn());
// we're enforcing a full rebuild in case of the addition of a required
// column without a default value that is not autoincrement
boolean requiresFullRebuild = false;
for (Iterator changeIt = changes.iterator(); !requiresFullRebuild && changeIt.hasNext();)
{
TableChange change = (TableChange)changeIt.next();
if (change instanceof AddColumnChange)
{
AddColumnChange addColumnChange = (AddColumnChange)change;
if (addColumnChange.getNewColumn().isRequired() &&
(addColumnChange.getNewColumn().getDefaultValue() == null) &&
!addColumnChange.getNewColumn().isAutoIncrement())
{
requiresFullRebuild = true;
}
}
}
if (!requiresFullRebuild)
{
processTableStructureChanges(currentModel, desiredModel, sourceTable, targetTable, parameters, changes);
}
if (!changes.isEmpty())
{
// we can only copy the data if no required columns without default value and
// non-autoincrement have been added
boolean canMigrateData = true;
for (Iterator it = changes.iterator(); canMigrateData && it.hasNext();)
{
TableChange change = (TableChange)it.next();
if (change instanceof AddColumnChange)
{
AddColumnChange addColumnChange = (AddColumnChange)change;
if (addColumnChange.getNewColumn().isRequired() &&
!addColumnChange.getNewColumn().isAutoIncrement() &&
(addColumnChange.getNewColumn().getDefaultValue() == null))
{
_log.warn("Data cannot be retained in table " + change.getChangedTable().getName() +
" because of the addition of the required column " + addColumnChange.getNewColumn().getName());
canMigrateData = false;
}
}
}
Table realTargetTable = getRealTargetTableFor(desiredModel, sourceTable, targetTable);
if (canMigrateData)
{
Table tempTable = getTemporaryTableFor(desiredModel, targetTable);
createTemporaryTable(desiredModel, tempTable, parameters);
writeCopyDataStatement(sourceTable, tempTable);
// Note that we don't drop the indices here because the DROP TABLE will take care of that
// Likewise, foreign keys have already been dropped as necessary