Author: wspeirs Date: Wed Aug 8 18:47:36 2012 New Revision: 1370883 URL: http://svn.apache.org/viewvc?rev=1370883&view=rev Log: - Applied patches from DBUTILS-87 to add insert methods
Modified: commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/QueryRunner.java commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/AsyncQueryRunnerTest.java commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java Modified: commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java?rev=1370883&r1=1370882&r2=1370883&view=diff ============================================================================== --- commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java (original) +++ commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java Wed Aug 8 18:47:36 2012 @@ -552,4 +552,65 @@ public class AsyncQueryRunner extends Ab }); } + /** + * Executes {@link QueryRunner#insert(String, ResultSetHandler)} asynchronously. + * + * @see QueryRunner#insert(String, ResultSetHandler) + */ + public <T> Future<T> insert(final String sql, final ResultSetHandler<T> rsh) throws SQLException { + return executorService.submit(new Callable<T>() { + + @Override + public T call() throws Exception { + return queryRunner.insert(sql, rsh); + } + + }); + } + + /** + * Executes {@link QueryRunner#insert(String, ResultSetHandler, Object...)} asynchronously. + * + * @see QueryRunner#insert(String, ResultSetHandler, Object...) + */ + public <T> Future<T> insert(final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException { + return executorService.submit(new Callable<T>() { + + @Override + public T call() throws Exception { + return queryRunner.insert(sql, rsh, params); + } + }); + } + + /** + * Executes {@link QueryRunner#insert(Connection, String, ResultSetHandler)} asynchronously. + * + * @see QueryRunner#insert(Connection, String, ResultSetHandler) + */ + public <T> Future<T> insert(final Connection conn, final String sql, final ResultSetHandler<T> rsh) throws SQLException { + return executorService.submit(new Callable<T>() { + + @Override + public T call() throws Exception { + return queryRunner.insert(conn, sql, rsh); + } + }); + } + + /** + * Executes {@link QueryRunner#insert(Connection, String, ResultSetHandler, Object...)} asynchronously. + * + * @see QueryRunner#insert(Connection, String, ResultSetHandler, Object...) + */ + public <T> Future<T> insert(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException { + return executorService.submit(new Callable<T>() { + + @Override + public T call() throws Exception { + return queryRunner.insert(conn, sql, rsh, params); + } + }); + } + } Modified: commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/QueryRunner.java URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/QueryRunner.java?rev=1370883&r1=1370882&r2=1370883&view=diff ============================================================================== --- commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/QueryRunner.java (original) +++ commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/QueryRunner.java Wed Aug 8 18:47:36 2012 @@ -20,6 +20,7 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; import javax.sql.DataSource; @@ -498,5 +499,60 @@ public class QueryRunner extends Abstrac return rows; } + + public <T> T insert(String sql, ResultSetHandler<T> rsh) throws SQLException { + return insert(this.prepareConnection(), true, sql, rsh, (Object[]) null); + } + + public <T> T insert(String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException { + return insert(this.prepareConnection(), true, sql, rsh, params); + } + + public <T> T insert(Connection conn, String sql, ResultSetHandler<T> rsh) throws SQLException { + return insert(conn, false, sql, rsh, (Object[]) null); + } + + public <T> T insert(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException { + return insert(conn, false, sql, rsh, params); + } + + private <T> T insert(Connection conn, boolean closeConn, String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException { + if (conn == null) { + throw new SQLException("Null connection"); + } + + if (sql == null) { + if (closeConn) { + close(conn); + } + throw new SQLException("Null SQL statement"); + } + + if (rsh == null) { + if (closeConn) { + close(conn); + } + throw new SQLException("Null ResultSetHandler"); + } + + PreparedStatement stmt = null; + T generatedKeys = null; + try { + stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); + this.fillStatement(stmt, params); + stmt.executeUpdate(); + ResultSet resultSet = stmt.getGeneratedKeys(); + generatedKeys = rsh.handle(resultSet); + } catch (SQLException e) { + this.rethrow(e, sql, params); + } finally { + close(stmt); + if (closeConn) { + close(conn); + } + } + + return generatedKeys; + } } Modified: commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/AsyncQueryRunnerTest.java URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/AsyncQueryRunnerTest.java?rev=1370883&r1=1370882&r2=1370883&view=diff ============================================================================== --- commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/AsyncQueryRunnerTest.java (original) +++ commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/AsyncQueryRunnerTest.java Wed Aug 8 18:47:36 2012 @@ -19,6 +19,7 @@ package org.apache.commons.dbutils; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -433,6 +434,22 @@ public class AsyncQueryRunnerTest { public void testTooManyParamsUpdate() throws Exception { callUpdateWithException("unit", "test", "fail"); } + + @Test + public void testInsertUsesGivenQueryRunner() throws Exception { + QueryRunner mockQueryRunner = mock(QueryRunner.class); + runner = new AsyncQueryRunner(Executors.newSingleThreadExecutor(), mockQueryRunner); + + runner.insert("1", handler); + runner.insert("2", handler, "param1"); + runner.insert(conn, "3", handler); + runner.insert(conn, "4", handler, "param1"); + + verify(mockQueryRunner).insert("1", handler); + verify(mockQueryRunner).insert("2", handler, "param1"); + verify(mockQueryRunner).insert(conn, "3", handler); + verify(mockQueryRunner).insert(conn, "4", handler, "param1"); + } @Test(expected=ExecutionException.class) public void testNullConnectionUpdate() throws Exception { Modified: commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java?rev=1370883&r1=1370882&r2=1370883&view=diff ============================================================================== --- commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java (original) +++ commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java Wed Aug 8 18:47:36 2012 @@ -18,7 +18,9 @@ package org.apache.commons.dbutils; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -29,10 +31,13 @@ import java.sql.ParameterMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; import javax.sql.DataSource; import org.apache.commons.dbutils.handlers.ArrayHandler; +import org.apache.commons.dbutils.handlers.ScalarHandler; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -392,6 +397,25 @@ public class QueryRunnerTest { runner = new QueryRunner(); callGoodUpdate(conn); } + + @Test + public void testGoodInsert() throws Exception { + results = mock(ResultSet.class); + + when(meta.getParameterCount()).thenReturn(2); + when(conn.prepareStatement(any(String.class), eq(Statement.RETURN_GENERATED_KEYS))).thenReturn(stmt); + when(stmt.getGeneratedKeys()).thenReturn(results); + when(results.next()).thenReturn(true).thenReturn(false); + when(results.getObject(1)).thenReturn(1L); + + Long generatedKey = runner.insert("INSERT INTO blah(col1, col2) VALUES(?,?)", new ScalarHandler<Long>(), "unit", "test"); + + verify(stmt, times(1)).executeUpdate(); + verify(stmt, times(1)).close(); // make sure we closed the statement + verify(conn, times(1)).close(); // make sure we closed the connection + + Assert.assertEquals(1L, generatedKey.longValue()); + } // helper method for calling batch when an exception is expected private void callUpdateWithException(Object... params) throws Exception {