IGNITE-5344: JDBC thin driver: support Statement.closeOnCompletion. This closes #2131.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3a917572 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3a917572 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3a917572 Branch: refs/heads/ignite-5896 Commit: 3a917572c9732795d1c027721d79a1a271e3f4cc Parents: d6cbc50 Author: tledkov-gridgain <[email protected]> Authored: Tue Sep 5 18:12:53 2017 +0300 Committer: devozerov <[email protected]> Committed: Tue Sep 5 18:12:53 2017 +0300 ---------------------------------------------------------------------- .../jdbc/thin/JdbcThinStatementSelfTest.java | 62 +++++++++++++++++++- .../internal/jdbc/thin/JdbcThinResultSet.java | 29 ++++++++- .../internal/jdbc/thin/JdbcThinStatement.java | 22 ++++--- 3 files changed, 101 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/3a917572/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java index 92f7255..a6046be 100644 --- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java @@ -300,6 +300,64 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest { } /** + * @throws Exception If failed. + */ + public void testCloseOnCompletionAfterQuery() throws Exception { + assert !stmt.isCloseOnCompletion() : "Invalid default closeOnCompletion"; + + ResultSet rs0 = stmt.executeQuery(SQL); + + ResultSet rs1 = stmt.executeQuery(SQL); + + assert rs0.isClosed() : "Result set must be closed implicitly"; + + assert !stmt.isClosed() : "Statement must not be closed"; + + rs1.close(); + + assert !stmt.isClosed() : "Statement must not be closed"; + + ResultSet rs2 = stmt.executeQuery(SQL); + + stmt.closeOnCompletion(); + + assert stmt.isCloseOnCompletion() : "Invalid closeOnCompletion"; + + rs2.close(); + + assert stmt.isClosed() : "Statement must be closed"; + } + + /** + * @throws Exception If failed. + */ + public void testCloseOnCompletionBeforeQuery() throws Exception { + assert !stmt.isCloseOnCompletion() : "Invalid default closeOnCompletion"; + + ResultSet rs0 = stmt.executeQuery(SQL); + + ResultSet rs1 = stmt.executeQuery(SQL); + + assert rs0.isClosed() : "Result set must be closed implicitly"; + + assert !stmt.isClosed() : "Statement must not be closed"; + + rs1.close(); + + assert !stmt.isClosed() : "Statement must not be closed"; + + stmt.closeOnCompletion(); + + ResultSet rs2 = stmt.executeQuery(SQL); + + assert stmt.isCloseOnCompletion() : "Invalid closeOnCompletion"; + + rs2.close(); + + assert stmt.isClosed() : "Statement must be closed"; + } + + /** * Person. */ @SuppressWarnings("UnusedDeclaration") @@ -309,11 +367,11 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest { private final int id; /** First name. */ - @QuerySqlField(index = false) + @QuerySqlField private final String firstName; /** Last name. */ - @QuerySqlField(index = false) + @QuerySqlField private final String lastName; /** Age. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/3a917572/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java index c4be5bc..9457b30 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java @@ -100,6 +100,9 @@ public class JdbcThinResultSet implements ResultSet { /** Update count. */ private long updCnt; + /** Close statement after close result set count. */ + private boolean closeStmt; + /** Jdbc metadata. Cache the JDBC object on the first access */ private JdbcThinResultSetMetadata jdbcMeta; @@ -139,10 +142,11 @@ public class JdbcThinResultSet implements ResultSet { * @param isQuery Is Result ser for Select query. * @param autoClose Is automatic close of server cursors enabled. * @param updCnt Update count. + * @param closeStmt Close statement on the result set close. */ @SuppressWarnings("OverlyStrongTypeCast") JdbcThinResultSet(JdbcThinStatement stmt, long qryId, int fetchSize, boolean finished, - List<List<Object>> rows, boolean isQuery, boolean autoClose, long updCnt) { + List<List<Object>> rows, boolean isQuery, boolean autoClose, long updCnt, boolean closeStmt) { assert stmt != null; assert fetchSize > 0; @@ -152,6 +156,7 @@ public class JdbcThinResultSet implements ResultSet { this.finished = finished; this.isQuery = isQuery; this.autoClose = autoClose; + this.closeStmt = closeStmt; if (isQuery) { this.fetchSize = fetchSize; @@ -208,7 +213,17 @@ public class JdbcThinResultSet implements ResultSet { /** {@inheritDoc} */ @Override public void close() throws SQLException { - if (closed || stmt == null || stmt.connection().isClosed()) + if (closeStmt) + stmt.close(); + + close0(); + } + + /** + * @throws SQLException On error. + */ + void close0() throws SQLException { + if (isClosed()) return; try { @@ -1259,7 +1274,7 @@ public class JdbcThinResultSet implements ResultSet { /** {@inheritDoc} */ @Override public boolean isClosed() throws SQLException { - return stmt.isClosed() || closed; + return closed || stmt == null || stmt.connection().isClosed(); } /** {@inheritDoc} */ @@ -1557,6 +1572,7 @@ public class JdbcThinResultSet implements ResultSet { } /** {@inheritDoc} */ + @SuppressWarnings("unchecked") @Override public <T> T unwrap(Class<T> iface) throws SQLException { if (!isWrapperFor(iface)) throw new SQLException("Result set is not a wrapper for " + iface.getName()); @@ -1723,6 +1739,13 @@ public class JdbcThinResultSet implements ResultSet { } /** + * @param closeStmt Close statement on this result set close. + */ + void closeStatement(boolean closeStmt) { + this.closeStmt = closeStmt; + } + + /** * @param val Number value. * @return Boolean value. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/3a917572/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java index 59a9db0..59594ec 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java @@ -64,12 +64,15 @@ public class JdbcThinStatement implements Statement { /** Fetch size. */ private int pageSize = DFLT_PAGE_SIZE; - /** */ + /** Result set or update count has been already read. */ private boolean alreadyRead; /** Batch. */ protected List<JdbcQuery> batch; + /** Close this statement on result set close. */ + private boolean closeOnCompletion; + /** * Creates new statement. * @@ -103,7 +106,7 @@ public class JdbcThinStatement implements Statement { ensureNotClosed(); if (rs != null) { - rs.close(); + rs.close0(); rs = null; } @@ -120,7 +123,7 @@ public class JdbcThinStatement implements Statement { assert res != null; rs = new JdbcThinResultSet(this, res.getQueryId(), pageSize, res.last(), res.items(), - res.isQuery(), conn.io().autoCloseServerCursor(), res.updateCount()); + res.isQuery(), conn.io().autoCloseServerCursor(), res.updateCount(), closeOnCompletion); } catch (IOException e) { conn.close(); @@ -150,7 +153,7 @@ public class JdbcThinStatement implements Statement { return; if (rs != null) - rs.close(); + rs.close0(); closed = true; } @@ -349,7 +352,7 @@ public class JdbcThinStatement implements Statement { ensureNotClosed(); if (rs != null) { - rs.close(); + rs.close0(); rs = null; } @@ -497,14 +500,19 @@ public class JdbcThinStatement implements Statement { /** {@inheritDoc} */ @Override public void closeOnCompletion() throws SQLException { - throw new SQLFeatureNotSupportedException("closeOnCompletion is not supported."); + ensureNotClosed(); + + closeOnCompletion = true; + + if (rs != null) + rs.closeStatement(true); } /** {@inheritDoc} */ @Override public boolean isCloseOnCompletion() throws SQLException { ensureNotClosed(); - return false; + return closeOnCompletion; } /**
