You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ws...@apache.org on 2012/03/27 03:39:28 UTC
svn commit: r1305706 - in /commons/proper/dbutils/trunk/src:
main/java/org/apache/commons/dbutils/AbstractQueryRunner.java
main/java/org/apache/commons/dbutils/AsyncQueryRunner.java
test/java/org/apache/commons/dbutils/AsyncQueryRunnerTest.java
Author: wspeirs
Date: Tue Mar 27 01:39:27 2012
New Revision: 1305706
URL: http://svn.apache.org/viewvc?rev=1305706&view=rev
Log:
- Applied DBUTILS88v2 patch
- Cleaned up a few things CheckStyle and FindBugs were unhappy about
Modified:
commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java
commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java
commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/AsyncQueryRunnerTest.java
Modified: commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java
URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java?rev=1305706&r1=1305705&r2=1305706&view=diff
==============================================================================
--- commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java (original)
+++ commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java Tue Mar 27 01:39:27 2012
@@ -33,20 +33,21 @@ import java.util.Arrays;
import javax.sql.DataSource;
/**
- * The base class for QueryRunner & AsyncQueryRunner.
- * This class is thread safe.
+ * The base class for QueryRunner & AsyncQueryRunner. This class is thread safe.
+ *
* @since 1.4 (mostly extracted from QueryRunner)
*/
public abstract class AbstractQueryRunner {
/**
- * Is {@link ParameterMetaData#getParameterType(int)} broken (have we tried it yet)?
+ * Is {@link ParameterMetaData#getParameterType(int)} broken (have we tried
+ * it yet)?
*/
private volatile boolean pmdKnownBroken = false;
/**
* The DataSource to retrieve connections from.
*/
- protected final DataSource ds;
+ private final DataSource ds;
/**
* Default constructor, sets pmdKnownBroken to false and ds to null.
@@ -57,9 +58,13 @@ public abstract class AbstractQueryRunne
/**
* Constructor to control the use of <code>ParameterMetaData</code>.
- * @param pmdKnownBroken Some drivers don't support {@link ParameterMetaData#getParameterType(int) };
- * if <code>pmdKnownBroken</code> is set to true, we won't even try it; if false, we'll try it,
- * and if it breaks, we'll remember not to use it again.
+ *
+ * @param pmdKnownBroken
+ * Some drivers don't support
+ * {@link ParameterMetaData#getParameterType(int) }; if
+ * <code>pmdKnownBroken</code> is set to true, we won't even try
+ * it; if false, we'll try it, and if it breaks, we'll remember
+ * not to use it again.
*/
public AbstractQueryRunner(boolean pmdKnownBroken) {
this.pmdKnownBroken = pmdKnownBroken;
@@ -67,25 +72,31 @@ public abstract class AbstractQueryRunne
}
/**
- * Constructor to provide a <code>DataSource</code>.
- * Methods that do not take a <code>Connection</code> parameter will
- * retrieve connections from this <code>DataSource</code>.
+ * Constructor to provide a <code>DataSource</code>. Methods that do not
+ * take a <code>Connection</code> parameter will retrieve connections from
+ * this <code>DataSource</code>.
*
- * @param ds The <code>DataSource</code> to retrieve connections from.
+ * @param ds
+ * The <code>DataSource</code> to retrieve connections from.
*/
public AbstractQueryRunner(DataSource ds) {
this.ds = ds;
}
/**
- * Constructor to provide a <code>DataSource</code> and control the use of <code>ParameterMetaData</code>.
- * Methods that do not take a <code>Connection</code> parameter will retrieve connections from this
+ * Constructor to provide a <code>DataSource</code> and control the use of
+ * <code>ParameterMetaData</code>. Methods that do not take a
+ * <code>Connection</code> parameter will retrieve connections from this
* <code>DataSource</code>.
*
- * @param ds The <code>DataSource</code> to retrieve connections from.
- * @param pmdKnownBroken Some drivers don't support {@link ParameterMetaData#getParameterType(int) };
- * if <code>pmdKnownBroken</code> is set to true, we won't even try it; if false, we'll try it,
- * and if it breaks, we'll remember not to use it again.
+ * @param ds
+ * The <code>DataSource</code> to retrieve connections from.
+ * @param pmdKnownBroken
+ * Some drivers don't support
+ * {@link ParameterMetaData#getParameterType(int) }; if
+ * <code>pmdKnownBroken</code> is set to true, we won't even try
+ * it; if false, we'll try it, and if it breaks, we'll remember
+ * not to use it again.
*/
public AbstractQueryRunner(DataSource ds, boolean pmdKnownBroken) {
this.pmdKnownBroken = pmdKnownBroken;
@@ -95,8 +106,7 @@ public abstract class AbstractQueryRunne
/**
* Returns the <code>DataSource</code> this runner is using.
* <code>QueryRunner</code> methods always call this method to get the
- * <code>DataSource</code> so subclasses can provide specialized
- * behavior.
+ * <code>DataSource</code> so subclasses can provide specialized behavior.
*
* @return DataSource the runner is using
*/
@@ -105,11 +115,14 @@ public abstract class AbstractQueryRunne
}
/**
- * Some drivers don't support {@link ParameterMetaData#getParameterType(int) };
- * if <code>pmdKnownBroken</code> is set to true, we won't even try it; if false, we'll try it,
- * and if it breaks, we'll remember not to use it again.
+ * Some drivers don't support
+ * {@link ParameterMetaData#getParameterType(int) }; if
+ * <code>pmdKnownBroken</code> is set to true, we won't even try it; if
+ * false, we'll try it, and if it breaks, we'll remember not to use it
+ * again.
*
- * @return the flag to skip (or not) {@link ParameterMetaData#getParameterType(int) }
+ * @return the flag to skip (or not)
+ * {@link ParameterMetaData#getParameterType(int) }
* @since 1.4
*/
public boolean isPmdKnownBroken() {
@@ -120,51 +133,60 @@ public abstract class AbstractQueryRunne
* Factory method that creates and initializes a
* <code>PreparedStatement</code> object for the given SQL.
* <code>QueryRunner</code> methods always call this method to prepare
- * statements for them. Subclasses can override this method to provide
- * special PreparedStatement configuration if needed. This implementation
+ * statements for them. Subclasses can override this method to provide
+ * special PreparedStatement configuration if needed. This implementation
* simply calls <code>conn.prepareStatement(sql)</code>.
*
- * @param conn The <code>Connection</code> used to create the
- * <code>PreparedStatement</code>
- * @param sql The SQL statement to prepare.
+ * @param conn
+ * The <code>Connection</code> used to create the
+ * <code>PreparedStatement</code>
+ * @param sql
+ * The SQL statement to prepare.
* @return An initialized <code>PreparedStatement</code>.
- * @throws SQLException if a database access error occurs
+ * @throws SQLException
+ * if a database access error occurs
*/
protected PreparedStatement prepareStatement(Connection conn, String sql)
- throws SQLException {
+ throws SQLException {
return conn.prepareStatement(sql);
}
/**
- * Factory method that creates and initializes a
- * <code>Connection</code> object. <code>QueryRunner</code> methods
- * always call this method to retrieve connections from its DataSource.
- * Subclasses can override this method to provide
- * special <code>Connection</code> configuration if needed. This
- * implementation simply calls <code>ds.getConnection()</code>.
+ * Factory method that creates and initializes a <code>Connection</code>
+ * object. <code>QueryRunner</code> methods always call this method to
+ * retrieve connections from its DataSource. Subclasses can override this
+ * method to provide special <code>Connection</code> configuration if
+ * needed. This implementation simply calls <code>ds.getConnection()</code>.
*
* @return An initialized <code>Connection</code>.
- * @throws SQLException if a database access error occurs
+ * @throws SQLException
+ * if a database access error occurs
* @since DbUtils 1.1
*/
protected Connection prepareConnection() throws SQLException {
if (this.getDataSource() == null) {
- throw new SQLException("QueryRunner requires a DataSource to be " +
- "invoked in this way, or a Connection should be passed in");
+ throw new SQLException(
+ "QueryRunner requires a DataSource to be "
+ + "invoked in this way, or a Connection should be passed in");
}
return this.getDataSource().getConnection();
}
/**
- * Fill the <code>PreparedStatement</code> replacement parameters with
- * the given objects.
- * @param stmt PreparedStatement to fill
- * @param params Query replacement parameters; <code>null</code> is a valid
- * value to pass in.
- * @throws SQLException if a database access error occurs
+ * Fill the <code>PreparedStatement</code> replacement parameters with the
+ * given objects.
+ *
+ * @param stmt
+ * PreparedStatement to fill
+ * @param params
+ * Query replacement parameters; <code>null</code> is a valid
+ * value to pass in.
+ * @throws SQLException
+ * if a database access error occurs
*/
- public void fillStatement(PreparedStatement stmt, Object... params) throws SQLException {
+ public void fillStatement(PreparedStatement stmt, Object... params)
+ throws SQLException {
// check the parameter count, if we can
ParameterMetaData pmd = null;
@@ -189,14 +211,15 @@ public abstract class AbstractQueryRunne
stmt.setObject(i + 1, params[i]);
} else {
// VARCHAR works with many drivers regardless
- // of the actual column type. Oddly, NULL and
+ // of the actual column type. Oddly, NULL and
// OTHER don't work with Oracle's drivers.
int sqlType = Types.VARCHAR;
if (!pmdKnownBroken) {
try {
/*
- * It's not possible for pmdKnownBroken to change from true to false,
- * (once true, always true) so pmd cannot be null here.
+ * It's not possible for pmdKnownBroken to change from
+ * true to false, (once true, always true) so pmd cannot
+ * be null here.
*/
sqlType = pmd.getParameterType(i + 1);
} catch (SQLException e) {
@@ -236,11 +259,14 @@ public abstract class AbstractQueryRunne
try {
value = method.invoke(bean, new Object[0]);
} catch (InvocationTargetException e) {
- throw new RuntimeException("Couldn't invoke method: " + method, e);
+ throw new RuntimeException("Couldn't invoke method: " + method,
+ e);
} catch (IllegalArgumentException e) {
- throw new RuntimeException("Couldn't invoke method with 0 arguments: " + method, e);
+ throw new RuntimeException(
+ "Couldn't invoke method with 0 arguments: " + method, e);
} catch (IllegalAccessException e) {
- throw new RuntimeException("Couldn't invoke method: " + method, e);
+ throw new RuntimeException("Couldn't invoke method: " + method,
+ e);
}
params[i] = value;
}
@@ -251,26 +277,33 @@ public abstract class AbstractQueryRunne
* Fill the <code>PreparedStatement</code> replacement parameters with the
* given object's bean property values.
*
- * @param stmt PreparedStatement to fill
- * @param bean A JavaBean object
- * @param propertyNames An ordered array of property names (these should match the
- * getters/setters); this gives the order to insert values in the
- * statement
- * @throws SQLException If a database access error occurs
+ * @param stmt
+ * PreparedStatement to fill
+ * @param bean
+ * A JavaBean object
+ * @param propertyNames
+ * An ordered array of property names (these should match the
+ * getters/setters); this gives the order to insert values in the
+ * statement
+ * @throws SQLException
+ * If a database access error occurs
*/
- public void fillStatementWithBean(PreparedStatement stmt, Object bean, String... propertyNames) throws SQLException {
+ public void fillStatementWithBean(PreparedStatement stmt, Object bean,
+ String... propertyNames) throws SQLException {
PropertyDescriptor[] descriptors;
try {
descriptors = Introspector.getBeanInfo(bean.getClass())
- .getPropertyDescriptors();
+ .getPropertyDescriptors();
} catch (IntrospectionException e) {
- throw new RuntimeException("Couldn't introspect bean " + bean.getClass().toString(), e);
+ throw new RuntimeException("Couldn't introspect bean "
+ + bean.getClass().toString(), e);
}
PropertyDescriptor[] sorted = new PropertyDescriptor[propertyNames.length];
for (int i = 0; i < propertyNames.length; i++) {
String propertyName = propertyNames[i];
if (propertyName == null) {
- throw new NullPointerException("propertyName can't be null: " + i);
+ throw new NullPointerException("propertyName can't be null: "
+ + i);
}
boolean found = false;
for (int j = 0; j < descriptors.length; j++) {
@@ -292,18 +325,22 @@ public abstract class AbstractQueryRunne
/**
* Throws a new exception with a more informative error message.
*
- * @param cause The original exception that will be chained to the new
- * exception when it's rethrown.
- *
- * @param sql The query that was executing when the exception happened.
+ * @param cause
+ * The original exception that will be chained to the new
+ * exception when it's rethrown.
+ *
+ * @param sql
+ * The query that was executing when the exception happened.
+ *
+ * @param params
+ * The query replacement parameters; <code>null</code> is a valid
+ * value to pass in.
*
- * @param params The query replacement parameters; <code>null</code> is a
- * valid value to pass in.
- *
- * @throws SQLException if a database access error occurs
+ * @throws SQLException
+ * if a database access error occurs
*/
protected void rethrow(SQLException cause, String sql, Object... params)
- throws SQLException {
+ throws SQLException {
String causeMessage = cause.getMessage();
if (causeMessage == null) {
@@ -329,14 +366,15 @@ public abstract class AbstractQueryRunne
}
/**
- * Wrap the <code>ResultSet</code> in a decorator before processing it.
- * This implementation returns the <code>ResultSet</code> it is given
- * without any decoration.
+ * Wrap the <code>ResultSet</code> in a decorator before processing it. This
+ * implementation returns the <code>ResultSet</code> it is given without any
+ * decoration.
*
* <p>
* Often, the implementation of this method can be done in an anonymous
* inner class like this:
* </p>
+ *
* <pre>
* QueryRunner run = new QueryRunner() {
* protected ResultSet wrap(ResultSet rs) {
@@ -345,8 +383,9 @@ public abstract class AbstractQueryRunne
* };
* </pre>
*
- * @param rs The <code>ResultSet</code> to decorate; never
- * <code>null</code>.
+ * @param rs
+ * The <code>ResultSet</code> to decorate; never
+ * <code>null</code>.
* @return The <code>ResultSet</code> wrapped in some decorator.
*/
protected ResultSet wrap(ResultSet rs) {
@@ -354,11 +393,14 @@ public abstract class AbstractQueryRunne
}
/**
- * Close a <code>Connection</code>. This implementation avoids closing if
- * null and does <strong>not</strong> suppress any exceptions. Subclasses
+ * Close a <code>Connection</code>. This implementation avoids closing if
+ * null and does <strong>not</strong> suppress any exceptions. Subclasses
* can override to provide special handling like logging.
- * @param conn Connection to close
- * @throws SQLException if a database access error occurs
+ *
+ * @param conn
+ * Connection to close
+ * @throws SQLException
+ * if a database access error occurs
* @since DbUtils 1.1
*/
protected void close(Connection conn) throws SQLException {
@@ -366,11 +408,14 @@ public abstract class AbstractQueryRunne
}
/**
- * Close a <code>Statement</code>. This implementation avoids closing if
- * null and does <strong>not</strong> suppress any exceptions. Subclasses
+ * Close a <code>Statement</code>. This implementation avoids closing if
+ * null and does <strong>not</strong> suppress any exceptions. Subclasses
* can override to provide special handling like logging.
- * @param stmt Statement to close
- * @throws SQLException if a database access error occurs
+ *
+ * @param stmt
+ * Statement to close
+ * @throws SQLException
+ * if a database access error occurs
* @since DbUtils 1.1
*/
protected void close(Statement stmt) throws SQLException {
@@ -378,11 +423,14 @@ public abstract class AbstractQueryRunne
}
/**
- * Close a <code>ResultSet</code>. This implementation avoids closing if
- * null and does <strong>not</strong> suppress any exceptions. Subclasses
+ * Close a <code>ResultSet</code>. This implementation avoids closing if
+ * null and does <strong>not</strong> suppress any exceptions. Subclasses
* can override to provide special handling like logging.
- * @param rs ResultSet to close
- * @throws SQLException if a database access error occurs
+ *
+ * @param rs
+ * ResultSet to close
+ * @throws SQLException
+ * if a database access error occurs
* @since DbUtils 1.1
*/
protected void close(ResultSet rs) throws SQLException {
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=1305706&r1=1305705&r2=1305706&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 Tue Mar 27 01:39:27 2012
@@ -36,6 +36,18 @@ import javax.sql.DataSource;
public class AsyncQueryRunner extends AbstractQueryRunner {
private final ExecutorService executorService;
+ private final QueryRunner queryRunner;
+
+ /**
+ * Constructor for AsyncQueryRunner which uses a provided ExecutorService and underlying QueryRunner.
+ *
+ * @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
+ * @param queryRunner the {@code QueryRunner} instance to use for the queries.
+ */
+ public AsyncQueryRunner(ExecutorService executorService, QueryRunner queryRunner) {
+ this.executorService = executorService;
+ this.queryRunner = queryRunner;
+ }
/**
* Constructor for AsyncQueryRunner.
@@ -47,6 +59,7 @@ public class AsyncQueryRunner extends Ab
}
/**
+ * @deprecated Use {@link #AsyncQueryRunner(ExecutorService, QueryRunner)} instead.
* Constructor for AsyncQueryRunner that controls the use of <code>ParameterMetaData</code>.
*
* @param pmdKnownBroken Some drivers don't support {@link java.sql.ParameterMetaData#getParameterType(int) };
@@ -54,11 +67,13 @@ public class AsyncQueryRunner extends Ab
* and if it breaks, we'll remember not to use it again.
* @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
*/
+ @Deprecated
public AsyncQueryRunner(boolean pmdKnownBroken, ExecutorService executorService) {
this(null, pmdKnownBroken, executorService);
}
/**
+ * @deprecated Use {@link #AsyncQueryRunner(ExecutorService, QueryRunner)} instead.
* Constructor for AsyncQueryRunner that takes a <code>DataSource</code>.
*
* Methods that do not take a <code>Connection</code> parameter will retrieve connections from this
@@ -67,11 +82,13 @@ public class AsyncQueryRunner extends Ab
* @param ds The <code>DataSource</code> to retrieve connections from.
* @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
*/
+ @Deprecated
public AsyncQueryRunner(DataSource ds, ExecutorService executorService) {
this(ds, false, executorService);
}
/**
+ * @deprecated Use {@link #AsyncQueryRunner(ExecutorService, QueryRunner)} instead.
* Constructor for AsyncQueryRunner that take a <code>DataSource</code> and controls the use of <code>ParameterMetaData</code>.
* Methods that do not take a <code>Connection</code> parameter will retrieve connections from this
* <code>DataSource</code>.
@@ -82,14 +99,18 @@ public class AsyncQueryRunner extends Ab
* and if it breaks, we'll remember not to use it again.
* @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
*/
+ @Deprecated
public AsyncQueryRunner(DataSource ds, boolean pmdKnownBroken, ExecutorService executorService) {
super(ds, pmdKnownBroken);
this.executorService = executorService;
+ this.queryRunner = new QueryRunner(ds, pmdKnownBroken);
}
/**
+ * @deprecated No longer used by this class. Will be removed in a future version.
* Class that encapsulates the continuation for batch calls.
*/
+ @Deprecated
protected class BatchCallableStatement implements Callable<int[]> {
private final String sql;
private final Object[][] params;
@@ -109,7 +130,7 @@ public class AsyncQueryRunner extends Ab
*/
public BatchCallableStatement(String sql, Object[][] params, Connection conn, boolean closeConn, PreparedStatement ps) {
this.sql = sql;
- this.params = params;
+ this.params = params.clone();
this.conn = conn;
this.closeConn = closeConn;
this.ps = ps;
@@ -151,8 +172,15 @@ public class AsyncQueryRunner extends Ab
* @return A <code>Future</code> which returns the number of rows updated per statement.
* @throws SQLException if a database access error occurs
*/
- public Future<int[]> batch(Connection conn, String sql, Object[][] params) throws SQLException {
- return executorService.submit(this.batch(conn, false, sql, params));
+ public Future<int[]> batch(final Connection conn, final String sql, final Object[][] params) throws SQLException {
+ return executorService.submit(new Callable<int[]>() {
+
+ @Override
+ public int[] call() throws Exception {
+ return queryRunner.batch(conn, sql, params);
+ }
+
+ });
}
/**
@@ -167,60 +195,15 @@ public class AsyncQueryRunner extends Ab
* @return A <code>Future</code> which returns the number of rows updated per statement.
* @throws SQLException if a database access error occurs
*/
- public Future<int[]> batch(String sql, Object[][] params) throws SQLException {
- Connection conn = this.prepareConnection();
+ public Future<int[]> batch(final String sql, final Object[][] params) throws SQLException {
+ return executorService.submit(new Callable<int[]>() {
- return executorService.submit(this.batch(conn, true, sql, params));
- }
-
- /**
- * Creates a continuation for a batch call, and returns it in a <code>Callable</code>.
- * @param conn The connection to use for the batch call.
- * @param closeConn True if the connection should be closed, false otherwise.
- * @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.
- * @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);
+ @Override
+ public int[] call() throws Exception {
+ return queryRunner.batch(sql, params);
}
- 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;
+ });
}
/**
@@ -289,56 +272,6 @@ public class AsyncQueryRunner extends Ab
}
/**
- * Creates a continuation for a query call, and returns it in a <code>Callable</code>.
- * @param conn The connection to use for the query call.
- * @param closeConn True if the connection should be closed, false otherwise.
- * @param sql The SQL statement to execute.
- * @param params An array of query replacement parameters. Each row in
- * this array is one set of query replacement values.
- * @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)
- 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;
- }
-
- /**
* Execute an SQL SELECT query with replacement parameters. The
* caller is responsible for closing the connection.
* @param <T> The type of object that the handler returns
@@ -349,8 +282,16 @@ public class AsyncQueryRunner extends Ab
* @return A <code>Future</code> which returns the result of the query call.
* @throws SQLException if a database access error occurs
*/
- public <T> Future<T> query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException {
- return executorService.submit(this.<T>query(conn, false, sql, rsh, params));
+ public <T> Future<T> query(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.query(conn, sql, rsh, params);
+ }
+
+ });
}
/**
@@ -363,8 +304,15 @@ public class AsyncQueryRunner extends Ab
* @return A <code>Future</code> which returns the result of the query call.
* @throws SQLException if a database access error occurs
*/
- public <T> Future<T> query(Connection conn, String sql, ResultSetHandler<T> rsh) throws SQLException {
- return executorService.submit(this.<T>query(conn, false, sql, rsh, (Object[]) null));
+ public <T> Future<T> query(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.query(conn, sql, rsh);
+ }
+
+ });
}
/**
@@ -380,9 +328,15 @@ public class AsyncQueryRunner extends Ab
* @return A <code>Future</code> which returns the result of the query call.
* @throws SQLException if a database access error occurs
*/
- public <T> Future<T> query(String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException {
- Connection conn = this.prepareConnection();
- return executorService.submit(this.<T>query(conn, true, sql, rsh, params));
+ public <T> Future<T> query(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.query(sql, rsh, params);
+ }
+
+ });
}
/**
@@ -397,14 +351,22 @@ public class AsyncQueryRunner extends Ab
* @return A <code>Future</code> which returns the result of the query call.
* @throws SQLException if a database access error occurs
*/
- public <T> Future<T> query(String sql, ResultSetHandler<T> rsh) throws SQLException {
- Connection conn = this.prepareConnection();
- return executorService.submit(this.<T>query(conn, true, sql, rsh, (Object[]) null));
+ public <T> Future<T> query(final String sql, final ResultSetHandler<T> rsh) throws SQLException {
+ return executorService.submit(new Callable<T>() {
+
+ @Override
+ public T call() throws Exception {
+ return queryRunner.query(sql, rsh);
+ }
+
+ });
}
/**
+ * @deprecated No longer used by this class. Will be removed in a future version.
* Class that encapsulates the continuation for update calls.
*/
+ @Deprecated
protected class UpdateCallableStatement implements Callable<Integer> {
private final String sql;
private final Object[] params;
@@ -458,48 +420,6 @@ public class AsyncQueryRunner extends Ab
}
/**
- * 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.
- * @param sql The SQL statement to execute.
- * @param params An array of update replacement parameters. Each row in
- * this array is one set of update replacement values.
- * @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;
- }
-
- /**
* Execute an SQL INSERT, UPDATE, or DELETE query without replacement
* parameters.
*
@@ -508,8 +428,15 @@ public class AsyncQueryRunner extends Ab
* @return A <code>Future</code> which returns the number of rows updated.
* @throws SQLException if a database access error occurs
*/
- public Future<Integer> update(Connection conn, String sql) throws SQLException {
- return executorService.submit(this.update(conn, false, sql, (Object[]) null));
+ public Future<Integer> update(final Connection conn, final String sql) throws SQLException {
+ return executorService.submit(new Callable<Integer>() {
+
+ @Override
+ public Integer call() throws Exception {
+ return queryRunner.update(conn, sql);
+ }
+
+ });
}
/**
@@ -522,8 +449,15 @@ public class AsyncQueryRunner extends Ab
* @return A <code>Future</code> which returns the number of rows updated.
* @throws SQLException if a database access error occurs
*/
- public Future<Integer> update(Connection conn, String sql, Object param) throws SQLException {
- return executorService.submit(this.update(conn, false, sql, new Object[]{param}));
+ public Future<Integer> update(final Connection conn, final String sql, final Object param) throws SQLException {
+ return executorService.submit(new Callable<Integer>() {
+
+ @Override
+ public Integer call() throws Exception {
+ return queryRunner.update(conn, sql, param);
+ }
+
+ });
}
/**
@@ -535,8 +469,15 @@ public class AsyncQueryRunner extends Ab
* @return A <code>Future</code> which returns the number of rows updated.
* @throws SQLException if a database access error occurs
*/
- public Future<Integer> update(Connection conn, String sql, Object... params) throws SQLException {
- return executorService.submit(this.update(conn, false, sql, params));
+ public Future<Integer> update(final Connection conn, final String sql, final Object... params) throws SQLException {
+ return executorService.submit(new Callable<Integer>() {
+
+ @Override
+ public Integer call() throws Exception {
+ return queryRunner.update(conn, sql, params);
+ }
+
+ });
}
/**
@@ -550,9 +491,15 @@ public class AsyncQueryRunner extends Ab
* @throws SQLException if a database access error occurs
* @return A <code>Future</code> which returns the number of rows updated.
*/
- public Future<Integer> update(String sql) throws SQLException {
- Connection conn = this.prepareConnection();
- return executorService.submit(this.update(conn, true, sql, (Object[]) null));
+ public Future<Integer> update(final String sql) throws SQLException {
+ return executorService.submit(new Callable<Integer>() {
+
+ @Override
+ public Integer call() throws Exception {
+ return queryRunner.update(sql);
+ }
+
+ });
}
/**
@@ -567,9 +514,15 @@ public class AsyncQueryRunner extends Ab
* @throws SQLException if a database access error occurs
* @return A <code>Future</code> which returns the number of rows updated.
*/
- public Future<Integer> update(String sql, Object param) throws SQLException {
- Connection conn = this.prepareConnection();
- return executorService.submit(this.update(conn, true, sql, new Object[]{param}));
+ public Future<Integer> update(final String sql, final Object param) throws SQLException {
+ return executorService.submit(new Callable<Integer>() {
+
+ @Override
+ public Integer call() throws Exception {
+ return queryRunner.update(sql, param);
+ }
+
+ });
}
/**
@@ -584,9 +537,15 @@ public class AsyncQueryRunner extends Ab
* @throws SQLException if a database access error occurs
* @return A <code>Future</code> which returns the number of rows updated.
*/
- public Future<Integer> update(String sql, Object... params) throws SQLException {
- Connection conn = this.prepareConnection();
- return executorService.submit(this.update(conn, true, sql, params));
+ public Future<Integer> update(final String sql, final Object... params) throws SQLException {
+ return executorService.submit(new Callable<Integer>() {
+
+ @Override
+ public Integer call() throws Exception {
+ return queryRunner.update(sql, params);
+ }
+
+ });
}
}
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=1305706&r1=1305705&r2=1305706&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 Tue Mar 27 01:39:27 2012
@@ -28,6 +28,7 @@ import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@@ -71,9 +72,10 @@ public class AsyncQueryRunnerTest {
private void callGoodBatch(Connection conn, Object[][] params) throws Exception {
when(meta.getParameterCount()).thenReturn(2);
Future<int[]> future = runner.batch(conn, "select * from blah where ? = ?", params);
- verify(stmt, times(2)).addBatch();
future.get();
+
+ verify(stmt, times(2)).addBatch();
verify(stmt, times(1)).executeBatch();
verify(stmt, times(1)).close(); // make sure we closed the statement
verify(conn, times(0)).close(); // make sure we closed the connection
@@ -82,9 +84,10 @@ public class AsyncQueryRunnerTest {
private void callGoodBatch(Object[][] params) throws Exception {
when(meta.getParameterCount()).thenReturn(2);
Future<int[]> future = runner.batch("select * from blah where ? = ?", params);
- verify(stmt, times(2)).addBatch();
future.get();
+
+ verify(stmt, times(2)).addBatch();
verify(stmt, times(1)).executeBatch();
verify(stmt, times(1)).close(); // make sure we closed the statement
verify(conn, times(1)).close(); // make sure we closed the connection
@@ -129,9 +132,10 @@ public class AsyncQueryRunnerTest {
try {
future = runner.batch(sql, params);
- verify(stmt, times(2)).addBatch();
-
+
future.get();
+
+ verify(stmt, times(2)).addBatch();
verify(stmt, times(1)).executeBatch();
verify(stmt, times(1)).close(); // make sure the statement is closed
verify(conn, times(1)).close(); // make sure the connection is closed
@@ -157,30 +161,30 @@ public class AsyncQueryRunnerTest {
callBatchWithException("select * from blah where ? = ?", params);
}
- @Test(expected=SQLException.class)
+ @Test(expected=ExecutionException.class)
public void testNullConnectionBatch() throws Exception {
String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
when(meta.getParameterCount()).thenReturn(2);
when(dataSource.getConnection()).thenReturn(null);
- runner.batch("select * from blah where ? = ?", params);
+ runner.batch("select * from blah where ? = ?", params).get();
}
- @Test(expected=SQLException.class)
+ @Test(expected=ExecutionException.class)
public void testNullSqlBatch() throws Exception {
String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
when(meta.getParameterCount()).thenReturn(2);
- runner.batch(null, params);
+ runner.batch(null, params).get();
}
- @Test(expected=SQLException.class)
+ @Test(expected=ExecutionException.class)
public void testNullParamsArgBatch() throws Exception {
when(meta.getParameterCount()).thenReturn(2);
- runner.batch("select * from blah where ? = ?", null);
+ runner.batch("select * from blah where ? = ?", null).get();
}
@Test
@@ -296,26 +300,26 @@ public class AsyncQueryRunnerTest {
callQueryWithException("unit", "test", "fail");
}
- @Test(expected=SQLException.class)
+ @Test(expected=ExecutionException.class)
public void testNullConnectionQuery() throws Exception {
when(meta.getParameterCount()).thenReturn(2);
when(dataSource.getConnection()).thenReturn(null);
- runner.query("select * from blah where ? = ?", handler, "unit", "test");
+ runner.query("select * from blah where ? = ?", handler, "unit", "test").get();
}
- @Test(expected=SQLException.class)
+ @Test(expected=ExecutionException.class)
public void testNullSqlQuery() throws Exception {
when(meta.getParameterCount()).thenReturn(2);
- runner.query(null, handler);
+ runner.query(null, handler).get();
}
- @Test(expected=SQLException.class)
+ @Test(expected=ExecutionException.class)
public void testNullHandlerQuery() throws Exception {
when(meta.getParameterCount()).thenReturn(2);
- runner.query("select * from blah where ? = ?", null);
+ runner.query("select * from blah where ? = ?", null).get();
}
@Test
@@ -430,19 +434,19 @@ public class AsyncQueryRunnerTest {
callUpdateWithException("unit", "test", "fail");
}
- @Test(expected=SQLException.class)
+ @Test(expected=ExecutionException.class)
public void testNullConnectionUpdate() throws Exception {
when(meta.getParameterCount()).thenReturn(2);
when(dataSource.getConnection()).thenReturn(null);
- runner.update("select * from blah where ? = ?", "unit", "test");
+ runner.update("select * from blah where ? = ?", "unit", "test").get();
}
- @Test(expected=SQLException.class)
+ @Test(expected=ExecutionException.class)
public void testNullSqlUpdate() throws Exception {
when(meta.getParameterCount()).thenReturn(2);
- runner.update(null);
+ runner.update(null).get();
}
@Test
@@ -455,36 +459,9 @@ public class AsyncQueryRunnerTest {
//
// Random tests
//
- class MyBean {
- private int a;
- private double b;
- private String c;
-
- public int getA() { return a; }
- public void setA(int a) { this.a = a; }
- public double getB() { return b; }
- public void setB(double b) { this.b = b; }
- public String getC() { return c; }
- public void setC(String c) { this.c = c; }
- }
-
- @Test
- public void testFillStatementWithBean() throws Exception {
- MyBean bean = new MyBean();
- when(meta.getParameterCount()).thenReturn(3);
- runner.fillStatementWithBean(stmt, bean, new String[] { "a", "b", "c" });
- }
-
- @Test(expected=NullPointerException.class)
- public void testFillStatementWithBeanNullNames() throws Exception {
- MyBean bean = new MyBean();
- when(meta.getParameterCount()).thenReturn(3);
- runner.fillStatementWithBean(stmt, bean, new String[] { "a", "b", null });
- }
-
- @Test(expected=SQLException.class)
+ @Test(expected=ExecutionException.class)
public void testBadPrepareConnection() throws Exception {
runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1));
- runner.update("update blah set unit = test");
+ runner.update("update blah set unit = test").get();
}
}
Re: svn commit: r1305706 - in /commons/proper/dbutils/trunk/src:
main/java/org/apache/commons/dbutils/AbstractQueryRunner.java
main/java/org/apache/commons/dbutils/AsyncQueryRunner.java test/java/org/apache/commons/dbutils/AsyncQueryRunnerTest.java
Posted by sebb <se...@gmail.com>.
On 27 March 2012 02:39, <ws...@apache.org> wrote:
> Author: wspeirs
> Date: Tue Mar 27 01:39:27 2012
> New Revision: 1305706
>
> URL: http://svn.apache.org/viewvc?rev=1305706&view=rev
> Log:
> - Applied DBUTILS88v2 patch
> - Cleaned up a few things CheckStyle and FindBugs were unhappy about
>
> Modified:
> commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java
> commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java
> commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/AsyncQueryRunnerTest.java
>
> Modified: commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java
> URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java?rev=1305706&r1=1305705&r2=1305706&view=diff
> ==============================================================================
> --- commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java (original)
> +++ commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java Tue Mar 27 01:39:27 2012
> @@ -33,20 +33,21 @@ import java.util.Arrays;
> import javax.sql.DataSource;
>
> /**
> - * The base class for QueryRunner & AsyncQueryRunner.
> - * This class is thread safe.
> + * The base class for QueryRunner & AsyncQueryRunner. This class is thread safe.
> + *
> * @since 1.4 (mostly extracted from QueryRunner)
> */
> public abstract class AbstractQueryRunner {
> /**
> - * Is {@link ParameterMetaData#getParameterType(int)} broken (have we tried it yet)?
> + * Is {@link ParameterMetaData#getParameterType(int)} broken (have we tried
> + * it yet)?
> */
> private volatile boolean pmdKnownBroken = false;
>
> /**
> * The DataSource to retrieve connections from.
> */
> - protected final DataSource ds;
> + private final DataSource ds;
That will break binary compatibility.
There is a public method which gives access to the field, but some
code may use the direct reference.
The field should remain protected, but could be deprecated with a view
to possibly removing it at a later stage.
Since the field is final, it does not particularly matter that there
is direct access to it.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org