Date: Wednesday, November 23, 2005 @ 15:13:48
  Author: gilles
    Path: /cvsroot/carob/carob

Modified: include/Connection.hpp (1.21 -> 1.22) src/Connection.cpp (1.24
          -> 1.25)

Applied Request classes changes
Implemented statementExecute() function


------------------------+
 include/Connection.hpp |   96 ++++++++++++++++------
 src/Connection.cpp     |  203 ++++++++++++++++++++++++++++++++++-------------
 2 files changed, 220 insertions(+), 79 deletions(-)


Index: carob/include/Connection.hpp
diff -u carob/include/Connection.hpp:1.21 carob/include/Connection.hpp:1.22
--- carob/include/Connection.hpp:1.21   Fri Nov 18 17:58:53 2005
+++ carob/include/Connection.hpp        Wed Nov 23 15:13:47 2005
@@ -22,8 +22,15 @@
 #ifndef _CONNECTION_H_
 #define _CONNECTION_H_
 
+#include <list>
+
+#include "CarobException.hpp"
+#include "Connection.hpp"
+#include "ConnectionParameters.hpp"
 #include "CriticalSection.hpp"
+#include "DriverResultSet.hpp"
 #include "DriverSocket.hpp"
+#include "RequestWithResultSetParameters.hpp"
 
 /** "Controller Ready" magic number. */
 #define ControllerPrompt                        0x1FA1501F
@@ -39,7 +46,7 @@
 //#define CallableStatementExecuteQuery           3
 //#define CallableStatementExecuteUpdate          4
 //#define CallableStatementExecute                5
-//#define StatementExecute                        6
+#define StatementExecute                        6
 #define Begin                                   20
 #define Commit                                  21
 #define Rollback                                22
@@ -82,12 +89,6 @@
 //#define DatabaseMetaDataGetVersionColumns       73
 //#define DatabaseStaticMetadata                  80
 
-//Forward declarations to reduce includes
-class AbstractRequest;
-class AbstractWriteRequest;
-class ConnectionParameters;
-class DriverResultSet;
-class SelectRequest;
 class Statement;
 /**
  * This class implements the communication protocol to the Controller.
@@ -112,8 +113,9 @@
         * @throws IOException on socket error
         * @throws DriverSQLException on protocol corruption
         */
-       static void sendCommand(const DriverSocket& socket, int32_t command)
-      throw (SocketIOException, ProtocolException, UnexpectedException);
+       static void        sendCommand(const DriverSocket& socket, int32_t 
command)
+                        throw (SocketIOException, ProtocolException,
+                        UnexpectedException);
   /**
    * If a connection is in auto-commit mode, then all its SQL statements will 
be
    * executed and committed as individual transactions. Otherwise, its SQL
@@ -169,27 +171,39 @@
   Statement*        createStatement() throw (SocketIOException,
                         DriverException, UnexpectedException);
   /**
+   * Performs a read request and returns the reply.
+   * 
+   * @param request the read request with result set parameters to execute
+   * @return a pointer to the resulting <code>DriverResultSet</code>
+   * @throw SocketIOException if an error occurs on the socket
+   */
+  DriverResultSet*  statementExecuteQuery(RequestWithResultSetParameters& 
request)
+                        throw (SocketIOException, BackendException, 
+                        ControllerException, ProtocolException,
+                        NotImplementedException, UnexpectedException);
+  /**
    * Performs a write request and return the number of rows affected.
    * 
    * @param r the write request to execute
    * @return number of rows affected, -1 if an error occured
    * @throws SocketIOException if an error occurs
    */
-  int32_t           execWriteRequest(AbstractWriteRequest& r)
+  int32_t           statementExecuteUpdate(Request& r)
                         throw (SocketIOException, BackendException, 
                         ControllerException, ProtocolException,
                         UnexpectedException);
   /**
-   * Performs a read request and returns the reply.
+   * Calls a request that returns a list of results.
    * 
-   * @param request the read request to execute
-   * @return a <code>DriverResultSet</code> pointer
-   * @throw SocketIOException if an error occurs on the socket
+   * @param request the request to execute
+   * @return a <code>list</code> of <code>ResultSetOrUpdateCount</code> 
elements
+   * @throws SocketIOException if an error occurs
    */
-  DriverResultSet*  execReadRequest(SelectRequest& request)
-                        throw (SocketIOException, BackendException, 
-                        ControllerException, ProtocolException,
-                        NotImplementedException, UnexpectedException);
+  list<ResultSetOrUpdateCount>  statementExecute(
+                                    RequestWithResultSetParameters request)
+                                    throw (SocketIOException, 
BackendException, 
+                                    ControllerException, ProtocolException,
+                                    UnexpectedException);
   /**
    * Closes the remote ResultSet given its cursor name.
    * 
@@ -197,11 +211,31 @@
    * @throw DriverSQLException if an error occurs
    * @throw SocketIOException if an error occurs on the socket
    */
-  void closeRemoteResultSet(wstring cursorName) throw (SocketIOException,
-                                                       BackendException,
-                                                       ControllerException,
-                                                       ProtocolException,
-                                                       UnexpectedException);
+  void              closeRemoteResultSet(wstring cursorName)
+                        throw (SocketIOException, BackendException,
+                        ControllerException, ProtocolException,
+                        UnexpectedException);
+  /**
+   * Tests to see if the connection is in read only Mode. Note that we cannot
+   * really put the database in read only mode, but we pretend we can by
+   * returning the value of the <code>readOnly</code> flag.
+   * 
+   * @return <code>true</code> if the connection is read only
+   */
+  bool              isReadOnly() { return readOnly; }
+  /**
+   * A connection can be put in read-only mode as a hint to enable database
+   * optimizations
+   * <p>
+   * <B>Note: </B> setReadOnly cannot be called while in the middle of a
+   * transaction with write requests.
+   * 
+   * @param readOnlyPrm  <code>true</code> enables read-only mode;
+   *                  <code>false</code> disables it
+   * @exception DriverSQLException if a database access error occurs
+   */
+  void              setReadOnly(bool readOnlyPrm) throw (SocketIOException,
+                        DriverException, UnexpectedException);
 
 protected:
   /** 
@@ -261,7 +295,7 @@
    * @param request the write request to send
    * @throw SocketIOException when an error occured on the stream
    */
-  void                writeRequestOnStream(const AbstractWriteRequest& request)
+  void                writeRequestOnStream(const Request& request)
                           throw (SocketIOException, UnexpectedException);
   
   /**
@@ -302,7 +336,7 @@
    * Set the autocommit mode and read-only status on this request.
    * @param request The request to set
    */
-  void setConnectionParametersOnRequest(AbstractRequest &request);
+  void                setConnectionParametersOnRequest(Request &request);
 
   /**
    * Returns a boolean read from the stream or throws the CarobException
@@ -344,7 +378,7 @@
    * Returns a string read from the stream or throws the CarobException
    * that came instead.
    * 
-   * @throws IOException stream or protocol error
+   * @throws SocketIOException stream or protocol error
    * @throws CarobException coming from the controller
    */
   wstring             receiveStringOrException() throw (SocketIOException,
@@ -365,6 +399,16 @@
                                                 ControllerException,
                                                 ProtocolException,
                                                 UnexpectedException);
+  /**
+   * Returns a DriverResultSet read from the stream or throws the Exception 
that
+   * came instead
+   * 
+   * @throws SocketIOException stream or protocol error
+   * @throws CarobException received from the controller
+   */
+  DriverResultSet*    receiveResultSetOrException() throw (SocketIOException,
+                          BackendException, ControllerException,
+                          ProtocolException, UnexpectedException);
 };
 
 #endif //_CONNECTION_H_
Index: carob/src/Connection.cpp
diff -u carob/src/Connection.cpp:1.24 carob/src/Connection.cpp:1.25
--- carob/src/Connection.cpp:1.24       Fri Nov 18 17:58:53 2005
+++ carob/src/Connection.cpp    Wed Nov 23 15:13:47 2005
@@ -18,13 +18,7 @@
  * Initial developer(s): Gilles Rayrat
  * Contributor(s): 
  */
-
-#include "AbstractWriteRequest.hpp"
-#include "CarobException.hpp"
 #include "Connection.hpp"
-#include "ConnectionParameters.hpp"
-#include "DriverResultSet.hpp"
-#include "SelectRequest.hpp"
 #include "Statement.hpp"
 
 Connection::~Connection()
@@ -223,7 +217,23 @@
   
   if (connectionPooling)
   {
-    //TODO: Pool connection
+    //TODO: real connection pooling...
+    throw NotImplementedException(L"Connection pooling not implemented yet");
+    try
+    {
+      if (isDebugEnabled())
+        logDebug(fctName, L"Resetting connection and adding it to the pool");
+      autoCommit = true;
+      readOnly = false;
+      sendCommand(*driverSocketPtr, Reset);
+      //TODO: Pool connection !!!
+    }
+    catch (SocketIOException sioe)
+    {
+      if (isErrorEnabled())
+        logError(fctName, L"I/O Error while closing the connection:"
+            + sioe.description());
+    }
   }
   else
   {
@@ -325,6 +335,16 @@
   connectionCS.Leave();
 }
 
+void Connection::setReadOnly(bool readOnlyPrm) throw (SocketIOException,
+DriverException, UnexpectedException)
+{
+  checkIfConnected();
+  if ((autoCommit == false) && writeExecutedInTransaction)
+    throw DriverException(
+        L"setReadOnly cannot be called in a transaction that has executed 
write requests.");
+  readOnly = readOnlyPrm;
+}
+
 void Connection::commit() throw (SocketIOException, DriverException,
     UnexpectedException)
 {
@@ -436,17 +456,66 @@
     throw SocketIOException(L"Request cannot be processed : connection is 
closed!");
 }
 
-void Connection::setConnectionParametersOnRequest(AbstractRequest &request)
+void Connection::setConnectionParametersOnRequest(Request &request)
 {
   request.setIsAutoCommit(autoCommit);
   request.setIsReadOnly(readOnly);
 }
 
-int32_t Connection::execWriteRequest(AbstractWriteRequest& r)
+//TODO: check that the code still sticks to java code
+DriverResultSet* Connection::statementExecuteQuery
+    (RequestWithResultSetParameters& request)
+    throw (SocketIOException, BackendException, ControllerException,
+    ProtocolException, NotImplementedException, UnexpectedException)
+{
+  
+  wstring fctName(L"Connection::statementExecuteQuery");
+  
+  connectionCS.Enter();
+
+  DriverResultSet* retVal = NULL;
+  
+  checkIfConnected();
+
+  try
+  {
+    setConnectionParametersOnRequest(request);
+    sendCommand(*driverSocketPtr, StatementExecuteQuery);
+    request.sendToStream(*driverSocketPtr, controllerNeedsSqlSkeleton);
+    
+    if (isDebugEnabled())
+      logDebug(fctName, L"Executing read request " + (wstring)request);
+
+    TypeTag tag(*driverSocketPtr);
+    switch(tag)
+    {
+      case TT_RESULTSET:
+        retVal = new DriverResultSet(this);
+        break;
+      //case TT_NULL_RESULTSET: nothing to do, just return NULL
+      case TT_EXCEPTION:
+        receiveException();
+        break;
+    }
+  }
+  catch (SocketIOException sioe)
+  {
+    //TODO: Reconnect and retry
+  }
+  catch (...)
+  {
+    connectionCS.Leave();
+    throw;
+  }
+  connectionCS.Leave();
+  return retVal;
+}
+
+int32_t Connection::statementExecuteUpdate(Request& request)
     throw (SocketIOException, BackendException, ControllerException,
     ProtocolException, UnexpectedException)
 {
-  wstring fctName(L"Connection::execWriteRequest");
+  wstring fctName(L"Connection::statementExecuteUpdate");
 
   connectionCS.Enter();
 
@@ -456,9 +525,9 @@
 
   try
   {
-    setConnectionParametersOnRequest(r);
+    setConnectionParametersOnRequest(request);
     sendCommand(*driverSocketPtr, StatementExecuteUpdate);
-    writeRequestOnStream(r);
+    writeRequestOnStream(request);
     controllerResponse = receiveIntOrException();
   }
   catch (SocketIOException sioe)
@@ -482,52 +551,57 @@
   return controllerResponse;
 }
 
-void Connection::writeRequestOnStream(const AbstractWriteRequest& request)
-    throw (SocketIOException, UnexpectedException )
+list<ResultSetOrUpdateCount> Connection::statementExecute(
+    RequestWithResultSetParameters request) throw (SocketIOException,
+    BackendException, ControllerException, ProtocolException,
+    UnexpectedException)
 {
-  if (!autoCommit)
-    writeExecutedInTransaction = true;
-
-  request.sendToStream(*driverSocketPtr, controllerNeedsSqlSkeleton);
+  wstring fctName(L"Connection::statementExecute");
 
-}
-
-DriverResultSet* Connection::execReadRequest(SelectRequest& sr)
-    throw (SocketIOException, BackendException, ControllerException,
-    ProtocolException, NotImplementedException, UnexpectedException){
-  
-  wstring fctName(L"Connection::execReadRequest");
-  
   connectionCS.Enter();
+  list<ResultSetOrUpdateCount> results;
 
-  DriverResultSet* retVal = NULL;
-  
   checkIfConnected();
 
   try
   {
-    setConnectionParametersOnRequest(sr);
-    sendCommand(*driverSocketPtr, StatementExecuteQuery);
-    sr.sendToStream(*driverSocketPtr, controllerNeedsSqlSkeleton);
-    
+    setConnectionParametersOnRequest(request);
+    sendCommand(*driverSocketPtr, StatementExecute);
+    writeRequestOnStream(request);
     if (isDebugEnabled())
-      logDebug(fctName, L"Executing read request " + (wstring)sr);
+      logDebug(fctName, L"Executing Statement.execute(" + (wstring)request + 
L")");
 
-    TypeTag tag(*driverSocketPtr);
-    switch(tag)
+    bool hasResult = false;
+    ResultSetOrUpdateCount resultReceived;
+    do
     {
-      case TT_RESULTSET:
-        retVal = new DriverResultSet(this);
-        break;
-      //case TT_NULL_RESULTSET: nothing to do, just return NULL
-      case TT_EXCEPTION:
-        receiveException();
-        break;
+      hasResult = receiveBoolOrException();
+      if (hasResult)
+      {
+        resultReceived.isResultSet = true;
+        resultReceived.value.resultSetPtr = receiveResultSetOrException();
+      }
+      else
+      {
+        resultReceived.isResultSet = false;
+        resultReceived.value.updateCount = receiveIntOrException();
+      }
+      results.push_back(resultReceived);
+      
     }
+    while (hasResult || resultReceived.value.updateCount != -1);
   }
   catch (SocketIOException sioe)
   {
-    //TODO: Reconnect and retry
+    wstring msg = L"Exception while executing request: "
+                  + sioe.description()
+                  + L"). Connection probably lost";
+    if (isErrorEnabled())
+      logError(fctName, msg);
+    connectionCS.Leave();
+    throw SocketIOException(msg);
+    //in case exception is not catched
+    return results;
   }
   catch (...)
   {
@@ -535,9 +609,20 @@
     throw;
   }
   connectionCS.Leave();
-  return retVal;
+  return results;
 }
 
+void Connection::writeRequestOnStream(const Request& request)
+    throw (SocketIOException, UnexpectedException )
+{
+  if (!autoCommit)
+    writeExecutedInTransaction = true;
+
+  request.sendToStream(*driverSocketPtr, controllerNeedsSqlSkeleton);
+
+}
+
+
 void Connection::closeRemoteResultSet(wstring cursorName)
     throw (SocketIOException, BackendException, ControllerException,
     ProtocolException, UnexpectedException)
@@ -658,12 +743,24 @@
   else throw ProtocolException(L"Received unknown exception type");
 }
 
-
-/*
- * Local Variables:
- * c-file-style: "bsd"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * End:
- */
-
+DriverResultSet* Connection::receiveResultSetOrException()
+    throw (SocketIOException, BackendException, ControllerException,
+    ProtocolException, UnexpectedException)
+{
+  TypeTag tag(*driverSocketPtr);
+  //if it's not an exception, receive the bool normally
+  if (tag == TT_NOT_EXCEPTION)
+  {
+    DriverResultSet* retVal = new DriverResultSet(this);
+    return retVal;
+  }
+  if (tag == TT_NULL_RESULTSET)
+  {
+    return NULL;
+  }
+  //if we are here, it's an exception, deserialize and throw it (at the same
+  //time)
+  receiveException();
+  //just to avoid compiler warnings
+  return NULL;
+}

_______________________________________________
Carob-commits mailing list
[email protected]
https://forge.continuent.org/mailman/listinfo/carob-commits

Reply via email to