Author: tomdz Date: Sun Jun 11 14:29:34 2006 New Revision: 413533 URL: http://svn.apache.org/viewvc?rev=413533&view=rev Log: Enhanced support for identity columns when inserting data into a database
Modified: db/ddlutils/trunk/build-sample.xml db/ddlutils/trunk/src/java/org/apache/ddlutils/PlatformInfo.java db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/oracle/Oracle8Platform.java db/ddlutils/trunk/src/test/org/apache/ddlutils/io/RoundtripTestBase.java db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestConstraints.java Modified: db/ddlutils/trunk/build-sample.xml URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/build-sample.xml?rev=413533&r1=413532&r2=413533&view=diff ============================================================================== --- db/ddlutils/trunk/build-sample.xml (original) +++ db/ddlutils/trunk/build-sample.xml Sun Jun 11 14:29:34 2006 @@ -16,6 +16,7 @@ <property name="sqloutputfile" value="schema.sql"/> <property name="platform" value=""/> <property name="alterdatabase" value="true"/> + <property name="delimitedsqlidentifiers" value="false"/> <!-- The classpath used for running the tasks --> <path id="project-classpath"> @@ -34,7 +35,7 @@ classpathref="project-classpath"/> <target name="createDb"> - <ddlToDatabase usedelimitedsqlidentifiers="false" + <ddlToDatabase usedelimitedsqlidentifiers="${delimitedsqlidentifiers}" catalogpattern="${catalogpattern}" schemapattern="${schemapattern}" databasetype="${platform}" > @@ -48,7 +49,7 @@ <target name="writeSchemaToDb"> <ddlToDatabase validatexml="false" - usedelimitedsqlidentifiers="false" + usedelimitedsqlidentifiers="${delimitedsqlidentifiers}" catalogpattern="${catalogpattern}" schemapattern="${schemapattern}" databasetype="${platform}" > @@ -68,7 +69,7 @@ <target name="writeSchemaSqlToFile"> <ddlToDatabase validatexml="false" - usedelimitedsqlidentifiers="false" + usedelimitedsqlidentifiers="${delimitedsqlidentifiers}" catalogpattern="${catalogpattern}" schemapattern="${schemapattern}" databasetype="${platform}" > @@ -84,6 +85,25 @@ dodrops="true" failonerror="false" outputfile="${sqloutputfile}"/> + </ddlToDatabase> + </target> + + <target name="writeDataToDb"> + <ddlToDatabase validatexml="false" + usedelimitedsqlidentifiers="${delimitedsqlidentifiers}" + catalogpattern="${catalogpattern}" + schemapattern="${schemapattern}" + databasetype="${platform}" > + <database driverclassname="${datasource.driverClassName}" + url="${datasource.url}" + username="${datasource.username}" + password="${datasource.password}"/> + <fileset dir="."> + <include name="${schemafiles}"/> + </fileset> + + <writedatatodatabase datafile="${datafile}" + usebatchmode="false"/> </ddlToDatabase> </target> </project> Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/PlatformInfo.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/PlatformInfo.java?rev=413533&r1=413532&r2=413533&view=diff ============================================================================== --- db/ddlutils/trunk/src/java/org/apache/ddlutils/PlatformInfo.java (original) +++ db/ddlutils/trunk/src/java/org/apache/ddlutils/PlatformInfo.java Sun Jun 11 14:29:34 2006 @@ -75,8 +75,12 @@ /** Whether the database returns a synthetic default value for non-identity required columns. */ private boolean _syntheticDefaultValueForRequiredReturned = false; + /** Whether the platform allows for the explicit specification of values for identity columns in INSERT + and UPDATE statements. */ + private boolean _identityOverrideAllowed = true; + /** Whether the platform is able to determine auto increment status from an existing database. */ - private boolean _autoIncrementStatusReadingSupported = true; + private boolean _identityStatusReadingSupported = true; // other ddl properties @@ -397,15 +401,37 @@ } /** + * Determines whether the platform is allows the explicit specification of values for + * identity columns in INSERT/UPDATE statements. + * + * @return <code>true</code> if values for identity columns can be specified + */ + public boolean isIdentityOverrideAllowed() + { + return _identityOverrideAllowed; + } + + /** + * Specifies whether the platform is allows the explicit specification of values for + * identity columns in INSERT/UPDATE statements. + * + * @param identityOverrideAllowed <code>true</code> if values for identity columns can be specified + */ + public void setIdentityOverrideAllowed(boolean identityOverrideAllowed) + { + _identityOverrideAllowed = identityOverrideAllowed; + } + + /** * Determines whether the platform is able to read the auto-increment status for columns * from an existing database. * * @return <code>true</code> if the auto-increment status can be determined from an existing * database */ - public boolean getAutoIncrementStatusReadingSupported() + public boolean getIdentityStatusReadingSupported() { - return _autoIncrementStatusReadingSupported; + return _identityStatusReadingSupported; } /** @@ -415,9 +441,9 @@ * @param canReadAutoIncrementStatus <code>true</code> if the auto-increment status can be * determined from an existing database */ - public void setAutoIncrementStatusReadingSupported(boolean canReadAutoIncrementStatus) + public void setIdentityStatusReadingSupported(boolean canReadAutoIncrementStatus) { - _autoIncrementStatusReadingSupported = canReadAutoIncrementStatus; + _identityStatusReadingSupported = canReadAutoIncrementStatus; } // other ddl properties Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java?rev=413533&r1=413532&r2=413533&view=diff ============================================================================== --- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java (original) +++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/PlatformImplBase.java Sun Jun 11 14:29:34 2006 @@ -1067,8 +1067,20 @@ public boolean evaluate(Object input) { SqlDynaProperty prop = (SqlDynaProperty)input; - return !prop.getColumn().isAutoIncrement() && - ((bean.get(prop.getName()) != null) || (prop.getColumn().getDefaultValue() == null)); + if (bean.get(prop.getName()) != null) + { + // we ignore properties for which a value is present in the bean + // only if they are auto-increment and the platform does not allow + // the override of the auto-increment specification + return getPlatformInfo().isIdentityOverrideAllowed() || !prop.getColumn().isAutoIncrement(); + } + else + { + // we also return properties without a value in the bean + // if they ain't auto-increment and don't have a default value + // in this case, a NULL is inserted + return !prop.getColumn().isAutoIncrement() && (prop.getColumn().getDefaultValue() == null); + } } }); @@ -1076,13 +1088,49 @@ } /** + * Returns all identity properties whose value were defined by the database and which + * now need to be read back from the DB. + * + * @param model The database model + * @param dynaClass The dyna class + * @param bean The bean + * @return The columns + */ + private Column[] getRelevantIdentityColumns(Database model, SqlDynaClass dynaClass, final DynaBean bean) + { + SqlDynaProperty[] properties = dynaClass.getSqlDynaProperties(); + + Collection relevantProperties = CollectionUtils.select(Arrays.asList(properties), new Predicate() { + public boolean evaluate(Object input) { + SqlDynaProperty prop = (SqlDynaProperty)input; + + // we only want those identity columns that were really specified by the DB + // if the platform allows specification of values for identity columns + // in INSERT/UPDATE statements, then we need to filter the corresponding + // columns out + return prop.getColumn().isAutoIncrement() && + (!getPlatformInfo().isIdentityOverrideAllowed() || (bean.get(prop.getName()) == null)); + } + }); + + Column[] columns = new Column[relevantProperties.size()]; + int idx = 0; + + for (Iterator propIt = relevantProperties.iterator(); propIt.hasNext(); idx++) + { + columns[idx] = ((SqlDynaProperty)propIt.next()).getColumn(); + } + return columns; + } + + /** * [EMAIL PROTECTED] */ public void insert(Connection connection, Database model, DynaBean dynaBean) throws DynaSqlException { SqlDynaClass dynaClass = model.getDynaClassFor(dynaBean); SqlDynaProperty[] properties = getPropertiesForInsertion(model, dynaClass, dynaBean); - Column[] autoIncrColumns = model.findTable(dynaClass.getTableName()).getAutoIncrementColumns(); + Column[] autoIncrColumns = getRelevantIdentityColumns(model, dynaClass, dynaBean); if ((properties.length == 0) && (autoIncrColumns.length == 0)) { @@ -1100,7 +1148,7 @@ } if ((autoIncrColumns.length > 0) && (queryIdSql == null)) { - _log.warn("The database does not support querying for auto-generated pk values"); + _log.warn("The database does not support querying for auto-generated column values"); } try @@ -1215,10 +1263,11 @@ */ public void insert(Connection connection, Database model, Collection dynaBeans) throws DynaSqlException { - SqlDynaClass dynaClass = null; - SqlDynaProperty[] properties = null; - PreparedStatement statement = null; - int addedStmts = 0; + SqlDynaClass dynaClass = null; + SqlDynaProperty[] properties = null; + PreparedStatement statement = null; + int addedStmts = 0; + boolean identityWarningPrinted = false; for (Iterator it = dynaBeans.iterator(); it.hasNext();) { @@ -1240,6 +1289,12 @@ { _log.warn("Cannot insert instances of type " + dynaClass + " because it has no usable properties"); continue; + } + if (!identityWarningPrinted && + (getRelevantIdentityColumns(model, curDynaClass, dynaBean).length > 0)) + { + _log.warn("Updating the bean properties corresponding to auto-increment columns is not supported in batch mode"); + identityWarningPrinted = true; } String insertSql = createInsertSql(model, dynaClass, properties, null); Modified: db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/oracle/Oracle8Platform.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/oracle/Oracle8Platform.java?rev=413533&r1=413532&r2=413533&view=diff ============================================================================== --- db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/oracle/Oracle8Platform.java (original) +++ db/ddlutils/trunk/src/java/org/apache/ddlutils/platform/oracle/Oracle8Platform.java Sun Jun 11 14:29:34 2006 @@ -58,7 +58,7 @@ info.setPrimaryKeyEmbedded(true); info.setForeignKeysEmbedded(false); info.setIndicesEmbedded(false); - info.setAutoIncrementStatusReadingSupported(false); + info.setIdentityStatusReadingSupported(false); // Note that the back-mappings are partially done by the model reader, not the driver info.addNativeTypeMapping(Types.ARRAY, "BLOB", Types.BLOB); Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/io/RoundtripTestBase.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/io/RoundtripTestBase.java?rev=413533&r1=413532&r2=413533&view=diff ============================================================================== --- db/ddlutils/trunk/src/test/org/apache/ddlutils/io/RoundtripTestBase.java (original) +++ db/ddlutils/trunk/src/test/org/apache/ddlutils/io/RoundtripTestBase.java Sun Jun 11 14:29:34 2006 @@ -423,7 +423,7 @@ assertEquals("Required status not the same for column "+actual.getName()+".", expected.isRequired(), actual.isRequired()); - if (getPlatformInfo().getAutoIncrementStatusReadingSupported()) + if (getPlatformInfo().getIdentityStatusReadingSupported()) { // we're only comparing this if the platform can actually read the // auto-increment status back from an existing database Modified: db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestConstraints.java URL: http://svn.apache.org/viewvc/db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestConstraints.java?rev=413533&r1=413532&r2=413533&view=diff ============================================================================== --- db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestConstraints.java (original) +++ db/ddlutils/trunk/src/test/org/apache/ddlutils/io/TestConstraints.java Sun Jun 11 14:29:34 2006 @@ -238,7 +238,7 @@ if (getPlatformInfo().isNonPKIdentityColumnsSupported()) { performConstraintsTest(TEST_AUTO_INCREMENT_INTEGER_MODEL, - getPlatformInfo().getAutoIncrementStatusReadingSupported()); + getPlatformInfo().getIdentityStatusReadingSupported()); } } @@ -248,7 +248,7 @@ public void testPrimaryKeyAutoIncrementColumn() { performConstraintsTest(TEST_PRIMARY_KEY_AUTO_INCREMENT_MODEL, - getPlatformInfo().getAutoIncrementStatusReadingSupported()); + getPlatformInfo().getIdentityStatusReadingSupported()); } /**