You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2019/07/30 21:42:37 UTC
[commons-dbcp] branch master updated: [DBCP-551]
org.apache.commons.dbcp2.DelegatingStatement.close() should try to close
ALL of its result sets.
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-dbcp.git
The following commit(s) were added to refs/heads/master by this push:
new 6e86e0d [DBCP-551] org.apache.commons.dbcp2.DelegatingStatement.close() should try to close ALL of its result sets.
6e86e0d is described below
commit 6e86e0de00af300293d2182e5395e17f4447f1ab
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Tue Jul 30 17:42:32 2019 -0400
[DBCP-551] org.apache.commons.dbcp2.DelegatingStatement.close() should
try to close ALL of its result sets.
---
src/changes/changes.xml | 3 +
.../apache/commons/dbcp2/DelegatingConnection.java | 20 +-
.../apache/commons/dbcp2/DelegatingStatement.java | 59 +--
.../org/apache/commons/dbcp2/SQLExceptionList.java | 51 +++
.../commons/dbcp2/TestDelegatingStatement.java | 400 +++++++++++----------
.../apache/commons/dbcp2/TestSQLExceptionList.java | 38 ++
.../org/apache/commons/dbcp2/TesterConnection.java | 3 +-
.../commons/dbcp2/TesterPreparedStatement.java | 1 +
.../org/apache/commons/dbcp2/TesterResultSet.java | 28 +-
.../org/apache/commons/dbcp2/TesterStatement.java | 21 +-
10 files changed, 406 insertions(+), 218 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index cd94f1d..b69108a 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -124,6 +124,9 @@ The <action> type attribute can be add,update,fix,remove.
<action dev="ggregory" type="update" due-to="Gary Gregory">
Update tests from org.mockito:mockito-core 2.28.2 to 3.0.0.
</action>
+ <action dev="ggregory" type="update" issue="DBCP-551" due-to="Gary Gregory">
+ org.apache.commons.dbcp2.DelegatingStatement.close() should try to close ALL of its result sets.
+ </action>
</release>
<release version="2.6.0" date="2019-02-14" description="This is a minor release, including bug fixes and enhancements.">
<action dev="chtompki" type="add" issue="DBCP-534" due-to="Peter Wicks">
diff --git a/src/main/java/org/apache/commons/dbcp2/DelegatingConnection.java b/src/main/java/org/apache/commons/dbcp2/DelegatingConnection.java
index fe0de9d..2b8853f 100644
--- a/src/main/java/org/apache/commons/dbcp2/DelegatingConnection.java
+++ b/src/main/java/org/apache/commons/dbcp2/DelegatingConnection.java
@@ -246,7 +246,23 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
}
protected void handleException(final SQLException e) throws SQLException {
- throw e;
+ handleException(e, true);
+ }
+
+ /**
+ * Rethrows the given {@code SQLException} if {@code rethrow} is true.
+ *
+ * @param e The SQLException
+ * @param rethrow Wether or not to rethrow
+ * @return the given {@code SQLException}
+ * @throws SQLException the given {@code SQLException}
+ * @since 2.7.0
+ */
+ protected SQLException handleException(final SQLException e, final boolean rethrow) throws SQLException {
+ if (rethrow) {
+ throw e;
+ }
+ return e;
}
private void initializeStatement(final DelegatingStatement ds) throws SQLException {
@@ -608,7 +624,7 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
// Statement's when it is closed.
// DBCP-288. Not all the traced objects will be statements
final List<AbandonedTrace> traces = getTrace();
- if (traces != null && traces.size() > 0) {
+ if (traces != null && !traces.isEmpty()) {
final Iterator<AbandonedTrace> traceIter = traces.iterator();
while (traceIter.hasNext()) {
final Object trace = traceIter.next();
diff --git a/src/main/java/org/apache/commons/dbcp2/DelegatingStatement.java b/src/main/java/org/apache/commons/dbcp2/DelegatingStatement.java
index 8a1725f..88f01e5 100644
--- a/src/main/java/org/apache/commons/dbcp2/DelegatingStatement.java
+++ b/src/main/java/org/apache/commons/dbcp2/DelegatingStatement.java
@@ -21,6 +21,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -125,35 +126,53 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
if (isClosed()) {
return;
}
+ final List<SQLException> thrown = new ArrayList<>();
try {
- try {
- if (connection != null) {
- connection.removeTrace(this);
- connection = null;
- }
+ if (connection != null) {
+ connection.removeTrace(this);
+ connection = null;
+ }
- // The JDBC spec requires that a statement close any open
- // ResultSet's when it is closed.
- // FIXME The PreparedStatement we're wrapping should handle this for us.
- // See bug 17301 for what could happen when ResultSets are closed twice.
- final List<AbandonedTrace> resultSets = getTrace();
- if (resultSets != null) {
- final ResultSet[] set = resultSets.toArray(new ResultSet[resultSets.size()]);
- for (final ResultSet element : set) {
- element.close();
+ // The JDBC spec requires that a statement close any open
+ // ResultSet's when it is closed.
+ // FIXME The PreparedStatement we're wrapping should handle this for us.
+ // See bug 17301 for what could happen when ResultSets are closed twice.
+ final List<AbandonedTrace> resultSetList = getTrace();
+ if (resultSetList != null) {
+ final int size = resultSetList.size();
+ final ResultSet[] resultSets = resultSetList.toArray(new ResultSet[size]);
+ for (final ResultSet resultSet : resultSets) {
+ if (resultSet != null) {
+ try {
+ resultSet.close();
+ } catch (SQLException e) {
+ if (connection != null) {
+ // Does not rethrow e.
+ connection.handleException(e, false);
+ }
+ thrown.add(e);
+ }
}
- clearTrace();
}
-
- if (statement != null) {
+ clearTrace();
+ }
+ if (statement != null) {
+ try {
statement.close();
+ } catch (SQLException e) {
+ if (connection != null) {
+ // Does not rethrow e.
+ connection.handleException(e, false);
+ }
+ thrown.add(e);
}
- } catch (final SQLException e) {
- handleException(e);
}
} finally {
closed = true;
statement = null;
+ if (!thrown.isEmpty()) {
+ throw new SQLExceptionList(thrown);
+ }
}
}
@@ -615,7 +634,7 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
}
/*
- * Note was protected prior to JDBC 4
+ * Note: This method was protected prior to JDBC 4.
*/
@Override
public boolean isClosed() throws SQLException {
diff --git a/src/main/java/org/apache/commons/dbcp2/SQLExceptionList.java b/src/main/java/org/apache/commons/dbcp2/SQLExceptionList.java
new file mode 100644
index 0000000..1df9356
--- /dev/null
+++ b/src/main/java/org/apache/commons/dbcp2/SQLExceptionList.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.dbcp2;
+
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * A SQLException based on a list of SQLException causes.
+ * <p>
+ * The first exception in the list is used as this exception's cause and is accessible with the usual
+ * {@link #getCause()} while the complete list is accessible with {@link #getCauseList()}.
+ * </p>
+ *
+ * @since 2.7.0
+ */
+public class SQLExceptionList extends SQLException {
+
+ private static final long serialVersionUID = 1L;
+ private final List<? extends SQLException> causeList;
+
+ /**
+ * Creates a new exception caused by a list of exceptions.
+ *
+ * @param causeList a list of cause exceptions.
+ */
+ public SQLExceptionList(List<? extends SQLException> causeList) {
+ super(String.format("%,d SQLExceptions: %s", causeList.size(), causeList), causeList.get(0));
+ this.causeList = causeList;
+ }
+
+ public List<? extends SQLException> getCauseList() {
+ return causeList;
+ }
+
+}
diff --git a/src/test/java/org/apache/commons/dbcp2/TestDelegatingStatement.java b/src/test/java/org/apache/commons/dbcp2/TestDelegatingStatement.java
index f9867f8..f187cbf 100644
--- a/src/test/java/org/apache/commons/dbcp2/TestDelegatingStatement.java
+++ b/src/test/java/org/apache/commons/dbcp2/TestDelegatingStatement.java
@@ -28,43 +28,71 @@ import static org.mockito.Mockito.verify;
import java.lang.reflect.Proxy;
import java.sql.Connection;
+import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class TestDelegatingStatement {
- private DelegatingConnection<Connection> conn = null;
- private Connection delegateConn = null;
- private Statement obj = null;
- private DelegatingStatement delegate = null;
+ private static class TesterStatementNonWrapping extends TesterStatement {
+
+ public TesterStatementNonWrapping(final Connection conn) {
+ super(conn);
+ }
+
+ @Override
+ public boolean isWrapperFor(final Class<?> iface) throws SQLException {
+ return false;
+ }
+ }
+
+ private DelegatingConnection<Connection> delegatingConnection;
+ private TesterConnection testerConnection;
+ private Statement mockedStatement;
+ private DelegatingStatement delegatingStatement;
+ private DelegatingStatement delegatingTesterStatement;
+ private TesterResultSet testerResultSet;
+ private TesterStatement testerStatement;
@BeforeEach
public void setUp() throws Exception {
- delegateConn = new TesterConnection("test", "test");
- conn = new DelegatingConnection<>(delegateConn);
- obj = mock(Statement.class);
- delegate = new DelegatingStatement(conn, obj);
+ testerConnection = new TesterConnection("test", "test");
+ delegatingConnection = new DelegatingConnection<>(testerConnection);
+ mockedStatement = mock(Statement.class);
+ testerStatement = new TesterStatement(testerConnection);
+ delegatingStatement = new DelegatingStatement(delegatingConnection, mockedStatement);
+ delegatingTesterStatement = new DelegatingStatement(delegatingConnection, testerStatement);
+ testerResultSet = new TesterResultSet(mockedStatement);
}
@Test
- public void testExecuteQueryReturnsNull() throws Exception {
- assertNull(delegate.executeQuery("null"));
+ public void testAddBatchString() throws Exception {
+ try {
+ delegatingStatement.addBatch("foo");
+ } catch (final SQLException e) {
+ }
+ verify(mockedStatement, times(1)).addBatch("foo");
}
@Test
- public void testGetDelegate() throws Exception {
- assertEquals(obj,delegate.getDelegate());
+ public void testCancel() throws Exception {
+ try {
+ delegatingStatement.cancel();
+ } catch (final SQLException e) {
+ }
+ verify(mockedStatement, times(1)).cancel();
}
@Test
public void testCheckOpen() throws Exception {
- delegate.checkOpen();
- delegate.close();
+ delegatingStatement.checkOpen();
+ delegatingStatement.close();
try {
- delegate.checkOpen();
+ delegatingStatement.checkOpen();
fail("Expecting SQLException");
} catch (final SQLException ex) {
// expected
@@ -72,222 +100,207 @@ public class TestDelegatingStatement {
}
@Test
- public void testIsWrapperFor() throws Exception {
- final TesterConnection tstConn = new TesterConnection("test", "test");
- final TesterStatement tstStmt = new TesterStatementNonWrapping(tstConn);
- final DelegatingConnection<TesterConnection> dconn = new DelegatingConnection<>(tstConn);
- final DelegatingStatement stamt = new DelegatingStatement(dconn, tstStmt);
-
- final Class<?> stmtProxyClass = Proxy.getProxyClass(
- this.getClass().getClassLoader(),
- Statement.class);
-
- assertTrue(stamt.isWrapperFor(DelegatingStatement.class));
- assertTrue(stamt.isWrapperFor(TesterStatement.class));
- assertFalse(stamt.isWrapperFor(stmtProxyClass));
-
- stamt.close();
- }
-
- private static class TesterStatementNonWrapping extends TesterStatement {
-
- public TesterStatementNonWrapping(final Connection conn) {
- super(conn);
- }
-
- @Override
- public boolean isWrapperFor(final Class<?> iface) throws SQLException {
- return false;
- }
- }
-
- @Test
- public void testAddBatchString() throws Exception {
+ public void testClearBatch() throws Exception {
try {
- delegate.addBatch("foo");
+ delegatingStatement.clearBatch();
} catch (final SQLException e) {
}
- verify(obj, times(1)).addBatch("foo");
+ verify(mockedStatement, times(1)).clearBatch();
}
@Test
- public void testCancel() throws Exception {
+ public void testClearWarnings() throws Exception {
try {
- delegate.cancel();
+ delegatingStatement.clearWarnings();
} catch (final SQLException e) {
}
- verify(obj, times(1)).cancel();
+ verify(mockedStatement, times(1)).clearWarnings();
}
@Test
- public void testClearBatch() throws Exception {
+ public void testClose() throws Exception {
try {
- delegate.clearBatch();
+ delegatingStatement.close();
} catch (final SQLException e) {
}
- verify(obj, times(1)).clearBatch();
+ verify(mockedStatement, times(1)).close();
}
@Test
- public void testClearWarnings() throws Exception {
+ public void testCloseWithResultSetCloseException() throws Exception {
try {
- delegate.clearWarnings();
+ testerResultSet.setSqlExceptionOnClose(true);
+ delegatingStatement.addTrace(testerResultSet);
+ delegatingStatement.close();
+ Assertions.fail("Excpected a SQLExceptionList");
} catch (final SQLException e) {
+ Assertions.assertTrue(e instanceof SQLExceptionList);
+ } finally {
+ testerResultSet.setSqlExceptionOnClose(false);
}
- verify(obj, times(1)).clearWarnings();
+ verify(mockedStatement, times(1)).close();
}
@Test
- public void testClose() throws Exception {
+ public void testCloseWithStatementCloseException() throws Exception {
try {
- delegate.close();
+ testerStatement.setSqlExceptionOnClose(true);
+ delegatingTesterStatement.close();
+ Assertions.fail("Excpected a SQLExceptionList");
} catch (final SQLException e) {
+ Assertions.assertTrue(e instanceof SQLExceptionList);
+ } finally {
+ testerStatement.setSqlExceptionOnClose(false);
}
- verify(obj, times(1)).close();
}
@Test
public void testCloseOnCompletion() throws Exception {
try {
- delegate.closeOnCompletion();
+ delegatingStatement.closeOnCompletion();
} catch (final SQLException e) {
}
- verify(obj, times(1)).closeOnCompletion();
+ verify(mockedStatement, times(1)).closeOnCompletion();
}
@Test
- public void testExecuteStringIntegerArray() throws Exception {
+ public void testExecuteBatch() throws Exception {
try {
- delegate.execute("foo", (int[]) null);
+ delegatingStatement.executeBatch();
} catch (final SQLException e) {
}
- verify(obj, times(1)).execute("foo", (int[]) null);
+ verify(mockedStatement, times(1)).executeBatch();
}
@Test
- public void testExecuteString() throws Exception {
+ public void testExecuteLargeBatch() throws Exception {
try {
- delegate.execute("foo");
+ delegatingStatement.executeLargeBatch();
} catch (final SQLException e) {
}
- verify(obj, times(1)).execute("foo");
+ verify(mockedStatement, times(1)).executeLargeBatch();
}
@Test
- public void testExecuteStringStringArray() throws Exception {
+ public void testExecuteLargeUpdateString() throws Exception {
try {
- delegate.execute("foo", (String[]) null);
+ delegatingStatement.executeLargeUpdate("foo");
} catch (final SQLException e) {
}
- verify(obj, times(1)).execute("foo", (String[]) null);
+ verify(mockedStatement, times(1)).executeLargeUpdate("foo");
}
@Test
- public void testExecuteStringInteger() throws Exception {
+ public void testExecuteLargeUpdateStringInteger() throws Exception {
try {
- delegate.execute("foo", 1);
+ delegatingStatement.executeLargeUpdate("foo", 1);
} catch (final SQLException e) {
}
- verify(obj, times(1)).execute("foo", 1);
+ verify(mockedStatement, times(1)).executeLargeUpdate("foo", 1);
}
@Test
- public void testExecuteBatch() throws Exception {
+ public void testExecuteLargeUpdateStringIntegerArray() throws Exception {
try {
- delegate.executeBatch();
+ delegatingStatement.executeLargeUpdate("foo", (int[]) null);
} catch (final SQLException e) {
}
- verify(obj, times(1)).executeBatch();
+ verify(mockedStatement, times(1)).executeLargeUpdate("foo", (int[]) null);
}
@Test
- public void testExecuteLargeBatch() throws Exception {
+ public void testExecuteLargeUpdateStringStringArray() throws Exception {
try {
- delegate.executeLargeBatch();
+ delegatingStatement.executeLargeUpdate("foo", (String[]) null);
} catch (final SQLException e) {
}
- verify(obj, times(1)).executeLargeBatch();
+ verify(mockedStatement, times(1)).executeLargeUpdate("foo", (String[]) null);
}
@Test
- public void testExecuteLargeUpdateStringInteger() throws Exception {
+ public void testExecuteQueryReturnsNull() throws Exception {
+ assertNull(delegatingStatement.executeQuery("null"));
+ }
+
+ @Test
+ public void testExecuteQueryString() throws Exception {
try {
- delegate.executeLargeUpdate("foo", 1);
+ delegatingStatement.executeQuery("foo");
} catch (final SQLException e) {
}
- verify(obj, times(1)).executeLargeUpdate("foo", 1);
+ verify(mockedStatement, times(1)).executeQuery("foo");
}
@Test
- public void testExecuteLargeUpdateStringIntegerArray() throws Exception {
+ public void testExecuteString() throws Exception {
try {
- delegate.executeLargeUpdate("foo", (int[]) null);
+ delegatingStatement.execute("foo");
} catch (final SQLException e) {
}
- verify(obj, times(1)).executeLargeUpdate("foo", (int[]) null);
+ verify(mockedStatement, times(1)).execute("foo");
}
@Test
- public void testExecuteLargeUpdateString() throws Exception {
+ public void testExecuteStringInteger() throws Exception {
try {
- delegate.executeLargeUpdate("foo");
+ delegatingStatement.execute("foo", 1);
} catch (final SQLException e) {
}
- verify(obj, times(1)).executeLargeUpdate("foo");
+ verify(mockedStatement, times(1)).execute("foo", 1);
}
@Test
- public void testExecuteLargeUpdateStringStringArray() throws Exception {
+ public void testExecuteStringIntegerArray() throws Exception {
try {
- delegate.executeLargeUpdate("foo", (String[]) null);
+ delegatingStatement.execute("foo", (int[]) null);
} catch (final SQLException e) {
}
- verify(obj, times(1)).executeLargeUpdate("foo", (String[]) null);
+ verify(mockedStatement, times(1)).execute("foo", (int[]) null);
}
@Test
- public void testExecuteQueryString() throws Exception {
+ public void testExecuteStringStringArray() throws Exception {
try {
- delegate.executeQuery("foo");
+ delegatingStatement.execute("foo", (String[]) null);
} catch (final SQLException e) {
}
- verify(obj, times(1)).executeQuery("foo");
+ verify(mockedStatement, times(1)).execute("foo", (String[]) null);
}
@Test
- public void testExecuteUpdateStringIntegerArray() throws Exception {
+ public void testExecuteUpdateString() throws Exception {
try {
- delegate.executeUpdate("foo", (int[]) null);
+ delegatingStatement.executeUpdate("foo");
} catch (final SQLException e) {
}
- verify(obj, times(1)).executeUpdate("foo", (int[]) null);
+ verify(mockedStatement, times(1)).executeUpdate("foo");
}
@Test
- public void testExecuteUpdateStringStringArray() throws Exception {
+ public void testExecuteUpdateStringInteger() throws Exception {
try {
- delegate.executeUpdate("foo", (String[]) null);
+ delegatingStatement.executeUpdate("foo", 1);
} catch (final SQLException e) {
}
- verify(obj, times(1)).executeUpdate("foo", (String[]) null);
+ verify(mockedStatement, times(1)).executeUpdate("foo", 1);
}
@Test
- public void testExecuteUpdateString() throws Exception {
+ public void testExecuteUpdateStringIntegerArray() throws Exception {
try {
- delegate.executeUpdate("foo");
+ delegatingStatement.executeUpdate("foo", (int[]) null);
} catch (final SQLException e) {
}
- verify(obj, times(1)).executeUpdate("foo");
+ verify(mockedStatement, times(1)).executeUpdate("foo", (int[]) null);
}
@Test
- public void testExecuteUpdateStringInteger() throws Exception {
+ public void testExecuteUpdateStringStringArray() throws Exception {
try {
- delegate.executeUpdate("foo", 1);
+ delegatingStatement.executeUpdate("foo", (String[]) null);
} catch (final SQLException e) {
}
- verify(obj, times(1)).executeUpdate("foo", 1);
+ verify(mockedStatement, times(1)).executeUpdate("foo", (String[]) null);
}
/**
@@ -299,163 +312,159 @@ public class TestDelegatingStatement {
@Test
public void testGetConnection() throws Exception {
try {
- delegate.getConnection();
+ delegatingStatement.getConnection();
} catch (final SQLException e) {
}
- verify(obj, times(0)).getConnection();
+ verify(mockedStatement, times(0)).getConnection();
+ }
+
+ @Test
+ public void testGetDelegate() throws Exception {
+ assertEquals(mockedStatement,delegatingStatement.getDelegate());
}
@Test
public void testGetFetchDirection() throws Exception {
try {
- delegate.getFetchDirection();
+ delegatingStatement.getFetchDirection();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getFetchDirection();
+ verify(mockedStatement, times(1)).getFetchDirection();
}
@Test
public void testGetFetchSize() throws Exception {
try {
- delegate.getFetchSize();
+ delegatingStatement.getFetchSize();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getFetchSize();
+ verify(mockedStatement, times(1)).getFetchSize();
}
@Test
public void testGetGeneratedKeys() throws Exception {
try {
- delegate.getGeneratedKeys();
+ delegatingStatement.getGeneratedKeys();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getGeneratedKeys();
+ verify(mockedStatement, times(1)).getGeneratedKeys();
}
@Test
public void testGetLargeMaxRows() throws Exception {
try {
- delegate.getLargeMaxRows();
+ delegatingStatement.getLargeMaxRows();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getLargeMaxRows();
+ verify(mockedStatement, times(1)).getLargeMaxRows();
}
@Test
public void testGetLargeUpdateCount() throws Exception {
try {
- delegate.getLargeUpdateCount();
+ delegatingStatement.getLargeUpdateCount();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getLargeUpdateCount();
+ verify(mockedStatement, times(1)).getLargeUpdateCount();
}
@Test
public void testGetMaxFieldSize() throws Exception {
try {
- delegate.getMaxFieldSize();
+ delegatingStatement.getMaxFieldSize();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getMaxFieldSize();
+ verify(mockedStatement, times(1)).getMaxFieldSize();
}
@Test
public void testGetMaxRows() throws Exception {
try {
- delegate.getMaxRows();
+ delegatingStatement.getMaxRows();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getMaxRows();
+ verify(mockedStatement, times(1)).getMaxRows();
}
@Test
- public void testGetMoreResultsInteger() throws Exception {
+ public void testGetMoreResults() throws Exception {
try {
- delegate.getMoreResults(1);
+ delegatingStatement.getMoreResults();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getMoreResults(1);
+ verify(mockedStatement, times(1)).getMoreResults();
}
@Test
- public void testGetMoreResults() throws Exception {
+ public void testGetMoreResultsInteger() throws Exception {
try {
- delegate.getMoreResults();
+ delegatingStatement.getMoreResults(1);
} catch (final SQLException e) {
}
- verify(obj, times(1)).getMoreResults();
+ verify(mockedStatement, times(1)).getMoreResults(1);
}
@Test
public void testGetQueryTimeout() throws Exception {
try {
- delegate.getQueryTimeout();
+ delegatingStatement.getQueryTimeout();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getQueryTimeout();
+ verify(mockedStatement, times(1)).getQueryTimeout();
}
@Test
public void testGetResultSet() throws Exception {
try {
- delegate.getResultSet();
+ delegatingStatement.getResultSet();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getResultSet();
+ verify(mockedStatement, times(1)).getResultSet();
}
@Test
public void testGetResultSetConcurrency() throws Exception {
try {
- delegate.getResultSetConcurrency();
+ delegatingStatement.getResultSetConcurrency();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getResultSetConcurrency();
+ verify(mockedStatement, times(1)).getResultSetConcurrency();
}
@Test
public void testGetResultSetHoldability() throws Exception {
try {
- delegate.getResultSetHoldability();
+ delegatingStatement.getResultSetHoldability();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getResultSetHoldability();
+ verify(mockedStatement, times(1)).getResultSetHoldability();
}
@Test
public void testGetResultSetType() throws Exception {
try {
- delegate.getResultSetType();
+ delegatingStatement.getResultSetType();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getResultSetType();
+ verify(mockedStatement, times(1)).getResultSetType();
}
@Test
public void testGetUpdateCount() throws Exception {
try {
- delegate.getUpdateCount();
+ delegatingStatement.getUpdateCount();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getUpdateCount();
+ verify(mockedStatement, times(1)).getUpdateCount();
}
@Test
public void testGetWarnings() throws Exception {
try {
- delegate.getWarnings();
+ delegatingStatement.getWarnings();
} catch (final SQLException e) {
}
- verify(obj, times(1)).getWarnings();
- }
-
- @Test
- public void testIsCloseOnCompletion() throws Exception {
- try {
- delegate.isCloseOnCompletion();
- } catch (final SQLException e) {
- }
- verify(obj, times(1)).isCloseOnCompletion();
+ verify(mockedStatement, times(1)).getWarnings();
}
/**
@@ -467,111 +476,138 @@ public class TestDelegatingStatement {
@Test
public void testIsClosed() throws Exception {
try {
- delegate.isClosed();
+ delegatingStatement.isClosed();
} catch (final SQLException e) {
}
- verify(obj, times(0)).isClosed();
+ verify(mockedStatement, times(0)).isClosed();
+ }
+
+ @Test
+ public void testIsCloseOnCompletion() throws Exception {
+ try {
+ delegatingStatement.isCloseOnCompletion();
+ } catch (final SQLException e) {
+ }
+ verify(mockedStatement, times(1)).isCloseOnCompletion();
}
@Test
public void testIsPoolable() throws Exception {
try {
- delegate.isPoolable();
+ delegatingStatement.isPoolable();
} catch (final SQLException e) {
}
- verify(obj, times(1)).isPoolable();
+ verify(mockedStatement, times(1)).isPoolable();
+ }
+
+ @Test
+ public void testIsWrapperFor() throws Exception {
+ final TesterConnection tstConn = new TesterConnection("test", "test");
+ final TesterStatement tstStmt = new TesterStatementNonWrapping(tstConn);
+ final DelegatingConnection<TesterConnection> dconn = new DelegatingConnection<>(tstConn);
+ final DelegatingStatement stamt = new DelegatingStatement(dconn, tstStmt);
+
+ final Class<?> stmtProxyClass = Proxy.getProxyClass(
+ this.getClass().getClassLoader(),
+ Statement.class);
+
+ assertTrue(stamt.isWrapperFor(DelegatingStatement.class));
+ assertTrue(stamt.isWrapperFor(TesterStatement.class));
+ assertFalse(stamt.isWrapperFor(stmtProxyClass));
+
+ stamt.close();
}
@Test
public void testSetCursorNameString() throws Exception {
try {
- delegate.setCursorName("foo");
+ delegatingStatement.setCursorName("foo");
} catch (final SQLException e) {
}
- verify(obj, times(1)).setCursorName("foo");
+ verify(mockedStatement, times(1)).setCursorName("foo");
}
@Test
public void testSetEscapeProcessingBoolean() throws Exception {
try {
- delegate.setEscapeProcessing(Boolean.TRUE);
+ delegatingStatement.setEscapeProcessing(Boolean.TRUE);
} catch (final SQLException e) {
}
- verify(obj, times(1)).setEscapeProcessing(Boolean.TRUE);
+ verify(mockedStatement, times(1)).setEscapeProcessing(Boolean.TRUE);
}
@Test
public void testSetFetchDirectionInteger() throws Exception {
try {
- delegate.setFetchDirection(1);
+ delegatingStatement.setFetchDirection(1);
} catch (final SQLException e) {
}
- verify(obj, times(1)).setFetchDirection(1);
+ verify(mockedStatement, times(1)).setFetchDirection(1);
}
@Test
public void testSetFetchSizeInteger() throws Exception {
try {
- delegate.setFetchSize(1);
+ delegatingStatement.setFetchSize(1);
} catch (final SQLException e) {
}
- verify(obj, times(1)).setFetchSize(1);
+ verify(mockedStatement, times(1)).setFetchSize(1);
}
@Test
public void testSetLargeMaxRowsLong() throws Exception {
try {
- delegate.setLargeMaxRows(1l);
+ delegatingStatement.setLargeMaxRows(1l);
} catch (final SQLException e) {
}
- verify(obj, times(1)).setLargeMaxRows(1l);
+ verify(mockedStatement, times(1)).setLargeMaxRows(1l);
}
@Test
public void testSetMaxFieldSizeInteger() throws Exception {
try {
- delegate.setMaxFieldSize(1);
+ delegatingStatement.setMaxFieldSize(1);
} catch (final SQLException e) {
}
- verify(obj, times(1)).setMaxFieldSize(1);
+ verify(mockedStatement, times(1)).setMaxFieldSize(1);
}
@Test
public void testSetMaxRowsInteger() throws Exception {
try {
- delegate.setMaxRows(1);
+ delegatingStatement.setMaxRows(1);
} catch (final SQLException e) {
}
- verify(obj, times(1)).setMaxRows(1);
+ verify(mockedStatement, times(1)).setMaxRows(1);
}
@Test
public void testSetPoolableBoolean() throws Exception {
try {
- delegate.setPoolable(Boolean.TRUE);
+ delegatingStatement.setPoolable(Boolean.TRUE);
} catch (final SQLException e) {
}
- verify(obj, times(1)).setPoolable(Boolean.TRUE);
+ verify(mockedStatement, times(1)).setPoolable(Boolean.TRUE);
}
@Test
public void testSetQueryTimeoutInteger() throws Exception {
try {
- delegate.setQueryTimeout(1);
+ delegatingStatement.setQueryTimeout(1);
} catch (final SQLException e) {
}
- verify(obj, times(1)).setQueryTimeout(1);
+ verify(mockedStatement, times(1)).setQueryTimeout(1);
}
@Test
public void testWrap() throws SQLException {
- assertEquals(delegate, delegate.unwrap(Statement.class));
- assertEquals(delegate, delegate.unwrap(DelegatingStatement.class));
- assertEquals(obj, delegate.unwrap(obj.getClass()));
- assertNull(delegate.unwrap(String.class));
- assertTrue(delegate.isWrapperFor(Statement.class));
- assertTrue(delegate.isWrapperFor(DelegatingStatement.class));
- assertTrue(delegate.isWrapperFor(obj.getClass()));
- assertFalse(delegate.isWrapperFor(String.class));
+ assertEquals(delegatingStatement, delegatingStatement.unwrap(Statement.class));
+ assertEquals(delegatingStatement, delegatingStatement.unwrap(DelegatingStatement.class));
+ assertEquals(mockedStatement, delegatingStatement.unwrap(mockedStatement.getClass()));
+ assertNull(delegatingStatement.unwrap(String.class));
+ assertTrue(delegatingStatement.isWrapperFor(Statement.class));
+ assertTrue(delegatingStatement.isWrapperFor(DelegatingStatement.class));
+ assertTrue(delegatingStatement.isWrapperFor(mockedStatement.getClass()));
+ assertFalse(delegatingStatement.isWrapperFor(String.class));
}
}
diff --git a/src/test/java/org/apache/commons/dbcp2/TestSQLExceptionList.java b/src/test/java/org/apache/commons/dbcp2/TestSQLExceptionList.java
new file mode 100644
index 0000000..ebb0bd8
--- /dev/null
+++ b/src/test/java/org/apache/commons/dbcp2/TestSQLExceptionList.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.dbcp2;
+
+import java.sql.SQLTransientException;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class TestSQLExceptionList {
+
+ @Test
+ public void testCause() {
+ final SQLTransientException cause = new SQLTransientException();
+ final List<SQLTransientException> list = Collections.singletonList(cause);
+ final SQLExceptionList sqlExceptionList = new SQLExceptionList(list);
+ Assertions.assertEquals(cause, sqlExceptionList.getCause());
+ Assertions.assertEquals(list, sqlExceptionList.getCauseList());
+ sqlExceptionList.printStackTrace();
+ }
+}
diff --git a/src/test/java/org/apache/commons/dbcp2/TesterConnection.java b/src/test/java/org/apache/commons/dbcp2/TesterConnection.java
index 4329b1f..dae4380 100644
--- a/src/test/java/org/apache/commons/dbcp2/TesterConnection.java
+++ b/src/test/java/org/apache/commons/dbcp2/TesterConnection.java
@@ -38,7 +38,8 @@ import java.util.concurrent.Executor;
/**
* A dummy {@link Connection}, for testing purposes.
*/
-public class TesterConnection implements Connection {
+public class TesterConnection extends AbandonedTrace implements Connection {
+
protected boolean _open = true;
protected boolean _autoCommit = true;
protected int _transactionIsolation = 1;
diff --git a/src/test/java/org/apache/commons/dbcp2/TesterPreparedStatement.java b/src/test/java/org/apache/commons/dbcp2/TesterPreparedStatement.java
index 5883cb8..5ee864d 100644
--- a/src/test/java/org/apache/commons/dbcp2/TesterPreparedStatement.java
+++ b/src/test/java/org/apache/commons/dbcp2/TesterPreparedStatement.java
@@ -39,6 +39,7 @@ import java.sql.SQLXML;
* A dummy {@link PreparedStatement}, for testing purposes.
*/
public class TesterPreparedStatement extends TesterStatement implements PreparedStatement {
+
private final ResultSetMetaData _resultSetMetaData = null;
private String _sql = null;
private String _catalog = null;
diff --git a/src/test/java/org/apache/commons/dbcp2/TesterResultSet.java b/src/test/java/org/apache/commons/dbcp2/TesterResultSet.java
index afc4c1e..0d37499 100644
--- a/src/test/java/org/apache/commons/dbcp2/TesterResultSet.java
+++ b/src/test/java/org/apache/commons/dbcp2/TesterResultSet.java
@@ -40,18 +40,16 @@ import java.sql.SQLXML;
/**
* A dummy {@link ResultSet}, for testing purposes.
*/
-public class TesterResultSet implements ResultSet {
+public class TesterResultSet extends AbandonedTrace implements ResultSet {
+
protected int _type = ResultSet.TYPE_FORWARD_ONLY;
-
protected int _concurrency = ResultSet.CONCUR_READ_ONLY;
-
protected Object[][] _data = null;
-
protected int _currentRow = -1;
protected Statement _statement = null;
-
protected int _rowsLeft = 2;
protected boolean _open = true;
+ protected boolean _sqlExceptionOnClose = false;
public TesterResultSet(final Statement stmt) {
_statement = stmt;
@@ -101,6 +99,10 @@ public class TesterResultSet implements ResultSet {
@Override
public void close() throws SQLException {
+ if (_sqlExceptionOnClose) {
+ throw new SQLException("TestSQLExceptionOnClose");
+ }
+
if (!_open) {
return;
}
@@ -641,6 +643,10 @@ public java.sql.Date getDate(final int columnIndex, final Calendar cal) throws S
return _rowsLeft == 0;
}
+ public boolean isSqlExceptionOnClose() {
+ return _sqlExceptionOnClose;
+ }
+
@Override
public boolean isWrapperFor(final Class<?> iface) throws SQLException {
throw new SQLException("Not implemented.");
@@ -720,6 +726,10 @@ public java.sql.Date getDate(final int columnIndex, final Calendar cal) throws S
checkOpen();
}
+ public void setSqlExceptionOnClose(final boolean sqlExceptionOnClose) {
+ this._sqlExceptionOnClose = sqlExceptionOnClose;
+ }
+
@Override
public <T> T unwrap(final Class<T> iface) throws SQLException {
throw new SQLException("Not implemented.");
@@ -742,6 +752,7 @@ public java.sql.Date getDate(final int columnIndex, final Calendar cal) throws S
throw new SQLException("Not implemented.");
}
+
@Override
public void updateAsciiStream(final int columnIndex, final InputStream inputStream, final long length) throws SQLException {
throw new SQLException("Not implemented.");
@@ -754,7 +765,6 @@ public java.sql.Date getDate(final int columnIndex, final Calendar cal) throws S
checkOpen();
}
-
@Override
public void updateAsciiStream(final String columnLabel, final InputStream inputStream) throws SQLException {
throw new SQLException("Not implemented.");
@@ -890,6 +900,7 @@ public java.sql.Date getDate(final int columnIndex, final Calendar cal) throws S
throw new SQLException("Not implemented.");
}
+
@Override
public void updateCharacterStream(final int columnIndex, final Reader reader, final long length) throws SQLException {
throw new SQLException("Not implemented.");
@@ -902,7 +913,6 @@ public java.sql.Date getDate(final int columnIndex, final Calendar cal) throws S
checkOpen();
}
-
@Override
public void updateCharacterStream(final String columnLabel, final Reader reader) throws SQLException {
throw new SQLException("Not implemented.");
@@ -1175,13 +1185,13 @@ public java.sql.Date getDate(final int columnIndex, final Calendar cal) throws S
public void updateTimestamp(final int columnIndex, final java.sql.Timestamp x) throws SQLException {
checkOpen();
}
-
+
@Override
public void updateTimestamp(final String columnName, final java.sql.Timestamp x)
throws SQLException {
checkOpen();
}
-
+
@Override
public boolean wasNull() throws SQLException {
checkOpen();
diff --git a/src/test/java/org/apache/commons/dbcp2/TesterStatement.java b/src/test/java/org/apache/commons/dbcp2/TesterStatement.java
index 99cc9f9..5a70f64 100644
--- a/src/test/java/org/apache/commons/dbcp2/TesterStatement.java
+++ b/src/test/java/org/apache/commons/dbcp2/TesterStatement.java
@@ -26,13 +26,11 @@ import java.sql.Statement;
/**
* A dummy {@link Statement}, for testing purposes.
*/
-public class TesterStatement implements Statement {
+public class TesterStatement extends AbandonedTrace implements Statement {
+
protected Connection _connection = null;
-
protected boolean _open = true;
-
protected long _rowsUpdated = 1;
-
protected boolean _executeResponse = true;
protected int _maxFieldSize = 1024;
protected long _maxRows = 1024;
@@ -45,15 +43,18 @@ public class TesterStatement implements Statement {
protected int _resultSetType = 1;
private int _resultSetHoldability = 1;
protected ResultSet _resultSet = null;
+ protected boolean _sqlExceptionOnClose = false;
public TesterStatement(final Connection conn) {
_connection = conn;
}
+
public TesterStatement(final Connection conn, final int resultSetType, final int resultSetConcurrency) {
_connection = conn;
_resultSetType = resultSetType;
_resultSetConcurrency = resultSetConcurrency;
}
+
public TesterStatement(final Connection conn, final int resultSetType, final int resultSetConcurrency,
final int resultSetHoldability) {
_connection = conn;
@@ -90,6 +91,10 @@ public class TesterStatement implements Statement {
@Override
public void close() throws SQLException {
+ if (_sqlExceptionOnClose) {
+ throw new SQLException("TestSQLExceptionOnClose");
+ }
+
// calling close twice has no effect
if (!_open) {
return;
@@ -331,6 +336,10 @@ public class TesterStatement implements Statement {
throw new SQLException("Not implemented.");
}
+ public boolean isSqlExceptionOnClose() {
+ return _sqlExceptionOnClose;
+ }
+
@Override
public boolean isWrapperFor(final Class<?> iface) throws SQLException {
throw new SQLException("Not implemented.");
@@ -389,6 +398,10 @@ public class TesterStatement implements Statement {
_queryTimeout = seconds;
}
+ public void setSqlExceptionOnClose(final boolean _sqlExceptionOnClose) {
+ this._sqlExceptionOnClose = _sqlExceptionOnClose;
+ }
+
@Override
public <T> T unwrap(final Class<T> iface) throws SQLException {
throw new SQLException("Not implemented.");