You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by jw...@apache.org on 2016/03/11 03:56:35 UTC
[1/2] groovy git commit: Ensure BatchingStatementWrapper is closed
when statement caching is enabled
Repository: groovy
Updated Branches:
refs/heads/GROOVY_2_4_X 778cb5432 -> 9fca80db4
Ensure BatchingStatementWrapper is closed when statement caching is enabled
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/9fca80db
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/9fca80db
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/9fca80db
Branch: refs/heads/GROOVY_2_4_X
Commit: 9fca80db49a390880e1fde033b5e4c4263edde3d
Parents: 77ee2fe
Author: John Wagenleitner <jw...@apache.org>
Authored: Thu Mar 10 18:28:53 2016 -0800
Committer: John Wagenleitner <jw...@apache.org>
Committed: Thu Mar 10 18:40:05 2016 -0800
----------------------------------------------------------------------
.../src/main/java/groovy/sql/Sql.java | 6 +++-
.../test/groovy/groovy/sql/SqlBatchTest.groovy | 34 ++++++++++++++++++++
2 files changed, 39 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/9fca80db/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 a3f2528..1fb05f2 100644
--- a/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
+++ b/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
@@ -4221,8 +4221,12 @@ public class Sql {
closeResources(connection);
}
- private void closeResources(BatchingStatementWrapper statement) {
+ private void closeResources(BatchingPreparedStatementWrapper statement) {
if (cacheStatements) return;
+ closeResources((BatchingStatementWrapper) statement);
+ }
+
+ private void closeResources(BatchingStatementWrapper statement) {
if (statement != null) {
try {
statement.close();
http://git-wip-us.apache.org/repos/asf/groovy/blob/9fca80db/subprojects/groovy-sql/src/test/groovy/groovy/sql/SqlBatchTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-sql/src/test/groovy/groovy/sql/SqlBatchTest.groovy b/subprojects/groovy-sql/src/test/groovy/groovy/sql/SqlBatchTest.groovy
index 3f9bafd..02a6d65 100644
--- a/subprojects/groovy-sql/src/test/groovy/groovy/sql/SqlBatchTest.groovy
+++ b/subprojects/groovy-sql/src/test/groovy/groovy/sql/SqlBatchTest.groovy
@@ -171,4 +171,38 @@ class SqlBatchTest extends GroovyTestCase {
// FINE: Successfully executed batch with 1 command(s)
}
+ void testWithBatchClosesStatement() {
+ // withBatch(int, Closure) should close connection even when statement caching is enabled
+ // since it is not cached because there is no sql text to use as the cache key.
+ BatchingStatementWrapper wrapper = null
+ sql.cacheStatements = true
+ sql.withBatch(1) { stmt ->
+ wrapper = (BatchingStatementWrapper)stmt
+ stmt.addBatch("insert into PERSON (id, firstname, lastname) values (999, 'Test', 'Closes')")
+ }
+ assert wrapper.@delegate.isClosed()
+ }
+
+ void testWithBatchClosureClosesOrCachesStatement() {
+ String sqlText = 'insert into PERSON (id, firstname, lastname) values (?, ?, ?)'
+ BatchingPreparedStatementWrapper wrapper = null
+
+ sql.cacheStatements = false
+ sql.withBatch(20, sqlText) { ps ->
+ wrapper = (BatchingPreparedStatementWrapper)ps
+ ps.addBatch(111, 'Test1', 'Closes1')
+ ps.addBatch(222, 'Test2', 'Closes2')
+ }
+ assert wrapper.@delegate.isClosed()
+
+ sql.cacheStatements = true
+ sql.withBatch(20, sqlText) { ps ->
+ wrapper = (BatchingPreparedStatementWrapper)ps
+ ps.addBatch(333, 'Test3', 'Closes3')
+ ps.addBatch(444, 'Test4', 'Closes4')
+ }
+ assert !wrapper.@delegate.isClosed()
+ assert sql.@statementCache.containsKey(sqlText)
+ assert sql.@statementCache[sqlText].is(wrapper.@delegate)
+ }
}
[2/2] groovy git commit: GROOVY-7751 - CallableStatement leak in
Sql.call() method (closes #263)
Posted by jw...@apache.org.
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/77ee2feb
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/77ee2feb
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/77ee2feb
Branch: refs/heads/GROOVY_2_4_X
Commit: 77ee2febc3bcd7cdfc81da4d567a8d1a81d5fe06
Parents: 778cb54
Author: John Wagenleitner <jw...@apache.org>
Authored: Thu Mar 10 18:27:49 2016 -0800
Committer: John Wagenleitner <jw...@apache.org>
Committed: Thu Mar 10 18:40:05 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/77ee2feb/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 1b47539..a3f2528 100644
--- a/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
+++ b/subprojects/groovy-sql/src/main/java/groovy/sql/Sql.java
@@ -3005,10 +3005,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());
@@ -3300,10 +3297,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;
@@ -4368,6 +4362,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) {
@@ -4503,6 +4505,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()]));
@@ -4527,6 +4530,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/77ee2feb/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)
+ }
+
}