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 2019/12/31 00:32:30 UTC
[commons-dbutils] branch 2_0 updated: Merge with
github.com/wspeirs/sop4j-dbutils
This is an automated email from the ASF dual-hosted git repository.
wspeirs pushed a commit to branch 2_0
in repository https://gitbox.apache.org/repos/asf/commons-dbutils.git
The following commit(s) were added to refs/heads/2_0 by this push:
new 180c099 Merge with github.com/wspeirs/sop4j-dbutils
180c099 is described below
commit 180c0990b1f0da4d0039904b68cc6b57f00558e5
Author: William Speirs <bi...@gmail.com>
AuthorDate: Mon Dec 30 19:27:42 2019 -0500
Merge with github.com/wspeirs/sop4j-dbutils
---
.gitignore | 1 +
pom.xml | 19 +-
.../apache/commons/dbutils2/AbstractExecutor.java | 120 ++++-----
.../commons/dbutils2/BaseResultSetHandler.java | 110 +++++----
.../apache/commons/dbutils2/BasicRowProcessor.java | 2 +-
.../org/apache/commons/dbutils2/BatchExecutor.java | 69 ++----
.../commons/dbutils2/BatchInsertExecutor.java | 3 +-
.../org/apache/commons/dbutils2/BeanProcessor.java | 19 +-
.../org/apache/commons/dbutils2/EntityUtils.java | 251 +++++++++++++++++++
.../apache/commons/dbutils2/InsertExecutor.java | 10 +-
.../org/apache/commons/dbutils2/QueryRunner.java | 273 +++++++++++++++++++++
.../commons/dbutils2/AbstractExecutorTest.java | 14 +-
.../apache/commons/dbutils2/AsyncExecutorTest.java | 7 +-
.../dbutils2/BaseResultSetHandlerTestCase.java | 1 -
.../org/apache/commons/dbutils2/BaseTestCase.java | 9 +-
.../commons/dbutils2/BasicRowProcessorTest.java | 3 -
.../apache/commons/dbutils2/BatchExecutorTest.java | 61 ++++-
.../commons/dbutils2/BatchInsertExecutorTest.java | 8 +-
.../apache/commons/dbutils2/BeanProcessorTest.java | 3 -
.../org/apache/commons/dbutils2/DbUtilsTest.java | 1 -
.../java/org/apache/commons/dbutils2/EnumTest.java | 36 +++
.../dbutils2/GenerousBeanProcessorTest.java | 2 +-
.../commons/dbutils2/InsertExecutorTest.java | 12 +-
.../org/apache/commons/dbutils2/MockResultSet.java | 4 +-
.../commons/dbutils2/MockResultSetMetaData.java | 2 -
.../apache/commons/dbutils2/ProxyFactoryTest.java | 2 -
.../apache/commons/dbutils2/QueryExecutorTest.java | 4 +-
.../apache/commons/dbutils2/QueryLoaderTest.java | 5 +-
.../apache/commons/dbutils2/QueryRunnerTest.java | 3 +-
.../commons/dbutils2/ResultSetIteratorTest.java | 2 -
.../java/org/apache/commons/dbutils2/TestBean.java | 14 ++
.../commons/dbutils2/UpdateExecutorTest.java | 8 +-
.../dbutils2/handlers/BeanMapHandlerTest.java | 4 +-
.../dbutils2/handlers/ColumnListHandlerTest.java | 1 -
.../dbutils2/handlers/KeyedHandlerTest.java | 1 -
.../commons/dbutils2/handlers/MapHandlerTest.java | 1 -
.../dbutils2/handlers/MapListHandlerTest.java | 1 -
.../dbutils2/handlers/ScalarHandlerTest.java | 1 -
.../wrappers/SqlNullCheckedResultSetTest.java | 1 -
.../wrappers/StringTrimmedResultSetTest.java | 2 -
40 files changed, 849 insertions(+), 241 deletions(-)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e420ee4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+target/*
diff --git a/pom.xml b/pom.xml
index bd7096d..07dacbc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -189,10 +189,27 @@
<name>Benedikt Ritter</name>
<email>bene at systemoutprintln dot de</email>
</contributor>
- </contributors>
+ <contributor>
+ <name>William Speirs</name>
+ <email>bill.speirs@gmail.com</email>
+ <roles>
+ <role>Java Developer</role>
+ </roles>
+ </contributor>
+ </contributors>
<dependencies>
<dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>javax.persistence-api</artifactId>
+ <version>2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-beanutils</groupId>
+ <artifactId>commons-beanutils</artifactId>
+ <version>1.9.4</version>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
diff --git a/src/main/java/org/apache/commons/dbutils2/AbstractExecutor.java b/src/main/java/org/apache/commons/dbutils2/AbstractExecutor.java
index 89f99e7..f2356cb 100644
--- a/src/main/java/org/apache/commons/dbutils2/AbstractExecutor.java
+++ b/src/main/java/org/apache/commons/dbutils2/AbstractExecutor.java
@@ -38,6 +38,7 @@ import java.util.regex.Pattern;
abstract class AbstractExecutor<T extends AbstractExecutor<T>> {
private static final String COLON = ":"; // TODO: change this to any character
+ private static final Pattern PARAM_PATTERN = Pattern.compile("(:\\w+)");
private final Connection conn;
private final String sql;
@@ -48,13 +49,16 @@ abstract class AbstractExecutor<T extends AbstractExecutor<T>> {
private int currentPosition = 0;
public AbstractExecutor(final Connection conn, final String sql) throws SQLException {
+ this(conn, sql, Statement.NO_GENERATED_KEYS);
+ }
+
+ public AbstractExecutor(final Connection conn, final String sql, final int autoGeneratedKeys) throws SQLException {
this.conn = conn;
this.sql = sql;
this.paramPosMap = new HashMap<String, List<Integer>>();
this.paramValueMap = new HashMap<String, Object>();
- final Pattern paramPattern = Pattern.compile("(:\\w+)");
- final Matcher matcher = paramPattern.matcher(sql);
+ final Matcher matcher = PARAM_PATTERN.matcher(sql);
// go through finding params
while (matcher.find()) {
@@ -62,7 +66,7 @@ abstract class AbstractExecutor<T extends AbstractExecutor<T>> {
}
// replace all of the :names with ?, and create a prepared statement
- stmt = conn.prepareStatement(sql.replaceAll(":\\w+", "\\?"));
+ stmt = conn.prepareStatement(sql.replaceAll(":\\w+", "\\?"), autoGeneratedKeys);
}
/**
@@ -115,21 +119,27 @@ abstract class AbstractExecutor<T extends AbstractExecutor<T>> {
* @throws SQLException if there are unmapped params.
*/
void throwIfUnmappedParams() throws SQLException {
- if (paramPosMap.size() != 0) {
- final Set<String> unmappedParams = paramPosMap.keySet();
- final StringBuilder sb = new StringBuilder("There are unbound parameters: ");
+ // if the sizes are the same, then we've filled all the parameters
+ if(paramValueMap.size() == paramPosMap.size()) {
+ return;
+ }
- for (String param:unmappedParams) {
- sb.append(param);
- sb.append(", ");
- }
+ final StringBuilder sb = new StringBuilder("There are unbound parameters: ");
+ final Set<String> unboundParams = paramPosMap.keySet();
- // remove the last comma
- sb.delete(sb.length() - 2, sb.length());
+ // compute the set difference
+ unboundParams.removeAll(paramValueMap.keySet());
- // throw our exception
- throw new SQLException(sb.toString());
+ for (String param:unboundParams) {
+ sb.append(param);
+ sb.append(", ");
}
+
+ // remove the last comma
+ sb.delete(sb.length() - 2, sb.length());
+
+ // throw our exception
+ throw new SQLException(sb.toString());
}
/**
@@ -140,8 +150,33 @@ abstract class AbstractExecutor<T extends AbstractExecutor<T>> {
* @return this execution object to provide the fluent style.
* @throws SQLException thrown if the parameter is not found, already bound, or there is an issue binding it.
*/
- public T bind(final String name, final Object value) throws SQLException {
- return bind(name, value, true);
+ public T bind(String name, final Object value) throws SQLException {
+ name = name.replace(COLON, ""); // so we can take ":name" or "name"
+
+ final List<Integer> pos = paramPosMap.get(name);
+
+ if (pos == null) {
+ throw new SQLException(name + " is not found in the SQL statement: " + getSql());
+ }
+
+ // make sure it isn't already bound
+ if(paramValueMap.containsKey(name)) {
+ throw new SQLException("You are attempting to bind the parameter " + name + " twice. It already has the value " + paramValueMap.get(name));
+ }
+
+ // go through and bind all of the positions for this name
+ for (Integer p:pos) {
+ stmt.setObject(p.intValue(), value);
+ }
+
+ // add the param and value to our map
+ paramValueMap.put(name, value);
+
+ // suppressed because the casting will always work here
+ @SuppressWarnings("unchecked")
+ final T ret = (T) this;
+
+ return ret;
}
/**
@@ -154,7 +189,7 @@ abstract class AbstractExecutor<T extends AbstractExecutor<T>> {
* @throws SQLException throw if the parameter is not found, already bound, or there is an issue binding null.
*/
public T bindNull(final String name) throws SQLException {
- return bindNull(name, Types.VARCHAR, true);
+ return bindNull(name, Types.VARCHAR);
}
/**
@@ -165,23 +200,10 @@ abstract class AbstractExecutor<T extends AbstractExecutor<T>> {
* @return this execution object to provide the fluent style.
* @throws SQLException throw if the parameter is not found, already bound, or there is an issue binding null.
*/
- public T bindNull(final String name, final int sqlType) throws SQLException {
- return bindNull(name, sqlType, true);
- }
-
- /**
- * Given a param name and sqlType, binds a null to that parameter.
- *
- * @param name the name of the parameter.
- * @param sqlType the type of the parameter.
- * @param removeFromPosMap if the param should be removed from the pos map.
- * @return this
- * @throws SQLException if there is an SQLException during binding.
- */
- T bindNull(String name, int sqlType, boolean removeFromPosMap) throws SQLException {
+ public T bindNull(String name, final int sqlType) throws SQLException {
name = name.replace(COLON, ""); // so we can take ":name" or "name"
- final List<Integer> pos = removeFromPosMap ? paramPosMap.remove(name) : paramPosMap.get(name);
+ final List<Integer> pos = paramPosMap.get(name);
if (pos == null) {
throw new SQLException(name + " is not found in the SQL statement");
@@ -203,40 +225,6 @@ abstract class AbstractExecutor<T extends AbstractExecutor<T>> {
}
/**
- * Binds value to name, but does not do the bookkeeping.
- *
- * @param name the parameter name.
- * @param value the value.
- * @param removeFromPosMap if the param should be removed from the pos map.
- * @return this
- * @throws SQLException if there is an SQLException during binding.
- */
- T bind(String name, final Object value, boolean removeFromPosMap) throws SQLException {
- name = name.replace(COLON, ""); // so we can take ":name" or "name"
-
- final List<Integer> pos = removeFromPosMap ? paramPosMap.remove(name) : paramPosMap.get(name);
-
- if (pos == null) {
- throw new SQLException(name + " is not found in the SQL statement");
- }
-
- // go through and bind all of the positions for this name
- for (Integer p:pos) {
- // TODO: need to figure out how to bind NULL
- stmt.setObject(p.intValue(), value);
- }
-
- // add the param and value to our map
- paramValueMap.put(name, value);
-
- // suppressed because the casting will always work here
- @SuppressWarnings("unchecked")
- final T ret = (T) this;
-
- return ret;
- }
-
- /**
* Used for batch calls so we can clear the map after the addBatch call.
*/
void clearValueMap() {
diff --git a/src/main/java/org/apache/commons/dbutils2/BaseResultSetHandler.java b/src/main/java/org/apache/commons/dbutils2/BaseResultSetHandler.java
index 8cf2673..854e69e 100644
--- a/src/main/java/org/apache/commons/dbutils2/BaseResultSetHandler.java
+++ b/src/main/java/org/apache/commons/dbutils2/BaseResultSetHandler.java
@@ -78,7 +78,6 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
*
* @return An Object initialized with <code>ResultSet</code> data
* @throws SQLException if a database access error occurs
- * @see {@link ResultSetHandler#handle(ResultSet)}
*/
protected abstract T handle() throws SQLException;
@@ -321,7 +320,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
- * @return
+ * @return the Reader.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getCharacterStream(int)
*/
@@ -379,7 +378,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
* @param cal the Calendar.
- * @return
+ * @return the Date.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getDate(int, java.util.Calendar)
*/
@@ -596,8 +595,8 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
- * @param map
- * @return
+ * @param map the map.
+ * @return the Object.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getObject(int, java.util.Map)
*/
@@ -607,7 +606,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
- * @return
+ * @return the Object.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getObject(int)
*/
@@ -617,8 +616,8 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnLabel the column's label.
- * @param map
- * @return
+ * @param map the map.
+ * @return the Object.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getObject(java.lang.String, java.util.Map)
*/
@@ -628,7 +627,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnLabel the column's label.
- * @return
+ * @return the Object.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getObject(java.lang.String)
*/
@@ -638,7 +637,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
- * @return
+ * @return the Ref.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getRef(int)
*/
@@ -648,7 +647,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnLabel the column's label.
- * @return
+ * @return the Ref.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getRef(java.lang.String)
*/
@@ -657,7 +656,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return the row.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getRow()
*/
@@ -667,7 +666,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
- * @return
+ * @return the RowId.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getRowId(int)
*/
@@ -677,7 +676,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnLabel the column's label.
- * @return
+ * @return the RowId.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getRowId(java.lang.String)
*/
@@ -687,7 +686,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
- * @return
+ * @return the SQLXML.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getSQLXML(int)
*/
@@ -697,7 +696,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnLabel the column's label.
- * @return
+ * @return the SQLXML.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getSQLXML(java.lang.String)
*/
@@ -707,7 +706,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
- * @return
+ * @return the short.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getShort(int)
*/
@@ -717,7 +716,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnLabel the column's label.
- * @return
+ * @return the short.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getShort(java.lang.String)
*/
@@ -726,7 +725,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return the Statement.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getStatement()
*/
@@ -736,7 +735,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
- * @return
+ * @return the String.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getString(int)
*/
@@ -746,7 +745,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnLabel the column's label.
- * @return
+ * @return the String.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getString(java.lang.String)
*/
@@ -757,7 +756,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
* @param cal the Calendar.
- * @return
+ * @return the Time.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getTime(int, java.util.Calendar)
*/
@@ -767,7 +766,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
- * @return
+ * @return the Time.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getTime(int)
*/
@@ -778,7 +777,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnLabel the column's label.
* @param cal the Calendar.
- * @return
+ * @return the Time.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getTime(java.lang.String, java.util.Calendar)
*/
@@ -788,7 +787,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnLabel the column's label.
- * @return
+ * @return the Time.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getTime(java.lang.String)
*/
@@ -799,7 +798,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
* @param cal the Calendar.
- * @return
+ * @return the Timestamp.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getTimestamp(int, java.util.Calendar)
*/
@@ -809,7 +808,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
- * @return
+ * @return the Timestamp.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getTimestamp(int)
*/
@@ -820,7 +819,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnLabel the column's label.
* @param cal the Calendar.
- * @return
+ * @return the Timestamp.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getTimestamp(java.lang.String, java.util.Calendar)
*/
@@ -830,7 +829,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnLabel the column's label.
- * @return
+ * @return the Timestamp.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getTimestamp(java.lang.String)
*/
@@ -839,7 +838,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return the type.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getType()
*/
@@ -849,7 +848,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnIndex the index of the column.
- * @return
+ * @return the URL.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getURL(int)
*/
@@ -859,7 +858,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
/**
* @param columnLabel the column's label.
- * @return
+ * @return the URL.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getURL(java.lang.String)
*/
@@ -868,7 +867,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return the SQLWarning.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#getWarnings()
*/
@@ -885,7 +884,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return true if it is after last.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#isAfterLast()
*/
@@ -894,7 +893,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return true if it is before first.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#isBeforeFirst()
*/
@@ -903,7 +902,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return true if closed.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#isClosed()
*/
@@ -912,7 +911,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return true if first.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#isFirst()
*/
@@ -921,7 +920,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return true if last.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#isLast()
*/
@@ -930,8 +929,8 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @param iface
- * @return
+ * @param iface the interface.
+ * @return true if it is a wrapper for the interface.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.Wrapper#isWrapperFor(java.lang.Class)
*/
@@ -940,7 +939,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return true if last.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#last()
*/
@@ -965,7 +964,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return true if there is a next.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#next()
*/
@@ -974,7 +973,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return true if there is a pervious.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#previous()
*/
@@ -991,8 +990,8 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @param rows
- * @return
+ * @param rows the rows.
+ * @return true if relative.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#relative(int)
*/
@@ -1001,7 +1000,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return true if row deleted.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#rowDeleted()
*/
@@ -1010,7 +1009,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return true if the row was inserted.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#rowInserted()
*/
@@ -1019,7 +1018,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return true if the row was updated.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#rowUpdated()
*/
@@ -1028,7 +1027,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @param direction
+ * @param direction the direction to fetch.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#setFetchDirection(int)
*/
@@ -1037,7 +1036,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @param rows
+ * @param rows the rows to fetch.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#setFetchSize(int)
*/
@@ -1046,8 +1045,8 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @param iface
- * @return
+ * @param iface the interface.
+ * @return the unwrapped object.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.Wrapper#unwrap(java.lang.Class)
*/
@@ -1904,7 +1903,7 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
}
/**
- * @return
+ * @return true if it was null.
* @throws SQLException thrown if there is an SQL error.
* @see java.sql.ResultSet#wasNull()
*/
@@ -1912,8 +1911,11 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
return rs.wasNull();
}
+ /**
+ * @return the adapted ResultSet
+ */
protected final ResultSet getAdaptedResultSet() {
return rs;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/commons/dbutils2/BasicRowProcessor.java b/src/main/java/org/apache/commons/dbutils2/BasicRowProcessor.java
index 264bf57..b4164c3 100644
--- a/src/main/java/org/apache/commons/dbutils2/BasicRowProcessor.java
+++ b/src/main/java/org/apache/commons/dbutils2/BasicRowProcessor.java
@@ -146,7 +146,7 @@ public class BasicRowProcessor implements RowProcessor {
if (null == columnName || 0 == columnName.length()) {
columnName = rsmd.getColumnName(i);
}
- result.put(columnName, rs.getObject(i));
+ result.put(columnName, rs.getObject(i));
}
return result;
diff --git a/src/main/java/org/apache/commons/dbutils2/BatchExecutor.java b/src/main/java/org/apache/commons/dbutils2/BatchExecutor.java
index f175a9b..603c0fc 100644
--- a/src/main/java/org/apache/commons/dbutils2/BatchExecutor.java
+++ b/src/main/java/org/apache/commons/dbutils2/BatchExecutor.java
@@ -18,7 +18,6 @@ package org.apache.commons.dbutils2;
import java.sql.Connection;
import java.sql.SQLException;
-import java.sql.Types;
/**
* This class provides the ability to execute a batch of statements.
@@ -30,10 +29,25 @@ import java.sql.Types;
public class BatchExecutor extends AbstractExecutor<BatchExecutor> {
private final boolean closeConn;
+ private boolean addBatchCalled = false;
/**
* Constructs a BatchExecutor given a connection and SQL statement.
- *
+ *
+ * @param conn The connection to use during execution.
+ * @param sql The SQL statement.
+ * @param closeConnection If the connection should be closed or not.
+ * @param autoGeneratedKeys If the statement should return auto generated keys or not.
+ * @throws SQLException thrown if there is an error during execution.
+ */
+ BatchExecutor(final Connection conn, final String sql, final boolean closeConnection, final int autoGeneratedKeys) throws SQLException {
+ super(conn, sql, autoGeneratedKeys);
+ this.closeConn = closeConnection;
+ }
+
+ /**
+ * Constructs a BatchExecutor given a connection and SQL statement.
+ *
* @param conn The connection to use during execution.
* @param sql The SQL statement.
* @param closeConnection If the connection should be closed or not.
@@ -53,47 +67,6 @@ public class BatchExecutor extends AbstractExecutor<BatchExecutor> {
}
/**
- * Binds a parameter name to a value for a given statement.
- *
- * @param name the name of the parameter.
- * @param value the value to bind to the parameter.
- * @return this object.
- * @throws SQLException thrown if the statement number does not exist, or any other SQLException.
- * @see org.apache.commons.dbutils2.UpdateExecutor#bind(String, Object)
- */
- @Override
- public BatchExecutor bind(final String name, final Object value) throws SQLException {
- return bind(name, value, false);
- }
-
- /**
- * Binds null to a parameter.
- * Types.VARCHAR is used as the type's parameter.
- * This usually works, but fails with some Oracle and MS SQL drivers.
- *
- * @param name the name of the parameter.
- * @return this execution object to provide the fluent style.
- * @throws SQLException throw if the parameter is not found, already bound, or there is an issue binding null.
- */
- @Override
- public BatchExecutor bindNull(final String name) throws SQLException {
- return bindNull(name, Types.VARCHAR, false);
- }
-
- /**
- * Binds null to a parameter, specifying the parameter's type.
- *
- * @param name the name of the parameter.
- * @param sqlType the type of the parameter.
- * @return this execution object to provide the fluent style.
- * @throws SQLException throw if the parameter is not found, already bound, or there is an issue binding null.
- */
- @Override
- public BatchExecutor bindNull(final String name, final int sqlType) throws SQLException {
- return bindNull(name, sqlType, false);
- }
-
- /**
* Adds the statement to the batch after binding all of the parameters.
*
* @return this object.
@@ -101,6 +74,11 @@ public class BatchExecutor extends AbstractExecutor<BatchExecutor> {
* @see java.sql.PreparedStatement#addBatch()
*/
public BatchExecutor addBatch() throws SQLException {
+ // throw an exception if there are unmapped parameters
+ this.throwIfUnmappedParams();
+
+ addBatchCalled = true;
+
try {
getStatement().addBatch();
clearValueMap();
@@ -119,8 +97,9 @@ public class BatchExecutor extends AbstractExecutor<BatchExecutor> {
* @see org.apache.commons.dbutils2.UpdateExecutor#execute()
*/
public int[] execute() throws SQLException {
- // throw an exception if there are unmapped parameters
- this.throwIfUnmappedParams();
+ if(!addBatchCalled) {
+ throw new SQLException("addBatch must be called before execute.");
+ }
try {
return getStatement().executeBatch();
diff --git a/src/main/java/org/apache/commons/dbutils2/BatchInsertExecutor.java b/src/main/java/org/apache/commons/dbutils2/BatchInsertExecutor.java
index 01f75d7..94e94b9 100644
--- a/src/main/java/org/apache/commons/dbutils2/BatchInsertExecutor.java
+++ b/src/main/java/org/apache/commons/dbutils2/BatchInsertExecutor.java
@@ -3,6 +3,7 @@ package org.apache.commons.dbutils2;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.Statement;
public class BatchInsertExecutor extends BatchExecutor {
@@ -16,7 +17,7 @@ public class BatchInsertExecutor extends BatchExecutor {
* @throws SQLException thrown if there is an error during execution.
*/
BatchInsertExecutor(final Connection conn, final String sql, final boolean closeConnection) throws SQLException {
- super(conn, sql, closeConnection);
+ super(conn, sql, closeConnection, Statement.RETURN_GENERATED_KEYS);
}
/**
diff --git a/src/main/java/org/apache/commons/dbutils2/BeanProcessor.java b/src/main/java/org/apache/commons/dbutils2/BeanProcessor.java
index 41f747a..4536e78 100644
--- a/src/main/java/org/apache/commons/dbutils2/BeanProcessor.java
+++ b/src/main/java/org/apache/commons/dbutils2/BeanProcessor.java
@@ -248,13 +248,14 @@ public class BeanProcessor {
private void callSetter(Object target, PropertyDescriptor prop, Object value)
throws SQLException {
- Method setter = prop.getWriteMethod();
+ final Method setter = prop.getWriteMethod();
if (setter == null) {
return;
}
- Class<?>[] params = setter.getParameterTypes();
+ final Class<?>[] params = setter.getParameterTypes();
+
try {
// convert types for some popular ones
if (value instanceof java.util.Date) {
@@ -270,8 +271,18 @@ public class BeanProcessor {
}
}
- // Don't call setter if the value object isn't the right type
- if (this.isCompatibleType(value, params[0])) {
+ // see if we can make it work with an enum
+
+ if(params[0].isEnum() && value != null) {
+ try {
+ final Class cz = Class.forName(params[0].getName());
+ setter.invoke(target, Enum.valueOf(cz, (String) value));
+ } catch(final ClassNotFoundException e) {
+ throw new SQLException("Attempted to set an Enum, but class "
+ + params[0].getName() + " was not found: " + e.getMessage());
+ }
+ } else if (this.isCompatibleType(value, params[0])) {
+ // Don't call setter if the value object isn't the right type
setter.invoke(target, new Object[]{value});
} else {
throw new SQLException(
diff --git a/src/main/java/org/apache/commons/dbutils2/EntityUtils.java b/src/main/java/org/apache/commons/dbutils2/EntityUtils.java
new file mode 100644
index 0000000..df1a272
--- /dev/null
+++ b/src/main/java/org/apache/commons/dbutils2/EntityUtils.java
@@ -0,0 +1,251 @@
+package org.apache.commons.dbutils2;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.apache.commons.beanutils.PropertyUtils;
+
+
+public class EntityUtils {
+
+ // static methods only
+ private EntityUtils() {
+ }
+
+ /**
+ * Given an entity, returns the table name for the entity.
+ * @param entity the entity to lookup.
+ * @return the name of the table for the entity.
+ */
+ public static String getTableName(final Class<?> entity) {
+ final Entity annotation = entity.getAnnotation(Entity.class);
+
+ if(annotation == null) {
+ throw new IllegalArgumentException(entity.getName() + " does not have the Entity annotation");
+ }
+
+ final Table table = entity.getAnnotation(Table.class);
+
+ // get the table's name from the annotation
+ if(table != null && !table.name().isEmpty()) {
+ return table.name();
+ } else {
+ return entity.getSimpleName();
+ }
+ }
+
+ /**
+ * Given an entity, gets the @Id of the entity, assuming only one ID column.
+ * @param entityClass the type of the entity.
+ * @param entity the instance of the entity.
+ * @return the value of the ID.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T, I> I getId(final Class<T> entityClass, T entity) {
+ Map<String, String> idColumns = getIdColumns(entityClass);
+
+ if(idColumns.size() != 1) {
+ throw new IllegalArgumentException("Cannot get ID for this entity, wrong number of IDs: " + idColumns.size());
+ }
+
+ try {
+ final String column = idColumns.keySet().toArray(new String[0])[0];
+ return (I) PropertyUtils.getSimpleProperty(entity, idColumns.get(column));
+ } catch (IllegalAccessException e) {
+ throw new IllegalArgumentException(e);
+ } catch (InvocationTargetException e) {
+ throw new IllegalArgumentException(e);
+ } catch (NoSuchMethodException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ /**
+ * Gets the names of the columns for a given entity, except those marked as @GeneratedValue.
+ * @param entity the entity to search.
+ * @return a map which contains column name, and field name.
+ */
+ static Map<String, String> getColumns(Class<?> entityClass) {
+ return getColumns(entityClass, false);
+ }
+
+ /**
+ * Gets the names of the columns for a given entity, except those marked as @GeneratedValue.
+ * @param entity the entity to search.
+ * @param excludeIds excludes columns marked with @Id when true
+ * @return a map which contains column name, and field name.
+ */
+ static Map<String, String> getColumns(Class<?> entityClass, boolean excludeIds) {
+ final Map<String, String> ret = new HashMap<String, String>();
+
+ if(entityClass.getAnnotation(Entity.class) == null) {
+ throw new IllegalArgumentException(entityClass.getName() + " does not have the Entity annotation");
+ }
+
+ // we need to walk up the inheritance chain
+ while(entityClass != null) {
+ for(Field field:entityClass.getDeclaredFields()) {
+ final Column column = field.getAnnotation(Column.class);
+ final Id id = field.getAnnotation(Id.class);
+ final GeneratedValue gen = field.getAnnotation(GeneratedValue.class);
+
+ // if we only want IDs, and this isn't an @Id, then skip
+ if(excludeIds && id != null) {
+ continue;
+ // if we want all columns, then must be marked as a column and not auto-generated
+ } else if(column == null || gen != null) {
+ continue;
+ }
+
+ String columnName;
+
+ // get the column name or field name
+ if(column.name().isEmpty()) {
+ columnName = field.getName();
+ } else {
+ columnName = column.name();
+ }
+
+ if(ret.put(columnName, field.getName()) != null) {
+ throw new IllegalArgumentException("Entity contains two columns with the same name: " + columnName);
+ }
+ }
+
+ // walk up the inheritance class
+ entityClass = entityClass.getSuperclass();
+ }
+
+ if(ret.isEmpty()) {
+ throw new IllegalArgumentException("Entity does not contain any columns");
+ }
+
+ return ret;
+ }
+
+ /**
+ * Gets the names of the columns that are marked with @Id.
+ * @param entity the entity to search.
+ * @return a map which contains column name, and field name.
+ */
+ public static Map<String, String> getIdColumns(Class<?> entityClass) {
+ final Map<String, String> ret = new HashMap<String, String>();
+
+ if(entityClass.getAnnotation(Entity.class) == null) {
+ throw new IllegalArgumentException(entityClass.getName() + " does not have the Entity annotation");
+ }
+
+ // we need to walk up the inheritance chain
+ while(entityClass != null) {
+ for(Field field:entityClass.getDeclaredFields()) {
+ final Column column = field.getAnnotation(Column.class);
+ final Id id = field.getAnnotation(Id.class);
+
+ // if we only want IDs, and this isn't an @Id, then skip
+ if(column == null || id == null) {
+ continue;
+ }
+
+ String columnName;
+
+ // get the column name or field name
+ if(column.name().isEmpty()) {
+ columnName = field.getName();
+ } else {
+ columnName = column.name();
+ }
+
+ if(ret.put(columnName, field.getName()) != null) {
+ throw new IllegalArgumentException("Entity contains two columns with the same name: " + columnName);
+ }
+ }
+
+ // walk up the inheritance class
+ entityClass = entityClass.getSuperclass();
+ }
+
+ if(ret.isEmpty()) {
+ throw new IllegalArgumentException("Entity does not contain any columns");
+ }
+
+ return ret;
+ }
+
+ /**
+ * Takes a set of strings (columns) and joins them with commas and a possible prefix.
+ * @param columns the set of columns.
+ * @param prefix a prefix.
+ * @return the joined columns.
+ */
+ static String joinColumnsWithComma(final Set<String> columns, final String prefix) {
+ final StringBuilder sb = new StringBuilder();
+
+ if(columns.isEmpty()) {
+ throw new IllegalArgumentException("Entity does not contain any columns");
+ }
+
+ final Iterator<String> it = columns.iterator();
+
+ if(prefix != null) {
+ sb.append(prefix);
+ }
+
+ sb.append(it.next());
+
+ while(it.hasNext()) {
+ sb.append(",");
+
+ if(prefix != null) {
+ sb.append(prefix);
+ }
+
+ sb.append(it.next());
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Takes a set of strings (columns) and joins them with equals and a delimiter.
+ * @param columns the columns to join.
+ * @param delimiter the delimiter between the pairs.
+ * @return the joined columns.
+ */
+ static String joinColumnsEquals(final Set<String> columns, final String delimiter) {
+ final StringBuilder sb = new StringBuilder();
+
+ if(columns.isEmpty()) {
+ throw new IllegalArgumentException("Entity does not contain any columns");
+ }
+
+ final Iterator<String> it = columns.iterator();
+
+ String column = it.next();
+
+ sb.append(column);
+ sb.append(" = :");
+ sb.append(column);
+
+ while(it.hasNext()) {
+ sb.append(delimiter);
+
+ column = it.next();
+
+ sb.append(column);
+ sb.append(" = :");
+ sb.append(column);
+ }
+
+ return sb.toString();
+ }
+
+}
diff --git a/src/main/java/org/apache/commons/dbutils2/InsertExecutor.java b/src/main/java/org/apache/commons/dbutils2/InsertExecutor.java
index 8fdd9db..2fc5a34 100644
--- a/src/main/java/org/apache/commons/dbutils2/InsertExecutor.java
+++ b/src/main/java/org/apache/commons/dbutils2/InsertExecutor.java
@@ -19,6 +19,7 @@ package org.apache.commons.dbutils2;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.Statement;
/**
@@ -39,7 +40,7 @@ public class InsertExecutor extends AbstractExecutor<InsertExecutor> {
* @throws SQLException thrown if there is an error during execution.
*/
InsertExecutor(final Connection conn, final String sql, final boolean closeConnection) throws SQLException {
- super(conn, sql);
+ super(conn, sql, Statement.RETURN_GENERATED_KEYS);
this.closeConn = closeConnection;
}
@@ -99,7 +100,12 @@ public class InsertExecutor extends AbstractExecutor<InsertExecutor> {
try {
// execute the insert
- return getStatement().executeUpdate();
+ int ret = getStatement().executeUpdate();
+
+ // get any generated keys, and just close the ResultSet
+ getStatement().getGeneratedKeys().close();
+
+ return ret;
} catch (SQLException e) {
this.rethrow(e);
} finally {
diff --git a/src/main/java/org/apache/commons/dbutils2/QueryRunner.java b/src/main/java/org/apache/commons/dbutils2/QueryRunner.java
index 2d5fe5c..8294fcf 100644
--- a/src/main/java/org/apache/commons/dbutils2/QueryRunner.java
+++ b/src/main/java/org/apache/commons/dbutils2/QueryRunner.java
@@ -16,10 +16,24 @@
*/
package org.apache.commons.dbutils2;
+import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.Entity;
import javax.sql.DataSource;
+import org.apache.commons.beanutils.PropertyUtils;
+
+import org.apache.commons.dbutils2.handlers.BeanHandler;
+import org.apache.commons.dbutils2.handlers.BeanListHandler;
+
/**
* Executes SQL queries with pluggable strategies for handling
* <code>ResultSet</code>s. This class is thread safe.
@@ -312,4 +326,263 @@ public class QueryRunner {
return new InsertExecutor(conn, sql, closeConn);
}
+
+ //
+ // Entity methods
+ //
+
+ /**
+ * Creates a new entity in the database by calling insert.
+ * @param entity the entity to insert.
+ * @throws SQLException if there is a problem inserting the entity.
+ */
+ public <T> void create(final Class<? extends T> entityClass, final T entity) throws SQLException {
+ internalEntityCreate(entityClass, entity, new HashSet<String>()).execute();
+ }
+
+ /*
+ * Internal method that returns the InsertExecutor making it easier to extend.
+ */
+ protected <T> InsertExecutor internalEntityCreate(final Class<? extends T> entityClass,
+ final T entity,
+ final Set<String> excludeColumns) throws SQLException {
+ final String tableName = EntityUtils.getTableName(entity.getClass());
+ final Map<String, String> columns = EntityUtils.getColumns(entityClass);
+
+ final StringBuilder sb = new StringBuilder("insert into ");
+
+ // create the SQL command
+ sb.append(tableName);
+ sb.append(" (");
+ sb.append(EntityUtils.joinColumnsWithComma(columns.keySet(), null));
+ sb.append(") values(");
+ sb.append(EntityUtils.joinColumnsWithComma(columns.keySet(), ":"));
+ sb.append(")");
+
+ // create the executor
+ final InsertExecutor exec = new InsertExecutor(this.prepareConnection(), sb.toString(), true);
+
+ for(String column:columns.keySet()) {
+ // don't bind the exclude columns
+ if(excludeColumns.contains(column)) {
+ continue;
+ }
+
+ try {
+ // bind all of the values
+ final Object value = PropertyUtils.getSimpleProperty(entity, columns.get(column));
+
+ if(value == null) {
+ exec.bindNull(column);
+ } else {
+ exec.bind(column, value);
+ }
+ } catch (final IllegalAccessException e) {
+ throw new SQLException(e);
+ } catch (final InvocationTargetException e) {
+ throw new SQLException(e);
+ } catch (final NoSuchMethodException e) {
+ throw new SQLException(e);
+ }
+ }
+
+ return exec;
+ }
+
+ /**
+ * Reads all of the entities of a given type.
+ * @param entity an entity marked with the {@link Entity} annotation.
+ * @return a list of the entities read .
+ * @throws SQLException If there are database or parameter errors.
+ */
+ public <T> List<T> read(final Class<T> entityClass) throws SQLException {
+ final Entity annotation = entityClass.getAnnotation(Entity.class);
+
+ if(annotation == null) {
+ throw new IllegalArgumentException(entityClass.getName() + " does not have the Entity annotation");
+ }
+
+ // get the table's name
+ final String tableName = EntityUtils.getTableName(entityClass);
+
+ final StringBuilder sb = new StringBuilder("select * from ");
+
+ sb.append(tableName);
+
+ // setup the QueryExecutor
+ final QueryExecutor exec = new QueryExecutor(prepareConnection(), sb.toString(), true);
+
+ // execute using the BeanHandler
+ return exec.execute(new BeanListHandler<T>(entityClass));
+ }
+
+ /**
+ * Reads a given entity based off the @Id columns.
+ * @param entityClass an entity marked with the {@link Entity} annotation.
+ * @param entity the entity to read.
+ * @return the entity read from the db.
+ * @throws SQLException If there are database or parameter errors.
+ */
+ public <T> T read(final Class<T> entityClass, final T entity) throws SQLException {
+ final Entity annotation = entityClass.getAnnotation(Entity.class);
+ final Map<String, String> idColumns = EntityUtils.getIdColumns(entityClass);
+
+ if(annotation == null) {
+ throw new IllegalArgumentException(entityClass.getName() + " does not have the Entity annotation");
+ }
+
+ if(idColumns.isEmpty()) {
+ throw new SQLException("Cannot read " + entityClass.getName() + " because it does not have any @Id columns");
+ }
+
+ // get the table's name
+ final String tableName = EntityUtils.getTableName(entityClass);
+
+ final StringBuilder sb = new StringBuilder("select * from ");
+
+ sb.append(tableName);
+ sb.append(" where ");
+ sb.append(EntityUtils.joinColumnsEquals(idColumns.keySet(), " and "));
+
+ // setup the QueryExecutor
+ final QueryExecutor exec = new QueryExecutor(prepareConnection(), sb.toString(), true);
+
+ // bind all the id columns
+ bindColumnValues(exec, idColumns, entity, Collections.<String>emptySet());
+
+ // execute using the BeanHandler
+ return exec.execute(new BeanHandler<T>(entityClass));
+ }
+
+ /**
+ * Constructs an {@link UpdateEntityExecutor} used to update entities.
+ * @param entity an entity marked with the {@link Entity} annotation.
+ * @return a {@link UpdateEntityExecutor} used to update entities.
+ * @throws SQLException If there are database or parameter errors.
+ */
+ public <T> int update(final Class<T> classType, final T entity) throws SQLException {
+ return update(classType, entity, Collections.<String>emptySet());
+ }
+
+ /**
+ * Constructs an {@link UpdateEntityExecutor} used to update entities that excludes columns during binding.
+ * @param entity an entity marked with the {@link Entity} annotation.
+ * @param excludeColumns a collection of columns to exclude.
+ * @return a {@link UpdateEntityExecutor} used to update entities.
+ * @throws SQLException If there are database or parameter errors.
+ */
+ public <T> int update(final Class<T> entityClass, final T entity, final Collection<String> excludeColumns) throws SQLException {
+ final Map<String, String> updateColumns = EntityUtils.getColumns(entityClass, true);
+ final Map<String, String> idColumns = EntityUtils.getIdColumns(entityClass);
+ final Entity annotation = entityClass.getAnnotation(Entity.class);
+
+ if(annotation == null) {
+ throw new IllegalArgumentException(entityClass.getName() + " does not have the Entity annotation");
+ }
+
+ if(idColumns.isEmpty()) {
+ throw new SQLException("Cannot update " + entityClass.getName() + " because it does not have any @Id columns");
+ }
+
+ // get the table's name
+ final String tableName = EntityUtils.getTableName(entityClass);
+
+ final StringBuilder sb = new StringBuilder("update ");
+
+ // create the SQL command
+ sb.append(tableName);
+ sb.append(" set ");
+ sb.append(EntityUtils.joinColumnsEquals(updateColumns.keySet(), ", "));
+
+ sb.append(" where ");
+ sb.append(EntityUtils.joinColumnsEquals(idColumns.keySet(), " and "));
+
+ // setup the QueryExecutor
+ final UpdateExecutor exec = new UpdateExecutor(prepareConnection(), sb.toString(), true);
+
+ // bind all the update column values
+ bindColumnValues(exec, updateColumns, entity, excludeColumns);
+
+ // bind all the id columns
+ bindColumnValues(exec, idColumns, entity, Collections.<String>emptySet());
+
+ // execute using the BeanHandler
+ return exec.execute();
+ }
+
+ /**
+ * Constructs an {@link DeleteEntityExecutor} used to delete entities.
+ * @param entity an entity marked with the {@link Entity} annotation.
+ * @return a {@link DeleteEntityExecutor} used to delete entities.
+ * @throws SQLException If there are database or parameter errors.
+ */
+ public <T> int delete(final Class<T> entityClass, final T entity) throws SQLException {
+ final Map<String, String> idColumns = EntityUtils.getIdColumns(entityClass);
+ final Entity annotation = entityClass.getAnnotation(Entity.class);
+
+ if(annotation == null) {
+ throw new IllegalArgumentException(entityClass.getName() + " does not have the Entity annotation");
+ }
+
+ if(idColumns.isEmpty()) {
+ throw new SQLException("Cannot update " + entityClass.getName() + " because it does not have any @Id columns");
+ }
+
+ // get the table's name
+ final String tableName = EntityUtils.getTableName(entityClass);
+
+ final StringBuilder sb = new StringBuilder("delete from ");
+
+ sb.append(tableName);
+
+ sb.append(" where ");
+ sb.append(EntityUtils.joinColumnsEquals(idColumns.keySet(), " and "));
+
+ // setup the QueryExecutor
+ final UpdateExecutor exec = new UpdateExecutor(prepareConnection(), sb.toString(), true);
+
+ // bind all the id columns
+ bindColumnValues(exec, idColumns, entity, Collections.<String>emptySet());
+
+ // execute using the BeanHandler
+ return exec.execute();
+ }
+
+ /**
+ * Binds values to an executor.
+ * @param exec
+ * @param columns
+ * @param entity
+ * @param excludes
+ * @throws SQLException
+ */
+ private <T> void bindColumnValues(final AbstractExecutor<?> exec,
+ final Map<String, String> columns,
+ final T entity,
+ final Collection<String> excludes) throws SQLException {
+ for(String column:columns.keySet()) {
+ // skip anything in the exclude set
+ if(excludes.contains(column)) {
+ continue;
+ }
+
+ try {
+ // bind all of the values
+ final Object value = PropertyUtils.getSimpleProperty(entity, columns.get(column));
+
+ if(value == null) {
+ exec.bindNull(column);
+ } else {
+ exec.bind(column, value);
+ }
+ } catch (final IllegalAccessException e) {
+ throw new SQLException(e);
+ } catch (final InvocationTargetException e) {
+ throw new SQLException(e);
+ } catch (final NoSuchMethodException e) {
+ throw new SQLException(e);
+ }
+ }
+ }
+
}
diff --git a/src/test/java/org/apache/commons/dbutils2/AbstractExecutorTest.java b/src/test/java/org/apache/commons/dbutils2/AbstractExecutorTest.java
index ff8e6d1..6ccc6c6 100644
--- a/src/test/java/org/apache/commons/dbutils2/AbstractExecutorTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/AbstractExecutorTest.java
@@ -21,12 +21,13 @@ import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
+import java.sql.Statement;
import java.sql.Types;
-import org.apache.commons.dbutils2.AbstractExecutor;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -46,6 +47,7 @@ public class AbstractExecutorTest {
MockitoAnnotations.initMocks(this);
when(conn.prepareStatement(any(String.class))).thenReturn(stmt);
+ when(conn.prepareStatement(any(String.class), any(Integer.class))).thenReturn(stmt);
}
@SuppressWarnings("rawtypes")
@@ -57,7 +59,7 @@ public class AbstractExecutorTest {
public void testGoodSql() throws SQLException {
createExecutor("select * from blah :first = first and :last=last and phone=:phone");
- verify(conn, times(1)).prepareStatement("select * from blah ? = first and ?=last and phone=?");
+ verify(conn, times(1)).prepareStatement("select * from blah ? = first and ?=last and phone=?", Statement.NO_GENERATED_KEYS);
executor.bind("first", "first_name")
.bind(":last", "last_name")
@@ -75,7 +77,7 @@ public class AbstractExecutorTest {
public void testNoParamsSql() throws SQLException {
createExecutor("select * from blah");
- verify(conn, times(1)).prepareStatement("select * from blah");
+ verify(conn, times(1)).prepareStatement("select * from blah", Statement.NO_GENERATED_KEYS);
verify(stmt, times(0)).setObject(any(Integer.class), any(Object.class));
executor.throwIfUnmappedParams();
@@ -85,7 +87,7 @@ public class AbstractExecutorTest {
public void testMissingParamSql() throws SQLException {
createExecutor("select * from blah :first = first and :last=last");
- verify(conn, times(1)).prepareStatement("select * from blah ? = first and ?=last");
+ verify(conn, times(1)).prepareStatement("select * from blah ? = first and ?=last", Statement.NO_GENERATED_KEYS);
executor.bind("first", "first_name")
.bind(":last", "last_name")
@@ -100,7 +102,7 @@ public class AbstractExecutorTest {
public void testDoubleBind() throws SQLException {
createExecutor("select * from blah :first = first and :last=last");
- verify(conn, times(1)).prepareStatement("select * from blah ? = first and ?=last");
+ verify(conn, times(1)).prepareStatement("select * from blah ? = first and ?=last", Statement.NO_GENERATED_KEYS);
executor.bind("first", "first_name")
.bind(":last", "last_name")
@@ -114,7 +116,7 @@ public class AbstractExecutorTest {
public void testNullBind() throws SQLException {
createExecutor("select * from blah :first = first and :last=last");
- verify(conn, times(1)).prepareStatement("select * from blah ? = first and ?=last");
+ verify(conn, times(1)).prepareStatement("select * from blah ? = first and ?=last", Statement.NO_GENERATED_KEYS);
executor.bindNull("first")
.bindNull(":last", Types.NULL);
diff --git a/src/test/java/org/apache/commons/dbutils2/AsyncExecutorTest.java b/src/test/java/org/apache/commons/dbutils2/AsyncExecutorTest.java
index 85657c3..62fd77f 100644
--- a/src/test/java/org/apache/commons/dbutils2/AsyncExecutorTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/AsyncExecutorTest.java
@@ -19,16 +19,11 @@ package org.apache.commons.dbutils2;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+
import java.sql.SQLException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
-import org.apache.commons.dbutils2.AsyncExecutor;
-import org.apache.commons.dbutils2.InsertExecutor;
-import org.apache.commons.dbutils2.QueryExecutor;
-import org.apache.commons.dbutils2.QueryRunner;
-import org.apache.commons.dbutils2.ResultSetHandler;
-import org.apache.commons.dbutils2.UpdateExecutor;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
diff --git a/src/test/java/org/apache/commons/dbutils2/BaseResultSetHandlerTestCase.java b/src/test/java/org/apache/commons/dbutils2/BaseResultSetHandlerTestCase.java
index f9cd433..c389c11 100644
--- a/src/test/java/org/apache/commons/dbutils2/BaseResultSetHandlerTestCase.java
+++ b/src/test/java/org/apache/commons/dbutils2/BaseResultSetHandlerTestCase.java
@@ -22,7 +22,6 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
-import org.apache.commons.dbutils2.BaseResultSetHandler;
import org.junit.Test;
public final class BaseResultSetHandlerTestCase extends BaseTestCase {
diff --git a/src/test/java/org/apache/commons/dbutils2/BaseTestCase.java b/src/test/java/org/apache/commons/dbutils2/BaseTestCase.java
index 0debc1f..d588067 100644
--- a/src/test/java/org/apache/commons/dbutils2/BaseTestCase.java
+++ b/src/test/java/org/apache/commons/dbutils2/BaseTestCase.java
@@ -40,7 +40,8 @@ public class BaseTestCase extends TestCase {
"nullObjectTest",
"nullPrimitiveTest",
"notDate",
- "columnProcessorDoubleTest" };
+ "columnProcessorDoubleTest",
+ "enumTest"};
/**
* The number of columns in the MockResultSet.
@@ -61,7 +62,8 @@ public class BaseTestCase extends TestCase {
null,
null,
new Date(),
- BigInteger.valueOf(13)};
+ BigInteger.valueOf(13),
+ "ENUM_ZERO"};
private static final Object[] row2 =
new Object[] {
@@ -74,7 +76,8 @@ public class BaseTestCase extends TestCase {
null,
null,
new Date(),
- BigInteger.valueOf(13)};
+ BigInteger.valueOf(13),
+ "ENUM_ONE"};
private static final Object[][] rows = new Object[][] { row1, row2 };
diff --git a/src/test/java/org/apache/commons/dbutils2/BasicRowProcessorTest.java b/src/test/java/org/apache/commons/dbutils2/BasicRowProcessorTest.java
index 684e9db..4767604 100644
--- a/src/test/java/org/apache/commons/dbutils2/BasicRowProcessorTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/BasicRowProcessorTest.java
@@ -24,9 +24,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
-import org.apache.commons.dbutils2.BasicRowProcessor;
-import org.apache.commons.dbutils2.RowProcessor;
-
/**
* Test the BasicRowProcessor class.
*/
diff --git a/src/test/java/org/apache/commons/dbutils2/BatchExecutorTest.java b/src/test/java/org/apache/commons/dbutils2/BatchExecutorTest.java
index 1ad3cd2..d8afa00 100644
--- a/src/test/java/org/apache/commons/dbutils2/BatchExecutorTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/BatchExecutorTest.java
@@ -16,16 +16,16 @@
*/
package org.apache.commons.dbutils2;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
-import org.apache.commons.dbutils2.BatchExecutor;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -42,8 +42,8 @@ public class BatchExecutorTest {
@Before
public void setup() throws SQLException {
MockitoAnnotations.initMocks(this);
-
- when(conn.prepareStatement(any(String.class))).thenReturn(stmt);
+
+ when(conn.prepareStatement(any(String.class), any(Integer.class))).thenReturn(stmt);
when(stmt.executeBatch()).thenReturn(new int[] { 2, 3, 4 });
}
@@ -53,8 +53,24 @@ public class BatchExecutorTest {
@Test
public void testGoodSQL() throws Exception {
- createExecutor("insert into blah");
-
+ createExecutor("insert into blah where a = :a and b = :b");
+
+ executor.bind("a", "a").bind("b", "b").addBatch();
+ int[] ret = executor.execute();
+
+ assertEquals(3, ret.length);
+ assertEquals(2, ret[0]);
+ assertEquals(3, ret[1]);
+ assertEquals(4, ret[2]);
+ verify(conn, times(1)).close();
+ verify(stmt, times(1)).close();
+ }
+
+ @Test(expected=SQLException.class)
+ public void testNoBinds() throws Exception {
+ createExecutor("insert into blah where a = :a and b = :b");
+
+ // no bindings done
executor.addBatch();
int[] ret = executor.execute();
@@ -65,5 +81,36 @@ public class BatchExecutorTest {
verify(conn, times(1)).close();
verify(stmt, times(1)).close();
}
-
+
+ @Test(expected=SQLException.class)
+ public void testNoAddBatch() throws Exception {
+ createExecutor("insert into blah where a = :a and b = :b");
+
+ // never called addBatch
+ int[] ret = executor.execute();
+
+ assertEquals(3, ret.length);
+ assertEquals(2, ret[0]);
+ assertEquals(3, ret[1]);
+ assertEquals(4, ret[2]);
+ verify(conn, times(1)).close();
+ verify(stmt, times(1)).close();
+ }
+
+ @Test(expected=SQLException.class)
+ public void testNotAllBound() throws Exception {
+ createExecutor("insert into blah where a = :a and b = :b");
+
+ // bind only a
+ executor.bind("a", "a").addBatch();
+ int[] ret = executor.execute();
+
+ assertEquals(3, ret.length);
+ assertEquals(2, ret[0]);
+ assertEquals(3, ret[1]);
+ assertEquals(4, ret[2]);
+ verify(conn, times(1)).close();
+ verify(stmt, times(1)).close();
+ }
+
}
diff --git a/src/test/java/org/apache/commons/dbutils2/BatchInsertExecutorTest.java b/src/test/java/org/apache/commons/dbutils2/BatchInsertExecutorTest.java
index 919374e..a9e341f 100644
--- a/src/test/java/org/apache/commons/dbutils2/BatchInsertExecutorTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/BatchInsertExecutorTest.java
@@ -18,13 +18,17 @@ package org.apache.commons.dbutils2;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.Statement;
+
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -43,8 +47,8 @@ public class BatchInsertExecutorTest {
@Before
public void setup() throws SQLException {
MockitoAnnotations.initMocks(this);
-
- when(conn.prepareStatement(any(String.class))).thenReturn(stmt);
+
+ when(conn.prepareStatement(any(String.class), eq(Statement.RETURN_GENERATED_KEYS))).thenReturn(stmt);
when(stmt.getGeneratedKeys()).thenReturn(resultSet);
when(handler.handle(any(ResultSet.class))).thenReturn(new Object());
}
diff --git a/src/test/java/org/apache/commons/dbutils2/BeanProcessorTest.java b/src/test/java/org/apache/commons/dbutils2/BeanProcessorTest.java
index 73fc26b..56044ca 100644
--- a/src/test/java/org/apache/commons/dbutils2/BeanProcessorTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/BeanProcessorTest.java
@@ -23,9 +23,6 @@ import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
-import org.apache.commons.dbutils2.BeanProcessor;
-import org.apache.commons.dbutils2.ProxyFactory;
-
public class BeanProcessorTest extends BaseTestCase {
private static final BeanProcessor beanProc = new BeanProcessor();
diff --git a/src/test/java/org/apache/commons/dbutils2/DbUtilsTest.java b/src/test/java/org/apache/commons/dbutils2/DbUtilsTest.java
index 7c00f90..b92b3ea 100644
--- a/src/test/java/org/apache/commons/dbutils2/DbUtilsTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/DbUtilsTest.java
@@ -27,7 +27,6 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
-import org.apache.commons.dbutils2.DbUtils;
import org.junit.Test;
public class DbUtilsTest {
diff --git a/src/test/java/org/apache/commons/dbutils2/EnumTest.java b/src/test/java/org/apache/commons/dbutils2/EnumTest.java
new file mode 100644
index 0000000..9db5a7d
--- /dev/null
+++ b/src/test/java/org/apache/commons/dbutils2/EnumTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.dbutils2;
+
+/**
+ * Test Enum class.
+ */
+public enum EnumTest {
+ /**
+ * Enum for zero.
+ */
+ ENUM_ZERO,
+
+ /**
+ * Enum for EnumTwo.
+ */
+ ENUM_ONE,
+
+ /**
+ * Enum for Three.
+ */
+ ENUM_TWO;
+}
diff --git a/src/test/java/org/apache/commons/dbutils2/GenerousBeanProcessorTest.java b/src/test/java/org/apache/commons/dbutils2/GenerousBeanProcessorTest.java
index 4b96e39..40ea521 100644
--- a/src/test/java/org/apache/commons/dbutils2/GenerousBeanProcessorTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/GenerousBeanProcessorTest.java
@@ -19,10 +19,10 @@ package org.apache.commons.dbutils2;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.when;
+
import java.beans.PropertyDescriptor;
import java.sql.ResultSetMetaData;
-import org.apache.commons.dbutils2.GenerousBeanProcessor;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
diff --git a/src/test/java/org/apache/commons/dbutils2/InsertExecutorTest.java b/src/test/java/org/apache/commons/dbutils2/InsertExecutorTest.java
index 3ebc56c..b86f2ab 100644
--- a/src/test/java/org/apache/commons/dbutils2/InsertExecutorTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/InsertExecutorTest.java
@@ -18,16 +18,17 @@ package org.apache.commons.dbutils2;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.Statement;
-import org.apache.commons.dbutils2.InsertExecutor;
-import org.apache.commons.dbutils2.ResultSetHandler;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -41,6 +42,7 @@ public class InsertExecutorTest {
@Mock private ResultSetHandler<Object> handler;
@Mock private Connection conn;
@Mock private PreparedStatement stmt;
+ @Mock private PreparedStatement stmtWithResults;
@Mock private ResultSet resultSet;
@Before
@@ -48,7 +50,8 @@ public class InsertExecutorTest {
MockitoAnnotations.initMocks(this);
when(conn.prepareStatement(any(String.class))).thenReturn(stmt);
- when(stmt.getGeneratedKeys()).thenReturn(resultSet);
+ when(conn.prepareStatement(any(String.class), eq(Statement.RETURN_GENERATED_KEYS))).thenReturn(stmtWithResults);
+ when(stmtWithResults.getGeneratedKeys()).thenReturn(resultSet);
when(handler.handle(any(ResultSet.class))).thenReturn(new Object());
}
@@ -65,7 +68,8 @@ public class InsertExecutorTest {
assertNotNull(ret);
verify(handler, times(1)).handle(resultSet);
verify(conn, times(1)).close();
- verify(stmt, times(1)).close();
+ verify(stmt, times(0)).close();
+ verify(stmtWithResults, times(1)).close();
}
@Test(expected=SQLException.class)
diff --git a/src/test/java/org/apache/commons/dbutils2/MockResultSet.java b/src/test/java/org/apache/commons/dbutils2/MockResultSet.java
index 6944dd1..6acdc31 100644
--- a/src/test/java/org/apache/commons/dbutils2/MockResultSet.java
+++ b/src/test/java/org/apache/commons/dbutils2/MockResultSet.java
@@ -26,8 +26,6 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import org.apache.commons.dbutils2.ProxyFactory;
-
/**
* MockResultSet dynamically implements the ResultSet interface.
*/
@@ -220,7 +218,7 @@ public class MockResultSet implements InvocationHandler {
}
/**
- * @throws SQLException
+ * @throws SQLException
*/
protected ResultSetMetaData getMetaData() throws SQLException {
return this.metaData;
diff --git a/src/test/java/org/apache/commons/dbutils2/MockResultSetMetaData.java b/src/test/java/org/apache/commons/dbutils2/MockResultSetMetaData.java
index d67a19e..e92d527 100644
--- a/src/test/java/org/apache/commons/dbutils2/MockResultSetMetaData.java
+++ b/src/test/java/org/apache/commons/dbutils2/MockResultSetMetaData.java
@@ -20,8 +20,6 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.ResultSetMetaData;
-import org.apache.commons.dbutils2.ProxyFactory;
-
/**
* MockResultSetMetaData dynamically implements the ResultSetMetaData
* interface.
diff --git a/src/test/java/org/apache/commons/dbutils2/ProxyFactoryTest.java b/src/test/java/org/apache/commons/dbutils2/ProxyFactoryTest.java
index f4125f2..b64a03b 100644
--- a/src/test/java/org/apache/commons/dbutils2/ProxyFactoryTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/ProxyFactoryTest.java
@@ -19,8 +19,6 @@ package org.apache.commons.dbutils2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
-import org.apache.commons.dbutils2.ProxyFactory;
-
/**
* ProxyFactoryTest performs simple type checking on proxy objects returned
* from a ProxyFactory.
diff --git a/src/test/java/org/apache/commons/dbutils2/QueryExecutorTest.java b/src/test/java/org/apache/commons/dbutils2/QueryExecutorTest.java
index bf6b760..e0d571b 100644
--- a/src/test/java/org/apache/commons/dbutils2/QueryExecutorTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/QueryExecutorTest.java
@@ -21,13 +21,12 @@ import static org.mockito.Matchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
-import org.apache.commons.dbutils2.QueryExecutor;
-import org.apache.commons.dbutils2.ResultSetHandler;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -48,6 +47,7 @@ public class QueryExecutorTest {
MockitoAnnotations.initMocks(this);
when(conn.prepareStatement(any(String.class))).thenReturn(stmt);
+ when(conn.prepareStatement(any(String.class), any(Integer.class))).thenReturn(stmt);
when(stmt.executeQuery()).thenReturn(resultSet);
when(handler.handle(any(ResultSet.class))).thenReturn(new Object());
}
diff --git a/src/test/java/org/apache/commons/dbutils2/QueryLoaderTest.java b/src/test/java/org/apache/commons/dbutils2/QueryLoaderTest.java
index ff09a2c..0daf44d 100644
--- a/src/test/java/org/apache/commons/dbutils2/QueryLoaderTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/QueryLoaderTest.java
@@ -19,15 +19,12 @@ package org.apache.commons.dbutils2;
import java.io.IOException;
import java.util.Map;
-import org.apache.commons.dbutils2.QueryLoader;
-
/**
* QueryLoaderTest
*/
public class QueryLoaderTest extends BaseTestCase {
- private static final String QUERIES =
- "/org/apache/commons/dbutils/TestQueries.properties";
+ private static final String QUERIES = "/TestQueries.properties";
public void testLoad() throws IOException {
try {
diff --git a/src/test/java/org/apache/commons/dbutils2/QueryRunnerTest.java b/src/test/java/org/apache/commons/dbutils2/QueryRunnerTest.java
index bc3de75..728a6c7 100644
--- a/src/test/java/org/apache/commons/dbutils2/QueryRunnerTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/QueryRunnerTest.java
@@ -20,11 +20,12 @@ import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+
import java.sql.Connection;
import java.sql.SQLException;
+
import javax.sql.DataSource;
-import org.apache.commons.dbutils2.QueryRunner;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
diff --git a/src/test/java/org/apache/commons/dbutils2/ResultSetIteratorTest.java b/src/test/java/org/apache/commons/dbutils2/ResultSetIteratorTest.java
index 89070a9..0c5f663 100644
--- a/src/test/java/org/apache/commons/dbutils2/ResultSetIteratorTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/ResultSetIteratorTest.java
@@ -18,8 +18,6 @@ package org.apache.commons.dbutils2;
import java.util.Iterator;
-import org.apache.commons.dbutils2.ResultSetIterator;
-
/**
* ResultSetIteratorTest
*/
diff --git a/src/test/java/org/apache/commons/dbutils2/TestBean.java b/src/test/java/org/apache/commons/dbutils2/TestBean.java
index fc3f8e6..d16c633 100644
--- a/src/test/java/org/apache/commons/dbutils2/TestBean.java
+++ b/src/test/java/org/apache/commons/dbutils2/TestBean.java
@@ -59,6 +59,13 @@ public class TestBean {
private double columnProcessorDoubleTest = -1;
/**
+ * the ResultSet will have a string in this column and the
+ * BeanProcessors should convert that to a enum of type EnumTest
+ * and store the value in this property.
+ */
+ private EnumTest enumTest;
+
+ /**
* Constructor for TestBean.
*/
public TestBean() {
@@ -145,4 +152,11 @@ public class TestBean {
columnProcessorDoubleTest = d;
}
+ public EnumTest getEnumTest() {
+ return enumTest;
+ }
+
+ public void setEnumTest(EnumTest enumTest) {
+ this.enumTest = enumTest;
+ }
}
diff --git a/src/test/java/org/apache/commons/dbutils2/UpdateExecutorTest.java b/src/test/java/org/apache/commons/dbutils2/UpdateExecutorTest.java
index 4b9a400..e493768 100644
--- a/src/test/java/org/apache/commons/dbutils2/UpdateExecutorTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/UpdateExecutorTest.java
@@ -16,16 +16,16 @@
*/
package org.apache.commons.dbutils2;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
-import org.apache.commons.dbutils2.UpdateExecutor;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -43,8 +43,8 @@ public class UpdateExecutorTest {
@Before
public void setup() throws SQLException {
MockitoAnnotations.initMocks(this);
-
- when(conn.prepareStatement(any(String.class))).thenReturn(stmt);
+
+ when(conn.prepareStatement(any(String.class), any(Integer.class))).thenReturn(stmt);
when(stmt.executeUpdate()).thenReturn(20);
}
diff --git a/src/test/java/org/apache/commons/dbutils2/handlers/BeanMapHandlerTest.java b/src/test/java/org/apache/commons/dbutils2/handlers/BeanMapHandlerTest.java
index c14951c..65511bb 100644
--- a/src/test/java/org/apache/commons/dbutils2/handlers/BeanMapHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/handlers/BeanMapHandlerTest.java
@@ -16,7 +16,8 @@
*/
package org.apache.commons.dbutils2.handlers;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.when;
import java.sql.ResultSet;
@@ -25,7 +26,6 @@ import java.util.Map;
import org.apache.commons.dbutils2.RowProcessor;
import org.apache.commons.dbutils2.TestBean;
-import org.apache.commons.dbutils2.handlers.BeanMapHandler;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
diff --git a/src/test/java/org/apache/commons/dbutils2/handlers/ColumnListHandlerTest.java b/src/test/java/org/apache/commons/dbutils2/handlers/ColumnListHandlerTest.java
index 4686e53..dee6612 100644
--- a/src/test/java/org/apache/commons/dbutils2/handlers/ColumnListHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/handlers/ColumnListHandlerTest.java
@@ -21,7 +21,6 @@ import java.util.List;
import org.apache.commons.dbutils2.BaseTestCase;
import org.apache.commons.dbutils2.ResultSetHandler;
-import org.apache.commons.dbutils2.handlers.ColumnListHandler;
/**
* ColumnListHandlerTest
diff --git a/src/test/java/org/apache/commons/dbutils2/handlers/KeyedHandlerTest.java b/src/test/java/org/apache/commons/dbutils2/handlers/KeyedHandlerTest.java
index f0cedc0..403ff7f 100644
--- a/src/test/java/org/apache/commons/dbutils2/handlers/KeyedHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/handlers/KeyedHandlerTest.java
@@ -22,7 +22,6 @@ import java.util.Map.Entry;
import org.apache.commons.dbutils2.BaseTestCase;
import org.apache.commons.dbutils2.ResultSetHandler;
-import org.apache.commons.dbutils2.handlers.KeyedHandler;
public class KeyedHandlerTest extends BaseTestCase {
diff --git a/src/test/java/org/apache/commons/dbutils2/handlers/MapHandlerTest.java b/src/test/java/org/apache/commons/dbutils2/handlers/MapHandlerTest.java
index d8dbf33..ba850a6 100644
--- a/src/test/java/org/apache/commons/dbutils2/handlers/MapHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/handlers/MapHandlerTest.java
@@ -21,7 +21,6 @@ import java.util.Map;
import org.apache.commons.dbutils2.BaseTestCase;
import org.apache.commons.dbutils2.ResultSetHandler;
-import org.apache.commons.dbutils2.handlers.MapHandler;
/**
* MapHandlerTest
diff --git a/src/test/java/org/apache/commons/dbutils2/handlers/MapListHandlerTest.java b/src/test/java/org/apache/commons/dbutils2/handlers/MapListHandlerTest.java
index d14a7c3..1c2a016 100644
--- a/src/test/java/org/apache/commons/dbutils2/handlers/MapListHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/handlers/MapListHandlerTest.java
@@ -23,7 +23,6 @@ import java.util.Map;
import org.apache.commons.dbutils2.BaseTestCase;
import org.apache.commons.dbutils2.ResultSetHandler;
-import org.apache.commons.dbutils2.handlers.MapListHandler;
/**
* MapListHandlerTest
diff --git a/src/test/java/org/apache/commons/dbutils2/handlers/ScalarHandlerTest.java b/src/test/java/org/apache/commons/dbutils2/handlers/ScalarHandlerTest.java
index f44592f..755c0a3 100644
--- a/src/test/java/org/apache/commons/dbutils2/handlers/ScalarHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/handlers/ScalarHandlerTest.java
@@ -20,7 +20,6 @@ import java.sql.SQLException;
import org.apache.commons.dbutils2.BaseTestCase;
import org.apache.commons.dbutils2.ResultSetHandler;
-import org.apache.commons.dbutils2.handlers.ScalarHandler;
public class ScalarHandlerTest extends BaseTestCase {
diff --git a/src/test/java/org/apache/commons/dbutils2/wrappers/SqlNullCheckedResultSetTest.java b/src/test/java/org/apache/commons/dbutils2/wrappers/SqlNullCheckedResultSetTest.java
index 406d298..d734d4d 100644
--- a/src/test/java/org/apache/commons/dbutils2/wrappers/SqlNullCheckedResultSetTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/wrappers/SqlNullCheckedResultSetTest.java
@@ -40,7 +40,6 @@ import java.util.Map;
import org.apache.commons.dbutils2.BaseTestCase;
import org.apache.commons.dbutils2.ProxyFactory;
-import org.apache.commons.dbutils2.wrappers.SqlNullCheckedResultSet;
/**
* Test cases for <code>SqlNullCheckedResultSet</code> class.
diff --git a/src/test/java/org/apache/commons/dbutils2/wrappers/StringTrimmedResultSetTest.java b/src/test/java/org/apache/commons/dbutils2/wrappers/StringTrimmedResultSetTest.java
index c5de076..ef22663 100644
--- a/src/test/java/org/apache/commons/dbutils2/wrappers/StringTrimmedResultSetTest.java
+++ b/src/test/java/org/apache/commons/dbutils2/wrappers/StringTrimmedResultSetTest.java
@@ -22,8 +22,6 @@ import java.sql.SQLException;
import org.apache.commons.dbutils2.BaseTestCase;
import org.apache.commons.dbutils2.MockResultSet;
import org.apache.commons.dbutils2.ProxyFactory;
-import org.apache.commons.dbutils2.wrappers.SqlNullCheckedResultSet;
-import org.apache.commons.dbutils2.wrappers.StringTrimmedResultSet;
/**
* StringTrimmedResultSetTest