You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2014/03/15 16:25:34 UTC

svn commit: r1577880 - in /cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access: jdbc/ translator/batch/

Author: aadamchik
Date: Sat Mar 15 15:25:34 2014
New Revision: 1577880

URL: http://svn.apache.org/r1577880
Log:
CAY-1915 BatchTranslator instead of performing bindings should return binding object whose values can be altered

Added:
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchParameterBinding.java
Modified:
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchTranslator.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslator.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/InsertBatchTranslator.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/SoftDeleteBatchTranslator.java
    cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslator.java

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java?rev=1577880&r1=1577879&r2=1577880&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java Sat Mar 15 15:25:34 2014
@@ -26,6 +26,7 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 
 import org.apache.cayenne.CayenneException;
 import org.apache.cayenne.ResultIterator;
@@ -33,8 +34,10 @@ import org.apache.cayenne.access.DataNod
 import org.apache.cayenne.access.OperationObserver;
 import org.apache.cayenne.access.OptimisticLockException;
 import org.apache.cayenne.access.jdbc.reader.RowReader;
+import org.apache.cayenne.access.translator.batch.BatchParameterBinding;
 import org.apache.cayenne.access.translator.batch.BatchTranslator;
 import org.apache.cayenne.access.translator.batch.BatchTranslatorFactory;
+import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.TypesMapping;
 import org.apache.cayenne.log.JdbcEventLogger;
 import org.apache.cayenne.map.DbAttribute;
@@ -54,6 +57,15 @@ public class BatchAction extends BaseSQL
     protected BatchQuery query;
     protected RowDescriptor keyRowDescriptor;
 
+    private static void bind(DbAdapter adapter, PreparedStatement statement, List<BatchParameterBinding> bindings)
+            throws SQLException, Exception {
+        int len = bindings.size();
+        for (int i = 1; i <= len; i++) {
+            BatchParameterBinding b = bindings.get(i);
+            adapter.bindParameter(statement, b.getValue(), i, b.getAttribute().getType(), b.getAttribute().getScale());
+        }
+    }
+
     /**
      * @since 3.2
      */
@@ -113,6 +125,7 @@ public class BatchAction extends BaseSQL
 
         // run batch
 
+        DbAdapter adapter = dataNode.getAdapter();
         PreparedStatement statement = con.prepareStatement(queryStr);
         try {
             for (BatchQueryRow row : query.getRows()) {
@@ -121,8 +134,10 @@ public class BatchAction extends BaseSQL
                     logger.logQueryParameters("batch bind", query.getDbAttributes(),
                             queryBuilder.getParameterValues(row), query instanceof InsertBatchQuery);
                 }
+                
+                List<BatchParameterBinding> bindings = queryBuilder.createBindings(row);
+                bind(adapter, statement, bindings);
 
-                queryBuilder.bindParameters(statement, row);
                 statement.addBatch();
             }
 
@@ -171,16 +186,18 @@ public class BatchAction extends BaseSQL
 
         // run batch queries one by one
 
+        DbAdapter adapter = dataNode.getAdapter();
         PreparedStatement statement = (generatesKeys) ? connection.prepareStatement(queryStr,
                 Statement.RETURN_GENERATED_KEYS) : connection.prepareStatement(queryStr);
         try {
-            for(BatchQueryRow row : query.getRows()) {
+            for (BatchQueryRow row : query.getRows()) {
                 if (isLoggable) {
                     logger.logQueryParameters("bind", query.getDbAttributes(), queryBuilder.getParameterValues(row),
                             query instanceof InsertBatchQuery);
                 }
 
-                queryBuilder.bindParameters(statement, row);
+                List<BatchParameterBinding> bindings = queryBuilder.createBindings(row);
+                bind(adapter, statement, bindings);
 
                 int updated = statement.executeUpdate();
                 if (useOptimisticLock && updated != 1) {
@@ -235,8 +252,8 @@ public class BatchAction extends BaseSQL
      * @since 3.2
      */
     @SuppressWarnings({ "rawtypes", "unchecked" })
-    protected void processGeneratedKeys(Statement statement, OperationObserver observer, BatchQueryRow row) throws SQLException,
-            CayenneException {
+    protected void processGeneratedKeys(Statement statement, OperationObserver observer, BatchQueryRow row)
+            throws SQLException, CayenneException {
 
         ResultSet keysRS = statement.getGeneratedKeys();
 

Added: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchParameterBinding.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchParameterBinding.java?rev=1577880&view=auto
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchParameterBinding.java (added)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchParameterBinding.java Sat Mar 15 15:25:34 2014
@@ -0,0 +1,47 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.access.translator.batch;
+
+import org.apache.cayenne.map.DbAttribute;
+
+/**
+ * @since 3.2
+ */
+public class BatchParameterBinding {
+
+    private DbAttribute attribute;
+    private Object value;
+
+    public BatchParameterBinding(DbAttribute attribute, Object value) {
+        this.attribute = attribute;
+        this.value = value;
+    }
+
+    public DbAttribute getAttribute() {
+        return attribute;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public void setValue(Object value) {
+        this.value = value;
+    }
+}

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchTranslator.java?rev=1577880&r1=1577879&r2=1577880&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchTranslator.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/BatchTranslator.java Sat Mar 15 15:25:34 2014
@@ -20,8 +20,6 @@
 package org.apache.cayenne.access.translator.batch;
 
 import java.io.IOException;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
 import java.sql.Types;
 import java.util.ArrayList;
 import java.util.List;
@@ -86,12 +84,9 @@ public abstract class BatchTranslator {
     }
 
     /**
-     * Binds parameters for the current batch iteration to the
-     * PreparedStatement.
-     * 
-     * @since 3.2
+     * Returns PreparedStatement bindings for a given row.
      */
-    public abstract void bindParameters(PreparedStatement statement, BatchQueryRow row) throws SQLException, Exception;
+    public abstract List<BatchParameterBinding> createBindings(BatchQueryRow row);
 
     /**
      * Returns a list of values for the current batch iteration. Used primarily

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslator.java?rev=1577880&r1=1577879&r2=1577880&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslator.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslator.java Sat Mar 15 15:25:34 2014
@@ -20,9 +20,9 @@
 package org.apache.cayenne.access.translator.batch;
 
 import java.io.IOException;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
+import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.QuotingStrategy;
@@ -73,16 +73,15 @@ public class DeleteBatchTranslator exten
     }
 
     /**
-     * Binds BatchQuery parameters to the PreparedStatement.
-     * 
      * @since 3.2
      */
     @Override
-    public void bindParameters(PreparedStatement statement, BatchQueryRow row) throws SQLException, Exception {
+    public List<BatchParameterBinding> createBindings(BatchQueryRow row) {
 
         DeleteBatchQuery deleteBatch = (DeleteBatchQuery) query;
+        List<BatchParameterBinding> bindings = new ArrayList<BatchParameterBinding>(deleteBatch
+                .getQualifierAttributes().size());
 
-        int parameterIndex = getFirstParameterIndex();
         int i = 0;
 
         for (DbAttribute attribute : deleteBatch.getQualifierAttributes()) {
@@ -93,15 +92,9 @@ public class DeleteBatchTranslator exten
                 continue;
             }
 
-            adapter.bindParameter(statement, value, parameterIndex++, attribute.getType(), attribute.getScale());
+            bindings.add(new BatchParameterBinding(attribute, value));
         }
-    }
 
-    /**
-     * @return index of first parameter in delete clause
-     */
-    protected int getFirstParameterIndex() {
-        return 1;
+        return bindings;
     }
-
 }

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/InsertBatchTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/InsertBatchTranslator.java?rev=1577880&r1=1577879&r2=1577880&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/InsertBatchTranslator.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/InsertBatchTranslator.java Sat Mar 15 15:25:34 2014
@@ -20,8 +20,6 @@
 package org.apache.cayenne.access.translator.batch;
 
 import java.io.IOException;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -41,27 +39,25 @@ public class InsertBatchTranslator exten
     }
 
     /**
-     * Binds parameters for the current batch iteration to the
-     * PreparedStatement. Performs filtering of attributes based on column
-     * generation rules.
-     * 
-     * @since 1.2
+     * @since 3.2
      */
     @Override
-    public void bindParameters(PreparedStatement statement, BatchQueryRow row) throws SQLException, Exception {
+    public List<BatchParameterBinding> createBindings(BatchQueryRow row) {
 
-        List<DbAttribute> dbAttributes = query.getDbAttributes();
-        int attributeCount = dbAttributes.size();
+        List<DbAttribute> attributes = query.getDbAttributes();
+        int len = attributes.size();
 
-        // must use an independent counter "j" for prepared statement index
-        for (int i = 0, j = 0; i < attributeCount; i++) {
-            DbAttribute attribute = dbAttributes.get(i);
-            if (includeInBatch(attribute)) {
-                j++;
+        List<BatchParameterBinding> bindings = new ArrayList<BatchParameterBinding>(len);
+
+        for (int i = 0; i < len; i++) {
+            DbAttribute a = attributes.get(i);
+            if (includeInBatch(a)) {
                 Object value = row.getValue(i);
-                adapter.bindParameter(statement, value, j, attribute.getType(), attribute.getScale());
+                bindings.add(new BatchParameterBinding(a, value));
             }
         }
+
+        return bindings;
     }
 
     /**

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/SoftDeleteBatchTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/SoftDeleteBatchTranslator.java?rev=1577880&r1=1577879&r2=1577880&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/SoftDeleteBatchTranslator.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/SoftDeleteBatchTranslator.java Sat Mar 15 15:25:34 2014
@@ -19,9 +19,8 @@
 package org.apache.cayenne.access.translator.batch;
 
 import java.io.IOException;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
 import java.sql.Types;
+import java.util.List;
 
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.QuotingStrategy;
@@ -60,18 +59,16 @@ public class SoftDeleteBatchTranslator e
     }
 
     @Override
-    protected int getFirstParameterIndex() {
-        return needSoftDelete() ? 2 : 1;
-    }
+    public List<BatchParameterBinding> createBindings(BatchQueryRow row) {
+
+        List<BatchParameterBinding> bindings = super.createBindings(row);
 
-    @Override
-    public void bindParameters(PreparedStatement statement, BatchQueryRow row) throws SQLException, Exception {
         if (needSoftDelete()) {
-            // binding first parameter (which is 'deleted') as true
-            adapter.bindParameter(statement, true, 1, Types.BOOLEAN, -1);
+            DbAttribute deleteAttribute = query.getDbEntity().getAttribute(deletedFieldName);
+            bindings.add(0, new BatchParameterBinding(deleteAttribute, true));
         }
 
-        super.bindParameters(statement, row);
+        return bindings;
     }
 
     /**

Modified: cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslator.java?rev=1577880&r1=1577879&r2=1577880&view=diff
==============================================================================
--- cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslator.java (original)
+++ cayenne/main/trunk/cayenne-server/src/main/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslator.java Sat Mar 15 15:25:34 2014
@@ -20,8 +20,7 @@
 package org.apache.cayenne.access.translator.batch;
 
 import java.io.IOException;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
@@ -81,35 +80,38 @@ public class UpdateBatchTranslator exten
         return buffer.toString();
     }
 
-    /**
-     * Binds BatchQuery parameters to the PreparedStatement.
-     */
     @Override
-    public void bindParameters(PreparedStatement statement, BatchQueryRow row) throws SQLException, Exception {
+    public List<BatchParameterBinding> createBindings(BatchQueryRow row) {
 
         UpdateBatchQuery updateBatch = (UpdateBatchQuery) query;
-        List<DbAttribute> qualifierAttributes = updateBatch.getQualifierAttributes();
+
         List<DbAttribute> updatedDbAttributes = updateBatch.getUpdatedAttributes();
+        List<DbAttribute> qualifierAttributes = updateBatch.getQualifierAttributes();
 
-        int len = updatedDbAttributes.size();
-        int parameterIndex = 1;
-        for (int i = 0; i < len; i++) {
+        int ul = updatedDbAttributes.size();
+        int ql = qualifierAttributes.size();
+
+        List<BatchParameterBinding> bindings = new ArrayList<BatchParameterBinding>(ul + ql);
+
+        for (int i = 0; i < ul; i++) {
             Object value = row.getValue(i);
 
-            DbAttribute attribute = updatedDbAttributes.get(i);
-            adapter.bindParameter(statement, value, parameterIndex++, attribute.getType(), attribute.getScale());
+            DbAttribute a = updatedDbAttributes.get(i);
+            bindings.add(new BatchParameterBinding(a, value));
         }
 
-        for (int i = 0; i < qualifierAttributes.size(); i++) {
-            Object value = row.getValue(len + i);
-            DbAttribute attribute = qualifierAttributes.get(i);
+        for (int i = 0; i < ql; i++) {
+            Object value = row.getValue(ul + i);
+            DbAttribute a = qualifierAttributes.get(i);
 
             // skip null attributes... they are translated as "IS NULL"
-            if (updateBatch.isNull(attribute)) {
+            if (updateBatch.isNull(a)) {
                 continue;
             }
 
-            adapter.bindParameter(statement, value, parameterIndex++, attribute.getType(), attribute.getScale());
+            bindings.add(new BatchParameterBinding(a, value));
         }
+
+        return bindings;
     }
 }