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

Reply via email to