db-ddlutils-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From to...@apache.org
Subject svn commit: r572524 [2/2] - in /db/ddlutils/trunk: ./ lib/ src/java/org/apache/ddlutils/io/ src/java/org/apache/ddlutils/model/ src/test/org/apache/ddlutils/io/
Date Tue, 04 Sep 2007 04:58:11 GMT
Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatabaseIO.java
URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatabaseIO.java?rev=572524&r1=572523&r2=572524&view=diff
==============================================================================
--- db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatabaseIO.java (original)
+++ db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestDatabaseIO.java Mon Sep  3 21:58:10 2007
@@ -22,13 +22,11 @@
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.sql.Types;
-import java.util.Arrays;
 
 import junit.framework.TestCase;
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.ddlutils.model.CascadeActionEnum;
 import org.apache.ddlutils.model.Column;
 import org.apache.ddlutils.model.Database;
 import org.apache.ddlutils.model.ForeignKey;
@@ -37,17 +35,15 @@
 import org.apache.ddlutils.model.ModelException;
 import org.apache.ddlutils.model.Reference;
 import org.apache.ddlutils.model.Table;
+import org.apache.ddlutils.model.TypeMap;
 
 /**
- * Tests the database reading/writing via the {@link org.apache.ddlutils.io.DatabaseIO} class.
+ * Tests the database XML reading/writing via the {@link org.apache.ddlutils.io.DatabaseIO} class.
  * 
  * @version $Revision: 289996 $
  */
 public class TestDatabaseIO extends TestCase
 {
-    /** The log for the tests. */
-    private final Log _log = LogFactory.getLog(TestDatabaseIO.class);
-
     /**
      * Reads the database model from the given string.
      * 
@@ -78,206 +74,1599 @@
     }
 
     /**
-     * Tests a simple database model.
+     * Asserts the data in a table object.
+     * 
+     * @param name                    The expected name
+     * @param description             The expected description
+     * @param numColumns              The expected number of columns
+     * @param numPrimaryKeyColumns    The expected number of primary key columns
+     * @param numAutoIncrementColumns The expected number of auto increment columns
+     * @param numForeignKeys          The expected number of foreign keys
+     * @param numIndexes              The expected number of indexes
+     * @param table                   The table
+     */
+    private void assertEquals(String name,
+                              String description,
+                              int    numColumns,
+                              int    numPrimaryKeyColumns,
+                              int    numAutoIncrementColumns,
+                              int    numForeignKeys,
+                              int    numIndexes,
+                              Table  table)
+    {
+        assertEquals(name, table.getName());
+        assertEquals(description, table.getDescription());
+        assertEquals(numColumns, table.getColumnCount());
+        assertEquals(numPrimaryKeyColumns, table.getPrimaryKeyColumns().length);
+        assertEquals(numAutoIncrementColumns, table.getAutoIncrementColumns().length);
+        assertEquals(numForeignKeys, table.getForeignKeyCount());
+        assertEquals(numIndexes, table.getIndexCount());
+    }
+
+    /**
+     * Asserts the data in a column object.
+     * 
+     * @param name            The expected name
+     * @param typeCode        The exected JDBC type code
+     * @param size            The expected size value
+     * @param scale           The expected scale value
+     * @param defaultValue    The expected default value
+     * @param description     The expected description
+     * @param javaName        The expected java name
+     * @param isPrimaryKey    The expected primary key status
+     * @param isRequired      The expected required satus
+     * @param isAutoIncrement The expected auto increment status
+     * @param column          The column
+     */
+    private void assertEquals(String  name,
+                              int     typeCode,
+                              int     size,
+                              int     scale,
+                              String  defaultValue,
+                              String  description,
+                              String  javaName,
+                              boolean isPrimaryKey,
+                              boolean isRequired,
+                              boolean isAutoIncrement,
+                              Column  column)
+    {
+        assertEquals(name, column.getName());
+        assertEquals(TypeMap.getJdbcTypeName(typeCode), column.getType());
+        assertEquals(typeCode, column.getTypeCode());
+        assertEquals(size, column.getSizeAsInt());
+        assertEquals(size, column.getPrecisionRadix());
+        assertEquals(scale, column.getScale());
+        if ((size <= 0) && (scale <= 0)) {
+            assertNull(column.getSize());
+        }
+        else if (scale == 0) {
+            assertEquals("" + size, column.getSize());
+        }
+        else {
+            assertEquals("" + size + "," + scale, column.getSize());
+        }
+        assertEquals(defaultValue, column.getDefaultValue());
+        assertEquals(description, column.getDescription());
+        assertEquals(javaName, column.getJavaName());
+        assertEquals(isPrimaryKey, column.isPrimaryKey());
+        assertEquals(isRequired, column.isRequired());
+        assertEquals(isAutoIncrement, column.isAutoIncrement());
+    }
+
+    /**
+     * Asserts data in a foreign key object.
+     * 
+     * @param name            The expected name
+     * @param onUpdate        The expected onUpdate action
+     * @param onDelete        The expected onDelete action
+     * @param referencedTable The expected referenced table
+     * @param numReferences   The expected number of references
+     * @param foreignKey      The foreign key
+     */
+    private void assertEquals(String            name,
+                              CascadeActionEnum onUpdate,
+                              CascadeActionEnum onDelete,
+                              Table             referencedTable,
+                              int               numReferences,
+                              ForeignKey        foreignKey)
+    {
+        assertEquals(name, foreignKey.getName());
+        assertEquals(onUpdate, foreignKey.getOnUpdate());
+        assertEquals(onDelete, foreignKey.getOnDelete());
+        assertEquals(referencedTable, foreignKey.getForeignTable());
+        assertEquals(referencedTable.getName(), foreignKey.getForeignTableName());
+        assertEquals(numReferences, foreignKey.getReferenceCount());
+    }
+
+    /**
+     * Asserts data in a reference object.
+     * 
+     * @param localColumn   The expected local column
+     * @param foreignColumn The expected foreign column
+     * @param ref           The reference
+     */
+    private void assertEquals(Column localColumn, Column foreignColumn, Reference ref)
+    {
+        assertEquals(localColumn, ref.getLocalColumn());
+        assertEquals(localColumn.getName(), ref.getLocalColumnName());
+        assertEquals(foreignColumn, ref.getForeignColumn());
+        assertEquals(foreignColumn.getName(), ref.getForeignColumnName());
+    }
+
+    /**
+     * Asserts data in an index object.
+     * 
+     * @param name       The expected name
+     * @param isUnique   The expected unique status
+     * @param numColumns The expected number of columns
+     * @param index      The index
+     */
+    private void assertEquals(String name, boolean isUnique, int numColumns, Index index)
+    {
+        assertEquals(name, index.getName());
+        assertEquals(isUnique, index.isUnique());
+        assertEquals(numColumns, index.getColumnCount());
+    }
+
+    /**
+     * Asserts data in an index column object.
+     * 
+     * @param column      The expected column
+     * @param size        The expected size value 
+     * @param indexColumn The index column
+     */
+    private void assertEquals(Column column, String size, IndexColumn indexColumn)
+    {
+        assertEquals(column, indexColumn.getColumn());
+        assertEquals(column.getName(), indexColumn.getName());
+        assertEquals(size, indexColumn.getSize());
+    }
+
+    /**
+     * Asserts that the given database model, written to XML, is equal to the given
+     * expected XML.
+     * 
+     * @param expectedXml The expected XML
+     * @param model       The database model
+     */
+    private void assertEquals(String expectedXml, Database model)
+    {
+        assertEquals(expectedXml, writeModel(model));
+    }
+
+    /**
+     * Tests an XML document without a database element.
+     */
+    public void testNoDatabaseElement()
+    {
+        assertNull(readModel("<data-base></data-base>"));
+    }
+
+    /**
+     * Tests that an exception is generated when the database element has no name attribute.
+     */
+    public void testDatabaseWithoutName()
+    {
+        try
+        {
+            readModel(
+                "<database>\n" +
+                "  <table name='TestTable'>\n" +
+                "    <column name='id'\n" +
+                "            type='INTEGER'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'/>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+    /**
+     * Tests a database model without tables.
      */
-    public void testSimple() throws Exception
+    public void testNoTables() throws Exception
     {
         Database model = readModel(
             "<database name='test'>\n" +
-            "  <table name='SomeTable'\n" +
-            "         description='Some table'>\n" +
-            "    <column name='ID'\n" +
-            "            type='INTEGER'\n" +
-            "            primaryKey='true'\n" +
-            "            required='true'\n" +
-            "            description='The primary key'\n" +
-            "            javaName='javaId'/>\n" +
-            "  </table>\n" +
             "</database>");
 
         assertEquals("test",
                      model.getName());
-        assertEquals(1,
+        assertEquals(0,
                      model.getTableCount());
-        
-        Table table = model.getTable(0);
 
-        assertEquals("SomeTable",
-                     table.getName());
-        assertEquals("Some table",
-                     table.getDescription());
-        assertEquals(0, table.getAutoIncrementColumns().length);
-        assertEquals(1,
-                     table.getColumnCount());
-        assertEquals(0,
-                     table.getForeignKeyCount());
-        assertEquals(0,
-                     table.getIndexCount());
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\" />\n",
+            model);
+    }
 
-        Column column = table.getColumn(0);
+    /**
+     * Tests a database model with a table without columns.
+     */
+    public void testTableWithoutColumns() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='SomeTable'\n" +
+            "         description='Some table'>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        assertEquals("SomeTable", "Some table", 0, 0, 0, 0, 0,
+                     model.getTable(0));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\" />\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests that an exception is generated when the table element has no name attribute.
+     */
+    public void testTableWithoutName()
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table>\n" +
+                "    <column name='id'\n" +
+                "            type='INTEGER'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'/>\n" +
+                "  </table>\n" +
+                "</database>");
 
-        assertEquals("ID",
-                     column.getName());
-        assertEquals("INTEGER",
-                     column.getType());
-        assertEquals(Types.INTEGER,
-                     column.getTypeCode());
-        assertTrue(column.isPrimaryKey());
-        assertTrue(column.isRequired());
-        assertFalse(column.isAutoIncrement());
-        assertNull(column.getDefaultValue());
-        assertEquals("The primary key",
-                     column.getDescription());
-        assertEquals("javaId", column.getJavaName());
-        assertEquals(
-            "<?xml version=\"1.0\"?>\n<!DOCTYPE database SYSTEM \"" + LocalEntityResolver.DTD_PREFIX + "\">\n" +
-            "  <database name=\"test\">\n" +
-            "    <table name=\"SomeTable\" description=\"Some table\">\n" +
-            "      <column name=\"ID\" primaryKey=\"true\" required=\"true\" type=\"INTEGER\" autoIncrement=\"false\" description=\"The primary key\" javaName=\"javaId\"/>\n" +
-            "    </table>\n" +
-            "  </database>\n",
-            writeModel(model));
+            fail();
+        }
+        catch (ModelException ex)
+        {}
     }
 
     /**
-     * Tests a database model containing a foreignkey.
+     * Tests a database model with a table with a single column.
      */
-    public void testForeignkey() throws Exception
+    public void testSingleColumn() throws Exception
     {
         Database model = readModel(
             "<database name='test'>\n" +
             "  <table name='SomeTable'\n" +
             "         description='Some table'>\n" +
             "    <column name='ID'\n" +
-            "            type='VARCHAR'\n" +
-            "            size='16'\n" +
-            "            primaryKey='true'\n" +
-            "            required='true'\n" +
-            "            description='The primary key'/>\n" +
-            "  </table>\n" +
-            "  <table name='AnotherTable'\n" +
-            "         description='And another table'>\n" +
-            "    <column name='Some_ID'\n" +
-            "            type='VARCHAR'\n" +
-            "            size='16'\n" +
-            "            description='The foreign key'/>\n" +
-            "    <foreign-key foreignTable='SomeTable'>\n" +
-            "       <reference local='Some_ID' foreign='ID'/>\n" +
-            "    </foreign-key>\n" +
+            "            type='INTEGER'/>\n" +
             "  </table>\n" +
             "</database>");
 
-        assertEquals("test",
-                     model.getName());
-        assertEquals(2,
-                     model.getTableCount());
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
 
-        Table someTable = model.getTable(0);
+        assertEquals("SomeTable", "Some table", 1, 0, 0, 0, 0,
+                     table);
+        assertEquals("ID", Types.INTEGER, 0, 0, null, null, null, false, false, false,
+                     table.getColumn(0));
 
-        assertEquals("SomeTable",
-                     someTable.getName());
-        assertEquals("Some table",
-                     someTable.getDescription());
-        assertEquals(0, someTable.getAutoIncrementColumns().length);
-        assertEquals(1,
-                     someTable.getColumnCount());
-        assertEquals(0,
-                     someTable.getForeignKeyCount());
-        assertEquals(0,
-                     someTable.getIndexCount());
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\">\n" +
+            "    <column name=\"ID\" primaryKey=\"false\" required=\"false\" type=\"INTEGER\" autoIncrement=\"false\" />\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
 
-        Column pkColumn = someTable.getColumn(0);
+    /**
+     * Tests that an exception is generated when the column element has no name attribute.
+     */
+    public void testColumnWithoutName()
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='TestTable'>\n" +
+                "    <column type='INTEGER'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'/>\n" +
+                "  </table>\n" +
+                "</database>");
 
-        assertEquals("ID",
-                     pkColumn.getName());
-        assertEquals("VARCHAR",
-                     pkColumn.getType());
-        assertEquals(Types.VARCHAR,
-                     pkColumn.getTypeCode());
-        assertEquals(16,
-                     pkColumn.getSizeAsInt());
-        assertTrue(pkColumn.isPrimaryKey());
-        assertTrue(pkColumn.isRequired());
-        assertFalse(pkColumn.isAutoIncrement());
-        assertNull(pkColumn.getDefaultValue());
-        assertEquals("The primary key",
-                     pkColumn.getDescription());
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
 
-        Table anotherTable = model.getTable(1);
+    /**
+     * Tests that an exception is generated when the column element has no type attribute.
+     */
+    public void testColumnWithoutType()
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='TestTable'>\n" +
+                "    <column name='id'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'/>\n" +
+                "  </table>\n" +
+                "</database>");
 
-        assertEquals("AnotherTable",
-                     anotherTable.getName());
-        assertEquals("And another table",
-                     anotherTable.getDescription());
-        assertEquals(0, anotherTable.getAutoIncrementColumns().length);
-        assertEquals(1,
-                     anotherTable.getColumnCount());
-        assertEquals(1,
-                     anotherTable.getForeignKeyCount());
-        assertEquals(0,
-                     anotherTable.getIndexCount());
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
 
-        Column fkColumn = anotherTable.getColumn(0);
+    /**
+     * Tests a database model columns of all possible datatypes.
+     */
+    public void testColumnTypes() throws Exception
+    {
+        StringBuffer modelXml = new StringBuffer();
+        int[]        types    = TypeMap.getSuportedJdbcTypes();
+
+        modelXml.append("<database name='test'>\n");
+        modelXml.append("  <table name='SomeTable'\n");
+        modelXml.append("         description='Some table'>\n");
+        for (int idx = 0; idx < types.length; idx++)
+        {
+            modelXml.append("    <column name='ID");
+            modelXml.append(idx);
+            modelXml.append("' type='");
+            modelXml.append(TypeMap.getJdbcTypeName(types[idx]));
+            modelXml.append("'/>\n");
+        }
+        modelXml.append("  </table>\n");
+        modelXml.append("</database>");
+
+        Database model = readModel(modelXml.toString());
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
+
+        assertEquals("SomeTable", "Some table", types.length, 0, 0, 0, 0,
+                     table);
+
+        for (int idx = 0; idx < types.length; idx++)
+        {
+            assertEquals("ID" + idx, types[idx], 0, 0, null, null, null, false, false, false,
+                         table.getColumn(idx));
+        }
+
+        modelXml.setLength(0);
+        modelXml.append("<?xml version='1.0' encoding='UTF-8'?>\n");
+        modelXml.append("<database name=\"test\">\n");
+        modelXml.append("  <table name=\"SomeTable\" description=\"Some table\">\n");
+        for (int idx = 0; idx < types.length; idx++)
+        {
+            modelXml.append("    <column name=\"ID");
+            modelXml.append(idx);
+            modelXml.append("\" primaryKey=\"false\" required=\"false\" type=\"");
+            modelXml.append(TypeMap.getJdbcTypeName(types[idx]));
+            modelXml.append("\" autoIncrement=\"false\" />\n");
+        }
+        modelXml.append("  </table>\n");
+        modelXml.append("</database>\n");
+
+        assertEquals(modelXml.toString(), model);
+    }
+
+    /**
+     * Tests an illegal column type.
+     */
+    public void testColumnWithIllegalType()
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='TestTable'>\n" +
+                "    <column name='id'\n" +
+                "            type='illegal'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'/>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+    /**
+     * Tests a database model with a table with a primary key column.
+     */
+    public void testPrimaryKeyColumn() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='SomeTable'\n" +
+            "         description='Some table'>\n" +
+            "    <column name='ID'\n" +
+            "            type='INTEGER'\n" +
+            "            primaryKey='true'/>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
+
+        assertEquals("SomeTable", "Some table", 1, 1, 0, 0, 0,
+                     table);
+
+        Column column = table.getColumn(0);
+
+        assertEquals("ID", Types.INTEGER, 0, 0, null, null, null, true, false, false,
+                     column);
+
+        assertEquals(column, table.getPrimaryKeyColumns()[0]);
+        
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\">\n" +
+            "    <column name=\"ID\" primaryKey=\"true\" required=\"false\" type=\"INTEGER\" autoIncrement=\"false\" />\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
 
-        assertEquals("Some_ID",
-                     fkColumn.getName());
-        assertEquals("VARCHAR",
-                     fkColumn.getType());
-        assertEquals(Types.VARCHAR,
-                     fkColumn.getTypeCode());
-        assertEquals(16,
-                     fkColumn.getSizeAsInt());
-        assertFalse(fkColumn.isPrimaryKey());
-        assertFalse(fkColumn.isRequired());
-        assertFalse(fkColumn.isAutoIncrement());
-        assertEquals("The foreign key",
-                     fkColumn.getDescription());
+    /**
+     * Tests a database model with a table with a required column.
+     */
+    public void testRequiredColumn() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='SomeTable'\n" +
+            "         description='Some table'>\n" +
+            "    <column name='ID'\n" +
+            "            type='INTEGER'\n" +
+            "            required='true'/>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
+
+        assertEquals("SomeTable", "Some table", 1, 0, 0, 0, 0,
+                     table);
+        assertEquals("ID", Types.INTEGER, 0, 0, null, null, null, false, true, false,
+                     table.getColumn(0));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\">\n" +
+            "    <column name=\"ID\" primaryKey=\"false\" required=\"true\" type=\"INTEGER\" autoIncrement=\"false\" />\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model with a table with an autoincrement column.
+     */
+    public void testAutoIncrementColumn() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='SomeTable'\n" +
+            "         description='Some table'>\n" +
+            "    <column name='ID'\n" +
+            "            type='INTEGER'\n" +
+            "            autoIncrement='true'/>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
+
+        assertEquals("SomeTable", "Some table", 1, 0, 1, 0, 0,
+                     table);
+
+        Column column = table.getColumn(0);
+
+        assertEquals("ID", Types.INTEGER, 0, 0, null, null, null, false, false, true,
+                     column);
+
+        assertEquals(column, table.getAutoIncrementColumns()[0]);
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\">\n" +
+            "    <column name=\"ID\" primaryKey=\"false\" required=\"false\" type=\"INTEGER\" autoIncrement=\"true\" />\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model with a table with a column with a size spec.
+     */
+    public void testColumnWithSize1() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='SomeTable'\n" +
+            "         description='Some table'>\n" +
+            "    <column name='ID'\n" +
+            "            type='VARCHAR'\n" +
+            "            size='20'/>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
+
+        assertEquals("SomeTable", "Some table", 1, 0, 0, 0, 0,
+                     table);
+        assertEquals("ID", Types.VARCHAR, 20, 0, null, null, null, false, false, false,
+                     table.getColumn(0));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\">\n" +
+            "    <column name=\"ID\" primaryKey=\"false\" required=\"false\" type=\"VARCHAR\" size=\"20\" autoIncrement=\"false\" />\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model with a table with a column with a size spec.
+     */
+    public void testColumnWithSize2() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='SomeTable'\n" +
+            "         description='Some table'>\n" +
+            "    <column name='ID'\n" +
+            "            type='DECIMAL'\n" +
+            "            size='10,3'/>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
+
+        assertEquals("SomeTable", "Some table", 1, 0, 0, 0, 0,
+                     table);
+        assertEquals("ID", Types.DECIMAL, 10, 3, null, null, null, false, false, false,
+                     table.getColumn(0));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\">\n" +
+            "    <column name=\"ID\" primaryKey=\"false\" required=\"false\" type=\"DECIMAL\" size=\"10,3\" autoIncrement=\"false\" />\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model with a table with a column with a description.
+     */
+    public void testColumnWithDescription() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='SomeTable'\n" +
+            "         description='Some table'>\n" +
+            "    <column name='ID'\n" +
+            "            type='INTEGER'\n" +
+            "            description='Foo'/>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
+
+        assertEquals("SomeTable", "Some table", 1, 0, 0, 0, 0,
+                     table);
+        assertEquals("ID", Types.INTEGER, 0, 0, null, "Foo", null, false, false, false,
+                     table.getColumn(0));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\">\n" +
+            "    <column name=\"ID\" primaryKey=\"false\" required=\"false\" type=\"INTEGER\" autoIncrement=\"false\" description=\"Foo\" />\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model with a table with a column with a default.
+     */
+    public void testColumnWithDefault() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='SomeTable'\n" +
+            "         description='Some table'>\n" +
+            "    <column name='ID'\n" +
+            "            type='VARCHAR'\n" +
+            "            size='32'\n" +
+            "            default='Test string'/>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
+
+        assertEquals("SomeTable", "Some table", 1, 0, 0, 0, 0,
+                     table);
+        assertEquals("ID", Types.VARCHAR, 32, 0, "Test string", null, null, false, false, false,
+                     table.getColumn(0));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\">\n" +
+            "    <column name=\"ID\" primaryKey=\"false\" required=\"false\" type=\"VARCHAR\" size=\"32\" default=\"Test string\" autoIncrement=\"false\" />\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model with a table with a column with a java name.
+     */
+    public void testColumnWithJavaName() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='SomeTable'\n" +
+            "         description='Some table'>\n" +
+            "    <column name='ID'\n" +
+            "            type='DOUBLE'\n" +
+            "            javaName='testString'/>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
+
+        assertEquals("SomeTable", "Some table", 1, 0, 0, 0, 0,
+                     table);
+        assertEquals("ID", Types.DOUBLE, 0, 0, null, null, "testString", false, false, false,
+                     table.getColumn(0));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\">\n" +
+            "    <column name=\"ID\" primaryKey=\"false\" required=\"false\" type=\"DOUBLE\" autoIncrement=\"false\" javaName=\"testString\" />\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model containing a single foreignkey.
+     */
+    public void testSingleForeignkey() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='SomeTable'\n" +
+            "         description='Some table'>\n" +
+            "    <column name='ID'\n" +
+            "            type='VARCHAR'\n" +
+            "            size='16'\n" +
+            "            primaryKey='true'\n" +
+            "            required='true'\n" +
+            "            description='The primary key'/>\n" +
+            "  </table>\n" +
+            "  <table name='AnotherTable'\n" +
+            "         description='And another table'>\n" +
+            "    <column name='Some_ID'\n" +
+            "            type='VARCHAR'\n" +
+            "            size='16'\n" +
+            "            description='The foreign key'/>\n" +
+            "    <foreign-key foreignTable='SomeTable'>\n" +
+            "       <reference local='Some_ID' foreign='ID'/>\n" +
+            "    </foreign-key>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(2, model.getTableCount());
+
+        Table someTable = model.getTable(0);
+
+        assertEquals("SomeTable", "Some table", 1, 1, 0, 0, 0,
+                     someTable);
+
+        Column pkColumn = someTable.getColumn(0);
+
+        assertEquals("ID", Types.VARCHAR, 16, 0, null, "The primary key", null, true, true, false,
+                     pkColumn);
+
+        Table anotherTable = model.getTable(1);
+
+        assertEquals("AnotherTable", "And another table", 1, 0, 0, 1, 0,
+                     anotherTable);
+
+        Column fkColumn = anotherTable.getColumn(0);
+
+        assertEquals("Some_ID", Types.VARCHAR, 16, 0, null, "The foreign key", null, false, false, false,
+                     fkColumn);
+
+        ForeignKey fk = anotherTable.getForeignKey(0);
+
+        assertEquals(null, CascadeActionEnum.NONE, CascadeActionEnum.NONE, someTable, 1, fk);
+        assertEquals(fkColumn, pkColumn, fk.getFirstReference());
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\">\n" +
+            "    <column name=\"ID\" primaryKey=\"true\" required=\"true\" type=\"VARCHAR\" size=\"16\" autoIncrement=\"false\" description=\"The primary key\" />\n" +
+            "  </table>\n" +
+            "  <table name=\"AnotherTable\" description=\"And another table\">\n" +
+            "    <column name=\"Some_ID\" primaryKey=\"false\" required=\"false\" type=\"VARCHAR\" size=\"16\" autoIncrement=\"false\" description=\"The foreign key\" />\n" +
+            "    <foreign-key foreignTable=\"SomeTable\">\n" +
+            "      <reference local=\"Some_ID\" foreign=\"ID\" />\n" +
+            "    </foreign-key>\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model containing a foreignkey with two references.
+     */
+    public void testForeignkeyWithTwoReferences() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='SomeTable'\n" +
+            "         description='Some table'>\n" +
+            "    <column name='ID'\n" +
+            "            type='VARCHAR'\n" +
+            "            size='16'\n" +
+            "            primaryKey='true'\n" +
+            "            required='true'\n" +
+            "            description='The primary key'/>\n" +
+            "    <column name='VALUE1'\n" +
+            "            type='INTEGER'\n" +
+            "            required='false'\n" +
+            "            description='A value'/>\n" +
+            "    <column name='VALUE2'\n" +
+            "            type='DOUBLE'\n" +
+            "            required='false'\n" +
+            "            description='Another value'/>\n" +
+            "  </table>\n" +
+            "  <table name='AnotherTable'\n" +
+            "         description='And another table'>\n" +
+            "    <column name='Some_ID'\n" +
+            "            type='VARCHAR'\n" +
+            "            size='16'\n" +
+            "            description='The foreign key'/>\n" +
+            "    <column name='Some_Value'\n" +
+            "            type='DOUBLE'/>\n" +
+            "    <foreign-key foreignTable='SomeTable'>\n" +
+            "       <reference local='Some_ID' foreign='ID'/>\n" +
+            "       <reference local='Some_Value' foreign='VALUE2'/>\n" +
+            "    </foreign-key>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(2, model.getTableCount());
+
+        Table someTable = model.getTable(0);
+
+        assertEquals("SomeTable", "Some table", 3, 1, 0, 0, 0,
+                     someTable);
+        assertEquals("ID", Types.VARCHAR, 16, 0, null, "The primary key", null, true, true, false,
+                     someTable.getColumn(0));
+
+        Table anotherTable = model.getTable(1);
+
+        assertEquals("AnotherTable", "And another table", 2, 0, 0, 1, 0,
+                     anotherTable);
+        assertEquals("Some_ID", Types.VARCHAR, 16, 0, null, "The foreign key", null, false, false, false,
+                     anotherTable.getColumn(0));
+
+        ForeignKey fk = anotherTable.getForeignKey(0);
+
+        assertEquals(null, CascadeActionEnum.NONE, CascadeActionEnum.NONE, someTable, 2, fk);
+        assertEquals(anotherTable.getColumn(0), someTable.getColumn(0), fk.getReference(0));
+        assertEquals(anotherTable.getColumn(1), someTable.getColumn(2), fk.getReference(1));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\">\n" +
+            "    <column name=\"ID\" primaryKey=\"true\" required=\"true\" type=\"VARCHAR\" size=\"16\" autoIncrement=\"false\" description=\"The primary key\" />\n" +
+            "    <column name=\"VALUE1\" primaryKey=\"false\" required=\"false\" type=\"INTEGER\" autoIncrement=\"false\" description=\"A value\" />\n" +
+            "    <column name=\"VALUE2\" primaryKey=\"false\" required=\"false\" type=\"DOUBLE\" autoIncrement=\"false\" description=\"Another value\" />\n" +
+            "  </table>\n" +
+            "  <table name=\"AnotherTable\" description=\"And another table\">\n" +
+            "    <column name=\"Some_ID\" primaryKey=\"false\" required=\"false\" type=\"VARCHAR\" size=\"16\" autoIncrement=\"false\" description=\"The foreign key\" />\n" +
+            "    <column name=\"Some_Value\" primaryKey=\"false\" required=\"false\" type=\"DOUBLE\" autoIncrement=\"false\" />\n" +
+            "    <foreign-key foreignTable=\"SomeTable\">\n" +
+            "      <reference local=\"Some_ID\" foreign=\"ID\" />\n" +
+            "      <reference local=\"Some_Value\" foreign=\"VALUE2\" />\n" +
+            "    </foreign-key>\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a foreign key without references.
+     */
+    public void testForeignKeyWithoutReferences()
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='SomeTable'\n" +
+                "         description='Some table'>\n" +
+                "    <column name='ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'\n" +
+                "            description='The primary key'/>\n" +
+                "  </table>\n" +
+                "  <table name='AnotherTable'\n" +
+                "         description='And another table'>\n" +
+                "    <column name='Some_ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            description='The foreign key'/>\n" +
+                "    <foreign-key foreignTable='SomeTable'>\n" +
+                "    </foreign-key>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+    /**
+     * Tests a database model containing a named foreignkey.
+     */
+    public void testNamedForeignkey() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='SomeTable'\n" +
+            "         description='Some table'>\n" +
+            "    <column name='ID'\n" +
+            "            type='VARCHAR'\n" +
+            "            size='16'\n" +
+            "            primaryKey='true'\n" +
+            "            required='true'\n" +
+            "            description='The primary key'/>\n" +
+            "  </table>\n" +
+            "  <table name='AnotherTable'\n" +
+            "         description='And another table'>\n" +
+            "    <column name='Some_ID'\n" +
+            "            type='VARCHAR'\n" +
+            "            size='16'\n" +
+            "            description='The foreign key'/>\n" +
+            "    <foreign-key name='The foreignkey' foreignTable='SomeTable'>\n" +
+            "       <reference local='Some_ID' foreign='ID'/>\n" +
+            "    </foreign-key>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(2, model.getTableCount());
+
+        Table someTable = model.getTable(0);
+
+        assertEquals("SomeTable", "Some table", 1, 1, 0, 0, 0,
+                     someTable);
+        assertEquals("ID", Types.VARCHAR, 16, 0, null, "The primary key", null, true, true, false,
+                     someTable.getColumn(0));
+
+        Table anotherTable = model.getTable(1);
+
+        assertEquals("AnotherTable", "And another table", 1, 0, 0, 1, 0,
+                     anotherTable);
+        assertEquals("Some_ID", Types.VARCHAR, 16, 0, null, "The foreign key", null, false, false, false,
+                     anotherTable.getColumn(0));
+
+        ForeignKey fk = anotherTable.getForeignKey(0);
+
+        assertEquals("The foreignkey", CascadeActionEnum.NONE, CascadeActionEnum.NONE, someTable, 1, fk);
+        assertEquals(anotherTable.getColumn(0), someTable.getColumn(0), fk.getReference(0));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\">\n" +
+            "    <column name=\"ID\" primaryKey=\"true\" required=\"true\" type=\"VARCHAR\" size=\"16\" autoIncrement=\"false\" description=\"The primary key\" />\n" +
+            "  </table>\n" +
+            "  <table name=\"AnotherTable\" description=\"And another table\">\n" +
+            "    <column name=\"Some_ID\" primaryKey=\"false\" required=\"false\" type=\"VARCHAR\" size=\"16\" autoIncrement=\"false\" description=\"The foreign key\" />\n" +
+            "    <foreign-key foreignTable=\"SomeTable\" name=\"The foreignkey\">\n" +
+            "      <reference local=\"Some_ID\" foreign=\"ID\" />\n" +
+            "    </foreign-key>\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a foreign key referencing a non-existing table.
+     */
+    public void testForeignKeyReferencingUndefinedTable()
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='SomeTable'\n" +
+                "         description='Some table'>\n" +
+                "    <column name='ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'\n" +
+                "            description='The primary key'/>\n" +
+                "  </table>\n" +
+                "  <table name='AnotherTable'\n" +
+                "         description='And another table'>\n" +
+                "    <column name='Some_ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            description='The foreign key'/>\n" +
+                "    <foreign-key foreignTable='TheTable'>\n" +
+                "       <reference local='Some_ID' foreign='ID'/>\n" +
+                "    </foreign-key>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+    /**
+     * Tests a foreign key using a non-existing column in the local table.
+     */
+    public void testForeignKeyUsingUndefinedColumn()
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='SomeTable'\n" +
+                "         description='Some table'>\n" +
+                "    <column name='ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'\n" +
+                "            description='The primary key'/>\n" +
+                "  </table>\n" +
+                "  <table name='AnotherTable'\n" +
+                "         description='And another table'>\n" +
+                "    <column name='Some_ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            description='The foreign key'/>\n" +
+                "    <foreign-key foreignTable='SomeTable'>\n" +
+                "       <reference local='ID' foreign='ID'/>\n" +
+                "    </foreign-key>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+    /**
+     * Tests a foreign key referencing a non-existing column in the foreign table.
+     */
+    public void testForeignKeyReferencingUndefinedColumn()
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='SomeTable'\n" +
+                "         description='Some table'>\n" +
+                "    <column name='ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'\n" +
+                "            description='The primary key'/>\n" +
+                "  </table>\n" +
+                "  <table name='AnotherTable'\n" +
+                "         description='And another table'>\n" +
+                "    <column name='Some_ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            description='The foreign key'/>\n" +
+                "    <foreign-key foreignTable='SomeTable'>\n" +
+                "       <reference local='Some_ID' foreign='TheID'/>\n" +
+                "    </foreign-key>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+    /**
+     * Tests a foreign key without a local column.
+     */
+    public void testForeignKeyWithoutLocalColumn()
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='SomeTable'\n" +
+                "         description='Some table'>\n" +
+                "    <column name='ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'\n" +
+                "            description='The primary key'/>\n" +
+                "  </table>\n" +
+                "  <table name='AnotherTable'\n" +
+                "         description='And another table'>\n" +
+                "    <column name='Some_ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            description='The foreign key'/>\n" +
+                "    <foreign-key foreignTable='SomeTable'>\n" +
+                "       <reference foreign='ID'/>\n" +
+                "    </foreign-key>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+    /**
+     * Tests a foreign key without a remote column.
+     */
+    public void testForeignKeyWithoutRemoteColumn()
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='SomeTable'\n" +
+                "         description='Some table'>\n" +
+                "    <column name='ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'\n" +
+                "            description='The primary key'/>\n" +
+                "  </table>\n" +
+                "  <table name='AnotherTable'\n" +
+                "         description='And another table'>\n" +
+                "    <column name='Some_ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            description='The foreign key'/>\n" +
+                "    <foreign-key foreignTable='SomeTable'>\n" +
+                "       <reference local='Some_ID'/>\n" +
+                "    </foreign-key>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+    /**
+     * Tests a database model containing two foreignkeys.
+     */
+    public void testTwoForeignkeys() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='SomeTable'\n" +
+            "         description='Some table'>\n" +
+            "    <column name='ID'\n" +
+            "            type='VARCHAR'\n" +
+            "            size='16'\n" +
+            "            primaryKey='true'\n" +
+            "            required='true'\n" +
+            "            description='The primary key'/>\n" +
+            "    <column name='VALUE1'\n" +
+            "            type='INTEGER'\n" +
+            "            required='false'\n" +
+            "            description='A value'/>\n" +
+            "    <column name='VALUE2'\n" +
+            "            type='DOUBLE'\n" +
+            "            required='false'\n" +
+            "            description='Another value'/>\n" +
+            "  </table>\n" +
+            "  <table name='AnotherTable'\n" +
+            "         description='And another table'>\n" +
+            "    <column name='Some_ID'\n" +
+            "            type='VARCHAR'\n" +
+            "            size='16'\n" +
+            "            description='The foreign key'/>\n" +
+            "    <column name='Some_Value'\n" +
+            "            type='DOUBLE'/>\n" +
+            "    <foreign-key foreignTable='SomeTable'>\n" +
+            "       <reference local='Some_ID' foreign='ID'/>\n" +
+            "    </foreign-key>\n" +
+            "    <foreign-key foreignTable='SomeTable'>\n" +
+            "       <reference local='Some_Value' foreign='VALUE2'/>\n" +
+            "    </foreign-key>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(2, model.getTableCount());
+
+        Table someTable = model.getTable(0);
+
+        assertEquals("SomeTable", "Some table", 3, 1, 0, 0, 0,
+                     someTable);
+        assertEquals("ID", Types.VARCHAR, 16, 0, null, "The primary key", null, true, true, false,
+                     someTable.getColumn(0));
+
+        Table anotherTable = model.getTable(1);
+
+        assertEquals("AnotherTable", "And another table", 2, 0, 0, 2, 0,
+                     anotherTable);
+        assertEquals("Some_ID", Types.VARCHAR, 16, 0, null, "The foreign key", null, false, false, false,
+                     anotherTable.getColumn(0));
+
+        ForeignKey fk = anotherTable.getForeignKey(0);
+
+        assertEquals(null, CascadeActionEnum.NONE, CascadeActionEnum.NONE, someTable, 1, fk);
+        assertEquals(anotherTable.getColumn(0), someTable.getColumn(0), fk.getReference(0));
+
+        fk = anotherTable.getForeignKey(1);
+
+        assertEquals(null, CascadeActionEnum.NONE, CascadeActionEnum.NONE, someTable, 1, fk);
+        assertEquals(anotherTable.getColumn(1), someTable.getColumn(2), fk.getReference(0));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"SomeTable\" description=\"Some table\">\n" +
+            "    <column name=\"ID\" primaryKey=\"true\" required=\"true\" type=\"VARCHAR\" size=\"16\" autoIncrement=\"false\" description=\"The primary key\" />\n" +
+            "    <column name=\"VALUE1\" primaryKey=\"false\" required=\"false\" type=\"INTEGER\" autoIncrement=\"false\" description=\"A value\" />\n" +
+            "    <column name=\"VALUE2\" primaryKey=\"false\" required=\"false\" type=\"DOUBLE\" autoIncrement=\"false\" description=\"Another value\" />\n" +
+            "  </table>\n" +
+            "  <table name=\"AnotherTable\" description=\"And another table\">\n" +
+            "    <column name=\"Some_ID\" primaryKey=\"false\" required=\"false\" type=\"VARCHAR\" size=\"16\" autoIncrement=\"false\" description=\"The foreign key\" />\n" +
+            "    <column name=\"Some_Value\" primaryKey=\"false\" required=\"false\" type=\"DOUBLE\" autoIncrement=\"false\" />\n" +
+            "    <foreign-key foreignTable=\"SomeTable\">\n" +
+            "      <reference local=\"Some_ID\" foreign=\"ID\" />\n" +
+            "    </foreign-key>\n" +
+            "    <foreign-key foreignTable=\"SomeTable\">\n" +
+            "      <reference local=\"Some_Value\" foreign=\"VALUE2\" />\n" +
+            "    </foreign-key>\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model containing two foreignkeys with the same name.
+     */
+    public void testTwoForeignkeysWithSameName() throws Exception
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='SomeTable'\n" +
+                "         description='Some table'>\n" +
+                "    <column name='ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'\n" +
+                "            description='The primary key'/>\n" +
+                "    <column name='VALUE1'\n" +
+                "            type='INTEGER'\n" +
+                "            required='false'\n" +
+                "            description='A value'/>\n" +
+                "    <column name='VALUE2'\n" +
+                "            type='DOUBLE'\n" +
+                "            required='false'\n" +
+                "            description='Another value'/>\n" +
+                "  </table>\n" +
+                "  <table name='AnotherTable'\n" +
+                "         description='And another table'>\n" +
+                "    <column name='Some_ID'\n" +
+                "            type='VARCHAR'\n" +
+                "            size='16'\n" +
+                "            description='The foreign key'/>\n" +
+                "    <column name='Some_Value'\n" +
+                "            type='DOUBLE'/>\n" +
+                "    <foreign-key name='The foreignkey' foreignTable='SomeTable'>\n" +
+                "       <reference local='Some_ID' foreign='ID'/>\n" +
+                "    </foreign-key>\n" +
+                "    <foreign-key name='The foreignkey' foreignTable='SomeTable'>\n" +
+                "       <reference local='Some_Value' foreign='VALUE2'/>\n" +
+                "    </foreign-key>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+    /**
+     * Tests a database model with an index.
+     */
+    public void testSingleIndex() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='TableWithIndex'>\n" +
+            "    <column name='id'\n" +
+            "            type='DOUBLE'\n" +
+            "            primaryKey='true'\n" +
+            "            required='true'/>\n" +
+            "    <column name='value'\n" +
+            "            type='SMALLINT'\n" +
+            "            default='1'/>\n" +
+            "    <index>\n" +
+            "      <index-column name='value'/>\n" +
+            "    </index>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
+
+        assertEquals("TableWithIndex", null, 2, 1, 0, 0, 1,
+                     table);
+        assertEquals("id", Types.DOUBLE, 0, 0, null, null, null, true, true, false,
+                     table.getColumn(0));
+        assertEquals("value", Types.SMALLINT, 0, 0, "1", null, null, false, false, false,
+                     table.getColumn(1));
+
+        Index index = table.getIndex(0);
+
+        assertEquals(null, false, 1, index);
+        assertEquals(table.getColumn(1), null, index.getColumn(0));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"TableWithIndex\">\n" +
+            "    <column name=\"id\" primaryKey=\"true\" required=\"true\" type=\"DOUBLE\" autoIncrement=\"false\" />\n" +
+            "    <column name=\"value\" primaryKey=\"false\" required=\"false\" type=\"SMALLINT\" default=\"1\" autoIncrement=\"false\" />\n" +
+            "    <index>\n" +
+            "      <index-column name=\"value\" />\n" +
+            "    </index>\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model with an index with two columns.
+     */
+    public void testIndexWithTwoColumns() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='TableWithIndex'>\n" +
+            "    <column name='id'\n" +
+            "            type='DOUBLE'\n" +
+            "            primaryKey='true'\n" +
+            "            required='true'/>\n" +
+            "    <column name='when'\n" +
+            "            type='TIMESTAMP'\n" +
+            "            required='true'/>\n" +
+            "    <column name='value'\n" +
+            "            type='SMALLINT'\n" +
+            "            default='1'/>\n" +
+            "    <index>\n" +
+            "      <index-column name='when'/>\n" +
+            "      <index-column name='id'/>\n" +
+            "    </index>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
+
+        assertEquals("TableWithIndex", null, 3, 1, 0, 0, 1,
+                     table);
+        assertEquals("id", Types.DOUBLE, 0, 0, null, null, null, true, true, false,
+                     table.getColumn(0));
+        assertEquals("when", Types.TIMESTAMP, 0, 0, null, null, null, false, true, false,
+                     table.getColumn(1));
+        assertEquals("value", Types.SMALLINT, 0, 0, "1", null, null, false, false, false,
+                     table.getColumn(2));
+
+        Index index = table.getIndex(0);
+
+        assertEquals(null, false, 2, index);
+        assertEquals(table.getColumn(1), null, index.getColumn(0));
+        assertEquals(table.getColumn(0), null, index.getColumn(1));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"TableWithIndex\">\n" +
+            "    <column name=\"id\" primaryKey=\"true\" required=\"true\" type=\"DOUBLE\" autoIncrement=\"false\" />\n" +
+            "    <column name=\"when\" primaryKey=\"false\" required=\"true\" type=\"TIMESTAMP\" autoIncrement=\"false\" />\n" +
+            "    <column name=\"value\" primaryKey=\"false\" required=\"false\" type=\"SMALLINT\" default=\"1\" autoIncrement=\"false\" />\n" +
+            "    <index>\n" +
+            "      <index-column name=\"when\" />\n" +
+            "      <index-column name=\"id\" />\n" +
+            "    </index>\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model with an index with a name.
+     */
+    public void testIndexWithName() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='TableWithIndex'>\n" +
+            "    <column name='id'\n" +
+            "            type='DOUBLE'\n" +
+            "            primaryKey='true'\n" +
+            "            required='true'/>\n" +
+            "    <column name='value'\n" +
+            "            type='SMALLINT'\n" +
+            "            default='1'/>\n" +
+            "    <index name='The Index'>\n" +
+            "      <index-column name='value'/>\n" +
+            "    </index>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
+
+        assertEquals("TableWithIndex", null, 2, 1, 0, 0, 1,
+                     table);
+        assertEquals("id", Types.DOUBLE, 0, 0, null, null, null, true, true, false,
+                     table.getColumn(0));
+        assertEquals("value", Types.SMALLINT, 0, 0, "1", null, null, false, false, false,
+                     table.getColumn(1));
+
+        Index index = table.getIndex(0);
+
+        assertEquals("The Index", false, 1, index);
+        assertEquals(table.getColumn(1), null, index.getColumn(0));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"TableWithIndex\">\n" +
+            "    <column name=\"id\" primaryKey=\"true\" required=\"true\" type=\"DOUBLE\" autoIncrement=\"false\" />\n" +
+            "    <column name=\"value\" primaryKey=\"false\" required=\"false\" type=\"SMALLINT\" default=\"1\" autoIncrement=\"false\" />\n" +
+            "    <index name=\"The Index\">\n" +
+            "      <index-column name=\"value\" />\n" +
+            "    </index>\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model with an index without index columns.
+     */
+    public void testIndexWithoutColumns() throws Exception
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='TableWithIndex'>\n" +
+                "    <column name='id'\n" +
+                "            type='DOUBLE'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'/>\n" +
+                "    <column name='value'\n" +
+                "            type='SMALLINT'\n" +
+                "            default='1'/>\n" +
+                "    <index>\n" +
+                "    </index>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+    /**
+     * Tests a database model with an index with an index column that references an undefined column.
+     */
+    public void testIndexWithUndefinedColumns() throws Exception
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='TableWithIndex'>\n" +
+                "    <column name='id'\n" +
+                "            type='DOUBLE'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'/>\n" +
+                "    <column name='value'\n" +
+                "            type='SMALLINT'\n" +
+                "            default='1'/>\n" +
+                "    <index>\n" +
+                "      <index-column name='theValue'/>\n" +
+                "    </index>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+    /**
+     * Tests a database model with an index with an index column that has no name.
+     */
+    public void testIndexWithNoNameColumn() throws Exception
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='TableWithIndex'>\n" +
+                "    <column name='id'\n" +
+                "            type='DOUBLE'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'/>\n" +
+                "    <column name='value'\n" +
+                "            type='SMALLINT'\n" +
+                "            default='1'/>\n" +
+                "    <index>\n" +
+                "      <index-column/>\n" +
+                "    </index>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+
+    /**
+     * Tests a database model with an unique index.
+     */
+    public void testSingleUniqueIndex() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='TableWithIndex'>\n" +
+            "    <column name='id'\n" +
+            "            type='DOUBLE'\n" +
+            "            primaryKey='true'\n" +
+            "            required='true'/>\n" +
+            "    <column name='value'\n" +
+            "            type='SMALLINT'\n" +
+            "            default='1'/>\n" +
+            "    <unique>\n" +
+            "      <unique-column name='value'/>\n" +
+            "    </unique>\n" +
+            "  </table>\n" +
+            "</database>");
 
-        ForeignKey fk = anotherTable.getForeignKey(0);
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
 
-        assertNull(fk.getName());
-        assertEquals(someTable,
-                     fk.getForeignTable());
-        assertEquals(someTable.getName(),
-                     fk.getForeignTableName());
-        assertEquals(1,
-                     fk.getReferenceCount());
+        assertEquals("TableWithIndex", null, 2, 1, 0, 0, 1,
+                     table);
+        assertEquals("id", Types.DOUBLE, 0, 0, null, null, null, true, true, false,
+                     table.getColumn(0));
+        assertEquals("value", Types.SMALLINT, 0, 0, "1", null, null, false, false, false,
+                     table.getColumn(1));
 
-        Reference ref = fk.getFirstReference();
+        Index index = table.getIndex(0);
 
-        assertEquals(fkColumn,
-                     ref.getLocalColumn());
-        assertEquals("Some_ID",
-                     ref.getLocalColumnName());
-        assertEquals(pkColumn,
-                     ref.getForeignColumn());
-        assertEquals("ID",
-                     ref.getForeignColumnName());
+        assertEquals(null, true, 1, index);
+        assertEquals(table.getColumn(1), null, index.getColumn(0));
 
         assertEquals(
-            "<?xml version=\"1.0\"?>\n<!DOCTYPE database SYSTEM \"" + LocalEntityResolver.DTD_PREFIX + "\">\n" +
-            "  <database name=\"test\">\n" +
-            "    <table name=\"SomeTable\" description=\"Some table\">\n" +
-            "      <column name=\"ID\" primaryKey=\"true\" required=\"true\" type=\"VARCHAR\" size=\"16\" autoIncrement=\"false\" description=\"The primary key\"/>\n" +
-            "    </table>\n" +
-            "    <table name=\"AnotherTable\" description=\"And another table\">\n" +
-            "      <column name=\"Some_ID\" primaryKey=\"false\" required=\"false\" type=\"VARCHAR\" size=\"16\" autoIncrement=\"false\" description=\"The foreign key\"/>\n" +
-            "      <foreign-key foreignTable=\"SomeTable\">\n" +
-            "        <reference local=\"Some_ID\" foreign=\"ID\"/>\n" +
-            "      </foreign-key>\n" +
-            "    </table>\n" +
-            "  </database>\n",
-            writeModel(model));
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"TableWithIndex\">\n" +
+            "    <column name=\"id\" primaryKey=\"true\" required=\"true\" type=\"DOUBLE\" autoIncrement=\"false\" />\n" +
+            "    <column name=\"value\" primaryKey=\"false\" required=\"false\" type=\"SMALLINT\" default=\"1\" autoIncrement=\"false\" />\n" +
+            "    <unique>\n" +
+            "      <unique-column name=\"value\" />\n" +
+            "    </unique>\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
     }
 
     /**
-     * Tests a database model with indices.
+     * Tests a database model with an unique index with two columns.
      */
-    public void testIndices1() throws Exception
+    public void testUniqueIndexWithTwoColumns() throws Exception
     {
         Database model = readModel(
             "<database name='test'>\n" +
-            "  <table name='TableWidthIndex'>\n" +
+            "  <table name='TableWithIndex'>\n" +
             "    <column name='id'\n" +
             "            type='DOUBLE'\n" +
             "            primaryKey='true'\n" +
@@ -288,138 +1677,195 @@
             "    <column name='value'\n" +
             "            type='SMALLINT'\n" +
             "            default='1'/>\n" +
-            "    <index name='test index'>\n" +
-            "      <index-column name='value'/>\n" +
-            "    </index>\n" +
-            "    <index>\n" +
-            "      <index-column name='when'/>\n" +
-            "      <index-column name='id'/>\n" +
-            "    </index>\n" +
+            "    <unique>\n" +
+            "      <unique-column name='when'/>\n" +
+            "      <unique-column name='id'/>\n" +
+            "    </unique>\n" +
             "  </table>\n" +
             "</database>");
 
-        assertEquals("test",
-                     model.getName());
-        assertEquals(1,
-                     model.getTableCount());
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
         
         Table table = model.getTable(0);
 
-        assertEquals("TableWidthIndex",
-                     table.getName());
-        assertNull(table.getDescription());
-        assertEquals(0, table.getAutoIncrementColumns().length);
-        assertEquals(3,
-                     table.getColumnCount());
-        assertEquals(0,
-                     table.getForeignKeyCount());
-        assertEquals(2,
-                     table.getIndexCount());
+        assertEquals("TableWithIndex", null, 3, 1, 0, 0, 1,
+                     table);
+        assertEquals("id", Types.DOUBLE, 0, 0, null, null, null, true, true, false,
+                     table.getColumn(0));
+        assertEquals("when", Types.TIMESTAMP, 0, 0, null, null, null, false, true, false,
+                     table.getColumn(1));
+        assertEquals("value", Types.SMALLINT, 0, 0, "1", null, null, false, false, false,
+                     table.getColumn(2));
 
-        Column column = table.getColumn(0);
+        Index index = table.getIndex(0);
+
+        assertEquals(null, true, 2, index);
+        assertEquals(table.getColumn(1), null, index.getColumn(0));
+        assertEquals(table.getColumn(0), null, index.getColumn(1));
+
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"TableWithIndex\">\n" +
+            "    <column name=\"id\" primaryKey=\"true\" required=\"true\" type=\"DOUBLE\" autoIncrement=\"false\" />\n" +
+            "    <column name=\"when\" primaryKey=\"false\" required=\"true\" type=\"TIMESTAMP\" autoIncrement=\"false\" />\n" +
+            "    <column name=\"value\" primaryKey=\"false\" required=\"false\" type=\"SMALLINT\" default=\"1\" autoIncrement=\"false\" />\n" +
+            "    <unique>\n" +
+            "      <unique-column name=\"when\" />\n" +
+            "      <unique-column name=\"id\" />\n" +
+            "    </unique>\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model with an unique index with a name.
+     */
+    public void testUniqueIndexWithName() throws Exception
+    {
+        Database model = readModel(
+            "<database name='test'>\n" +
+            "  <table name='TableWithIndex'>\n" +
+            "    <column name='id'\n" +
+            "            type='DOUBLE'\n" +
+            "            primaryKey='true'\n" +
+            "            required='true'/>\n" +
+            "    <column name='value'\n" +
+            "            type='SMALLINT'\n" +
+            "            default='1'/>\n" +
+            "    <unique name='The Index'>\n" +
+            "      <unique-column name='value'/>\n" +
+            "    </unique>\n" +
+            "  </table>\n" +
+            "</database>");
+
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
+        
+        Table table = model.getTable(0);
 
-        assertEquals("id",
-                     column.getName());
-        assertEquals("DOUBLE",
-                     column.getType());
-        assertEquals(Types.DOUBLE,
-                     column.getTypeCode());
-        assertTrue(column.isPrimaryKey());
-        assertTrue(column.isRequired());
-        assertFalse(column.isAutoIncrement());
-        assertNull(column.getDefaultValue());
-        assertNull(column.getDefaultValue());
-        assertNull(column.getDescription());
-
-        column = table.getColumn(1);
-
-        assertEquals("when",
-                     column.getName());
-        assertEquals("TIMESTAMP",
-                     column.getType());
-        assertEquals(Types.TIMESTAMP,
-                     column.getTypeCode());
-        assertFalse(column.isPrimaryKey());
-        assertTrue(column.isRequired());
-        assertFalse(column.isAutoIncrement());
-        assertNull(column.getDefaultValue());
-        assertNull(column.getDescription());
-
-        column = table.getColumn(2);
-
-        assertEquals("value",
-                     column.getName());
-        assertEquals("SMALLINT",
-                     column.getType());
-        assertEquals(Types.SMALLINT,
-                     column.getTypeCode());
-        assertFalse(column.isPrimaryKey());
-        assertFalse(column.isRequired());
-        assertFalse(column.isAutoIncrement());
-        assertEquals("1",
-                     column.getDefaultValue());
-        assertNull(column.getDescription());
+        assertEquals("TableWithIndex", null, 2, 1, 0, 0, 1,
+                     table);
+        assertEquals("id", Types.DOUBLE, 0, 0, null, null, null, true, true, false,
+                     table.getColumn(0));
+        assertEquals("value", Types.SMALLINT, 0, 0, "1", null, null, false, false, false,
+                     table.getColumn(1));
 
         Index index = table.getIndex(0);
 
-        assertEquals("test index",
-                     index.getName());
-        assertFalse(index.isUnique());
-        assertEquals(1,
-                     index.getColumnCount());
-
-        IndexColumn indexColumn = index.getColumn(0);
-
-        assertEquals("value",
-                     indexColumn.getName());
-        assertNull(indexColumn.getSize());
+        assertEquals("The Index", true, 1, index);
+        assertEquals(table.getColumn(1), null, index.getColumn(0));
 
-        index = table.getIndex(1);
+        assertEquals(
+            "<?xml version='1.0' encoding='UTF-8'?>\n" +
+            "<database name=\"test\">\n" +
+            "  <table name=\"TableWithIndex\">\n" +
+            "    <column name=\"id\" primaryKey=\"true\" required=\"true\" type=\"DOUBLE\" autoIncrement=\"false\" />\n" +
+            "    <column name=\"value\" primaryKey=\"false\" required=\"false\" type=\"SMALLINT\" default=\"1\" autoIncrement=\"false\" />\n" +
+            "    <unique name=\"The Index\">\n" +
+            "      <unique-column name=\"value\" />\n" +
+            "    </unique>\n" +
+            "  </table>\n" +
+            "</database>\n",
+            model);
+    }
+
+    /**
+     * Tests a database model with an unique index without index columns.
+     */
+    public void testUniqueIndexWithoutColumns() throws Exception
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='TableWithIndex'>\n" +
+                "    <column name='id'\n" +
+                "            type='DOUBLE'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'/>\n" +
+                "    <column name='value'\n" +
+                "            type='SMALLINT'\n" +
+                "            default='1'/>\n" +
+                "    <unique>\n" +
+                "    </unique>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+    /**
+     * Tests a database model with an unique index with an index column that references an undefined column.
+     */
+    public void testUniqueIndexWithUndefinedColumns() throws Exception
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='TableWithIndex'>\n" +
+                "    <column name='id'\n" +
+                "            type='DOUBLE'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'/>\n" +
+                "    <column name='value'\n" +
+                "            type='SMALLINT'\n" +
+                "            default='1'/>\n" +
+                "    <unique>\n" +
+                "      <unique-column name='theValue'/>\n" +
+                "    </unique>\n" +
+                "  </table>\n" +
+                "</database>");
+
+            fail();
+        }
+        catch (ModelException ex)
+        {}
+    }
+
+    /**
+     * Tests a database model with an unique index with an index column that has no name.
+     */
+    public void testUniqueIndexWithNoNameColumn() throws Exception
+    {
+        try
+        {
+            readModel(
+                "<database name='test'>\n" +
+                "  <table name='TableWithIndex'>\n" +
+                "    <column name='id'\n" +
+                "            type='DOUBLE'\n" +
+                "            primaryKey='true'\n" +
+                "            required='true'/>\n" +
+                "    <column name='value'\n" +
+                "            type='SMALLINT'\n" +
+                "            default='1'/>\n" +
+                "    <unique>\n" +
+                "      <unique-column/>\n" +
+                "    </unique>\n" +
+                "  </table>\n" +
+                "</database>");
 
-        assertNull(index.getName());
-        assertFalse(index.isUnique());
-        assertEquals(2,
-                     index.getColumnCount());
-
-        indexColumn = index.getColumn(0);
-
-        assertEquals("when",
-                     indexColumn.getName());
-        assertNull(indexColumn.getSize());
-
-        indexColumn = index.getColumn(1);
-
-        assertEquals("id",
-                     indexColumn.getName());
-        assertNull(indexColumn.getSize());
-
-        assertEquals(
-            "<?xml version=\"1.0\"?>\n<!DOCTYPE database SYSTEM \"" + LocalEntityResolver.DTD_PREFIX + "\">\n" +
-            "  <database name=\"test\">\n" +
-            "    <table name=\"TableWidthIndex\">\n" +
-            "      <column name=\"id\" primaryKey=\"true\" required=\"true\" type=\"DOUBLE\" autoIncrement=\"false\"/>\n" +
-            "      <column name=\"when\" primaryKey=\"false\" required=\"true\" type=\"TIMESTAMP\" autoIncrement=\"false\"/>\n" +
-            "      <column name=\"value\" primaryKey=\"false\" required=\"false\" type=\"SMALLINT\" default=\"1\" autoIncrement=\"false\"/>\n" +
-            "      <index name=\"test index\">\n" +
-            "        <index-column name=\"value\"/>\n" +
-            "      </index>\n" +
-            "      <index>\n" +
-            "        <index-column name=\"when\"/>\n" +
-            "        <index-column name=\"id\"/>\n" +
-            "      </index>\n" +
-            "    </table>\n" +
-            "  </database>\n",
-            writeModel(model));
+            fail();
+        }
+        catch (ModelException ex)
+        {}
     }
 
     /**
      * Tests a database model with indices, both uniques and non-uniques.
      */
-    public void testIndices2() throws Exception
+    public void testMixedIndexes() throws Exception
     {
         Database model = readModel(
             "<database name='test'>\n" +
-            "  <table name='TableWidthIndices'>\n" +
+            "  <table name='TableWithIndexes'>\n" +
             "    <column name='id'\n" +
             "            type='SMALLINT'\n" +
             "            primaryKey='false'\n" +
@@ -436,97 +1882,44 @@
             "  </table>\n" +
             "</database>");
 
-        assertEquals("test",
-                     model.getName());
-        assertEquals(1,
-                     model.getTableCount());
+        assertEquals("test", model.getName());
+        assertEquals(1, model.getTableCount());
         
         Table table = model.getTable(0);
 
-        assertEquals("TableWidthIndices",
-                     table.getName());
-        assertNull(table.getDescription());
-        assertEquals(2,
-                     table.getColumnCount());
-        assertEquals(0,
-                     table.getForeignKeyCount());
-        assertEquals(2,
-                     table.getIndexCount());
-
-        Column column = table.getColumn(0);
-
-        assertEquals("id",
-                     column.getName());
-        assertEquals("SMALLINT",
-                     column.getType());
-        assertEquals(Types.SMALLINT,
-                     column.getTypeCode());
-        assertFalse(column.isPrimaryKey());
-        assertTrue(column.isRequired());
-        assertTrue(column.isAutoIncrement());
-        assertNull(column.getDefaultValue());
-        assertNull(column.getDefaultValue());
-        assertNull(column.getDescription());
-        
-        assertEquals(1, table.getAutoIncrementColumns().length);
-        assertEquals(column, table.getAutoIncrementColumns()[0]);
-
-        column = table.getColumn(1);
-
-        assertEquals("when",
-                     column.getName());
-        assertEquals("DATE",
-                     column.getType());
-        assertEquals(Types.DATE,
-                     column.getTypeCode());
-        assertFalse(column.isPrimaryKey());
-        assertFalse(column.isRequired());
-        assertFalse(column.isAutoIncrement());
-        assertNull(column.getDefaultValue());
-        assertNull(column.getDescription());
+        assertEquals("TableWithIndexes", null, 2, 0, 1, 0, 2,
+                     table);
+        assertEquals("id", Types.SMALLINT, 0, 0, null, null, null, false, true, true,
+                     table.getColumn(0));
+        assertEquals("when", Types.DATE, 0, 0, null, null, null, false, false, false,
+                     table.getColumn(1));
+        assertEquals(table.getColumn(0), table.getAutoIncrementColumns()[0]);
 
         Index index = table.getIndex(0);
 
-        assertEquals("important column",
-                     index.getName());
-        assertTrue(index.isUnique());
-        assertEquals(1,
-                     index.getColumnCount());
-
-        IndexColumn indexColumn = index.getColumn(0);
-
-        assertEquals("id",
-                     indexColumn.getName());
-        assertNull(indexColumn.getSize());
+        assertEquals("important column", true, 1, index);
+        assertEquals(table.getColumn(0), null, index.getColumn(0));
 
         index = table.getIndex(1);
 
-        assertNull(index.getName());
-        assertFalse(index.isUnique());
-        assertEquals(1,
-                     index.getColumnCount());
-
-        indexColumn = index.getColumn(0);
-
-        assertEquals("when",
-                     indexColumn.getName());
-        assertNull(indexColumn.getSize());
-
-        assertEquals(

[... 679 lines stripped ...]


Mime
View raw message