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 2007/04/03 03:45:27 UTC

svn commit: r524994 - in /cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql: MySQLActionBuilder.java MySQLProcedureAction.java

Author: aadamchik
Date: Mon Apr  2 18:45:26 2007
New Revision: 524994

URL: http://svn.apache.org/viewvc?view=rev&rev=524994
Log:
CAY-773: MySQL stored procedure support

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLProcedureAction.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLActionBuilder.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLActionBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLActionBuilder.java?view=diff&rev=524994&r1=524993&r2=524994
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLActionBuilder.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLActionBuilder.java Mon Apr  2 18:45:26 2007
@@ -26,6 +26,7 @@
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.JdbcActionBuilder;
 import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.query.ProcedureQuery;
 import org.apache.cayenne.query.SQLAction;
 import org.apache.cayenne.query.SelectQuery;
 
@@ -51,5 +52,9 @@
                 return translator;
             }
         };
+    }
+
+    public SQLAction procedureAction(ProcedureQuery query) {
+        return new MySQLProcedureAction(query, getAdapter(), getEntityResolver());
     }
 }

Added: cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLProcedureAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLProcedureAction.java?view=auto&rev=524994
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLProcedureAction.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/dba/mysql/MySQLProcedureAction.java Mon Apr  2 18:45:26 2007
@@ -0,0 +1,149 @@
+/*****************************************************************
+ *   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.dba.mysql;
+
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.apache.cayenne.access.OperationObserver;
+import org.apache.cayenne.access.QueryLogger;
+import org.apache.cayenne.access.jdbc.ProcedureAction;
+import org.apache.cayenne.access.jdbc.RowDescriptor;
+import org.apache.cayenne.access.trans.ProcedureTranslator;
+import org.apache.cayenne.dba.DbAdapter;
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.query.ProcedureQuery;
+
+/**
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+class MySQLProcedureAction extends ProcedureAction {
+
+    public MySQLProcedureAction(ProcedureQuery query, DbAdapter adapter,
+            EntityResolver entityResolver) {
+        super(query, adapter, entityResolver);
+    }
+
+    public void performAction(Connection connection, OperationObserver observer)
+            throws SQLException, Exception {
+
+        processedResultSets = 0;
+
+        ProcedureTranslator transl = createTranslator(connection);
+        CallableStatement statement = (CallableStatement) transl.createStatement();
+
+        try {
+
+            // this is one difference with super - we need to read the first result set
+            // without calling 'getMoreResults' - which may actually be a good default
+            // strategy?
+            boolean firstResult = statement.execute();
+
+            // read out parameters
+            readProcedureOutParameters(statement, observer);
+
+            // read first result
+            if (firstResult) {
+                processResultSet(statement, observer);
+            }
+            else if (!processUpdate(statement, observer)) {
+                return;
+            }
+
+            // read the rest of the query
+            while (true) {
+                if (statement.getMoreResults()) {
+                    processResultSet(statement, observer);
+                }
+                else if (!processUpdate(statement, observer)) {
+                    break;
+                }
+            }
+        }
+        finally {
+            try {
+                statement.close();
+            }
+            catch (SQLException ex) {
+
+            }
+        }
+    }
+
+    private void processResultSet(CallableStatement statement, OperationObserver observer)
+            throws Exception {
+        ResultSet rs = statement.getResultSet();
+
+        try {
+            RowDescriptor descriptor = describeResultSet(rs, processedResultSets++);
+            readResultSet(rs, descriptor, query, observer);
+        }
+        finally {
+            try {
+                rs.close();
+            }
+            catch (SQLException ex) {
+            }
+        }
+    }
+
+    private boolean processUpdate(CallableStatement statement, OperationObserver observer)
+            throws Exception {
+        int updateCount = statement.getUpdateCount();
+        if (updateCount == -1) {
+            return false;
+        }
+        QueryLogger.logUpdateCount(updateCount);
+        observer.nextCount(query, updateCount);
+
+        return true;
+    }
+
+    /**
+     * Creates a translator that adds parenthesis to no-param queries.
+     */
+    // see CAY-750 for the problem description
+    protected ProcedureTranslator createTranslator(Connection connection) {
+        ProcedureTranslator translator = new MySQLProcedureTranslator();
+        translator.setAdapter(getAdapter());
+        translator.setQuery(query);
+        translator.setEntityResolver(getEntityResolver());
+        translator.setConnection(connection);
+        return translator;
+    }
+
+    // same as postgres translator - should we make this the default?
+    static class MySQLProcedureTranslator extends ProcedureTranslator {
+
+        protected String createSqlString() {
+
+            String sql = super.createSqlString();
+
+            // add empty parameter parenthesis
+            if (sql.endsWith("}") && !sql.endsWith(")}")) {
+                sql = sql.substring(0, sql.length() - 1) + "()}";
+            }
+
+            return sql;
+        }
+    }
+}