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 rh...@apache.org on 2006/04/22 00:50:26 UTC

svn commit: r396028 - in /db/derby/code/trunk/java: client/org/apache/derby/client/net/NetConnection40.java testing/org/apache/derbyTesting/functionTests/tests/jdbc4/TestConnectionMethods.java

Author: rhillegas
Date: Fri Apr 21 15:50:25 2006
New Revision: 396028

URL: http://svn.apache.org/viewcvs?rev=396028&view=rev
Log:
DERBY-1090: Olav's patch to enable Connection.isValid() in the network client.

Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection40.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/TestConnectionMethods.java

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection40.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection40.java?rev=396028&r1=396027&r2=396028&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection40.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection40.java Fri Apr 21 15:50:25 2006
@@ -28,6 +28,8 @@
 import java.sql.ClientInfoException;
 import java.sql.Clob;
 import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.SQLXML;
 import java.util.Properties;
@@ -37,7 +39,13 @@
 import org.apache.derby.shared.common.reference.SQLState;
 
 public class  NetConnection40 extends org.apache.derby.client.net.NetConnection {
-    
+    /**
+     * Prepared statement that is used each time isValid() is called on this
+     * connection. The statement is created the first time isValid is called
+     * and closed when the connection is closed (by the close call).
+     */
+    private PreparedStatement isValidStmt = null;
+
     /*
      *-------------------------------------------------------
      * JDBC 4.0 
@@ -117,10 +125,71 @@
         throw SQLExceptionFactory.notImplemented ("createSQLXML ()");
     }
 
+    /**
+     * Checks if the connection has not been closed and is still valid. 
+     * The validity is checked by running a simple query against the 
+     * database.
+     *
+     * @param timeout The time in seconds to wait for the database
+     * operation used to validate the connection to complete. If the 
+     * timeout period expires before the operation completes, this 
+     * method returns false. A value of 0 indicates a timeout is not 
+     * applied to the database operation.
+     * @return true if the connection is valid, false otherwise
+     * @exception SQLException if the parameter value is illegal or if a
+     * database error has occured
+     */
     public boolean isValid(int timeout) throws SQLException {
-        throw SQLExceptionFactory.notImplemented ("isValid ()");
+        // Validate that the timeout has a legal value
+        if (timeout < 0) {
+            throw Util.generateCsSQLException(SQLState.INVALID_API_PARAMETER,
+                                              new Integer(timeout), "timeout",
+                                              "java.sql.Connection.isValid");
+        }
+
+        // Check if the connection is closed
+        if (isClosed()) {
+            return false;
+        }
+
+        // Do a simple query against the database
+        synchronized(this) {
+            try {
+                // If this is the first time this method is called on this 
+                // connection we prepare the query 
+                if (isValidStmt == null) {
+                    isValidStmt = prepareStatement("VALUES (1)");
+                }
+
+                // Set the query timeout
+                isValidStmt.setQueryTimeout(timeout);
+
+                // Run the query against the database
+                ResultSet rs = isValidStmt.executeQuery();
+                rs.close();
+            } catch(SQLException e) {
+                // If an SQL exception is thrown the connection is not valid,
+                // we ignore the exception and return false.
+                return false;
+            }
+	 }
+
+        return true;  // The connection is valid
     }
 
+    /**
+     * Close the connection and release its resources. 
+     * @exception SQLException if a database-access error occurs.
+     */
+    synchronized public void close() throws SQLException {
+        // Release resources owned by the prepared statement used by isValid
+        if (isValidStmt != null) {
+            isValidStmt.close();
+            isValidStmt = null;
+        }
+        super.close();
+    }
+   
     public void setClientInfo(String name, String value)
 		throws SQLException{
 	throw SQLExceptionFactory.notImplemented ("setClientInfo (String, String)");

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/TestConnectionMethods.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/TestConnectionMethods.java?rev=396028&r1=396027&r2=396028&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/TestConnectionMethods.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/TestConnectionMethods.java Fri Apr 21 15:50:25 2006
@@ -26,6 +26,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.InetAddress;
 import java.sql.Blob;
 import java.sql.Clob;
 import java.sql.Connection;
@@ -38,9 +39,11 @@
 import java.sql.Statement;
 import java.util.Properties;
 import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.drda.NetworkServerControl;
 import org.apache.derby.tools.ij;
 import org.apache.derby.shared.common.reference.SQLState;
 import org.apache.derbyTesting.functionTests.util.SQLStateConstants;
+import org.apache.derbyTesting.functionTests.util.TestUtil;
 
 /**
  * This class is used to test the implementations of the JDBC 4.0 methods
@@ -183,10 +186,9 @@
     }
 
     /**
-     * Test the Connection.isValid method in the embedded driver.
+     * Test the Connection.isValid method
      */
-    void t_isValid_Embed() {
-
+    void t_isValid() {
         /*
          * Test illegal parameter values
          */
@@ -243,9 +245,7 @@
                                "Unexpected exception: " + e);
         }
 
-        /*
-         * Open a new connection and test it
-         */
+        /* Open a new connection and test it */
         try {
             conn = ij.startJBMS();
         } catch (Exception e) {
@@ -264,17 +264,11 @@
         }
 
         /*
-         * Test on stopped DB: stop Derby
+         * Test on stopped database
          */
-        try {
-            DriverManager.getConnection("jdbc:derby:;shutdown=true");
-        } catch(SQLException e) {
-            // Ignore any exceptions from shutdown
-        }
+        shutdownDatabase();
 
-        /*
-         * Test if the connection is still valid
-         */
+        /* Test if that connection is not valid */
         try {
             if (conn.isValid(0)) {
                 System.out.println("FAIL: isValid(0) on stopped database: " + 
@@ -285,16 +279,15 @@
                                "Unexpected exception: " + e);
         } 
 
-        /*
-         * Start Derby by getting a new connection and check that
-         * the new connection is valid.
-         */
+        /* Start the database by getting a new connection to it */
         try {
             conn = ij.startJBMS();
         } catch (Exception e) {
             System.out.println("FAIL: failed to re-start database: " +
                                "Unexpected exception: " + e);
         }
+
+        /* Check that a new connection to the newly started database is valid */
         try {
             if (!conn.isValid(0)) {
                 System.out.println("FAIL: isValid(0) on new connection: " + 
@@ -304,22 +297,52 @@
             System.out.println("FAIL: isValid(0) on new connection: " + 
                                "Unexpected exception: " + e);
         }
-    }
 
-    void t_isValid_Client() {
-        boolean ret;
-        try {
-            ret = conn.isValid(0);
-            System.out.println("unimplemented exception not thrown in code");
-        } catch(SQLException e) {
-            if(SQLState.NOT_IMPLEMENTED.equals (e.getSQLState())) {
-                System.out.println("Unexpected SQLException"+e);
+        /*
+         * Test on stopped Network Server client
+         */
+        if ( !usingEmbeddedClient() ) {
+            stopNetworkServer();
+
+            /* Test that the connection is not valid */
+            try {
+                if (conn.isValid(0)) {
+                    System.out.println("FAIL: isValid(0) on stopped database: " +
+                                      "returned true");
+                }
+            } catch(Exception e) {
+                System.out.println("FAIL: isValid(0) on a stopped database: " + 
+                                   "Unexpected exception: " + e);
+            } 
+
+            /*
+             * Start the network server and get a new connection and check that
+             * the new connection is valid.
+             */
+            startNetworkServer();
+
+            try {
+                // Get a new connection to the database
+                conn = ij.startJBMS();
+            } catch (Exception e) {
+                System.out.println("FAIL: failed to re-start database: " +
+                                   "Unexpected exception: " + e);
+                e.printStackTrace();
+            }
+
+            /* Check that a new connection to the newly started Derby is valid */
+            try {
+                if (!conn.isValid(0)) {
+                    System.out.println("FAIL: isValid(0) on new connection: " + 
+                                       "returned false");
+                }
+            } catch(Exception e) {
+                System.out.println("FAIL: isValid(0) on new connection: " + 
+                                  "Unexpected exception: " + e);
             }
-        } catch(Exception e) {
-            System.out.println("Unexpected exception caught in function"+e);
         }
     }
-    
+
     void t_setClientInfo1(){
         try {
             conn.setClientInfo("prop1","value1");
@@ -435,7 +458,7 @@
         t_createBlob_Client();
         t_createNClob();
         t_createSQLXML();
-        t_isValid_Client();
+        t_isValid();
         t_setClientInfo1();
         t_setClientInfo2();
         t_getClientInfo1();
@@ -448,13 +471,96 @@
         t_createBlob();
         t_createNClob();
         t_createSQLXML();
-        t_isValid_Embed();
+        t_isValid();
         t_setClientInfo1();
         t_setClientInfo2();
         t_getClientInfo1();
         t_getClientInfo2();
         t_wrapper();
     }
+
+    /**
+     * Shut down the test database
+     */
+    private void shutdownDatabase() {
+        try {
+            // Get the name for the database from the test's property file
+            String databaseName = System.getProperty("ij.dataSource.databaseName");
+            if (databaseName != null) {
+                TestUtil.getConnection(databaseName, "shutdown=true");
+            }
+            else {
+                System.out.println("FAIL: shutdownDatabase: " +
+                           "property ij.dataSource.databaseName not defined");
+            }
+	 } catch (Exception e) {
+            // Ignore any exeptions from shutdown
+	 }
+    }
+
+
+    /**
+     * Stop the network server
+     */
+    private void stopNetworkServer() {
+        try {
+            NetworkServerControl networkServer = new NetworkServerControl();
+            networkServer.shutdown();
+        } catch(Exception e) {
+            System.out.println("INFO: Network server shutdown returned: " + e);
+        }
+    }
+
+
+    /**
+     * Start the network server
+     */
+    private void startNetworkServer() {
+        String hostName = null;
+        int serverPort;
+
+        // Determines which host and port to run the network server on
+        // This is based how it is done in the test testSecMec.java
+        String serverName = TestUtil.getHostName();
+        if (serverName.equals("localhost")) {
+            serverPort = 1527;
+        }
+        else {
+            serverPort = 20000;
+        }
+
+        try {
+            NetworkServerControl networkServer = 
+                     new NetworkServerControl(InetAddress.getByName(serverName), 
+                                              serverPort);
+            networkServer.start(null);
+
+            // Wait for the network server to start
+            boolean started = false;
+            int retries = 10;         // Max retries = max seconds to wait
+            while (!started && retries > 0) {
+                try {
+                    // Sleep 1 second and then ping the network server
+		      Thread.sleep(1000);
+                    networkServer.ping();
+
+                    // If ping does not throw an exception the server has started
+                    started = true;
+                } catch(Exception e) {
+                    System.out.println("INFO: ping returned: " + e);
+                    retries--;
+	         }
+	     }
+
+            // Check if we got a reply on ping
+            if (!started) {
+                System.out.println("FAIL: Failed to start network server");
+            }
+        } catch (Exception e) {
+            System.out.println("FAIL: startNetworkServer got exception: " + e);
+        }
+    }
+
 
 	/**
 	 * <p>