You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by da...@apache.org on 2006/03/23 20:06:08 UTC
svn commit: r388234 - in /db/derby/code/trunk/java:
client/org/apache/derby/client/am/ engine/org/apache/derby/impl/jdbc/
testing/org/apache/derbyTesting/functionTests/suites/
testing/org/apache/derbyTesting/functionTests/tests/jdbc4/
Author: davidvc
Date: Thu Mar 23 11:06:05 2006
New Revision: 388234
URL: http://svn.apache.org/viewcvs?rev=388234&view=rev
Log:
DERBY-953: Add Statement.isClosed() JDBC4 method
DERBY-1097: Add tests for Statement.isClosed() JDBC4 method
Contributed by Kristian Waagan.
I modified his patch for DERBY-953 to match
Dan's suggested approach. I also added StatementTest.junit to the jdbc40
test suite, which passes. Since this is a JDBC40-specific feature, and
only new code has been added (no existing code has been modified) I did
not run derbyall
Added:
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementTest.java (with props)
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementTestSetup.java (with props)
Modified:
db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc40.runall
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java?rev=388234&r1=388233&r2=388234&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java Thu Mar 23 11:06:05 2006
@@ -463,6 +463,24 @@
}
}
+ /**
+ * Tell whether the statement has been closed or not.
+ *
+ * @return <code>true</code> if closed, <code>false</code> otherwise.
+ * @exception SQLException if a database access error occurs (according to
+ * spec). Never thrown by this implementation.
+ */
+ public boolean isClosed()
+ throws SQLException {
+ if (agent_.loggingEnabled()) {
+ agent_.logWriter_.traceEntry(this, "isClosed", !openOnClient_);
+ }
+ if (agent_.loggingEnabled()) {
+ agent_.logWriter_.traceExit(this, "isClosed", !openOnClient_);
+ }
+ return !openOnClient_;
+ }
+
// The server holds statement resources until transaction end.
public void close() throws SQLException {
try
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java?rev=388234&r1=388233&r2=388234&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java Thu Mar 23 11:06:05 2006
@@ -234,6 +234,23 @@
}
/**
+ * Tell whether this statment has been closed or not.
+ *
+ * @return <code>true</code> is closed, <code>false</code> otherwise.
+ * @exception SQLException if a database access error occurs.
+ */
+ public boolean isClosed() throws SQLException {
+ // If active, verify state by consulting parent connection.
+ if (active) {
+ try {
+ checkExecStatus();
+ } catch (SQLException sqle) {
+ }
+ }
+ return !active;
+ }
+
+ /**
* In many cases, it is desirable to immediately release a
* Statements's database and JDBC resources instead of waiting for
* this to happen when it is automatically closed; the close
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc40.runall
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc40.runall?rev=388234&r1=388233&r2=388234&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc40.runall (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc40.runall Thu Mar 23 11:06:05 2006
@@ -5,3 +5,4 @@
jdbc4/TestQueryObject.java
jdbc4/TestDbMetaData.java
jdbc4/TestJDBC40Exception.java
+jdbc4/StatementTest.junit
Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementTest.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementTest.java?rev=388234&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementTest.java Thu Mar 23 11:06:05 2006
@@ -0,0 +1,242 @@
+/*
+ *
+ * Derby - Class StatementTest
+ *
+ * Copyright 2006 The Apache Software Foundation or its
+ * licensors, as applicable.
+ *
+ * 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.derbyTesting.functionTests.tests.jdbc4;
+
+import org.apache.derby.shared.common.reference.SQLState;
+import org.apache.derbyTesting.functionTests.util.BaseJDBCTestCase;
+
+import junit.framework.*;
+
+import java.sql.*;
+
+/**
+ * Tests for new methods added for Statement in JDBC4.
+ */
+public class StatementTest
+ extends BaseJDBCTestCase {
+
+ /** Default connection used by the tests. */
+ private Connection con = null;
+ /** Default statement used by the tests. */
+ private Statement stmt = null;
+
+ /**
+ * Create a new test with the given name.
+ *
+ * @param name name of the test.
+ */
+ public StatementTest(String name) {
+ super(name);
+ }
+
+ /**
+ * Create default connection and statement.
+ *
+ * @throws SQLException if setAutoCommit, createStatement or
+ * BaseJDBCTestCase.getConnection fails.
+ */
+ public void setUp()
+ throws SQLException {
+ con = getConnection();
+ assertFalse("Connection must be open initially", con.isClosed());
+ con.setAutoCommit(false);
+ // Create a default statement.
+ stmt = con.createStatement();
+ assertFalse("First statement must be open initially",
+ stmt.isClosed());
+ }
+
+ /**
+ * Close default connection and statement if necessary.
+ *
+ * @throws SQLException if a database access exception occurs.
+ */
+ public void tearDown()
+ throws SQLException {
+ // Close default statement
+ if (stmt != null) {
+ stmt.close();
+ }
+ // Close default connection
+ // Check if connection is open to avoid exception on rollback.
+ if (con != null && !con.isClosed()) {
+ // Abort changes that may have been done in the test.
+ // The test-method may however commit these itself.
+ con.rollback();
+ con.close();
+ }
+ }
+
+ /**
+ * Check that <code>isClosed</code> returns <code>true</code> after
+ * the statement has been explicitly closed.
+ */
+ public void testIsClosedBasic()
+ throws SQLException {
+ ResultSet rs = stmt.executeQuery("select count(*) from stmtTable");
+ assertFalse("Statement should still be open", stmt.isClosed());
+ rs.close();
+ assertFalse("Statement should be open after ResultSet has been " +
+ "closed", stmt.isClosed());
+ stmt.close();
+ assertTrue("Statement should be closed, close() has been called",
+ stmt.isClosed());
+ }
+
+ /**
+ * Test that creating two statements on the same connection does not
+ * cause side effects on the statements.
+ */
+ public void testIsClosedWithTwoStatementsOnSameConnection()
+ throws SQLException {
+ // Create a second statement on the default connection.
+ Statement stmt2 = con.createStatement();
+ assertFalse("Second statement must be open initially",
+ stmt2.isClosed());
+ assertFalse("First statement should not be closed when " +
+ "creating a second statement", stmt.isClosed());
+ ResultSet rs = stmt2.executeQuery("select count(*) from stmtTable");
+ assertFalse("Second statement should be open after call to " +
+ "execute()", stmt2.isClosed());
+ assertFalse("First statement should be open after call to " +
+ "second statment's execute()", stmt.isClosed());
+ stmt2.close();
+ assertTrue("Second statement should be closed, close() has " +
+ "been called!", stmt2.isClosed());
+ assertFalse("First statement should be open after call to " +
+ "second statment's close()", stmt.isClosed());
+ }
+
+ /**
+ * Test that the two statements created on the connection are closed
+ * when the connection itself is closed.
+ */
+ public void testIsClosedWhenClosingConnection()
+ throws SQLException {
+ // Create an extra statement for good measure.
+ Statement stmt2 = con.createStatement();
+ assertFalse("Second statement must be open initially",
+ stmt2.isClosed());
+ // Exeute something on it, as opposed to the default statement.
+ stmt2.execute("select count(*) from stmtTable");
+ assertFalse("Second statement should be open after call to " +
+ "execute()", stmt2.isClosed());
+ // Close the connection. We must commit/rollback first, or else a
+ // "Invalid transaction state" exception is raised.
+ con.rollback();
+ con.close();
+ assertTrue("Connection should be closed after close()",
+ con.isClosed());
+ assertTrue("First statement should be closed, as parent " +
+ "connection has been closed", stmt.isClosed());
+ assertTrue("Second statement should be closed, as parent " +
+ "connection has been closed", stmt2.isClosed());
+ }
+
+ /**
+ * Check the state of the statement when the connection is first attempted
+ * closed when in an invalid transaction state, then closed after a
+ * commit. According to the JDBC 4 API documentation: </i>"It is strongly
+ * recommended that an application explictly commits or rolls back an
+ * active transaction prior to calling the close method. If the close
+ * method is called and there is an active transaction,
+ * the results are implementation-defined."</i>
+ * Derby throws an exception and keeps the connection open.
+ */
+ public void testIsClosedWhenClosingConnectionInInvalidState()
+ throws SQLException {
+ stmt.executeQuery("select count(*) from stmtTable");
+ // Connection should now be in an invalid transaction state.
+ try {
+ con.close();
+ fail("Invalid transaction state exception was not thrown");
+ } catch (SQLException sqle) {
+ if (usingEmbedded()) {
+ assertEquals("Unexpected exception thrown: " + sqle.getMessage(),
+ SQLState.LANG_INVALID_TRANSACTION_STATE,
+ sqle.getSQLState());
+ } else {
+ // TODO: Compare with SQLState when implemented on the client side.
+ assertEquals("Unexpected exception thrown: " + sqle.getMessage(),
+ "java.sql.Connection.close() requested while a " +
+ "transaction is in progress on the connection.The " +
+ "transaction remains active, and the connection " +
+ "cannot be closed.",
+ sqle.getMessage());
+ }
+ }
+ assertFalse("Statement should still be open, because " +
+ "Connection.close() failed", stmt.isClosed());
+ assertFalse("Connection should still be open", con.isClosed());
+ // Do a commit here, since we do a rollback in another test.
+ con.commit();
+ con.close();
+ assertTrue("Connection should be closed after close()",
+ con.isClosed());
+ assertTrue("Statement should be closed, because " +
+ "the connection has been closed", stmt.isClosed());
+ stmt.close();
+ assertTrue("Statement should still be closed", stmt.isClosed());
+ }
+
+ /**
+ * Execute a query on a statement after the parent connection has been
+ * closed.
+ */
+ public void testStatementExecuteAfterConnectionClose()
+ throws SQLException {
+ con.close();
+ assertTrue("Connection should be closed after close()",
+ con.isClosed());
+ try {
+ stmt.executeQuery("select count(*) from stmtTable");
+ } catch (SQLException sqle) {
+ // Different error messages are returned for embedded and client.
+ if (usingEmbedded()) {
+ assertEquals("Unexpected SQL state for performing " +
+ "operations on a closed statement.",
+ SQLState.NO_CURRENT_CONNECTION,
+ sqle.getSQLState());
+ } else {
+ // TODO: Compare with SQLState when implemented on client side.
+ assertEquals("Unexpected SQL state for performing " +
+ "operations on a closed statement.",
+ "Invalid operation: statement closed",
+ sqle.getMessage());
+ }
+ }
+ assertTrue("Statement should be closed, because " +
+ "the connection has been closed", stmt.isClosed());
+ }
+
+ /**
+ * Create test suite for StatementTest.
+ */
+ public static Test suite() {
+ TestSuite suite = new TestSuite("StatementTest suite");
+ // Decorate test suite with a TestSetup class.
+ suite.addTest(new StatementTestSetup(
+ new TestSuite(StatementTest.class)));
+
+ return suite;
+ }
+
+} // End class StatementTest
Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementTestSetup.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementTestSetup.java?rev=388234&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementTestSetup.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementTestSetup.java Thu Mar 23 11:06:05 2006
@@ -0,0 +1,101 @@
+/*
+ *
+ * Derby - Class StatementTestSetup
+ *
+ * Copyright 2006 The Apache Software Foundation or its
+ * licensors, as applicable.
+ *
+ * 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.derbyTesting.functionTests.tests.jdbc4;
+
+import org.apache.derbyTesting.functionTests.util.BaseJDBCTestCase;
+
+import junit.framework.Test;
+import junit.extensions.TestSetup;
+
+import java.sql.*;
+
+/**
+ * Create the table necessary for running {@link StatementTest}.
+ *
+ * @see StatementTest
+ */
+public class StatementTestSetup
+ extends TestSetup {
+
+ /**
+ * Initialize database schema.
+ * Uses the framework specified by the test harness.
+ *
+ * @see StatementTest
+ */
+ public StatementTestSetup(Test test) {
+ super(test);
+ }
+
+ /**
+ * Create the table and data needed for the test.
+ *
+ * @throws SQLException if database operations fail.
+ *
+ * @see StatementTest
+ */
+ public void setUp()
+ throws SQLException {
+ Connection con = BaseJDBCTestCase.getConnection();
+ // Create tables used by the test.
+ Statement stmt = con.createStatement();
+ // See if the table is already there, and if so, delete it.
+ try {
+ stmt.execute("select count(*) from stmtTable");
+ // Only get here is the table already exists.
+ stmt.execute("drop table stmtTable");
+ } catch (SQLException sqle) {
+ // Table does not exist, so we can go ahead and create it.
+ assertEquals("Unexpected error when accessing non-existing table.",
+ "42X05",
+ sqle.getSQLState());
+ }
+ stmt.execute("create table stmtTable (id int, val varchar(10))");
+ stmt.execute("insert into stmtTable values (1, 'one'),(2,'two')");
+ // Check just to be sure, and to notify developers if the database
+ // contents are changed at a later time.
+ ResultSet rs = stmt.executeQuery("select count(*) from stmtTable");
+ rs.next();
+ assertEquals("Number of rows are not as expected",
+ 2, rs.getInt(1));
+ rs.close();
+ stmt.close();
+ con.commit();
+ con.close();
+ }
+
+ /**
+ * Clean up after the tests.
+ * Deletes the table that was created for the tests.
+ *
+ * @throws SQLException if database operations fail.
+ */
+ public void tearDown()
+ throws SQLException {
+ Connection con = BaseJDBCTestCase.getConnection();
+ Statement stmt = con.createStatement();
+ stmt.execute("drop table stmtTable");
+ stmt.close();
+ con.commit();
+ con.close();
+ }
+
+} // End class StatementTestSetup
Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementTestSetup.java
------------------------------------------------------------------------------
svn:eol-style = native