On Wed, Feb 8, 2012 at 5:04 AM, William Speirs <wspe...@apache.org> wrote:
> This is not a bad idea, but I would need to give it more thought. > > I tried to reduce code dup when I created AsyncQueryRunner by creating > AbstractQueryRunner[1], could we just add more code to that class? > I was thinking of having the AsyncQueryWrapper decorate the QueryRunner with async behaviour, in the same way a BufferedInputStream might decorate an InputStream. Here's a patch that shows what I mean. It causes all the interaction-based tests to fail, but I just wanted to get your take on whether this was a good/feasible idea. Moandji
Index: src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java =================================================================== --- src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java (revision 1238942) +++ src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java (working copy) @@ -17,8 +17,6 @@ package org.apache.commons.dbutils; import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -36,6 +34,12 @@ public class AsyncQueryRunner extends AbstractQueryRunner { private final ExecutorService executorService; + private final QueryRunner queryRunner; + + public AsyncQueryRunner(ExecutorService executorService, QueryRunner queryRunner) { + this.executorService = executorService; + this.queryRunner = queryRunner; + } /** * Constructor for AsyncQueryRunner. @@ -85,59 +89,7 @@ public AsyncQueryRunner(DataSource ds, boolean pmdKnownBroken, ExecutorService executorService) { super(ds, pmdKnownBroken); this.executorService = executorService; - } - - /** - * Class that encapsulates the continuation for batch calls. - */ - protected class BatchCallableStatement implements Callable<int[]> { - private final String sql; - private final Object[][] params; - private final Connection conn; - private final boolean closeConn; - private final PreparedStatement ps; - - /** - * Creates a new BatchCallableStatement instance. - * - * @param sql The SQL statement to execute. - * @param params An array of query replacement parameters. Each row in - * this array is one set of batch replacement values. - * @param conn The connection to use for the batch call. - * @param closeConn True if the connection should be closed, false otherwise. - * @param ps The {@link PreparedStatement} to be executed. - */ - public BatchCallableStatement(String sql, Object[][] params, Connection conn, boolean closeConn, PreparedStatement ps) { - this.sql = sql; - this.params = params; - this.conn = conn; - this.closeConn = closeConn; - this.ps = ps; - } - - /** - * The actual call to executeBatch. - * - * @return an array of update counts containing one element for each command in the batch. - * @throws SQLException if a database access error occurs or one of the commands sent to the database fails. - * @see PreparedStatement#executeBatch() - */ - public int[] call() throws SQLException { - int[] ret = null; - - try { - ret = ps.executeBatch(); - } catch (SQLException e) { - rethrow(e, sql, (Object[])params); - } finally { - close(ps); - if (closeConn) { - close(conn); - } - } - - return ret; - } + this.queryRunner = new QueryRunner(ds, pmdKnownBroken); } /** @@ -183,109 +135,13 @@ * @return A <code>Callable</code> which returns the number of rows updated per statement. * @throws SQLException If there are database or parameter errors. */ - private Callable<int[]> batch(Connection conn, boolean closeConn, String sql, 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 (params == null) { - if (closeConn) { - close(conn); - } - throw new SQLException("Null parameters. If parameters aren't need, pass an empty array."); - } - - PreparedStatement stmt = null; - Callable<int[]> ret = null; - try { - stmt = this.prepareStatement(conn, sql); - - for (int i = 0; i < params.length; i++) { - this.fillStatement(stmt, params[i]); - stmt.addBatch(); - } - - ret = new BatchCallableStatement(sql, params, conn, closeConn, stmt); - - } catch (SQLException e) { - close(stmt); - close(conn); - this.rethrow(e, sql, (Object[])params); - } - - return ret; - } - - /** - * Class that encapsulates the continuation for query calls. - * @param <T> The type of the result from the call to handle. - */ - protected class QueryCallableStatement<T> implements Callable<T> { - private final String sql; - private final Object[] params; - private final Connection conn; - private final boolean closeConn; - private final PreparedStatement ps; - private final ResultSetHandler<T> rsh; - - /** - * Creates a new {@code QueryCallableStatement} instance. - * - * @param conn The connection to use for the batch call. - * @param closeConn True if the connection should be closed, false otherwise. - * @param ps The {@link PreparedStatement} to be executed. - * @param rsh The handler that converts the results into an object. - * @param sql The SQL statement to execute. - * @param params An array of query replacement parameters. Each row in - * this array is one set of batch replacement values. - */ - public QueryCallableStatement(Connection conn, boolean closeConn, PreparedStatement ps, - ResultSetHandler<T> rsh, String sql, Object... params) { - this.sql = sql; - this.params = params; - this.conn = conn; - this.closeConn = closeConn; - this.ps = ps; - this.rsh = rsh; - } - - /** - * The actual call to {@code handle()} method. - * - * @return an array of update counts containing one element for each command in the batch. - * @throws SQLException if a database access error occurs. - * @see ResultSetHandler#handle(ResultSet) - */ - public T call() throws SQLException { - ResultSet rs = null; - T ret = null; - - try { - rs = wrap(ps.executeQuery()); - ret = rsh.handle(rs); - } catch (SQLException e) { - rethrow(e, sql, params); - } finally { - try { - close(rs); - } finally { - close(ps); - if (closeConn) { - close(conn); - } - } - } - - return ret; - } - + private Callable<int[]> batch(final Connection conn, boolean closeConn, final String sql, final Object[][] params) throws SQLException { + return new Callable<int[]>() { + @Override + public int[] call() throws Exception { + return queryRunner.batch(conn, sql, params); + } + }; } /** @@ -298,44 +154,14 @@ * @return A <code>Callable</code> which returns the result of the query call. * @throws SQLException If there are database or parameter errors. */ - private <T> Callable<T> query(Connection conn, boolean closeConn, String sql, ResultSetHandler<T> rsh, Object... params) + private <T> Callable<T> query(final Connection conn, boolean closeConn, final String sql, final ResultSetHandler<T> rsh, Object... params) throws SQLException { - PreparedStatement stmt = null; - Callable<T> ret = null; - - 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"); - } - - try { - stmt = this.prepareStatement(conn, sql); - this.fillStatement(stmt, params); - - ret = new QueryCallableStatement<T>(conn, closeConn, stmt, rsh, sql, params); - - } catch (SQLException e) { - close(stmt); - if (closeConn) { - close(conn); - } - this.rethrow(e, sql, params); - } - - return ret; + return new Callable<T>() { + @Override + public T call() throws Exception { + return queryRunner.query(conn, sql, rsh); + } + }; } /** @@ -403,61 +229,6 @@ } /** - * Class that encapsulates the continuation for update calls. - */ - protected class UpdateCallableStatement implements Callable<Integer> { - private final String sql; - private final Object[] params; - private final Connection conn; - private final boolean closeConn; - private final PreparedStatement ps; - - /** - * - * - * @param conn The connection to use for the batch call. - * @param closeConn True if the connection should be closed, false otherwise. - * @param ps The {@link PreparedStatement} to be executed. - * @param sql The SQL statement to execute. - * @param params An array of query replacement parameters. Each row in - * this array is one set of batch replacement values. - */ - public UpdateCallableStatement(Connection conn, boolean closeConn, PreparedStatement ps, String sql, Object... params) { - this.sql = sql; - this.params = params; - this.conn = conn; - this.closeConn = closeConn; - this.ps = ps; - } - - /** - * The actual call to {@code executeUpdate()} method. - * - * @return either (1) the row count for SQL Data Manipulation Language (DML) statements or - * (2) 0 for SQL statements that return nothing - * @throws SQLException if a database access error occurs. - * @see PreparedStatement#executeUpdate() - */ - public Integer call() throws SQLException { - int rows = 0; - - try { - rows = ps.executeUpdate(); - } catch (SQLException e) { - rethrow(e, sql, params); - } finally { - close(ps); - if (closeConn) { - close(conn); - } - } - - return Integer.valueOf(rows); - } - - } - - /** * Creates a continuation for an update call, and returns it in a <code>Callable</code>. * @param conn The connection to use for the update call. * @param closeConn True if the connection should be closed, false otherwise. @@ -467,36 +238,13 @@ * @return A <code>Callable</code> which returns the number of rows updated. * @throws SQLException If there are database or parameter errors. */ - private Callable<Integer> update(Connection conn, boolean closeConn, String sql, Object... params) throws SQLException { - PreparedStatement stmt = null; - Callable<Integer> ret = null; - - if (conn == null) { - throw new SQLException("Null connection"); - } - - if (sql == null) { - if (closeConn) { - close(conn); - } - throw new SQLException("Null SQL statement"); - } - - try { - stmt = this.prepareStatement(conn, sql); - this.fillStatement(stmt, params); - - ret = new UpdateCallableStatement(conn, closeConn, stmt, sql, params); - - } catch (SQLException e) { - close(stmt); - if (closeConn) { - close(conn); - } - this.rethrow(e, sql, params); - } - - return ret; + private Callable<Integer> update(final Connection conn, boolean closeConn, final String sql, final Object... params) throws SQLException { + return new Callable<Integer>() { + @Override + public Integer call() throws Exception { + return queryRunner.update(conn, sql, params); + } + }; } /**
--------------------------------------------------------------------- To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org