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());
     }
 
     /**


Reply via email to