Author: tomdz Date: Sun Jan 28 19:21:02 2007 New Revision: 500929 URL: http://svn.apache.org/viewvc?view=rev&rev=500929 Log: Fixed DDLUTILS-150 Added ability to define table creation parameters for the tests Adjusted the MySQL sample test jdbc properties so that InnoDB tables are created
Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/model/ForeignKey.java db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/mysql/MySqlBuilder.java db/ddlutils/trunk/src/test/jdbc.properties.mysql db/ddlutils/trunk/src/test/jdbc.properties.mysql50 db/ddlutils/trunk/src/test/org/apache/ddlutils/TestDatabaseWriterBase.java db/ddlutils/trunk/src/test/org/apache/ddlutils/TestSummaryCreatorTask.java db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestAlteration.java db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestMisc.java Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/model/ForeignKey.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/model/ForeignKey.java?view=diff&rev=500929&r1=500928&r2=500929 ============================================================================== --- db/ddlutils/trunk/src/java/org/apache/ddlutils/model/ForeignKey.java (original) +++ db/ddlutils/trunk/src/java/org/apache/ddlutils/model/ForeignKey.java Sun Jan 28 19:21:02 2007 @@ -34,13 +34,15 @@ public class ForeignKey implements Cloneable { /** The name of the foreign key, may be <code>null</code>. */ - private String _name; + private String _name; /** The target table. */ - private Table _foreignTable; + private Table _foreignTable; /** The name of the foreign table. */ - private String _foreignTableName; + private String _foreignTableName; /** The references between local and remote columns. */ private ListOrderedSet _references = new ListOrderedSet(); + /** Whether this foreign key has an associated auto-generated index. */ + private boolean _autoIndexPresent; /** * Creates a new foreign key object that has no name. @@ -213,6 +215,26 @@ public void removeReference(int idx) { _references.remove(idx); + } + + /** + * Determines whether this foreign key has an auto-generated associated index. + * + * @return <code>true</code> if an auto-generated index exists + */ + public boolean isAutoIndexPresent() + { + return _autoIndexPresent; + } + + /** + * Specifies whether this foreign key has an auto-generated associated index. + * + * @param autoIndexPresent <code>true</code> if an auto-generated index exists + */ + public void setAutoIndexPresent(boolean autoIndexPresent) + { + _autoIndexPresent = autoIndexPresent; } /** Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java?view=diff&rev=500929&r1=500928&r2=500929 ============================================================================== --- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java (original) +++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/JdbcModelReader.java Sun Jan 28 19:21:02 2007 @@ -651,6 +651,7 @@ if (!index.isUnique() && matches(index, columnNames) && isInternalForeignKeyIndex(metaData, table, fk, index)) { + fk.setAutoIndexPresent(true); table.removeIndex(indexIdx); break; } Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/mysql/MySqlBuilder.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/mysql/MySqlBuilder.java?view=diff&rev=500929&r1=500928&r2=500929 ============================================================================== --- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/mysql/MySqlBuilder.java (original) +++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/mysql/MySqlBuilder.java Sun Jan 28 19:21:02 2007 @@ -152,10 +152,14 @@ print("DROP FOREIGN KEY "); printIdentifier(getForeignKeyName(table, foreignKey)); printEndOfStatement(); - writeTableAlterStmt(table); - print("DROP INDEX "); - printIdentifier(getForeignKeyName(table, foreignKey)); - printEndOfStatement(); + + if (foreignKey.isAutoIndexPresent()) + { + writeTableAlterStmt(table); + print("DROP INDEX "); + printIdentifier(getForeignKeyName(table, foreignKey)); + printEndOfStatement(); + } } /** Modified: db/ddlutils/trunk/src/test/jdbc.properties.mysql URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/jdbc.properties.mysql?view=diff&rev=500929&r1=500928&r2=500929 ============================================================================== --- db/ddlutils/trunk/src/test/jdbc.properties.mysql (original) +++ db/ddlutils/trunk/src/test/jdbc.properties.mysql Sun Jan 28 19:21:02 2007 @@ -13,4 +13,7 @@ datasource.driverClassName=com.mysql.jdbc.Driver datasource.url=jdbc:mysql://localhost/ddlutils datasource.username=root -datasource.password=root123 +datasource.password= + +# We want to test against InnoDB tables (so that we get e.g. foreign keys) +ddlutils.tableCreation.ENGINE=InnoDB Modified: db/ddlutils/trunk/src/test/jdbc.properties.mysql50 URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/jdbc.properties.mysql50?view=diff&rev=500929&r1=500928&r2=500929 ============================================================================== --- db/ddlutils/trunk/src/test/jdbc.properties.mysql50 (original) +++ db/ddlutils/trunk/src/test/jdbc.properties.mysql50 Sun Jan 28 19:21:02 2007 @@ -3,7 +3,7 @@ # class configured via the datasource.class property # Use this property if ddlutils does not recognize the platform from the settings -ddlutils.platform=MySql50 +ddlutils.platform=MySql5 # # Using the plain DBCP datasource @@ -13,4 +13,7 @@ datasource.driverClassName=com.mysql.jdbc.Driver datasource.url=jdbc:mysql://localhost/ddlutils datasource.username=root -datasource.password=root123 +datasource.password= + +# We want to test against InnoDB tables (so that we get e.g. foreign keys) +ddlutils.tableCreation.ENGINE=InnoDB Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/TestDatabaseWriterBase.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/TestDatabaseWriterBase.java?view=diff&rev=500929&r1=500928&r2=500929 ============================================================================== --- db/ddlutils/trunk/src/test/org/apache/ddlutils/TestDatabaseWriterBase.java (original) +++ db/ddlutils/trunk/src/test/org/apache/ddlutils/TestDatabaseWriterBase.java Sun Jan 28 19:21:02 2007 @@ -35,6 +35,7 @@ import org.apache.ddlutils.io.DataReader; import org.apache.ddlutils.io.DataToDatabaseSink; import org.apache.ddlutils.model.Database; +import org.apache.ddlutils.platform.CreationParameters; /** * Base class for database writer tests. @@ -50,7 +51,13 @@ /** The prefix for properties for ddlutils. */ public static final String DDLUTILS_PROPERTY_PREFIX = "ddlutils."; /** The property for specifying the platform. */ - public static final String PLATFORM_PROPERTY = DDLUTILS_PROPERTY_PREFIX + "platform"; + public static final String DDLUTILS_PLATFORM_PROPERTY = DDLUTILS_PROPERTY_PREFIX + "platform"; + /** The property specifying the catalog for the tests. */ + public static final String DDLUTILS_CATALOG_PROPERTY = DDLUTILS_PROPERTY_PREFIX + "catalog"; + /** The property specifying the schema for the tests. */ + public static final String DDLUTILS_SCHEMA_PROPERTY = DDLUTILS_PROPERTY_PREFIX + "schema"; + /** The prefix for table creation properties. */ + public static final String DDLUTILS_TABLE_CREATION_PREFIX = DDLUTILS_PROPERTY_PREFIX + "tableCreation."; /** The test properties as defined by an external properties file. */ private static Properties _testProps; @@ -144,7 +151,7 @@ throw new DatabaseOperationException(ex); } - _databaseName = props.getProperty(PLATFORM_PROPERTY); + _databaseName = props.getProperty(DDLUTILS_PLATFORM_PROPERTY); if (_databaseName == null) { // property not set, then try to determine @@ -157,6 +164,34 @@ } /** + * Returns the test table creation parameters for the given model. + * + * @param model The model + * @return The creation parameters + */ + protected CreationParameters getTableCreationParameters(Database model) + { + CreationParameters params = new CreationParameters(); + + for (Iterator entryIt = _testProps.entrySet().iterator(); entryIt.hasNext();) + { + Map.Entry entry = (Map.Entry)entryIt.next(); + String name = (String)entry.getKey(); + String value = (String)entry.getValue(); + + if (name.startsWith(DDLUTILS_TABLE_CREATION_PREFIX)) + { + name = name.substring(DDLUTILS_TABLE_CREATION_PREFIX.length()); + for (int tableIdx = 0; tableIdx < model.getTableCount(); tableIdx++) + { + params.addParameter(model.getTable(tableIdx), name, value); + } + } + } + return params; + } + + /** * Returns the data source. * * @return The data source @@ -232,7 +267,7 @@ _model = model; getPlatform().setSqlCommentsOn(false); - getPlatform().createTables(_model, false, false); + getPlatform().createTables(_model, getTableCreationParameters(_model), false, false); } catch (Exception ex) { @@ -262,8 +297,8 @@ protected void alterDatabase(Database model) throws DatabaseOperationException { Properties props = getTestProperties(); - String catalog = props.getProperty(DDLUTILS_PROPERTY_PREFIX + "catalog"); - String schema = props.getProperty(DDLUTILS_PROPERTY_PREFIX + "schema"); + String catalog = props.getProperty(DDLUTILS_CATALOG_PROPERTY); + String schema = props.getProperty(DDLUTILS_SCHEMA_PROPERTY); try { @@ -271,7 +306,7 @@ _model.resetDynaClassCache(); getPlatform().setSqlCommentsOn(false); - getPlatform().alterTables(catalog, schema, null, _model, false); + getPlatform().alterTables(catalog, schema, null, _model, getTableCreationParameters(_model), false); } catch (Exception ex) { @@ -321,8 +356,8 @@ protected Database readModelFromDatabase(String databaseName) { Properties props = getTestProperties(); - String catalog = props.getProperty(DDLUTILS_PROPERTY_PREFIX + "catalog"); - String schema = props.getProperty(DDLUTILS_PROPERTY_PREFIX + "schema"); + String catalog = props.getProperty(DDLUTILS_CATALOG_PROPERTY); + String schema = props.getProperty(DDLUTILS_SCHEMA_PROPERTY); return getPlatform().readModelFromDatabase(databaseName, catalog, schema, null); } @@ -336,8 +371,8 @@ protected String getAlterTablesSql(Database desiredModel) { Properties props = getTestProperties(); - String catalog = props.getProperty(DDLUTILS_PROPERTY_PREFIX + "catalog"); - String schema = props.getProperty(DDLUTILS_PROPERTY_PREFIX + "schema"); + String catalog = props.getProperty(DDLUTILS_CATALOG_PROPERTY); + String schema = props.getProperty(DDLUTILS_SCHEMA_PROPERTY); return getPlatform().getAlterTablesSql(catalog, schema, null, desiredModel); } Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/TestSummaryCreatorTask.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/TestSummaryCreatorTask.java?view=diff&rev=500929&r1=500928&r2=500929 ============================================================================== --- db/ddlutils/trunk/src/test/org/apache/ddlutils/TestSummaryCreatorTask.java (original) +++ db/ddlutils/trunk/src/test/org/apache/ddlutils/TestSummaryCreatorTask.java Sun Jan 28 19:21:02 2007 @@ -304,7 +304,7 @@ } } - String platformName = props.getProperty(TestDatabaseWriterBase.PLATFORM_PROPERTY); + String platformName = props.getProperty(TestDatabaseWriterBase.DDLUTILS_PLATFORM_PROPERTY); if (platformName == null) { Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestAlteration.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestAlteration.java?view=diff&rev=500929&r1=500928&r2=500929 ============================================================================== --- db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestAlteration.java (original) +++ db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestAlteration.java Sun Jan 28 19:21:02 2007 @@ -127,6 +127,55 @@ } /** + * Tests the alteration of the datatypes of PK and FK columns. + */ + public void testChangePKAndFKDatatypes() + { + final String model1Xml = + "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+ + "<database name='roundtriptest'>\n"+ + " <table name='roundtrip1'>\n"+ + " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+ + " </table>\n"+ + " <table name='roundtrip2'>\n"+ + " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+ + " <column name='fk' type='INTEGER' required='false'/>\n"+ + " <foreign-key foreignTable='roundtrip1'>\n"+ + " <reference local='fk' foreign='pk'/>\n"+ + " </foreign-key>\n"+ + " </table>\n"+ + "</database>"; + final String model2Xml = + "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+ + "<database name='roundtriptest'>\n"+ + " <table name='roundtrip1'>\n"+ + " <column name='pk' type='VARCHAR' primaryKey='true' required='true'/>\n"+ + " </table>\n"+ + " <table name='roundtrip2'>\n"+ + " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+ + " <column name='fk' type='VARCHAR' required='false'/>\n"+ + " <foreign-key foreignTable='roundtrip1'>\n"+ + " <reference local='fk' foreign='pk'/>\n"+ + " </foreign-key>\n"+ + " </table>\n"+ + "</database>"; + + createDatabase(model1Xml); + + insertRow("roundtrip1", new Object[] { new Integer(1) }); + insertRow("roundtrip2", new Object[] { new Integer(1), new Integer(1) }); + + alterDatabase(model2Xml); + + assertEquals(getAdjustedModel(), + readModelFromDatabase("roundtriptest")); + + List beans = getRows("roundtrip2"); + + assertEquals((Object)"1", beans.get(0), "fk"); + } + + /** * Tests the alteration of a column size. */ public void testChangeSize() @@ -1443,6 +1492,91 @@ } /** + * Tests the removal of several foreign keys. Test for DDLUTILS-150. + */ + public void testDropFKs() + { + final String model1Xml = + "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+ + "<database name='roundtriptest'>\n"+ + " <table name='roundtrip1'>\n"+ + " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+ + " </table>\n"+ + " <table name='roundtrip2'>\n"+ + " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+ + " </table>\n"+ + " <table name='roundtrip3'>\n"+ + " <column name='pk1' type='INTEGER' primaryKey='true' required='true'/>\n"+ + " <column name='pk2' type='INTEGER' primaryKey='true' required='true'/>\n"+ + " </table>\n"+ + " <table name='roundtrip4'>\n"+ + " <column name='pk' primaryKey='true' required='true' type='INTEGER' />\n"+ + " <column name='fk1' required='true' type='INTEGER' />\n"+ + " <column name='fk2' type='INTEGER' required='false' />\n"+ + " <foreign-key name='roundtrip1_fk' foreignTable='roundtrip1'>\n"+ + " <reference foreign='pk' local='pk' />\n"+ + " </foreign-key>\n"+ + " <foreign-key name='roundtrip2_fk1' foreignTable='roundtrip2'>\n"+ + " <reference foreign='pk' local='fk1' />\n"+ + " </foreign-key>\n"+ + " <foreign-key name='roundtrip2_fk2' foreignTable='roundtrip2'>\n"+ + " <reference foreign='pk' local='fk2' />\n"+ + " </foreign-key>\n"+ + " <foreign-key name='roundtrip3_fk' foreignTable='roundtrip3'>\n"+ + " <reference foreign='pk1' local='pk' />\n"+ + " <reference foreign='pk2' local='fk2' />\n"+ + " </foreign-key>\n"+ + " </table> \n"+ + "</database>"; + final String model2Xml = + "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+ + "<database name='roundtriptest'>\n"+ + " <table name='roundtrip1'>\n"+ + " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+ + " </table>\n"+ + " <table name='roundtrip2'>\n"+ + " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+ + " </table>\n"+ + " <table name='roundtrip3'>\n"+ + " <column name='pk1' type='INTEGER' primaryKey='true' required='true'/>\n"+ + " <column name='pk2' type='INTEGER' primaryKey='true' required='true'/>\n"+ + " </table>\n"+ + " <table name='roundtrip4'>\n"+ + " <column name='pk' primaryKey='true' required='true' type='INTEGER' />\n"+ + " <column name='fk1' required='true' type='INTEGER' />\n"+ + " <column name='fk2' type='INTEGER' required='false' />\n"+ + " </table> \n"+ + "</database>"; + + createDatabase(model1Xml); + + insertRow("roundtrip1", new Object[] { new Integer(1) }); + insertRow("roundtrip2", new Object[] { new Integer(2) }); + insertRow("roundtrip2", new Object[] { new Integer(3) }); + insertRow("roundtrip3", new Object[] { new Integer(1), new Integer(2) }); + insertRow("roundtrip4", new Object[] { new Integer(1), new Integer(3), new Integer(2) }); + + alterDatabase(model2Xml); + + assertEquals(getAdjustedModel(), + readModelFromDatabase("roundtriptest")); + + List beans1 = getRows("roundtrip1"); + List beans2 = getRows("roundtrip2"); + List beans3 = getRows("roundtrip3"); + List beans4 = getRows("roundtrip4"); + + assertEquals(new Integer(1), beans1.get(0), "pk"); + assertEquals(new Integer(2), beans2.get(0), "pk"); + assertEquals(new Integer(3), beans2.get(1), "pk"); + assertEquals(new Integer(1), beans3.get(0), "pk1"); + assertEquals(new Integer(2), beans3.get(0), "pk2"); + assertEquals(new Integer(1), beans4.get(0), "pk"); + assertEquals(new Integer(3), beans4.get(0), "fk1"); + assertEquals(new Integer(2), beans4.get(0), "fk2"); + } + + /** * Tests the addition of a reference to a foreign key. */ public void testAddReferenceToFK() @@ -1825,8 +1959,8 @@ createDatabase(modelXml); Properties props = getTestProperties(); - String catalog = props.getProperty(DDLUTILS_PROPERTY_PREFIX + "catalog"); - String schema = props.getProperty(DDLUTILS_PROPERTY_PREFIX + "schema"); + String catalog = props.getProperty(DDLUTILS_CATALOG_PROPERTY); + String schema = props.getProperty(DDLUTILS_SCHEMA_PROPERTY); Database model = parseDatabaseFromString(modelXml); getPlatform().setSqlCommentsOn(false); Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestMisc.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestMisc.java?view=diff&rev=500929&r1=500928&r2=500929 ============================================================================== --- db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestMisc.java (original) +++ db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestMisc.java Sun Jan 28 19:21:02 2007 @@ -486,6 +486,78 @@ } /** + * Tests the backup and restore of a self-referencing data set (with multiple self references + * in the same table). + */ + public void testMultiSelfReferences() throws Exception + { + if (!getPlatformInfo().isIdentityOverrideAllowed()) + { + // TODO: for testing these platforms, we need deleteRows + return; + } + + final String modelXml = + "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+ + "<database name='roundtriptest'>\n"+ + " <table name='misc'>\n"+ + " <column name='id' primaryKey='true' required='true' type='SMALLINT' size='2' autoIncrement='true'/>\n"+ + " <column name='left_id' primaryKey='false' required='false' type='SMALLINT' size='2' autoIncrement='false'/>\n"+ + " <column name='right_id' primaryKey='false' required='false' type='SMALLINT' size='2' autoIncrement='false'/>\n"+ + " <foreign-key foreignTable='misc' name='misc_left_fk'>\n"+ + " <reference local='left_id' foreign='id'/>\n"+ + " </foreign-key>\n"+ + " <foreign-key foreignTable='misc' name='misc_right_fk'>\n"+ + " <reference local='right_id' foreign='id'/>\n"+ + " </foreign-key>\n"+ + " </table>\n"+ + "</database>"; + final String dataXml = + "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+ + "<data>\n"+ + " <misc id='1' left_id='2' right_id='3'/>\n"+ + " <misc id='3' left_id='2' right_id='4'/>\n"+ + " <misc id='2' left_id='5' right_id='4'/>\n"+ + " <misc id='5' right_id='6'/>\n"+ + " <misc id='6'/>\n"+ + " <misc id='4' left_id='6'/>\n"+ + "</data>"; + + createDatabase(modelXml); + + getPlatform().setIdentityOverrideOn(true); + + DatabaseDataIO dataIO = new DatabaseDataIO(); + StringReader stringReader = new StringReader(dataXml); + + dataIO.writeDataToDatabase(getPlatform(), new Reader[] { stringReader }); + + List beans = getRows("misc"); + + assertEquals(6, beans.size()); + // this is the order of actual insertion (the fk order) + // expected insertion order is: 6, 5, 4, 2, 3, 1 + assertEquals(new Integer(6), beans.get(0), "id"); + assertEquals((Object)null, beans.get(0), "left_id"); + assertEquals((Object)null, beans.get(0), "right_id"); + assertEquals(new Integer(5), beans.get(1), "id"); + assertEquals((Object)null, beans.get(1), "left_id"); + assertEquals(new Integer(6), beans.get(1), "right_id"); + assertEquals(new Integer(4), beans.get(2), "id"); + assertEquals(new Integer(6), beans.get(2), "left_id"); + assertEquals((Object)null, beans.get(2), "right_id"); + assertEquals(new Integer(2), beans.get(3), "id"); + assertEquals(new Integer(5), beans.get(3), "left_id"); + assertEquals(new Integer(4), beans.get(3), "right_id"); + assertEquals(new Integer(3), beans.get(4), "id"); + assertEquals(new Integer(2), beans.get(4), "left_id"); + assertEquals(new Integer(4), beans.get(4), "right_id"); + assertEquals(new Integer(1), beans.get(5), "id"); + assertEquals(new Integer(2), beans.get(5), "left_id"); + assertEquals(new Integer(3), beans.get(5), "right_id"); + } + + /** * Tests the backup and restore of several tables with complex relationships with an identity column and a foreign key to * itself while identity override is off. */