Index: src/test/groovy/sql/SqlBatchTest.groovy =================================================================== --- src/test/groovy/sql/SqlBatchTest.groovy (revision 16420) +++ src/test/groovy/sql/SqlBatchTest.groovy Sat Apr 25 14:22:42 EST 2009 @@ -53,17 +53,30 @@ try { connection.autoCommit = false def stmt = connection.createStatement() - others.eachWithIndex {entry, index -> - stmt.addBatch("insert into PERSON (id, firstname, lastname) values (${index + numRows + 1}, '$entry.key', '$entry.value')") + others.eachWithIndex {k, v, index -> + def id = index + numRows + 1 + stmt.addBatch("insert into PERSON (id, firstname, lastname) values ($id, '$k', '$v')") } assert stmt.executeBatch() == [1, 1] connection.autoCommit = true } catch (Exception e) { e.printStackTrace() - println e.dump() } } assert sql.rows("SELECT * FROM PERSON").size() == 5 } + void testWithBatch() { + def numRows = sql.rows("SELECT * FROM PERSON").size() + assert numRows == 3 + def result = sql.withBatch { stmt -> + others.eachWithIndex { k, v, index -> + def id = index + numRows + 1 + stmt.addBatch("insert into PERSON (id, firstname, lastname) values ($id, '$k', '$v')") -} + } + } + assert result == [1, 1] + assert sql.rows("SELECT * FROM PERSON").size() == 5 + } + +} Index: src/main/groovy/sql/Sql.java =================================================================== --- src/main/groovy/sql/Sql.java (revision 16420) +++ src/main/groovy/sql/Sql.java Wed May 06 23:05:06 EST 2009 @@ -1641,6 +1641,39 @@ } } + /** + * Performs the closure within a batch using a cached connection. + * The closure will be called with a single argument; the statement + * associated with this batch. + * + * @param closure the given closure + * @return an array of update counts containing one element for each + * command in the batch. The elements of the array are ordered according + * to the order in which commands were added to the batch. + * @exception SQLException if a database access error occurs, + * this method is called on a closed Statement or the + * driver does not support batch statements. Throws {@link java.sql.BatchUpdateException} + * (a subclass of SQLException) if one of the commands sent to the + * database fails to execute properly or attempts to return a result set. + */ + public synchronized int[] withBatch(Closure closure) throws SQLException { + boolean savedCacheConnection = cacheConnection; + cacheConnection = true; + Connection connection = null; + Statement statement = null; + try { + connection = createConnection(); + connection.setAutoCommit(false); + statement = connection.createStatement(); + closure.call(statement); + return statement.executeBatch(); + } finally { + if (connection != null) connection.setAutoCommit(true); + closeResources(connection, statement); + cacheConnection = savedCacheConnection; + } + } + private void handleError(Connection connection, Throwable t) throws SQLException { if (connection != null) { log.log(Level.INFO, "Rolling back due to: " + t.getMessage(), t);