groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jwagenleit...@apache.org
Subject [1/2] groovy git commit: GROOVY-7751 - CallableStatement leak in Sql.call() method (closes #263)
Date Fri, 11 Mar 2016 02:52:27 GMT
Repository: groovy
Updated Branches:
  refs/heads/master 37f7905c3 -> 195af4bfd


GROOVY-7751 - CallableStatement leak in Sql.call() method (closes #263)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/dca1e26c
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/dca1e26c
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/dca1e26c

Branch: refs/heads/master
Commit: dca1e26c936b720760cbf5085fa8f916212d1878
Parents: 37f7905
Author: John Wagenleitner <jwagenleitner@apache.org>
Authored: Thu Mar 10 18:27:49 2016 -0800
Committer: John Wagenleitner <jwagenleitner@apache.org>
Committed: Thu Mar 10 18:27:49 2016 -0800

----------------------------------------------------------------------
 .../src/main/java/groovy/sql/Sql.java           | 26 +++++++++----
 .../test/groovy/groovy/sql/SqlCallTest.groovy   | 39 ++++++++++++++++++++
 2 files changed, 57 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/dca1e26c/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java b/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
index 1345486..1fa81e8 100644
--- a/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
+++ b/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
@@ -3007,10 +3007,7 @@ public class Sql {
         Connection connection = createConnection();
         CallableStatement statement = null;
         try {
-            LOG.fine(sql + " | " + params);
-            statement = connection.prepareCall(sql);
-            setParameters(params, statement);
-            configure(statement);
+            statement = getCallableStatement(connection, sql, params);
             return statement.executeUpdate();
         } catch (SQLException e) {
             LOG.warning("Failed to execute: " + sql + " because: " + e.getMessage());
@@ -3302,10 +3299,7 @@ public class Sql {
         CallableStatement statement = null;
         List<GroovyResultSet> resultSetResources = new ArrayList<GroovyResultSet>();
         try {
-            statement = connection.prepareCall(sql);
-
-            LOG.fine(sql + " | " + params);
-            setParameters(params, statement);
+            statement = getCallableStatement(connection, sql, params);
             boolean hasResultSet = statement.execute();
             List<Object> results = new ArrayList<Object>();
             int indx = 0;
@@ -4364,6 +4358,14 @@ public class Sql {
         return statement;
     }
 
+    private CallableStatement getCallableStatement(Connection connection, String sql, List<Object>
params) throws SQLException {
+        LOG.fine(sql + " | " + params);
+        CallableStatement statement = (CallableStatement) getAbstractStatement(new CreateCallableStatementCommand(),
connection, sql);
+        setParameters(params, statement);
+        configure(statement);
+        return statement;
+    }
+
     public SqlWithParams checkForNamedParams(String sql, List<Object> params) {
         SqlWithParams preCheck = buildSqlWithIndexedProps(sql);
         if (preCheck == null) {
@@ -4499,6 +4501,7 @@ public class Sql {
             this.returnGeneratedKeys = returnGeneratedKeys;
         }
 
+        @Override
         protected PreparedStatement execute(Connection connection, String sql) throws SQLException
{
             if (returnGeneratedKeys == USE_COLUMN_NAMES && keyColumnNames != null)
{
                 return connection.prepareStatement(sql, keyColumnNames.toArray(new String[keyColumnNames.size()]));
@@ -4523,6 +4526,13 @@ public class Sql {
         }
     }
 
+    private class CreateCallableStatementCommand extends AbstractStatementCommand {
+        @Override
+        protected CallableStatement execute(Connection connection, String sql) throws SQLException
{
+            return connection.prepareCall(sql);
+        }
+    }
+
     private class CreateStatementCommand extends AbstractStatementCommand {
         @Override
         protected Statement execute(Connection conn, String sql) throws SQLException {

http://git-wip-us.apache.org/repos/asf/groovy/blob/dca1e26c/subprojects/groovy-sql/src/test/groovy/groovy/sql/SqlCallTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-sql/src/test/groovy/groovy/sql/SqlCallTest.groovy b/subprojects/groovy-sql/src/test/groovy/groovy/sql/SqlCallTest.groovy
index 3068861..8dc6189 100644
--- a/subprojects/groovy-sql/src/test/groovy/groovy/sql/SqlCallTest.groovy
+++ b/subprojects/groovy-sql/src/test/groovy/groovy/sql/SqlCallTest.groovy
@@ -19,6 +19,7 @@
 package groovy.sql
 
 import javax.sql.DataSource
+import java.sql.CallableStatement
 
 import static groovy.sql.SqlTestConstants.*
 
@@ -295,4 +296,42 @@ class SqlCallTest extends GroovyTestCase {
         assert lastRows[0].lastname == 'Ventura'
     }
 
+    void testCallWithStatementCaching() {
+        String sqlText = '{call FindByFirst(?, ?)}'
+        CallableStatement statement = null
+        sql.withStatement { statement = (CallableStatement)it }
+
+        sql.cacheStatements = false
+        sql.call sqlText, ['James', Sql.VARCHAR]
+        assert statement.isClosed()
+        assert sql.@statementCache.isEmpty()
+
+        sql.cacheStatements = true
+        sql.call sqlText, ['James', Sql.VARCHAR]
+        assert !statement.isClosed()
+        assert sql.@statementCache.containsKey(sqlText)
+        assert sql.@statementCache[sqlText].is(statement)
+    }
+
+    void testCallWithRowsStatementCaching() {
+        String sqlText = '{call FindByFirst(?, ?)}'
+        CallableStatement statement = null
+        sql.withStatement { statement = (CallableStatement)it }
+
+        sql.cacheStatements = false
+        sql.call sqlText, ['James', Sql.VARCHAR], { ans ->
+            // no-op
+        }
+        assert statement.isClosed()
+        assert sql.@statementCache.isEmpty()
+
+        sql.cacheStatements = true
+        sql.call sqlText, ['James', Sql.VARCHAR], { ans ->
+            // no-op
+        }
+        assert !statement.isClosed()
+        assert sql.@statementCache.containsKey(sqlText)
+        assert sql.@statementCache[sqlText].is(statement)
+    }
+
 }


Mime
View raw message