Fix for DDLUTILS-214: Primary Key Column order lost (a problem if there are multiple Primary Keys)
git-svn-id: https://svn.apache.org/repos/asf/db/ddlutils/trunk@684633 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/ddlutils/platform/SqlBuilder.java b/src/main/java/org/apache/ddlutils/platform/SqlBuilder.java
index fb52445..33f8d2a 100644
--- a/src/main/java/org/apache/ddlutils/platform/SqlBuilder.java
+++ b/src/main/java/org/apache/ddlutils/platform/SqlBuilder.java
@@ -1052,12 +1052,15 @@
}
/**
- * Creates the SQL for deleting an object from the specified table.
- * If values are given then a concrete delete statement is created, otherwise an
- * delete statement usable in a prepared statement is build.
+ * Creates the SQL for deleting an object from the specified table. Depending on
+ * the value of <code>genPlaceholders</code>, the generated SQL will contain
+ * prepared statement place holders or concrete values. Only those primary key
+ * columns wil be used that are present in the given map. If the map is null or
+ * completely empty, then the SQL will not have a WHERE clause. The SQL will contain
+ * the columns in the order defined in the table.
*
* @param table The table
- * @param pkValues The primary key values indexed by the column names, can be empty
+ * @param pkValues The primary key columns to use, and optionally their values
* @param genPlaceholders Whether to generate value placeholders for a
* prepared statement
* @return The delete sql
@@ -1071,26 +1074,30 @@
if ((pkValues != null) && !pkValues.isEmpty())
{
buffer.append(" WHERE ");
- for (Iterator it = pkValues.entrySet().iterator(); it.hasNext();)
+
+ Column[] pkCols = table.getPrimaryKeyColumns();
+
+ for (int pkColIdx = 0; pkColIdx < pkCols.length; pkColIdx++)
{
- Map.Entry entry = (Map.Entry)it.next();
- Column column = table.findColumn((String)entry.getKey());
-
- if (addSep)
- {
- buffer.append(" AND ");
+ Column column = pkCols[pkColIdx];
+
+ if (pkValues.containsKey(column.getName())) {
+ if (addSep)
+ {
+ buffer.append(" AND ");
+ }
+ buffer.append(getDelimitedIdentifier(column.getName()));
+ buffer.append(" = ");
+ if (genPlaceholders)
+ {
+ buffer.append("?");
+ }
+ else
+ {
+ buffer.append(getValueAsString(column, pkValues.get(column.getName())));
+ }
+ addSep = true;
}
- buffer.append(getDelimitedIdentifier(entry.getKey().toString()));
- buffer.append(" = ");
- if (genPlaceholders)
- {
- buffer.append("?");
- }
- else
- {
- buffer.append(column == null ? entry.getValue() : getValueAsString(column, entry.getValue()));
- }
- addSep = true;
}
}
return buffer.toString();
diff --git a/src/test/java/org/apache/ddlutils/io/TestMisc.java b/src/test/java/org/apache/ddlutils/io/TestMisc.java
index 7c3da99..8b2c8d4 100644
--- a/src/test/java/org/apache/ddlutils/io/TestMisc.java
+++ b/src/test/java/org/apache/ddlutils/io/TestMisc.java
@@ -1058,11 +1058,11 @@
" <database xmlns='" + DatabaseIO.DDLUTILS_NAMESPACE + "' name='roundtriptest'>\n"+
" <table name='ad_sequence_no'>\n"+
" <column name='ad_sequence_id' required='true' type='NUMERIC' size='10'/>\n"+
- " <column name='year' required='true' type='VARCHAR' size='4' default='0000'/>\n"+
+ " <column name='ad_year' required='true' type='VARCHAR' size='4' default='0000'/>\n"+
" <column name='ad_client_id' required='true' type='NUMERIC' size='10'/>\n"+
" <unique name='ad_sequence_no_key'>\n"+
" <unique-column name='ad_sequence_id'/>\n"+
- " <unique-column name='year'/>\n"+
+ " <unique-column name='ad_year'/>\n"+
" </unique>\n"+
" </table>\n"+
"</database>";
@@ -1157,4 +1157,62 @@
}
}
}
+
+ /**
+ * Test for DDLUTILS-214.
+ */
+ public void testDdlUtils214() throws Exception
+ {
+ final String modelXml =
+ "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+
+ "<database xmlns='" + DatabaseIO.DDLUTILS_NAMESPACE + "' name='roundtriptest'>\n"+
+ " <table name='roundtrip1'>\n"+
+ " <column name='pk1' type='INTEGER' primaryKey='true' required='true'/>\n"+
+ " <column name='pk2' type='VARCHAR' primaryKey='true' required='true'/>\n"+
+ " </table>\n"+
+ " <table name='roundtrip2'>\n"+
+ " <column name='pk2' type='VARCHAR' primaryKey='true' required='true'/>\n"+
+ " <column name='pk1' type='INTEGER' primaryKey='true' required='true'/>\n"+
+ " </table>\n"+
+ "</database>";
+
+ createDatabase(modelXml);
+
+ Database readModel = readModelFromDatabase("roundtriptest");
+
+ assertEquals(getAdjustedModel(),
+ readModel);
+
+ insertRow("roundtrip1", new Object[] { new Integer(1), "foo" });
+ insertRow("roundtrip1", new Object[] { new Integer(2), "bar" });
+ insertRow("roundtrip2", new Object[] { "foo", new Integer(1) });
+ insertRow("roundtrip2", new Object[] { "bar", new Integer(2) });
+
+ List beans1 = getRows("roundtrip1", "pk1");
+ List beans2 = getRows("roundtrip2", "pk1");
+
+ assertEquals(2, beans1.size());
+ assertEquals(2, beans2.size());
+ assertEquals(new Integer(1), beans1.get(0), "pk1");
+ assertEquals((Object)"foo", beans1.get(0), "pk2");
+ assertEquals(new Integer(2), beans1.get(1), "pk1");
+ assertEquals((Object)"bar", beans1.get(1), "pk2");
+ assertEquals(new Integer(1), beans2.get(0), "pk1");
+ assertEquals((Object)"foo", beans2.get(0), "pk2");
+ assertEquals(new Integer(2), beans2.get(1), "pk1");
+ assertEquals((Object)"bar", beans2.get(1), "pk2");
+
+ deleteRow("roundtrip1", new Object[] { new Integer(1), "foo" });
+ deleteRow("roundtrip2", new Object[] { "foo", new Integer(1) });
+
+ beans1 = getRows("roundtrip1", "pk1");
+ beans2 = getRows("roundtrip2", "pk1");
+
+ assertEquals(1, beans1.size());
+ assertEquals(1, beans2.size());
+ assertEquals(new Integer(2), beans1.get(0), "pk1");
+ assertEquals((Object)"bar", beans1.get(0), "pk2");
+ assertEquals(new Integer(2), beans2.get(0), "pk1");
+ assertEquals((Object)"bar", beans2.get(0), "pk2");
+ }
}