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 ka...@apache.org on 2006/04/25 14:22:46 UTC

svn commit: r396859 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/jdbc/ engine/org/apache/derby/jdbc/ testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ testing/org/apache/derbyTesting/functionTests/util/

Author: kahatlen
Date: Tue Apr 25 05:22:08 2006
New Revision: 396859

URL: http://svn.apache.org/viewcvs?rev=396859&view=rev
Log:
DERBY-941 (partial): Add JDBC4 support for Statement Events

a) provide the imlementation for StatementEventListener methods in
   EmbedXAConnection40
b) Modify TestUtil.java to return EmbedXADataSource40 when running
   with mustang
c) remove testing for LSE_COMPILATION_PREFIX as the prefix for the
   SQLState when throwing the Statement Error Occurred events.

Patch contributed by V. Narayanan <V....@Sun.COM>.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java
    db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAConnection40.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementEventsTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/TestUtil.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java?rev=396859&r1=396858&r2=396859&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java Tue Apr 25 05:22:08 2006
@@ -205,14 +205,32 @@
 
 
 	/**
-		Additional close to close our activation.
-
-		@exception SQLException	thrown on failure
+	 * Additional close to close our activation.
+	 * In the case that a XAConnection is involved in the creation of this
+	 * PreparedStatement for e.g in the following case
+	 *
+	 *      <code>
+	 *      XAConnection xaconn = xadatasource.getXAConnection();//where xadatasource is an object of XADataSource
+	 *      Connection conn = xaconnection.getConnection();
+	 *      PreparedStatement ps = conn.preparedStatement("values 1");
+	 *      </code>
+	 *
+	 * In the above case the PreparedStatement will actually be a 
+	 * BrokeredPreparedStatement40 object. Hence when we call 
+	 * bcc.onStatementClose and pass the PreparedStatement that caused it
+	 * applicationStatement will be the appropriate choice since it will 
+	 * contain the appropriate instance of PreparedStatement in each case
+	 *
+	 * @throws SQLException upon failure
+	 *
 	 */
 	void closeActions() throws SQLException {
 
-                if (bcc!=null)
-                        bcc.onStatementClose(this);
+		if (bcc!=null) {
+			java.sql.PreparedStatement ps_app = 
+				(java.sql.PreparedStatement)applicationStatement;
+			bcc.onStatementClose(ps_app);
+		}
 		//we release the resource for preparedStatement
 		preparedStatement = null;
 
@@ -1471,25 +1489,34 @@
          * Method calls onStatementError occurred on the 
          * BrokeredConnectionControl class after checking the 
          * SQLState of the SQLException thrown.
+         *
+         * In the case that a XAConnection is involved in the creation of this
+         * PreparedStatement for e.g in the following case
+         *
+         *      <code>
+         *      XAConnection xaconn = xadatasource.getXAConnection();//where xadatasource is an object of XADataSource
+         *      Connection conn = xaconnection.getConnection();
+         *      PreparedStatement ps = conn.preparedStatement("values 1");
+         *      </code>
+         *
+         * In the above case the PreparedStatement will actually be a 
+         * BrokeredPreparedStatement40 object. Hence when we call 
+         * bcc.onStatementClose and pass the PreparedStatement that caused it
+         * applicationStatement will be the appropriate choice since it will 
+         * contain the appropriate instance of PreparedStatement in each case
+         *
          */
         
         private void checkStatementValidity(SQLException sqle) throws SQLException {
             /*
-             * The subclass of SQLException thrown when the SQLState class value is
-             * '42'. This indicates that the in-progress query has violated SQL
-             * syntax rules.
-             *
              * Check if the exception has occurred because the connection
              * associated with the PreparedStatement has been closed
-             *
-             * This exception has the SQLState of 08003 which is represented
-             * by the constant SQLState.ERROR_CLOSE
              */
-            if(bcc != null && (sqle.getSQLState().equals("08003")
-            || sqle.getSQLState().startsWith(SQLState.LSE_COMPILATION_PREFIX)) ) {
+            if(bcc != null && isClosed()) {
                 //call the BrokeredConnectionControl interface method
                 //onStatementErrorOccurred
-                bcc.onStatementErrorOccurred(this,sqle);
+                bcc.onStatementErrorOccurred((java.sql.PreparedStatement)
+                                                applicationStatement,sqle);
             }
             throw sqle;
         }

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=396859&r1=396858&r2=396859&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 Tue Apr 25 05:22:08 2006
@@ -68,8 +68,12 @@
      * this Statement. Normally set to this, but if this was
      * created by a Connection from an XAConnection then this
      * will be a reference to the BrokeredStatement.
+     *
+     * Making it protected to allow access from EmbedPreparedStatement40
+     * to be used for StatementEvents
+     *
      */
-    private EngineStatement applicationStatement;
+    protected EngineStatement applicationStatement;
 
 	int updateCount = -1;
 	java.sql.ResultSet results;

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAConnection40.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAConnection40.java?rev=396859&r1=396858&r2=396859&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAConnection40.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAConnection40.java Tue Apr 25 05:22:08 2006
@@ -20,7 +20,10 @@
 
 package org.apache.derby.jdbc;
 
+import java.util.Vector;
+import java.sql.PreparedStatement;
 import java.sql.SQLException;
+import javax.sql.StatementEvent;
 import javax.sql.StatementEventListener;
 import javax.sql.XAConnection;
 import org.apache.derby.iapi.jdbc.ResourceAdapter;
@@ -31,6 +34,10 @@
 final class EmbedXAConnection40 extends EmbedXAConnection
         implements XAConnection {
     
+    //using generics to avoid casting problems
+    protected final Vector<StatementEventListener> statementEventListeners =
+            new Vector<StatementEventListener>();
+    
     /**
      * Creates EmbedXAConnection40.
      * @param ds 
@@ -57,8 +64,9 @@
      * @since 1.6
      */
     public void removeStatementEventListener(StatementEventListener listener) {
-        throw new UnsupportedOperationException (
-                "addStatementEventListener(StatementEventListener listener)");
+        if (listener == null)
+            return;
+        statementEventListeners.removeElement(listener);
     }
 
     /**
@@ -77,8 +85,48 @@
      * @since 1.6
      */
     public void addStatementEventListener(StatementEventListener listener) {
-        throw new UnsupportedOperationException (
-                "addStatementEventListener(StatementEventListener listener)");
+         if (!isActive)
+            return;
+        if (listener == null)
+            return;
+        statementEventListeners.addElement(listener);
+    }
+    
+    /**
+     * Raise the statementClosed event for all the listeners when the
+     * corresponding events occurs
+     * @param statement PreparedStatement
+     */
+    public void onStatementClose(PreparedStatement statement) {
+        if (!statementEventListeners.isEmpty()){
+            StatementEvent event = new StatementEvent(this,statement);
+            //synchronized block on statementEventListeners to make it thread
+            //safe
+            synchronized(statementEventListeners) {
+                for (StatementEventListener l : statementEventListeners) {
+                    l.statementClosed(event);
+                }
+            }
+        }
+    }
+    
+    /**
+     * Raise the statementErrorOccurred event for all the listeners when the
+     * corresponding events occurs
+     * @param statement PreparedStatement
+     * @param sqle      SQLException
+     */
+    public void onStatementErrorOccurred(PreparedStatement statement,SQLException sqle) {
+        if (!statementEventListeners.isEmpty()){
+            StatementEvent event = new StatementEvent(this,statement,sqle);
+            //synchronized block on statementEventListeners to make it thread
+            //safe
+            synchronized(statementEventListeners) {
+                for (StatementEventListener l : statementEventListeners){
+                    l.statementErrorOccurred(event);
+                }
+            }
+        }
     }
    
 }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementEventsTest.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementEventsTest.java?rev=396859&r1=396858&r2=396859&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementEventsTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/StatementEventsTest.java Tue Apr 25 05:22:08 2006
@@ -32,8 +32,11 @@
 */
 public class StatementEventsTest extends BaseJDBCTestCase 
         implements StatementEventListener {
-    
+    //used to test StatementEvents raised from PooledConnection
     PooledConnection pooledConnection;
+    //used to test StatementEvents raised from XAConnection
+    XAConnection xaconnection;
+    
     Connection conn;
     PreparedStatement ps_close;
     PreparedStatement ps_error;
@@ -57,36 +60,19 @@
      *
      */
     public void setUp() throws SQLException {
+        XADataSource xadatasource = getXADataSource();
         ConnectionPoolDataSource cpds = getConnectionPoolDataSource();
+        
         pooledConnection = cpds.getPooledConnection();
+        xaconnection = xadatasource.getXAConnection();
         //register this class as a event listener for the
         //statement events
+        //registering as a listener for the 
+        //PooledConnection object
         pooledConnection.addStatementEventListener(this);
-        
-        //Get a connection from the PooledConnection object
-        conn = pooledConnection.getConnection();
-    }
-    
-    /**
-     *
-     * Close the PooledConnection object and the connection and the 
-     * statements obtained from it.
-     * 
-     */
-    
-    public void tearDown() throws SQLException {
-        if(ps_close != null && !ps_close.isClosed()) {
-            ps_close.close();
-        }
-        if(ps_error != null && !ps_error.isClosed()) {
-            ps_error.close();
-        }
-        if(conn != null && !conn.isClosed()) {
-            conn.rollback();
-            conn.close();
-        }
-        if(pooledConnection != null)
-            pooledConnection.close();
+        //registering as a listener for the 
+        //XAConnection
+        xaconnection.addStatementEventListener(this);
     }
     
     /*
@@ -95,8 +81,7 @@
     */
     void raiseCloseEvent() {
         try {
-            ps_close = conn.prepareStatement("create table temp(n int)");
-
+            ps_close = conn.prepareStatement("values 1");
             //call the close method on this prepared statement object
             //this should result in a statement event being generated 
             //control is transferred to the sattementCLosed function
@@ -115,7 +100,7 @@
     */
     void raiseErrorEvent() {
         try {
-            ps_error = conn.prepareStatement("create table temp(n int)");
+            ps_error = conn.prepareStatement("values 1");
             
             //close the connection associated with this prepared statement
             conn.close();
@@ -156,17 +141,99 @@
         }
     }
     
-    /*
-        Check to see if the events were properly raised during execution
+    /**
+     *
+     * Check to see if the events were properly raised during execution.
+     * raise the close and the error event for the PooledConnection and
+     * check if they occur properly.
+     * 
+     * @throws java.sql.SQLException 
+     *
+     */
+    public void testIfEventOccurredInPooledConnection() throws SQLException {
+        //Get a connection from the PooledConnection object
+        conn = pooledConnection.getConnection();
+        raiseCloseEvent();
+        raiseErrorEvent();
+        
+        //reset the flags to enable it to be used for 
+        //both the cases of XAConnection and PooledConnection
+        if(statementCloseEventOccurred != true) {
+            System.out.println("The Close Event did not occur");
+        }
+        else {
+            statementCloseEventOccurred = false;
+        }
+            
+        if(statementErrorEventOccurred != true) {
+            System.out.println("The Error Event did not occur");
+        }
+        else {
+            statementErrorEventOccurred = false;
+        }
+        
+        //close the used prepared statements and connections
+        //for the PooledConnection StatementEventListener tests
+        //so that if tests on PooledConnection is the first instance of the 
+        //tests that are run then we can run the same for
+        //XAConnection.
+        if(ps_close != null && !ps_close.isClosed()) {
+            ps_close.close();
+        }
+        if(ps_error != null && !ps_error.isClosed()) {
+            ps_error.close();
+        }
+        if(conn != null && !conn.isClosed()) {
+            conn.rollback();
+            conn.close();
+        }
+        if(pooledConnection != null)
+            pooledConnection.close();
+    }
+    
+    /**
+     * Check to see if the events were properly raised during execution.
+     * Raise the close and the error event for the XAConnection and check if 
+     * if they occur properly.
+     *
+     * @throws java.sql.SQLExeption
      */
-    public void testIfEventOccurred() {
+    public void testIfEventOccurredInXAConnection() throws SQLException {
+        //Get a connection from the XAConnection object
+        conn = xaconnection.getConnection();
         raiseCloseEvent();
         raiseErrorEvent();
+        
+        //reset the flags to enable it to be used for 
+        //both the cases of XAConnection and PooledConnection
         if(statementCloseEventOccurred != true) {
             System.out.println("The Close Event did not occur");
         }
+        else {
+            statementCloseEventOccurred = false;
+        }
+        
         if(statementErrorEventOccurred != true) {
             System.out.println("The Error Event did not occur");
+        }
+        else {
+            statementErrorEventOccurred = false;
+        }
+        
+        //close the used prepared statements and connections
+        //for the XAConnection StatementEventListener tests
+        //so that if tests on XAConnection is the first instance of the 
+        //tests that are run then we can run the same for
+        //PooledConnection.
+        if(ps_close != null) {
+            ps_close.close();
+        }
+        if(ps_error != null) {
+            ps_error.close();
+        }
+        if(conn != null && !conn.isClosed()) {
+            conn.rollback();
+            conn.close();
         }
     }
     

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/TestUtil.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/TestUtil.java?rev=396859&r1=396858&r2=396859&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/TestUtil.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/TestUtil.java Tue Apr 25 05:22:08 2006
@@ -333,6 +333,7 @@
 	{
 		
 		String classname = getDataSourcePrefix() + XA_DATASOURCE_STRING + "DataSource";
+		classname = checkForJDBC40Implementation(classname);
 		return (javax.sql.XADataSource) getDataSourceWithReflection(classname, attrs);
 	}