You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ddlutils-dev@db.apache.org by to...@apache.org on 2007/12/10 09:21:39 UTC

svn commit: r602807 [7/15] - in /db/ddlutils/trunk: ./ src/java/org/apache/ddlutils/ src/java/org/apache/ddlutils/alteration/ src/java/org/apache/ddlutils/model/ src/java/org/apache/ddlutils/platform/ src/java/org/apache/ddlutils/platform/axion/ src/ja...

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/sybase/SybaseBuilder.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/sybase/SybaseBuilder.java?rev=602807&r1=602806&r2=602807&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/sybase/SybaseBuilder.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/sybase/SybaseBuilder.java Mon Dec 10 00:20:47 2007
@@ -21,30 +21,18 @@
 
 import java.io.IOException;
 import java.sql.Types;
-import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
 
 import org.apache.ddlutils.Platform;
-import org.apache.ddlutils.alteration.AddColumnChange;
-import org.apache.ddlutils.alteration.AddPrimaryKeyChange;
-import org.apache.ddlutils.alteration.ColumnAutoIncrementChange;
-import org.apache.ddlutils.alteration.ColumnChange;
-import org.apache.ddlutils.alteration.ColumnDefaultValueChange;
-import org.apache.ddlutils.alteration.PrimaryKeyChange;
-import org.apache.ddlutils.alteration.RemoveColumnChange;
-import org.apache.ddlutils.alteration.RemovePrimaryKeyChange;
-import org.apache.ddlutils.alteration.TableChange;
 import org.apache.ddlutils.model.Column;
 import org.apache.ddlutils.model.Database;
 import org.apache.ddlutils.model.ForeignKey;
 import org.apache.ddlutils.model.Index;
 import org.apache.ddlutils.model.Table;
-import org.apache.ddlutils.platform.CreationParameters;
 import org.apache.ddlutils.platform.SqlBuilder;
 import org.apache.ddlutils.util.Jdbc3Utils;
+import org.apache.ddlutils.util.StringUtils;
 
 /**
  * The SQL Builder for Sybase.
@@ -69,7 +57,7 @@
      */
     public void createTable(Database database, Table table, Map parameters) throws IOException
     {
-        writeQuotationOnStatement();
+        turnOnQuotation();
         super.createTable(database, table, parameters);
     }
 
@@ -196,7 +184,7 @@
      */
     public void dropTable(Table table) throws IOException
     {
-        writeQuotationOnStatement();
+        turnOnQuotation();
         print("IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = ");
         printAlwaysSingleQuotedIdentifier(getTableName(table));
         println(")");
@@ -211,7 +199,7 @@
     /**
      * {@inheritDoc}
      */
-    protected void writeExternalForeignKeyDropStmt(Table table, ForeignKey foreignKey) throws IOException
+    public void dropForeignKey(Table table, ForeignKey foreignKey) throws IOException
     {
         String constraintName = getForeignKeyName(table, foreignKey);
 
@@ -229,7 +217,7 @@
     /**
      * {@inheritDoc}
      */
-    public void writeExternalIndexDropStmt(Table table, Index index) throws IOException
+    public void dropIndex(Table table, Index index) throws IOException
     {
         print("DROP INDEX ");
         printIdentifier(getTableName(table));
@@ -241,10 +229,10 @@
     /**
      * {@inheritDoc}
      */
-    public void dropExternalForeignKeys(Table table) throws IOException
+    public void dropForeignKeys(Table table) throws IOException
     {
-        writeQuotationOnStatement();
-        super.dropExternalForeignKeys(table);
+        turnOnQuotation();
+        super.dropForeignKeys(table);
     }
 
     /**
@@ -309,9 +297,36 @@
     /**
      * Writes the statement that turns on the ability to write delimited identifiers.
      */
-    private void writeQuotationOnStatement() throws IOException
+    public void turnOnQuotation() throws IOException
     {
-        print(getQuotationOnStatement());
+        String quotationStmt = getQuotationOnStatement();
+
+        if (!StringUtils.isEmpty(quotationStmt))
+        {
+            print(quotationStmt);
+            printEndOfStatement();
+        }
+    }
+
+    /**
+     * Writes the statement that turns on identity override mode.
+     * 
+     * @param table The table to enable the mode for
+     */
+    public void turnOnIdentityOverride(Table table) throws IOException
+    {
+        print(getEnableIdentityOverrideSql(table));
+        printEndOfStatement();
+    }
+
+    /**
+     * Writes the statement that turns off identity override mode.
+     * 
+     * @param table The table to disable the mode for
+     */
+    public void turnOffIdentityOverride(Table table) throws IOException
+    {
+        print(getDisableIdentityOverrideSql(table));
         printEndOfStatement();
     }
 
@@ -331,23 +346,30 @@
     /**
      * {@inheritDoc}
      */
-    protected void writeCopyDataStatement(Table sourceTable, Table targetTable) throws IOException
+    protected void copyData(Table sourceTable, Table targetTable) throws IOException
     {
-        boolean hasIdentity = targetTable.getAutoIncrementColumns().length > 0;
+        // We need to turn on identity override except when the identity column was added to the column
+        Column[] targetAutoIncrCols   = targetTable.getAutoIncrementColumns();
+        boolean  needIdentityOverride = false;
 
-        if (hasIdentity)
+        if (targetAutoIncrCols.length > 0)
         {
-            print("SET IDENTITY_INSERT ");
-            printIdentifier(getTableName(targetTable));
-            print(" ON");
+            needIdentityOverride = true;
+            // Sybase only allows for one identity column per table
+            if (sourceTable.findColumn(targetAutoIncrCols[0].getName(), getPlatform().isDelimitedIdentifierModeOn()) == null)
+            {
+                needIdentityOverride = false;
+            }
+        }
+        if (needIdentityOverride)
+        {
+            print(getEnableIdentityOverrideSql(targetTable));
             printEndOfStatement();
         }
-        super.writeCopyDataStatement(sourceTable, targetTable);
-        if (hasIdentity)
+        super.copyData(sourceTable, targetTable);
+        if (needIdentityOverride)
         {
-            print("SET IDENTITY_INSERT ");
-            printIdentifier(getTableName(targetTable));
-            print(" OFF");
+            print(getDisableIdentityOverrideSql(targetTable));
             printEndOfStatement();
         }
     }
@@ -377,198 +399,42 @@
     /**
      * {@inheritDoc}
      */
-    protected void processChanges(Database currentModel, Database desiredModel, List changes, CreationParameters params) throws IOException
-    {
-        if (!changes.isEmpty())
-        {
-            writeQuotationOnStatement();
-        }
-        super.processChanges(currentModel, desiredModel, changes, params);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    protected void processTableStructureChanges(Database currentModel,
-                                                Database desiredModel,
-                                                Table    sourceTable,
-                                                Table    targetTable,
-                                                Map      parameters,
-                                                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();
-            }
-            else if (change instanceof PrimaryKeyChange)
-            {
-                PrimaryKeyChange    pkChange    = (PrimaryKeyChange)change;
-                AddPrimaryKeyChange addPkChange = new AddPrimaryKeyChange(pkChange.getChangedTable(),
-                                                                          pkChange.getNewPrimaryKeyColumns());
-
-                processChange(currentModel, desiredModel, addPkChange);
-                changeIt.remove();
-            }
-        }
-    }
-
-
-    /**
-     * Processes the addition of a column to a table.
-     * 
-     * @param currentModel The current database schema
-     * @param desiredModel The desired database schema
-     * @param change       The change object
-     */
-    protected void processChange(Database        currentModel,
-                                 Database        desiredModel,
-                                 AddColumnChange change) throws IOException
+    public void addColumn(Table table, Column newColumn) throws IOException
     {
         print("ALTER TABLE ");
-        printlnIdentifier(getTableName(change.getChangedTable()));
+        printlnIdentifier(getTableName(table));
         printIndent();
         print("ADD ");
-        writeColumn(change.getChangedTable(), change.getNewColumn());
+        writeColumn(table, newColumn);
         printEndOfStatement();
-        change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn());
     }
 
     /**
-     * Processes the removal of a column from a table.
+     * Writes the SQL to drop a column.
      * 
-     * @param currentModel The current database schema
-     * @param desiredModel The desired database schema
-     * @param change       The change object
+     * @param table  The table
+     * @param column The column to drop
      */
-    protected void processChange(Database           currentModel,
-                                 Database           desiredModel,
-                                 RemoveColumnChange change) throws IOException
+    public void dropColumn(Table table, Column column) throws IOException
     {
         print("ALTER TABLE ");
-        printlnIdentifier(getTableName(change.getChangedTable()));
+        printlnIdentifier(getTableName(table));
         printIndent();
         print("DROP ");
-        printIdentifier(getColumnName(change.getChangedColumn()));
+        printIdentifier(getColumnName(column));
         printEndOfStatement();
-        change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn());
     }
 
     /**
-     * Processes the removal of a primary key from a table.
+     * Writes the SQL to drop the primary key of the given table.
      * 
-     * @param currentModel The current database schema
-     * @param desiredModel The desired database schema
-     * @param change       The change object
+     * @param table The table
      */
-    protected void processChange(Database               currentModel,
-                                 Database               desiredModel,
-                                 RemovePrimaryKeyChange change) throws IOException
+    public void dropPrimaryKey(Table table) throws IOException
     {
-        // TODO: this would be easier when named primary keys are supported
-        //       because then we can use ALTER TABLE DROP
-        String tableName         = getTableName(change.getChangedTable());
+        // this would be easier when named primary keys are supported
+        // because then we can use ALTER TABLE DROP
+        String tableName         = getTableName(table);
         String tableNameVar      = "tn" + createUniqueIdentifier();
         String constraintNameVar = "cn" + createUniqueIdentifier();
 
@@ -589,96 +455,87 @@
         println("  END");
         print("END");
         printEndOfStatement();
-        change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn());
     }
 
     /**
-     * Processes the change of the default value of a column. Note that this method is only
-     * used if it is the only change to that column.
+     * Writes the SQL to set the default value of the given column.
      * 
-     * @param currentModel The current database schema
-     * @param desiredModel The desired database schema
-     * @param change       The change object
+     * @param table           The table
+     * @param column          The column to change
+     * @param newDefaultValue The new default value
      */
-    protected void processChange(Database                 currentModel,
-                                 Database                 desiredModel,
-                                 ColumnDefaultValueChange change) throws IOException
+    public void changeColumnDefaultValue(Table table, Column column, String newDefaultValue) throws IOException
     {
         print("ALTER TABLE ");
-        printlnIdentifier(getTableName(change.getChangedTable()));
+        printlnIdentifier(getTableName(table));
         printIndent();
         print("REPLACE ");
-        printIdentifier(getColumnName(change.getChangedColumn()));
-
-        Table  curTable  = currentModel.findTable(change.getChangedTable().getName(), getPlatform().isDelimitedIdentifierModeOn());
-        Column curColumn = curTable.findColumn(change.getChangedColumn().getName(), getPlatform().isDelimitedIdentifierModeOn());
-
+        printIdentifier(getColumnName(column));
         print(" DEFAULT ");
-        if (isValidDefaultValue(change.getNewDefaultValue(), curColumn.getTypeCode()))
+        if (isValidDefaultValue(newDefaultValue, column.getTypeCode()))
         {
-            printDefaultValue(change.getNewDefaultValue(), curColumn.getTypeCode());
+            printDefaultValue(newDefaultValue, column.getTypeCode());
         }
         else
         {
             print("NULL");
         }
         printEndOfStatement();
-        change.apply(currentModel, getPlatform().isDelimitedIdentifierModeOn());
     }
 
     /**
-     * Processes a change to a column.
+     * Writes the SQL to change the given column.
      * 
-     * @param sourceTable  The current table
-     * @param targetTable  The desired table
-     * @param sourceColumn The current column
-     * @param targetColumn The desired column
-     */
-    protected void processColumnChange(Table  sourceTable,
-                                       Table  targetTable,
-                                       Column sourceColumn,
-                                       Column targetColumn) throws IOException
-    {
-        Object oldParsedDefault = sourceColumn.getParsedDefaultValue();
-        Object newParsedDefault = targetColumn.getParsedDefaultValue();
-        String newDefault       = targetColumn.getDefaultValue();
+     * @param table     The table
+     * @param column    The column to change
+     * @param newColumn The new column definition
+     */
+    public void changeColumn(Table table, Column column, Column newColumn) throws IOException
+    {
+        Object oldParsedDefault = column.getParsedDefaultValue();
+        Object newParsedDefault = newColumn.getParsedDefaultValue();
+        String newDefault       = newColumn.getDefaultValue();
         boolean defaultChanges  = ((oldParsedDefault == null) && (newParsedDefault != null)) ||
                                   ((oldParsedDefault != null) && !oldParsedDefault.equals(newParsedDefault));
 
         // Sybase does not like it if there is a default spec in the ALTER TABLE ALTER
         // statement; thus we have to change the default afterwards
-        if (newDefault != null)
-        {
-            targetColumn.setDefaultValue(null);
-        }
         if (defaultChanges)
         {
             // we're first removing the default as it might make problems when the
             // datatype changes
             print("ALTER TABLE ");
-            printlnIdentifier(getTableName(sourceTable));
+            printlnIdentifier(getTableName(table));
             printIndent();
             print("REPLACE ");
-            printIdentifier(getColumnName(sourceColumn));
+            printIdentifier(getColumnName(column));
             print(" DEFAULT NULL");
             printEndOfStatement();
         }
         print("ALTER TABLE ");
-        printlnIdentifier(getTableName(sourceTable));
+        printlnIdentifier(getTableName(table));
         printIndent();
         print("MODIFY ");
-        writeColumn(sourceTable, targetColumn);
+        if (newDefault != null)
+        {
+            newColumn.setDefaultValue(null);
+        }
+        writeColumn(table, newColumn);
+        if (newDefault != null)
+        {
+            newColumn.setDefaultValue(newDefault);
+        }
         printEndOfStatement();
         if (defaultChanges)
         {
             print("ALTER TABLE ");
-            printlnIdentifier(getTableName(sourceTable));
+            printlnIdentifier(getTableName(table));
             printIndent();
             print("REPLACE ");
-            printIdentifier(getColumnName(sourceColumn));
+            printIdentifier(getColumnName(column));
             if (newDefault != null)
             {
-                writeColumnDefaultValueStmt(sourceTable, targetColumn);
+                writeColumnDefaultValueStmt(table, newColumn);
             }
             else
             {

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/sybase/SybasePlatform.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/sybase/SybasePlatform.java?rev=602807&r1=602806&r2=602807&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/sybase/SybasePlatform.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/sybase/SybasePlatform.java Mon Dec 10 00:20:47 2007
@@ -32,11 +32,24 @@
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.ddlutils.DatabaseOperationException;
+import org.apache.ddlutils.DdlUtilsException;
 import org.apache.ddlutils.PlatformInfo;
+import org.apache.ddlutils.alteration.AddColumnChange;
+import org.apache.ddlutils.alteration.AddPrimaryKeyChange;
+import org.apache.ddlutils.alteration.ColumnDefinitionChange;
+import org.apache.ddlutils.alteration.ModelComparator;
+import org.apache.ddlutils.alteration.RemoveColumnChange;
+import org.apache.ddlutils.alteration.RemovePrimaryKeyChange;
+import org.apache.ddlutils.alteration.TableChange;
+import org.apache.ddlutils.alteration.TableDefinitionChangesPredicate;
+import org.apache.ddlutils.model.Column;
 import org.apache.ddlutils.model.Database;
 import org.apache.ddlutils.model.Table;
 import org.apache.ddlutils.model.TypeMap;
+import org.apache.ddlutils.platform.CreationParameters;
+import org.apache.ddlutils.platform.DefaultTableDefinitionChangesPredicate;
 import org.apache.ddlutils.platform.PlatformImplBase;
 
 /**
@@ -67,6 +80,7 @@
 
         info.setMaxIdentifierLength(28);
         info.setNullAsDefaultValueRequired(true);
+        info.setIdentityColumnAutomaticallyRequired(true);
         info.setCommentPrefix("/*");
         info.setCommentSuffix("*/");
 
@@ -331,5 +345,142 @@
     protected void afterUpdate(Connection connection, Table table) throws SQLException
     {
         afterInsert(connection, table);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected ModelComparator getModelComparator()
+    {
+        ModelComparator comparator = super.getModelComparator();
+
+        comparator.setGeneratePrimaryKeyChanges(false);
+        comparator.setCanDropPrimaryKeyColumns(false);
+        return comparator;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected TableDefinitionChangesPredicate getTableDefinitionChangesPredicate()
+    {
+        return new DefaultTableDefinitionChangesPredicate()
+        {
+            protected boolean isSupported(Table intermediateTable, TableChange change)
+            {
+                if ((change instanceof RemoveColumnChange) ||
+                    (change instanceof AddPrimaryKeyChange) ||
+                    (change instanceof RemovePrimaryKeyChange))
+                {
+                    return true;
+                }
+                else if (change instanceof AddColumnChange)
+                {
+                    AddColumnChange addColumnChange = (AddColumnChange)change;
+
+                    // Sybase can only add not insert columns, and they cannot be IDENTITY columns
+                    // We also have to force recreation of the table if a required column is added
+                    // that is neither IDENTITY nor has a default value
+                    return (addColumnChange.getNextColumn() == null) &&
+                           !addColumnChange.getNewColumn().isAutoIncrement() &&
+                           (!addColumnChange.getNewColumn().isRequired() || !StringUtils.isEmpty(addColumnChange.getNewColumn().getDefaultValue()));
+                }
+                else if (change instanceof ColumnDefinitionChange)
+                {
+                    ColumnDefinitionChange columnChange = (ColumnDefinitionChange)change;
+                    Column                 oldColumn    = intermediateTable.findColumn(columnChange.getChangedColumn(), isDelimitedIdentifierModeOn());
+
+                    // Sybase cannot change the IDENTITY state of a column via ALTER TABLE MODIFY
+                    return oldColumn.isAutoIncrement() == columnChange.getNewColumn().isAutoIncrement();
+                }
+                else
+                {
+                    return false;
+                }
+            }
+        };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected Database processChanges(Database model, Collection changes, CreationParameters params) throws IOException, DdlUtilsException
+    {
+        if (!changes.isEmpty())
+        {
+            ((SybaseBuilder)getSqlBuilder()).turnOnQuotation();
+        }
+
+        return super.processChanges(model, changes, params);
+    }
+
+    /**
+     * Processes the removal of a column from a table.
+     * 
+     * @param currentModel The current database schema
+     * @param params       The parameters used in the creation of new tables. Note that for existing
+     *                     tables, the parameters won't be applied
+     * @param change       The change object
+     */
+    public void processChange(Database           currentModel,
+                              CreationParameters params,
+                              RemoveColumnChange change) throws IOException
+    {
+        Table  changedTable  = findChangedTable(currentModel, change);
+        Column removedColumn = changedTable.findColumn(change.getChangedColumn(), isDelimitedIdentifierModeOn());
+
+        ((SybaseBuilder)getSqlBuilder()).dropColumn(changedTable, removedColumn);
+        change.apply(currentModel, isDelimitedIdentifierModeOn());
+    }
+
+    /**
+     * Processes the removal of a primary key from a table.
+     * 
+     * @param currentModel The current database schema
+     * @param params       The parameters used in the creation of new tables. Note that for existing
+     *                     tables, the parameters won't be applied
+     * @param change       The change object
+     */
+    public void processChange(Database               currentModel,
+                              CreationParameters     params,
+                              RemovePrimaryKeyChange change) throws IOException
+    {
+        Table changedTable = findChangedTable(currentModel, change);
+
+        ((SybaseBuilder)getSqlBuilder()).dropPrimaryKey(changedTable);
+        change.apply(currentModel, isDelimitedIdentifierModeOn());
+    }
+
+
+    /**
+     * Processes the change of a column definition..
+     * 
+     * @param currentModel The current database schema
+     * @param params       The parameters used in the creation of new tables. Note that for existing
+     *                     tables, the parameters won't be applied
+     * @param change       The change object
+     */
+    public void processChange(Database               currentModel,
+                              CreationParameters     params,
+                              ColumnDefinitionChange change) throws IOException
+    {
+        Table         changedTable  = findChangedTable(currentModel, change);
+        Column        changedColumn = changedTable.findColumn(change.getChangedColumn(), isDelimitedIdentifierModeOn());
+        Column        newColumn     = change.getNewColumn();
+        SybaseBuilder sqlBuilder    = (SybaseBuilder)getSqlBuilder();
+
+        // if we only change the default value, then we need to use different SQL
+        if (!ColumnDefinitionChange.isTypeChanged(getPlatformInfo(), changedColumn, newColumn) &&
+            !ColumnDefinitionChange.isSizeChanged(getPlatformInfo(), changedColumn, newColumn) &&
+            !ColumnDefinitionChange.isRequiredStatusChanged(changedColumn, newColumn) &&
+            !ColumnDefinitionChange.isAutoIncrementChanged(changedColumn, newColumn))
+        {
+            sqlBuilder.changeColumnDefaultValue(changedTable, changedColumn, newColumn.getDefaultValue());
+        }
+        else
+        {
+            sqlBuilder.changeColumn(changedTable, changedColumn, newColumn);
+        }
+        change.apply(currentModel, isDelimitedIdentifierModeOn());
     }
 }

Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteSchemaSqlToFileCommand.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteSchemaSqlToFileCommand.java?rev=602807&r1=602806&r2=602807&view=diff
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteSchemaSqlToFileCommand.java (original)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/task/WriteSchemaSqlToFileCommand.java Mon Dec 10 00:20:47 2007
@@ -21,6 +21,7 @@
 
 import java.io.File;
 import java.io.FileWriter;
+import java.io.IOException;
 import java.sql.Connection;
 import java.sql.SQLException;
 
@@ -121,10 +122,11 @@
         Platform           platform        = getPlatform();
         boolean            isCaseSensitive = platform.isDelimitedIdentifierModeOn();
         CreationParameters params          = getFilteredParameters(model, platform.getName(), isCaseSensitive);
+        FileWriter         writer          = null;
 
         try
         {
-            FileWriter writer = new FileWriter(_outputFile);
+            writer = new FileWriter(_outputFile);
 
             platform.setScriptModeOn(true);
             if (platform.getPlatformInfo().isSqlCommentsSupported())
@@ -132,7 +134,6 @@
                 // we're generating SQL comments if possible
                 platform.setSqlCommentsOn(true);
             }
-            platform.getSqlBuilder().setWriter(writer);
 
             boolean shouldAlter = isAlterDatabase();
 
@@ -167,18 +168,31 @@
                                              platform.readModelFromDatabase("unnamed", getCatalogPattern(), getSchemaPattern(), null) :
                                              platform.readModelFromDatabase("unnamed");
 
-                platform.getSqlBuilder().alterDatabase(currentModel, model, params);
+                writer.write(platform.getAlterModelSql(currentModel, model, params));
             }
             else
             {
-                platform.getSqlBuilder().createTables(model, params, _doDrops);
+                writer.write(platform.getCreateModelSql(model, params, _doDrops, !isFailOnError()));
             }
-            writer.close();
             _log.info("Written schema SQL to " + _outputFile.getAbsolutePath());
         }
         catch (Exception ex)
         {
             handleException(ex, ex.getMessage());
+        }
+        finally
+        {
+            if (writer != null)
+            {
+                try
+                {
+                    writer.close();
+                }
+                catch (IOException ex)
+                {
+                    _log.error("Could not close file " + _outputFile.getAbsolutePath(), ex);
+                }
+            }
         }
     }
 }

Added: db/ddlutils/trunk/src/java/org/apache/ddlutils/util/StringUtils.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/util/StringUtils.java?rev=602807&view=auto
==============================================================================
--- db/ddlutils/trunk/src/java/org/apache/ddlutils/util/StringUtils.java (added)
+++ db/ddlutils/trunk/src/java/org/apache/ddlutils/util/StringUtils.java Mon Dec 10 00:20:47 2007
@@ -0,0 +1,42 @@
+package org.apache.ddlutils.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Helper class containing string utility functions.
+ * 
+ * @version $Revision: $
+ */
+public class StringUtils extends org.apache.commons.lang.StringUtils
+{
+    /**
+     * Compares the two given strings in a case sensitive or insensitive manner
+     * depending on the <code>caseSensitive</code> parameter.
+     * 
+     * @param strA          The first string
+     * @param strB          The second string
+     * @param caseSensitive Whether case matters in the comparison
+     * @return <code>true</code> if the two strings are equal
+     */
+    public static final boolean equals(String strA, String strB, boolean caseSensitive)
+    {
+        return caseSensitive ? equals(strA, strB) : equalsIgnoreCase(strA, strB);
+    }
+}

Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/RunAllTests.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/RunAllTests.java?rev=602807&r1=602806&r2=602807&view=diff
==============================================================================
--- db/ddlutils/trunk/src/test/org/apache/ddlutils/RunAllTests.java (original)
+++ db/ddlutils/trunk/src/test/org/apache/ddlutils/RunAllTests.java Mon Dec 10 00:20:47 2007
@@ -20,13 +20,15 @@
  */
 
 import org.apache.ddlutils.alteration.TestAlterationAlgorithm;
-import org.apache.ddlutils.alteration.TestModelComparator;
+import org.apache.ddlutils.alteration.TestModelComparison;
 import org.apache.ddlutils.dynabean.TestDynaSqlQueries;
+import org.apache.ddlutils.io.TestAddColumn;
 import org.apache.ddlutils.io.TestAlteration;
 import org.apache.ddlutils.io.TestConstraints;
 import org.apache.ddlutils.io.TestDataReaderAndWriter;
 import org.apache.ddlutils.io.TestDatabaseIO;
 import org.apache.ddlutils.io.TestDatatypes;
+import org.apache.ddlutils.io.TestDropColumn;
 import org.apache.ddlutils.io.TestMisc;
 import org.apache.ddlutils.io.converters.TestDateConverter;
 import org.apache.ddlutils.io.converters.TestTimeConverter;
@@ -116,7 +118,7 @@
         suite.addTestSuite(TestPostgresqlPlatform.class);
         suite.addTestSuite(TestSapDbPlatform.class);
         suite.addTestSuite(TestSybasePlatform.class);
-        suite.addTestSuite(TestModelComparator.class);
+        suite.addTestSuite(TestModelComparison.class);
         suite.addTestSuite(TestAlterationAlgorithm.class);
 
         // tests that need a live database
@@ -126,6 +128,8 @@
             suite.addTestSuite(TestDatatypes.class);
             suite.addTestSuite(TestConstraints.class);
             suite.addTestSuite(TestAlteration.class);
+            suite.addTestSuite(TestAddColumn.class);
+            suite.addTestSuite(TestDropColumn.class);
             suite.addTestSuite(TestMisc.class);
         }
 

Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/alteration/TestAlterationAlgorithm.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/alteration/TestAlterationAlgorithm.java?rev=602807&r1=602806&r2=602807&view=diff
==============================================================================
--- db/ddlutils/trunk/src/test/org/apache/ddlutils/alteration/TestAlterationAlgorithm.java (original)
+++ db/ddlutils/trunk/src/test/org/apache/ddlutils/alteration/TestAlterationAlgorithm.java Mon Dec 10 00:20:47 2007
@@ -20,7 +20,6 @@
  */
 
 import java.io.IOException;
-import java.io.StringWriter;
 
 import org.apache.ddlutils.Platform;
 import org.apache.ddlutils.TestBase;
@@ -36,17 +35,13 @@
 {
     /** The tested platform. */
     private Platform _platform;
-    /** The writer that the builder of the platform writes to. */
-    private StringWriter _writer;
 
     /**
      * {@inheritDoc}
      */
     protected void setUp() throws Exception
     {
-        _writer   = new StringWriter();
         _platform = new TestPlatform();
-        _platform.getSqlBuilder().setWriter(_writer);
         _platform.setSqlCommentsOn(false);
         _platform.setDelimitedIdentifierModeOn(true);
     }
@@ -57,7 +52,6 @@
     protected void tearDown() throws Exception
     {
         _platform = null;
-        _writer   = null;
     }
 
     /**
@@ -67,14 +61,12 @@
      * @param desiredSchema The desired schema XML 
      * @return The sql
      */
-    protected String getAlterDatabaseSQL(String currentSchema, String desiredSchema) throws IOException
+    protected String getAlterModelSQL(String currentSchema, String desiredSchema) throws IOException
     {
         Database currentModel = parseDatabaseFromString(currentSchema);
         Database desiredModel = parseDatabaseFromString(desiredSchema);
 
-        _platform.getSqlBuilder().alterDatabase(currentModel, desiredModel, null);
-
-        return _writer.toString();
+        return _platform.getAlterModelSql(currentModel, desiredModel);
     }
 
     /**
@@ -102,7 +94,7 @@
 
         assertEqualsIgnoringWhitespaces(
             "",
-            getAlterDatabaseSQL(modelXml, modelXml));
+            getAlterModelSQL(modelXml, modelXml));
     }
 
     /**
@@ -134,7 +126,7 @@
             "    \"COLPK\" INTEGER NOT NULL,\n"+
             "    PRIMARY KEY (\"COLPK\")\n"+
             ");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -172,7 +164,7 @@
             "    PRIMARY KEY (\"COLPK\")\n"+
             ");\n"+
             "CREATE INDEX \"TESTINDEX\" ON \"TABLEB\" (\"COL\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -210,7 +202,7 @@
             "    PRIMARY KEY (\"COLPK\")\n"+
             ");\n"+
             "CREATE UNIQUE INDEX \"TESTINDEX\" ON \"TABLEB\" (\"COL\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -248,7 +240,7 @@
             "    PRIMARY KEY (\"COLPK\")\n"+
             ");\n"+
             "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -294,7 +286,7 @@
             ");\n"+
             "ALTER TABLE \"TableA\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"ColFK\") REFERENCES \"TABLEB\" (\"COLPK\");\n"+
             "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -322,7 +314,7 @@
 
         assertEqualsIgnoringWhitespaces(
             "DROP TABLE \"TableA\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -354,7 +346,7 @@
 
         assertEqualsIgnoringWhitespaces(
             "DROP TABLE \"TableA\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -387,7 +379,7 @@
         assertEqualsIgnoringWhitespaces(
             "ALTER TABLE \"TableA\" DROP CONSTRAINT \"TESTFK\";\n"+
             "DROP TABLE \"TableA\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -421,7 +413,7 @@
         assertEqualsIgnoringWhitespaces(
             "ALTER TABLE \"TableA\" DROP CONSTRAINT \"TESTFK\";\n"+
             "DROP TABLE \"TABLEB\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -457,7 +449,7 @@
             "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+
             "DROP TABLE \"TableA\";\n"+
             "DROP TABLE \"TABLEB\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -487,7 +479,7 @@
 
         assertEqualsIgnoringWhitespaces(
             "CREATE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -517,7 +509,7 @@
 
         assertEqualsIgnoringWhitespaces(
             "CREATE UNIQUE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -547,7 +539,7 @@
 
         assertEqualsIgnoringWhitespaces(
             "DROP INDEX \"TestIndex\" ON \"TableA\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -577,7 +569,7 @@
 
         assertEqualsIgnoringWhitespaces(
             "DROP INDEX \"TestIndex\" ON \"TableA\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -604,7 +596,7 @@
 
         assertEqualsIgnoringWhitespaces(
             "ALTER TABLE \"TableA\" ADD CONSTRAINT \"TableA_PK\" PRIMARY KEY (\"ColPK1\",\"ColPK2\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -631,25 +623,9 @@
             "</database>";
 
         assertEqualsIgnoringWhitespaces(
-            "CREATE TABLE \"TableA_\"\n"+
-            "(\n"+
-            "    \"ColPK1\" INTEGER NOT NULL,\n"+
-            "    \"ColPK2\" VARCHAR(64) NOT NULL,\n"+
-            "    \"Col\" DOUBLE,\n"+
-            "    PRIMARY KEY (\"ColPK1\",\"ColPK2\")\n"+
-            ");\n"+
-            "INSERT INTO \"TableA_\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA\";\n"+
-            "DROP TABLE \"TableA\";\n"+
-            "CREATE TABLE \"TableA\"\n"+
-            "(\n"+
-            "    \"ColPK1\" INTEGER NOT NULL,\n"+
-            "    \"ColPK2\" VARCHAR(64) NOT NULL,\n"+
-            "    \"Col\" DOUBLE,\n"+
-            "    PRIMARY KEY (\"ColPK1\",\"ColPK2\")\n"+
-            ");\n"+
-            "INSERT INTO \"TableA\" (\"ColPK1\",\"ColPK2\",\"Col\") SELECT \"ColPK1\",\"ColPK2\",\"Col\" FROM \"TableA_\";\n"+
-            "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            "ALTER TABLE \"TableA\" ADD COLUMN \"Col\" DOUBLE;\n"+
+            "ALTER TABLE \"TableA\" ADD CONSTRAINT \"TableA_PK\" PRIMARY KEY (\"ColPK1\",\"ColPK2\");\n",
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -689,7 +665,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK1\", \"ColPK2\") SELECT \"ColPK1\", \"ColPK2\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -714,23 +690,8 @@
             "</database>";
 
         assertEqualsIgnoringWhitespaces(
-            "CREATE TABLE \"TableA_\"\n"+
-            "(\n"+
-            "    \"ColPK\" INTEGER NOT NULL,\n"+
-            "    \"Col\" VARCHAR(64),\n"+
-            "    PRIMARY KEY (\"ColPK\")\n"+
-            ");\n"+
-            "INSERT INTO \"TableA_\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA\";\n"+
-            "DROP TABLE \"TableA\";\n"+
-            "CREATE TABLE \"TableA\"\n"+
-            "(\n"+
-            "    \"ColPK\" INTEGER NOT NULL,\n"+
-            "    \"Col\" VARCHAR(64),\n"+
-            "    PRIMARY KEY (\"ColPK\")\n"+
-            ");\n"+
-            "INSERT INTO \"TableA\" (\"ColPK\", \"Col\") SELECT \"ColPK\", \"Col\" FROM \"TableA_\";\n"+
-            "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            "ALTER TABLE \"TableA\" ADD COLUMN \"Col\" VARCHAR(64);\n",
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -769,7 +730,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -810,7 +771,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK1\", \"ColPK2\") SELECT \"ColPK1\", \"ColPK2\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -849,7 +810,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK1\") SELECT \"ColPK1\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -908,26 +869,9 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n"+
-            "CREATE TABLE \"TABLEB_\"\n"+
-            "(\n"+
-            "    \"COLPK\" DOUBLE NOT NULL,\n"+
-            "    \"COLFK1\" INTEGER,\n"+
-            "    \"COLFK2\" DOUBLE,\n"+
-            "    PRIMARY KEY (\"COLPK\")\n"+
-            ");\n"+
-            "INSERT INTO \"TABLEB_\" (\"COLPK\",\"COLFK1\") SELECT \"COLPK\",\"COLFK1\" FROM \"TABLEB\";\n"+
-            "DROP TABLE \"TABLEB\";\n"+
-            "CREATE TABLE \"TABLEB\"\n"+
-            "(\n"+
-            "    \"COLPK\" DOUBLE NOT NULL,\n"+
-            "    \"COLFK1\" INTEGER,\n"+
-            "    \"COLFK2\" DOUBLE,\n"+
-            "    PRIMARY KEY (\"COLPK\")\n"+
-            ");\n"+
-            "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK1\",\"COLFK2\") SELECT \"COLPK\",\"COLFK1\",\"COLFK2\" FROM \"TABLEB_\";\n"+
-            "DROP TABLE \"TABLEB_\";\n"+
+            "ALTER TABLE \"TABLEB\" ADD COLUMN \"COLFK2\" DOUBLE;\n"+
             "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK1\",\"COLFK2\") REFERENCES \"TableA\" (\"ColPK1\",\"ColPK2\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1001,7 +945,7 @@
             "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK1\") SELECT \"COLPK\",\"COLFK1\" FROM \"TABLEB_\";\n"+
             "DROP TABLE \"TABLEB_\";\n"+
             "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK1\") REFERENCES \"TableA\" (\"ColPK1\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1036,26 +980,9 @@
 
         assertEqualsIgnoringWhitespaces(
             "DROP INDEX \"TESTINDEX\" ON \"TableA\";\n"+
-            "CREATE TABLE \"TableA_\"\n"+
-            "(\n"+
-            "    \"ColPK\" INTEGER NOT NULL,\n"+
-            "    \"Col1\" DOUBLE,\n"+
-            "    \"Col2\" VARCHAR(64),\n"+
-            "    PRIMARY KEY (\"ColPK\")\n"+
-            ");\n"+
-            "INSERT INTO \"TableA_\" (\"ColPK\",\"Col1\") SELECT \"ColPK\",\"Col1\" FROM \"TableA\";\n"+
-            "DROP TABLE \"TableA\";\n"+
-            "CREATE TABLE \"TableA\"\n"+
-            "(\n"+
-            "    \"ColPK\" INTEGER NOT NULL,\n"+
-            "    \"Col1\" DOUBLE,\n"+
-            "    \"Col2\" VARCHAR(64),\n"+
-            "    PRIMARY KEY (\"ColPK\")\n"+
-            ");\n"+
-            "INSERT INTO \"TableA\" (\"ColPK\",\"Col1\",\"Col2\") SELECT \"ColPK\",\"Col1\",\"Col2\" FROM \"TableA_\";\n"+
-            "DROP TABLE \"TableA_\";\n"+
+            "ALTER TABLE \"TableA\" ADD COLUMN \"Col2\" VARCHAR(64);\n"+
             "CREATE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\",\"Col2\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1107,7 +1034,7 @@
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col1\") SELECT \"ColPK\",\"Col1\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n"+
             "CREATE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1142,26 +1069,9 @@
 
         assertEqualsIgnoringWhitespaces(
             "DROP INDEX \"TESTINDEX\" ON \"TableA\";\n"+
-            "CREATE TABLE \"TableA_\"\n"+
-            "(\n"+
-            "    \"ColPK\" INTEGER NOT NULL,\n"+
-            "    \"Col1\" DOUBLE,\n"+
-            "    \"Col2\" VARCHAR(64),\n"+
-            "    PRIMARY KEY (\"ColPK\")\n"+
-            ");\n"+
-            "INSERT INTO \"TableA_\" (\"ColPK\",\"Col1\") SELECT \"ColPK\",\"Col1\" FROM \"TableA\";\n"+
-            "DROP TABLE \"TableA\";\n"+
-            "CREATE TABLE \"TableA\"\n"+
-            "(\n"+
-            "    \"ColPK\" INTEGER NOT NULL,\n"+
-            "    \"Col1\" DOUBLE,\n"+
-            "    \"Col2\" VARCHAR(64),\n"+
-            "    PRIMARY KEY (\"ColPK\")\n"+
-            ");\n"+
-            "INSERT INTO \"TableA\" (\"ColPK\",\"Col1\",\"Col2\") SELECT \"ColPK\",\"Col1\",\"Col2\" FROM \"TableA_\";\n"+
-            "DROP TABLE \"TableA_\";\n"+
+            "ALTER TABLE \"TableA\" ADD COLUMN \"Col2\" VARCHAR(64);\n"+
             "CREATE UNIQUE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\",\"Col2\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1213,7 +1123,7 @@
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col1\") SELECT \"ColPK\",\"Col1\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n"+
             "CREATE UNIQUE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
 
@@ -1247,26 +1157,8 @@
             "</database>";
 
         assertEqualsIgnoringWhitespaces(
-            "CREATE TABLE \"TableA_\"\n"+
-            "(\n"+
-            "    \"ColPK\" INTEGER NOT NULL,\n"+
-            "    \"Col1\" DOUBLE,\n"+
-            "    \"Col2\" VARCHAR(64),\n"+
-            "    PRIMARY KEY (\"ColPK\")\n"+
-            ");\n"+
-            "INSERT INTO \"TableA_\" (\"ColPK\",\"Col1\") SELECT \"ColPK\",\"Col1\" FROM \"TableA\";\n"+
-            "DROP TABLE \"TableA\";\n"+
-            "CREATE TABLE \"TableA\"\n"+
-            "(\n"+
-            "    \"ColPK\" INTEGER NOT NULL,\n"+
-            "    \"Col1\" DOUBLE,\n"+
-            "    \"Col2\" VARCHAR(64),\n"+
-            "    PRIMARY KEY (\"ColPK\")\n"+
-            ");\n"+
-            "CREATE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\");\n"+
-            "INSERT INTO \"TableA\" (\"ColPK\",\"Col1\",\"Col2\") SELECT \"ColPK\",\"Col1\",\"Col2\" FROM \"TableA_\";\n"+
-            "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            "ALTER TABLE \"TableA\" ADD COLUMN \"Col2\" VARCHAR(64);\n",
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1305,29 +1197,12 @@
             "</database>";
 
         assertEqualsIgnoringWhitespaces(
-            "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+
-            "CREATE TABLE \"TABLEB_\"\n"+
-            "(\n"+
-            "    \"COLPK\" INTEGER NOT NULL,\n"+
-            "    \"COLFK\" INTEGER,\n"+
-            "    \"COL\" DOUBLE,\n"+
-            "    PRIMARY KEY (\"COLPK\")\n"+
-            ");\n"+
-            "INSERT INTO \"TABLEB_\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB\";\n"+
-            "DROP TABLE \"TABLEB\";\n"+
-            "CREATE TABLE \"TABLEB\"\n"+
-            "(\n"+
-            "    \"COLPK\" INTEGER NOT NULL,\n"+
-            "    \"COLFK\" INTEGER,\n"+
-            "    \"COL\" DOUBLE,\n"+
-            "    PRIMARY KEY (\"COLPK\")\n"+
-            ");\n"+
-            "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK\",\"COL\") SELECT \"COLPK\",\"COLFK\",\"COL\" FROM \"TABLEB_\";\n"+
-            "DROP TABLE \"TABLEB_\";\n"+
-            "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            "ALTER TABLE \"TABLEB\" ADD COLUMN \"COL\" DOUBLE;\n",
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
+    // TODO: insert column (not add) into table (also with index/foreign key)
+
     /**
      * Tests the addition of a column to a table that is referenced by a foreign key.
      */
@@ -1364,25 +1239,65 @@
             "</database>";
 
         assertEqualsIgnoringWhitespaces(
+            "ALTER TABLE \"TableA\" ADD COLUMN \"Col\" DOUBLE;\n",
+            getAlterModelSQL(model1Xml, model2Xml));
+    }
+
+    /**
+     * Tests the addition of a column to a table that is referenced by a foreign key.
+     */
+    public void testInsertColumnToTableReferencedByForeignKey() throws IOException
+    {
+        final String model1Xml = 
+            "<?xml version='1.0' encoding='ISO-8859-1'?>\n" +
+            "<database name='test'>\n" +
+            "  <table name='TableA'>\n" +
+            "    <column name='ColPK' type='INTEGER' primaryKey='true' required='true'/>\n" +
+            "  </table>\n" +
+            "  <table name='TABLEB'>\n" +
+            "    <column name='COLPK' type='INTEGER' primaryKey='true' required='true'/>\n" +
+            "    <column name='COLFK' type='INTEGER'/>\n" +
+            "    <foreign-key name='TESTFK' foreignTable='TableA'>\n" +
+            "      <reference local='COLFK' foreign='ColPK'/>\n" +
+            "    </foreign-key>\n" +
+            "  </table>\n" +
+            "</database>";
+        final String model2Xml = 
+            "<?xml version='1.0' encoding='ISO-8859-1'?>\n" +
+            "<database name='test'>\n" +
+            "  <table name='TableA'>\n" +
+            "    <column name='Col' type='DOUBLE'/>\n" +
+            "    <column name='ColPK' type='INTEGER' primaryKey='true' required='true'/>\n" +
+            "  </table>\n" +
+            "  <table name='TABLEB'>\n" +
+            "    <column name='COLPK' type='INTEGER' primaryKey='true' required='true'/>\n" +
+            "    <column name='COLFK' type='INTEGER'/>\n" +
+            "    <foreign-key name='TESTFK' foreignTable='TableA'>\n" +
+            "      <reference local='COLFK' foreign='ColPK'/>\n" +
+            "    </foreign-key>\n" +
+            "  </table>\n" +
+            "</database>";
+
+        assertEqualsIgnoringWhitespaces(
             "ALTER TABLE \"TABLEB\" DROP CONSTRAINT \"TESTFK\";\n"+
             "CREATE TABLE \"TableA_\"\n"+
             "(\n"+
-            "    \"ColPK\" INTEGER NOT NULL,\n"+
             "    \"Col\" DOUBLE,\n"+
+            "    \"ColPK\" INTEGER NOT NULL,\n"+
             "    PRIMARY KEY (\"ColPK\")\n"+
             ");\n"+
             "INSERT INTO \"TableA_\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA\";\n"+
             "DROP TABLE \"TableA\";\n"+
             "CREATE TABLE \"TableA\"\n"+
             "(\n"+
-            "    \"ColPK\" INTEGER NOT NULL,\n"+
             "    \"Col\" DOUBLE,\n"+
+            "    \"ColPK\" INTEGER NOT NULL,\n"+
             "    PRIMARY KEY (\"ColPK\")\n"+
             ");\n"+
-            "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
+            "INSERT INTO \"TableA\" (\"Col\",\"ColPK\") SELECT \"Col\",\"ColPK\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n"+
             "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1424,7 +1339,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1466,7 +1381,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1527,7 +1442,7 @@
             "INSERT INTO \"TableA\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n"+
             "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK2\",\"COLFK1\") REFERENCES \"TableA\" (\"ColPK1\",\"ColPK2\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1588,7 +1503,7 @@
             "INSERT INTO \"TableA\" (\"ColPK1\",\"ColPK2\") SELECT \"ColPK1\",\"ColPK2\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n"+
             "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK2\") REFERENCES \"TableA\" (\"ColPK1\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1625,7 +1540,7 @@
         assertEqualsIgnoringWhitespaces(
             "DROP INDEX \"TESTINDEX\" ON \"TableA\";\n"+
             "CREATE UNIQUE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\",\"Col2\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1662,7 +1577,7 @@
         assertEqualsIgnoringWhitespaces(
             "DROP INDEX \"TESTINDEX\" ON \"TableA\";\n"+
             "CREATE INDEX \"TESTINDEX\" ON \"TableA\" (\"Col1\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1717,7 +1632,7 @@
             "INSERT INTO \"TableA\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n"+
             "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1759,7 +1674,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1801,7 +1716,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1850,7 +1765,7 @@
             "CREATE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1920,7 +1835,7 @@
             "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB_\";\n"+
             "DROP TABLE \"TABLEB_\";\n"+
             "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -1962,7 +1877,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2004,7 +1919,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2053,7 +1968,7 @@
             "CREATE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2123,7 +2038,7 @@
             "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB_\";\n"+
             "DROP TABLE \"TABLEB_\";\n"+
             "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2165,7 +2080,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2207,7 +2122,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2256,7 +2171,7 @@
             "CREATE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2326,7 +2241,7 @@
             "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB_\";\n"+
             "DROP TABLE \"TABLEB_\";\n"+
             "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2368,7 +2283,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2410,7 +2325,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2459,7 +2374,7 @@
             "CREATE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2514,7 +2429,7 @@
             "INSERT INTO \"TableA\" (\"ColPK\") SELECT \"ColPK\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n"+
             "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2556,7 +2471,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2598,7 +2513,7 @@
             ");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2647,7 +2562,7 @@
             "CREATE INDEX \"TestIndex\" ON \"TableA\" (\"Col\");\n"+
             "INSERT INTO \"TableA\" (\"ColPK\",\"Col\") SELECT \"ColPK\",\"Col\" FROM \"TableA_\";\n"+
             "DROP TABLE \"TableA_\";\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 
     /**
@@ -2718,6 +2633,6 @@
             "INSERT INTO \"TABLEB\" (\"COLPK\",\"COLFK\") SELECT \"COLPK\",\"COLFK\" FROM \"TABLEB_\";\n"+
             "DROP TABLE \"TABLEB_\";\n"+
             "ALTER TABLE \"TABLEB\" ADD CONSTRAINT \"TESTFK\" FOREIGN KEY (\"COLFK\") REFERENCES \"TableA\" (\"ColPK\");\n",
-            getAlterDatabaseSQL(model1Xml, model2Xml));
+            getAlterModelSQL(model1Xml, model2Xml));
     }
 }

Added: db/ddlutils/trunk/src/test/org/apache/ddlutils/alteration/TestComparisonBase.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/alteration/TestComparisonBase.java?rev=602807&view=auto
==============================================================================
--- db/ddlutils/trunk/src/test/org/apache/ddlutils/alteration/TestComparisonBase.java (added)
+++ db/ddlutils/trunk/src/test/org/apache/ddlutils/alteration/TestComparisonBase.java Mon Dec 10 00:20:47 2007
@@ -0,0 +1,177 @@
+package org.apache.ddlutils.alteration;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.sql.Types;
+
+import org.apache.ddlutils.Platform;
+import org.apache.ddlutils.PlatformInfo;
+import org.apache.ddlutils.TestBase;
+import org.apache.ddlutils.model.Column;
+import org.apache.ddlutils.model.ForeignKey;
+import org.apache.ddlutils.model.Index;
+import org.apache.ddlutils.model.Table;
+import org.apache.ddlutils.platform.TestPlatform;
+
+/**
+ * Base class for model comparison tests.
+ * 
+ * @version $Revision: $
+ */
+public abstract class TestComparisonBase extends TestBase
+{
+    /**
+     * Creates a new platform object.
+     *
+     * @param delimitedIdentifierModeOn Whether delimited identifiers shall be used
+     * @return The platform object
+     */
+    protected Platform getPlatform(boolean delimitedIdentifierModeOn)
+    {
+        TestPlatform platform = new TestPlatform() {
+            protected TableDefinitionChangesPredicate getTableDefinitionChangesPredicate()
+            {
+                return null;
+            }
+        };
+
+        PlatformInfo platformInfo = platform.getPlatformInfo();
+
+        platform.setDelimitedIdentifierModeOn(delimitedIdentifierModeOn);
+        platformInfo.setHasSize(Types.DECIMAL, true);
+        platformInfo.setHasSize(Types.NUMERIC, true);
+        platformInfo.setHasSize(Types.CHAR, true);
+        platformInfo.setHasSize(Types.VARCHAR, true);
+
+        return platform;
+    }
+
+    /**
+     * Asserts the given table.
+     * 
+     * @param name        The expected name
+     * @param description The expected description
+     * @param columnCount The expected number of columns
+     * @param fkCount     The expected number of foreign keys
+     * @param indexCount  The expected number of indexes
+     * @param table       The table to assert
+     */
+    protected void assertTable(String name, String description, int columnCount, int fkCount, int indexCount, Table table)
+    {
+        assertEquals(name,
+                     table.getName());
+        assertEquals(description,
+                     table.getDescription());
+        assertEquals(columnCount,
+                     table.getColumnCount());
+        assertEquals(fkCount,
+                     table.getForeignKeyCount());
+        assertEquals(indexCount,
+                     table.getIndexCount());
+    }
+
+    /**
+     * Asserts the given column.
+     * 
+     * @param name            The expected name
+     * @param typeCode        The expected type code
+     * @param sizeSpec        The expected size
+     * @param defaultValue    The expected default value
+     * @param isPrimaryKey    The expected primary key status
+     * @param isRequired      The expected required status
+     * @param isAutoIncrement The expected auto increment status
+     * @param column          The column to assert
+     */
+    protected void assertColumn(String  name,
+                                int     typeCode,
+                                String  sizeSpec,
+                                String  defaultValue,
+                                boolean isPrimaryKey,
+                                boolean isRequired,
+                                boolean isAutoIncrement,
+                                Column  column)
+    {
+        assertEquals(name,
+                     column.getName());
+        assertEquals(typeCode,
+                     column.getTypeCode());
+        assertEquals(sizeSpec,
+                     column.getSize());
+        assertEquals(defaultValue,
+                     column.getDefaultValue());
+        assertEquals(isPrimaryKey,
+                     column.isPrimaryKey());
+        assertEquals(isRequired,
+                     column.isRequired());
+        assertEquals(isAutoIncrement,
+                     column.isAutoIncrement());
+    }
+
+    /**
+     * Asserts the given index.
+     * 
+     * @param name         The expected name
+     * @param isUnique     Whether the index is expected to be a unique index
+     * @param indexColumns The names of the columns expected to be in the index
+     * @param index        The index to assert
+     */
+    protected void assertIndex(String name, boolean isUnique, String[] indexColumns, Index index)
+    {
+        assertEquals(name,
+                     index.getName());
+        assertEquals(isUnique,
+                     index.isUnique());
+        assertEquals(indexColumns.length,
+                     index.getColumnCount());
+        for (int idx = 0; idx < indexColumns.length; idx++)
+        {
+            assertEquals(indexColumns[idx],
+                         index.getColumn(idx).getName());
+            assertEquals(indexColumns[idx],
+                         index.getColumn(idx).getColumn().getName());
+        }
+    }
+
+    /**
+     * Asserts the given foreign key.
+     * 
+     * @param name               The expected name
+     * @param targetTableName    The name of the expected target table
+     * @param localColumnNames   The names of the expected local columns
+     * @param foreignColumnNames The names of the expected foreign columns
+     * @param fk                 The foreign key to assert
+     */
+    protected void assertForeignKey(String name, String targetTableName, String[] localColumnNames, String[] foreignColumnNames, ForeignKey fk)
+    {
+        assertEquals(name,
+                     fk.getName());
+        assertEquals(targetTableName,
+                     fk.getForeignTable().getName());
+        assertEquals(localColumnNames.length,
+                     fk.getReferenceCount());
+        for (int idx = 0; idx < localColumnNames.length; idx++)
+        {
+            assertEquals(localColumnNames[idx],
+                         fk.getReference(idx).getLocalColumnName());
+            assertEquals(foreignColumnNames[idx],
+                         fk.getReference(idx).getForeignColumnName());
+        }
+    }
+}