Fixed update() implementation for primary key updates
Adjusted onUpdate/onDelete tests
git-svn-id: https://svn.apache.org/repos/asf/db/ddlutils/trunk@576220 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/java/org/apache/ddlutils/Platform.java b/src/java/org/apache/ddlutils/Platform.java
index 18f9be5..d0e3e57 100644
--- a/src/java/org/apache/ddlutils/Platform.java
+++ b/src/java/org/apache/ddlutils/Platform.java
@@ -815,7 +815,8 @@
public void insert(Connection connection, Database model, Collection dynaBeans) throws DatabaseOperationException;
/**
- * Returns the sql for updating the given bean in the database.
+ * Returns the sql for updating the given bean in the database. Note that this method can not be used to
+ * generate SQL for updating primary key columns.
*
* @param model The database model to use
* @param dynaBean The bean
@@ -824,7 +825,19 @@
public String getUpdateSql(Database model, DynaBean dynaBean);
/**
- * Updates the given bean in the database, assuming the primary key values are specified.
+ * Returns the sql for updating the given bean in the database. Note that this method can not be used to
+ * generate SQL for updating primary key columns.
+ *
+ * @param model The database model to use
+ * @param oldDynaBean The bean identifying the row to update
+ * @param newDynaBean The bean containing the new values
+ * @return The update sql
+ */
+ public String getUpdateSql(Database model, DynaBean oldDynaBean, DynaBean newDynaBan);
+
+ /**
+ * Updates the given bean in the database, assuming the primary key values are specified. Note that this means
+ * that this method will not update the primary key columns.
*
* @param model The database model to use
* @param dynaBean The bean
@@ -832,7 +845,8 @@
public void update(Database model, DynaBean dynaBean) throws DatabaseOperationException;
/**
- * Updates the row which maps to the given bean.
+ * Updates the row which maps to the given bean. Note that this means that this method will not update the
+ * primary key columns.
*
* @param connection The database connection
* @param model The database model to use
@@ -842,7 +856,7 @@
/**
* Updates the row identified by the given <code>oldDynaBean</code> in the database with the
- * values in <code>newDynaBean</code>.
+ * values in <code>newDynaBean</code>. This method can be used to update primary key columns.
*
* @param model The database model to use
* @param oldDynaBean The bean identifying the row (which means the primary key fields need to be specified)
@@ -852,7 +866,7 @@
/**
* Updates the row identified by the given <code>oldDynaBean</code> in the database with the
- * values in <code>newDynaBean</code>.
+ * values in <code>newDynaBean</code>. This method can be used to update primary key columns.
*
* @param connection The database connection
* @param model The database model to use
diff --git a/src/java/org/apache/ddlutils/PlatformInfo.java b/src/java/org/apache/ddlutils/PlatformInfo.java
index 11842eb..970144d 100644
--- a/src/java/org/apache/ddlutils/PlatformInfo.java
+++ b/src/java/org/apache/ddlutils/PlatformInfo.java
@@ -56,9 +56,6 @@
/** Whether embedded foreign key constraints are explicitly named. */
private boolean _embeddedForeignKeysNamed = false;
- /** Whether the set-default action is supportd for onDelete/onUpdate in a foreign key. */
- private boolean _setDefaultActionSupported = true;
-
/** Whether non-unique indices are supported. */
private boolean _indicesSupported = true;
@@ -290,28 +287,6 @@
}
/**
- * Determines whether the set-default action is supported for onUpdate/onDelete
- * in foreign keys.
- *
- * @return <code>true</code> if set-default is supported
- */
- public boolean isSetDefaultActionSupported()
- {
- return _setDefaultActionSupported;
- }
-
- /**
- * Specifies whether the set-default action is supported for onUpdate/onDelete
- * in foreign keys.
- *
- * @param setDefaultActionSupported <code>true</code> if set-default is supported
- */
- public void setSetDefaultActionSupported(boolean setDefaultActionSupported)
- {
- _setDefaultActionSupported = setDefaultActionSupported;
- }
-
- /**
* Determines whether indices are supported.
*
* @return <code>true</code> if indices are supported
diff --git a/src/java/org/apache/ddlutils/platform/PlatformImplBase.java b/src/java/org/apache/ddlutils/platform/PlatformImplBase.java
index d52f697..fd93fb5 100644
--- a/src/java/org/apache/ddlutils/platform/PlatformImplBase.java
+++ b/src/java/org/apache/ddlutils/platform/PlatformImplBase.java
@@ -1599,100 +1599,71 @@
}
/**
- * {@inheritDoc}
+ * Creates the SQL for updating an object of the given type. If a concrete bean is given,
+ * then a concrete update statement is created, otherwise an update statement usable in a
+ * prepared statement is build.
+ *
+ * @param model The database model
+ * @param dynaClass The type
+ * @param primaryKeys The primary keys
+ * @param properties The properties to write
+ * @param bean Optionally the concrete bean to update
+ * @return The SQL required to update the instance
*/
- public String getUpdateSql(Database model, DynaBean dynaBean)
+ protected String createUpdateSql(Database model, SqlDynaClass dynaClass, SqlDynaProperty[] primaryKeys, SqlDynaProperty[] properties, DynaBean oldBean, DynaBean newBean)
{
- SqlDynaClass dynaClass = model.getDynaClassFor(dynaBean);
- SqlDynaProperty[] primaryKeys = dynaClass.getPrimaryKeyProperties();
+ Table table = model.findTable(dynaClass.getTableName());
+ HashMap oldColumnValues = toColumnValues(primaryKeys, oldBean);
+ HashMap newColumnValues = toColumnValues(properties, newBean);
if (primaryKeys.length == 0)
{
_log.info("Cannot update instances of type " + dynaClass + " because it has no primary keys");
return null;
}
-
- return createUpdateSql(model, dynaClass, primaryKeys, dynaClass.getNonPrimaryKeyProperties(), dynaBean);
+ else
+ {
+ return _builder.getUpdateSql(table, oldColumnValues, newColumnValues, newBean == null);
+ }
}
/**
* {@inheritDoc}
*/
- public void update(Connection connection, Database model, DynaBean oldDynaBean, DynaBean newDynaBean) throws DatabaseOperationException
+ public String getUpdateSql(Database model, DynaBean dynaBean)
{
- SqlDynaClass dynaClass = model.getDynaClassFor(oldDynaBean);
- SqlDynaProperty[] primaryKeys = dynaClass.getPrimaryKeyProperties();
+ SqlDynaClass dynaClass = model.getDynaClassFor(dynaBean);
+ SqlDynaProperty[] primaryKeys = dynaClass.getPrimaryKeyProperties();
+ SqlDynaProperty[] nonPrimaryKeys = dynaClass.getNonPrimaryKeyProperties();
- if (!dynaClass.getTable().equals(model.getDynaClassFor(newDynaBean)))
- {
- throw new DatabaseOperationException("The old and new dyna beans need to be for the same table");
- }
if (primaryKeys.length == 0)
{
_log.info("Cannot update instances of type " + dynaClass + " because it has no primary keys");
- return;
+ return null;
}
-
- SqlDynaProperty[] properties = dynaClass.getSqlDynaProperties();
- String sql = createUpdateSql(model, dynaClass, primaryKeys, properties, null);
- PreparedStatement statement = null;
-
- if (_log.isDebugEnabled())
+ else
{
- _log.debug("About to execute SQL: " + sql);
- }
- try
- {
- beforeUpdate(connection, dynaClass.getTable());
-
- statement = connection.prepareStatement(sql);
-
- int sqlIndex = 1;
-
- for (int idx = 0; idx < properties.length; idx++)
- {
- setObject(statement, sqlIndex++, newDynaBean, properties[idx]);
- }
- for (int idx = 0; idx < primaryKeys.length; idx++)
- {
- setObject(statement, sqlIndex++, oldDynaBean, primaryKeys[idx]);
- }
-
- int count = statement.executeUpdate();
-
- afterUpdate(connection, dynaClass.getTable());
-
- if (count != 1)
- {
- _log.warn("Attempted to insert a single row " + newDynaBean +
- " into table " + dynaClass.getTableName() +
- " but changed " + count + " row(s)");
- }
- }
- catch (SQLException ex)
- {
- throw new DatabaseOperationException("Error while updating in the database", ex);
- }
- finally
- {
- closeStatement(statement);
+ return createUpdateSql(model, dynaClass, primaryKeys, nonPrimaryKeys, dynaBean);
}
}
/**
* {@inheritDoc}
*/
- public void update(Database model, DynaBean oldDynaBean, DynaBean newDynaBean) throws DatabaseOperationException
+ public String getUpdateSql(Database model, DynaBean oldDynaBean, DynaBean newDynaBean)
{
- Connection connection = borrowConnection();
+ SqlDynaClass dynaClass = model.getDynaClassFor(oldDynaBean);
+ SqlDynaProperty[] primaryKeys = dynaClass.getPrimaryKeyProperties();
+ SqlDynaProperty[] nonPrimaryKeys = dynaClass.getNonPrimaryKeyProperties();
- try
+ if (primaryKeys.length == 0)
{
- update(connection, model, oldDynaBean, newDynaBean);
+ _log.info("Cannot update instances of type " + dynaClass + " because it has no primary keys");
+ return null;
}
- finally
+ else
{
- returnConnection(connection);
+ return createUpdateSql(model, dynaClass, primaryKeys, nonPrimaryKeys, oldDynaBean, newDynaBean);
}
}
@@ -1774,6 +1745,87 @@
}
/**
+ * {@inheritDoc}
+ */
+ public void update(Connection connection, Database model, DynaBean oldDynaBean, DynaBean newDynaBean) throws DatabaseOperationException
+ {
+ SqlDynaClass dynaClass = model.getDynaClassFor(oldDynaBean);
+ SqlDynaProperty[] primaryKeys = dynaClass.getPrimaryKeyProperties();
+
+ if (!dynaClass.getTable().equals(model.getDynaClassFor(newDynaBean).getTable()))
+ {
+ throw new DatabaseOperationException("The old and new dyna beans need to be for the same table");
+ }
+ if (primaryKeys.length == 0)
+ {
+ _log.info("Cannot update instances of type " + dynaClass + " because it has no primary keys");
+ return;
+ }
+
+ SqlDynaProperty[] properties = dynaClass.getSqlDynaProperties();
+ String sql = createUpdateSql(model, dynaClass, primaryKeys, properties, null, null);
+ PreparedStatement statement = null;
+
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("About to execute SQL: " + sql);
+ }
+ try
+ {
+ beforeUpdate(connection, dynaClass.getTable());
+
+ statement = connection.prepareStatement(sql);
+
+ int sqlIndex = 1;
+
+ for (int idx = 0; idx < properties.length; idx++)
+ {
+ setObject(statement, sqlIndex++, newDynaBean, properties[idx]);
+ }
+ for (int idx = 0; idx < primaryKeys.length; idx++)
+ {
+ setObject(statement, sqlIndex++, oldDynaBean, primaryKeys[idx]);
+ }
+
+ int count = statement.executeUpdate();
+
+ afterUpdate(connection, dynaClass.getTable());
+
+ if (count != 1)
+ {
+ _log.warn("Attempted to insert a single row " + newDynaBean +
+ " into table " + dynaClass.getTableName() +
+ " but changed " + count + " row(s)");
+ }
+ }
+ catch (SQLException ex)
+ {
+ throw new DatabaseOperationException("Error while updating in the database", ex);
+ }
+ finally
+ {
+ closeStatement(statement);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void update(Database model, DynaBean oldDynaBean, DynaBean newDynaBean) throws DatabaseOperationException
+ {
+ Connection connection = borrowConnection();
+
+ try
+ {
+ update(connection, model, oldDynaBean, newDynaBean);
+ }
+ finally
+ {
+ returnConnection(connection);
+ }
+ }
+
+ /**
* Allows platforms to issue statements directly before rows are updated in
* the specified table.
*
diff --git a/src/java/org/apache/ddlutils/platform/SqlBuilder.java b/src/java/org/apache/ddlutils/platform/SqlBuilder.java
index 6cb31fb..10d4dae 100644
--- a/src/java/org/apache/ddlutils/platform/SqlBuilder.java
+++ b/src/java/org/apache/ddlutils/platform/SqlBuilder.java
@@ -1526,7 +1526,61 @@
*/
public String getUpdateSql(Table table, Map columnValues, boolean genPlaceholders)
{
- return getUpdateSql(table, columnValues, columnValues, genPlaceholders);
+ StringBuffer buffer = new StringBuffer("UPDATE ");
+ boolean addSep = false;
+
+ buffer.append(getDelimitedIdentifier(getTableName(table)));
+ buffer.append(" SET ");
+
+ for (int idx = 0; idx < table.getColumnCount(); idx++)
+ {
+ Column column = table.getColumn(idx);
+
+ if (!column.isPrimaryKey() && columnValues.containsKey(column.getName()))
+ {
+ if (addSep)
+ {
+ buffer.append(", ");
+ }
+ buffer.append(getDelimitedIdentifier(column.getName()));
+ buffer.append(" = ");
+ if (genPlaceholders)
+ {
+ buffer.append("?");
+ }
+ else
+ {
+ buffer.append(getValueAsString(column, columnValues.get(column.getName())));
+ }
+ addSep = true;
+ }
+ }
+ buffer.append(" WHERE ");
+ addSep = false;
+ for (int idx = 0; idx < table.getColumnCount(); idx++)
+ {
+ Column column = table.getColumn(idx);
+
+ if (column.isPrimaryKey() && columnValues.containsKey(column.getName()))
+ {
+ if (addSep)
+ {
+ buffer.append(" AND ");
+ }
+ buffer.append(getDelimitedIdentifier(column.getName()));
+ buffer.append(" = ");
+ if (genPlaceholders)
+ {
+ buffer.append("?");
+ }
+ else
+ {
+ buffer.append(getValueAsString(column, columnValues.get(column.getName())));
+ }
+ addSep = true;
+ }
+ }
+ return buffer.toString();
}
/**
@@ -1536,9 +1590,7 @@
*
* @param table The table
* @param oldColumnValues Contains the column values to identify the row to update
- * @param columnValues Contains the values for the columns to update, and should also
- * contain the primary key values to identify the object to update
- * in case <code>genPlaceholders</code> is <code>false</code>
+ * @param newColumnValues Contains the values for the columns to update
* @param genPlaceholders Whether to generate value placeholders for a
* prepared statement (both for the pk values and the object values)
* @return The update sql
@@ -1555,7 +1607,7 @@
{
Column column = table.getColumn(idx);
- if (!column.isPrimaryKey() && newColumnValues.containsKey(column.getName()))
+ if (newColumnValues.containsKey(column.getName()))
{
if (addSep)
{
@@ -1580,7 +1632,7 @@
{
Column column = table.getColumn(idx);
- if (column.isPrimaryKey() && oldColumnValues.containsKey(column.getName()))
+ if (oldColumnValues.containsKey(column.getName()))
{
if (addSep)
{
@@ -2599,6 +2651,9 @@
case CascadeActionEnum.VALUE_SET_NULL:
print("SET NULL");
break;
+ case CascadeActionEnum.VALUE_SET_DEFAULT:
+ print("SET DEFAULT");
+ break;
case CascadeActionEnum.VALUE_RESTRICT:
print("RESTRICT");
break;
@@ -2631,6 +2686,9 @@
case CascadeActionEnum.VALUE_SET_NULL:
print("SET NULL");
break;
+ case CascadeActionEnum.VALUE_SET_DEFAULT:
+ print("SET DEFAULT");
+ break;
case CascadeActionEnum.VALUE_RESTRICT:
print("RESTRICT");
break;
diff --git a/src/java/org/apache/ddlutils/platform/derby/DerbyPlatform.java b/src/java/org/apache/ddlutils/platform/derby/DerbyPlatform.java
index 5d26c7b..d0a162f 100644
--- a/src/java/org/apache/ddlutils/platform/derby/DerbyPlatform.java
+++ b/src/java/org/apache/ddlutils/platform/derby/DerbyPlatform.java
@@ -51,7 +51,6 @@
public DerbyPlatform()
{
super();
- getPlatformInfo().setSetDefaultActionSupported(false);
getPlatformInfo().addNativeTypeMapping(Types.DOUBLE, "DOUBLE");
getPlatformInfo().addNativeTypeMapping(Types.FLOAT, "DOUBLE", Types.DOUBLE);
setSqlBuilder(new DerbyBuilder(this));
diff --git a/src/test/org/apache/ddlutils/io/TestConstraints.java b/src/test/org/apache/ddlutils/io/TestConstraints.java
index 85c334d..b294637 100644
--- a/src/test/org/apache/ddlutils/io/TestConstraints.java
+++ b/src/test/org/apache/ddlutils/io/TestConstraints.java
@@ -25,6 +25,7 @@
import org.apache.commons.lang.StringUtils;
import org.apache.ddlutils.DdlUtilsException;
import org.apache.ddlutils.model.Database;
+import org.apache.ddlutils.platform.derby.DerbyPlatform;
import org.apache.ddlutils.platform.sybase.SybasePlatform;
import junit.framework.Test;
@@ -580,7 +581,7 @@
*/
public void testForeignKeyWithOnDeleteSetDefault()
{
- if (getPlatformInfo().isSetDefaultActionSupported())
+ if (!DerbyPlatform.DATABASENAME.equals(getPlatform().getName()))
{
final String modelXml =
"<?xml version='1.0' encoding='ISO-8859-1'?>\n"+
@@ -590,7 +591,7 @@
" </table>\n"+
" <table name='roundtrip_2'>\n"+
" <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+
- " <column name='avalue' type='INTEGER' required='false' default='0'/>\n"+
+ " <column name='avalue' type='INTEGER' required='false' default='2'/>\n"+
" <foreign-key foreignTable='roundtrip_1' onDelete='setdefault'>\n"+
" <reference local='avalue' foreign='pk'/>\n"+
" </foreign-key>\n"+
@@ -600,14 +601,16 @@
performConstraintsTest(modelXml, true);
insertRow("roundtrip_1", new Object[] { new Integer(1) });
+ insertRow("roundtrip_1", new Object[] { new Integer(2) });
insertRow("roundtrip_2", new Object[] { new Integer(5), new Integer(1) });
List beansTable1 = getRows("roundtrip_1");
List beansTable2 = getRows("roundtrip_2");
- assertEquals(1, beansTable1.size());
+ assertEquals(2, beansTable1.size());
assertEquals(1, beansTable2.size());
assertEquals(new Integer(1), beansTable1.get(0), "pk");
+ assertEquals(new Integer(2), beansTable1.get(1), "pk");
assertEquals(new Integer(5), beansTable2.get(0), "pk");
assertEquals(new Integer(1), beansTable2.get(0), "avalue");
@@ -616,10 +619,11 @@
beansTable1 = getRows("roundtrip_1");
beansTable2 = getRows("roundtrip_2");
- assertEquals(0, beansTable1.size());
+ assertEquals(1, beansTable1.size());
assertEquals(1, beansTable2.size());
+ assertEquals(new Integer(2), beansTable1.get(0), "pk");
assertEquals(new Integer(5), beansTable2.get(0), "pk");
- assertEquals(new Integer(0), beansTable2.get(0), "avalue");
+ assertEquals(new Integer(2), beansTable2.get(0), "avalue");
}
}
@@ -671,99 +675,7 @@
*/
public void testForeignKeyWithOnUpdateCascade()
{
- final String modelXml =
- "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+
- "<database name='roundtriptest'>\n"+
- " <table name='roundtrip_1'>\n"+
- " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+
- " </table>\n"+
- " <table name='roundtrip_2'>\n"+
- " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+
- " <column name='avalue' type='INTEGER' required='true'/>\n"+
- " <foreign-key foreignTable='roundtrip_1' onUpdate='cascade'>\n"+
- " <reference local='avalue' foreign='pk'/>\n"+
- " </foreign-key>\n"+
- " </table>\n"+
- "</database>";
-
- performConstraintsTest(modelXml, true);
-
- insertRow("roundtrip_1", new Object[] { new Integer(1) });
- insertRow("roundtrip_2", new Object[] { new Integer(5), new Integer(1) });
-
- List beansTable1 = getRows("roundtrip_1");
- List beansTable2 = getRows("roundtrip_2");
-
- assertEquals(1, beansTable1.size());
- assertEquals(1, beansTable2.size());
- assertEquals(new Integer(1), beansTable1.get(0), "pk");
- assertEquals(new Integer(5), beansTable2.get(0), "pk");
- assertEquals(new Integer(1), beansTable2.get(0), "avalue");
-
- updateRow("roundtrip_1", (DynaBean)beansTable1.get(0), new Object[] { new Integer(2) });
-
- beansTable1 = getRows("roundtrip_1");
- beansTable2 = getRows("roundtrip_2");
-
- assertEquals(1, beansTable1.size());
- assertEquals(1, beansTable2.size());
- assertEquals(new Integer(2), beansTable1.get(0), "pk");
- assertEquals(new Integer(5), beansTable2.get(0), "pk");
- assertEquals(new Integer(2), beansTable2.get(0), "avalue");
- }
-
- /**
- * Tests two tables with a foreign key with a set-null onUpdate action.
- */
- public void testForeignKeyWithOnUpdateSetNull()
- {
- final String modelXml =
- "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+
- "<database name='roundtriptest'>\n"+
- " <table name='roundtrip_1'>\n"+
- " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+
- " </table>\n"+
- " <table name='roundtrip_2'>\n"+
- " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+
- " <column name='avalue' type='INTEGER' required='false'/>\n"+
- " <foreign-key foreignTable='roundtrip_1' onUpdate='setnull'>\n"+
- " <reference local='avalue' foreign='pk'/>\n"+
- " </foreign-key>\n"+
- " </table>\n"+
- "</database>";
-
- performConstraintsTest(modelXml, true);
-
- insertRow("roundtrip_1", new Object[] { new Integer(1) });
- insertRow("roundtrip_2", new Object[] { new Integer(5), new Integer(1) });
-
- List beansTable1 = getRows("roundtrip_1");
- List beansTable2 = getRows("roundtrip_2");
-
- assertEquals(1, beansTable1.size());
- assertEquals(1, beansTable2.size());
- assertEquals(new Integer(1), beansTable1.get(0), "pk");
- assertEquals(new Integer(5), beansTable2.get(0), "pk");
- assertEquals(new Integer(1), beansTable2.get(0), "avalue");
-
- updateRow("roundtrip_1", (DynaBean)beansTable1.get(0), new Object[] { new Integer(2) });
-
- beansTable1 = getRows("roundtrip_1");
- beansTable2 = getRows("roundtrip_2");
-
- assertEquals(1, beansTable1.size());
- assertEquals(1, beansTable2.size());
- assertEquals(new Integer(2), beansTable1.get(0), "pk");
- assertEquals(new Integer(5), beansTable2.get(0), "pk");
- assertEquals((Object)null, beansTable2.get(0), "avalue");
- }
-
- /**
- * Tests two tables with a foreign key with a det-default onUpdate action.
- */
- public void testForeignKeyWithOnUpdateSetDefault()
- {
- if (getPlatformInfo().isSetDefaultActionSupported())
+ if (!DerbyPlatform.DATABASENAME.equals(getPlatform().getName()))
{
final String modelXml =
"<?xml version='1.0' encoding='ISO-8859-1'?>\n"+
@@ -773,7 +685,105 @@
" </table>\n"+
" <table name='roundtrip_2'>\n"+
" <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+
- " <column name='avalue' type='INTEGER' required='false' default='2'/>\n"+
+ " <column name='avalue' type='INTEGER' required='true'/>\n"+
+ " <foreign-key foreignTable='roundtrip_1' onUpdate='cascade'>\n"+
+ " <reference local='avalue' foreign='pk'/>\n"+
+ " </foreign-key>\n"+
+ " </table>\n"+
+ "</database>";
+
+ performConstraintsTest(modelXml, true);
+
+ insertRow("roundtrip_1", new Object[] { new Integer(1) });
+ insertRow("roundtrip_2", new Object[] { new Integer(5), new Integer(1) });
+
+ List beansTable1 = getRows("roundtrip_1");
+ List beansTable2 = getRows("roundtrip_2");
+
+ assertEquals(1, beansTable1.size());
+ assertEquals(1, beansTable2.size());
+ assertEquals(new Integer(1), beansTable1.get(0), "pk");
+ assertEquals(new Integer(5), beansTable2.get(0), "pk");
+ assertEquals(new Integer(1), beansTable2.get(0), "avalue");
+
+ updateRow("roundtrip_1", (DynaBean)beansTable1.get(0), new Object[] { new Integer(2) });
+
+ beansTable1 = getRows("roundtrip_1");
+ beansTable2 = getRows("roundtrip_2");
+
+ assertEquals(1, beansTable1.size());
+ assertEquals(1, beansTable2.size());
+ assertEquals(new Integer(2), beansTable1.get(0), "pk");
+ assertEquals(new Integer(5), beansTable2.get(0), "pk");
+ assertEquals(new Integer(2), beansTable2.get(0), "avalue");
+ }
+ }
+
+ /**
+ * Tests two tables with a foreign key with a set-null onUpdate action.
+ */
+ public void testForeignKeyWithOnUpdateSetNull()
+ {
+ if (!DerbyPlatform.DATABASENAME.equals(getPlatform().getName()))
+ {
+ final String modelXml =
+ "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+
+ "<database name='roundtriptest'>\n"+
+ " <table name='roundtrip_1'>\n"+
+ " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+
+ " </table>\n"+
+ " <table name='roundtrip_2'>\n"+
+ " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+
+ " <column name='avalue' type='INTEGER' required='false'/>\n"+
+ " <foreign-key foreignTable='roundtrip_1' onUpdate='setnull'>\n"+
+ " <reference local='avalue' foreign='pk'/>\n"+
+ " </foreign-key>\n"+
+ " </table>\n"+
+ "</database>";
+
+ performConstraintsTest(modelXml, true);
+
+ insertRow("roundtrip_1", new Object[] { new Integer(1) });
+ insertRow("roundtrip_2", new Object[] { new Integer(5), new Integer(1) });
+
+ List beansTable1 = getRows("roundtrip_1");
+ List beansTable2 = getRows("roundtrip_2");
+
+ assertEquals(1, beansTable1.size());
+ assertEquals(1, beansTable2.size());
+ assertEquals(new Integer(1), beansTable1.get(0), "pk");
+ assertEquals(new Integer(5), beansTable2.get(0), "pk");
+ assertEquals(new Integer(1), beansTable2.get(0), "avalue");
+
+ updateRow("roundtrip_1", (DynaBean)beansTable1.get(0), new Object[] { new Integer(2) });
+
+ beansTable1 = getRows("roundtrip_1");
+ beansTable2 = getRows("roundtrip_2");
+
+ assertEquals(1, beansTable1.size());
+ assertEquals(1, beansTable2.size());
+ assertEquals(new Integer(2), beansTable1.get(0), "pk");
+ assertEquals(new Integer(5), beansTable2.get(0), "pk");
+ assertEquals((Object)null, beansTable2.get(0), "avalue");
+ }
+ }
+
+ /**
+ * Tests two tables with a foreign key with a det-default onUpdate action.
+ */
+ public void testForeignKeyWithOnUpdateSetDefault()
+ {
+ if (!DerbyPlatform.DATABASENAME.equals(getPlatform().getName()))
+ {
+ final String modelXml =
+ "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+
+ "<database name='roundtriptest'>\n"+
+ " <table name='roundtrip_1'>\n"+
+ " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+
+ " </table>\n"+
+ " <table name='roundtrip_2'>\n"+
+ " <column name='pk' type='INTEGER' primaryKey='true' required='true'/>\n"+
+ " <column name='avalue' type='INTEGER' required='false' default='1'/>\n"+
" <foreign-key foreignTable='roundtrip_1' onUpdate='setdefault'>\n"+
" <reference local='avalue' foreign='pk'/>\n"+
" </foreign-key>\n"+
@@ -784,7 +794,7 @@
insertRow("roundtrip_1", new Object[] { new Integer(1) });
insertRow("roundtrip_1", new Object[] { new Integer(2) });
- insertRow("roundtrip_2", new Object[] { new Integer(5), new Integer(1) });
+ insertRow("roundtrip_2", new Object[] { new Integer(5), new Integer(2) });
List beansTable1 = getRows("roundtrip_1");
List beansTable2 = getRows("roundtrip_2");
@@ -794,19 +804,19 @@
assertEquals(new Integer(1), beansTable1.get(0), "pk");
assertEquals(new Integer(2), beansTable1.get(1), "pk");
assertEquals(new Integer(5), beansTable2.get(0), "pk");
- assertEquals(new Integer(1), beansTable2.get(0), "avalue");
+ assertEquals(new Integer(2), beansTable2.get(0), "avalue");
- updateRow("roundtrip_1", (DynaBean)beansTable1.get(0), new Object[] { new Integer(0) });
+ updateRow("roundtrip_1", (DynaBean)beansTable1.get(1), new Object[] { new Integer(0) });
beansTable1 = getRows("roundtrip_1");
beansTable2 = getRows("roundtrip_2");
assertEquals(2, beansTable1.size());
assertEquals(1, beansTable2.size());
- assertEquals(new Integer(0), beansTable1.get(0), "pk");
- assertEquals(new Integer(2), beansTable1.get(1), "pk");
+ assertEquals(new Integer(1), beansTable1.get(0), "pk");
+ assertEquals(new Integer(0), beansTable1.get(1), "pk");
assertEquals(new Integer(5), beansTable2.get(0), "pk");
- assertEquals(new Integer(2), beansTable2.get(0), "avalue");
+ assertEquals(new Integer(1), beansTable2.get(0), "avalue");
}
}
}
diff --git a/src/test/org/apache/ddlutils/platform/TestSqlBuilder.java b/src/test/org/apache/ddlutils/platform/TestSqlBuilder.java
index afe1bd8..b51a3e6 100644
--- a/src/test/org/apache/ddlutils/platform/TestSqlBuilder.java
+++ b/src/test/org/apache/ddlutils/platform/TestSqlBuilder.java
@@ -36,7 +36,7 @@
/**
* Tests the {@link SqlBuilder#getUpdateSql(Table, Map, boolean)} method.
*/
- public void testUpdateSql()
+ public void testUpdateSql1()
{
final String modelXml =
"<?xml version='1.0' encoding='ISO-8859-1'?>\n"+
@@ -62,4 +62,37 @@
assertEquals("UPDATE \"TestTable\" SET \"name\" = 'ddlutils' WHERE \"id\" = '0'",
sql);
}
+
+ /**
+ * Tests the {@link SqlBuilder#getUpdateSql(Table, Map, Map, boolean)} method.
+ */
+ public void testUpdateSql2()
+ {
+ final String modelXml =
+ "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+
+ "<database name='ddlutils'>\n"+
+ " <table name='TestTable'>\n"+
+ " <column name='id' autoIncrement='true' type='INTEGER' primaryKey='true'/>\n"+
+ " <column name='name' type='VARCHAR' size='15'/>\n"+
+ " </table>\n"+
+ "</database>";
+
+ TestPlatform platform = new TestPlatform();
+ SqlBuilder sqlBuilder = platform.getSqlBuilder();
+ Database database = parseDatabaseFromString(modelXml);
+ Map oldMap = new HashMap();
+ Map newMap = new HashMap();
+
+ oldMap.put("id", new Integer(0));
+
+ newMap.put("name", "ddlutils");
+ newMap.put("id", new Integer(1));
+
+ platform.setDelimitedIdentifierModeOn(true);
+
+ String sql = sqlBuilder.getUpdateSql(database.getTable(0), oldMap, newMap, false);
+
+ assertEquals("UPDATE \"TestTable\" SET \"id\" = '1', \"name\" = 'ddlutils' WHERE \"id\" = '0'",
+ sql);
+ }
}