Date: Friday, February 17, 2006 @ 17:15:45
  Author: gilles
    Path: /cvsroot/carob/carob

Modified: include/Connection.hpp (1.60 -> 1.61) src/Connection.cpp (1.67
          -> 1.68)

Implemented statementExecuteUpdateWithKeys (untested)
Fixed statementExecute result retrieval after failure


------------------------+
 include/Connection.hpp |   47 +++++++++++++++----
 src/Connection.cpp     |  112 +++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 146 insertions(+), 13 deletions(-)


Index: carob/include/Connection.hpp
diff -u carob/include/Connection.hpp:1.60 carob/include/Connection.hpp:1.61
--- carob/include/Connection.hpp:1.60   Thu Feb 16 16:07:47 2006
+++ carob/include/Connection.hpp        Fri Feb 17 17:15:45 2006
@@ -45,14 +45,14 @@
 #define Ping                                    -1
 #define StatementExecuteQuery                   0
 #define StatementExecuteUpdate                  1
-//#define StatementExecuteUpdateWithKeys          2
+#define StatementExecuteUpdateWithKeys          2
 //#define CallableStatementExecuteQuery           3
 //#define CallableStatementExecuteUpdate          4
 //#define CallableStatementExecute                5
 #define RetrieveExecuteQueryResult              10
 #define RetrieveExecuteUpdateResult             11
 #define RetrieveExecuteResult                   12
-//#define RetrieveExecuteUpdateWithKeysResult     13
+#define RetrieveExecuteUpdateWithKeysResult     13
 #define RetrieveCommitResult                    14
 #define RetrieveRollbackResult                  15
 #define StatementExecute                        6
@@ -220,8 +220,8 @@
    * @param stPtr pointer to the statement to destroy
    * @throw DriverException if the given statement is not in our list
    */
-  void                deleteStatement(Statement* stPtr) throw (DriverException,
-                          UnexpectedException);
+  void              deleteStatement(Statement* stPtr) throw (DriverException,
+                        UnexpectedException);
   /**
    * Performs a read request and returns the reply.
    * 
@@ -254,11 +254,26 @@
    * @return a <code>list</code> of <code>ResultSetOrUpdateCount</code> 
elements
    * @throws SocketIOException if an error occurs
    */
-  std::list<ResultSetOrUpdateCount>  statementExecute(
-                                    RequestWithResultSetParameters& request)
-                                    throw (SocketIOException, 
BackendException, 
-                                    ControllerException, ProtocolException,
-                                    UnexpectedException);
+  std::list<ResultSetOrUpdateCount> statementExecute(
+                                        RequestWithResultSetParameters& 
request)
+                                        throw (SocketIOException,
+                                        BackendException, ControllerException,
+                                        ProtocolException, 
UnexpectedException);
+  /**
+   * Performs a write request and returns the auto-generated keys
+   * 
+   * @param request the write request to execute
+   * @return a <code>list</code> of 2 <code>ResultSetOrUpdateCount</code>
+   *          elements in which the first element is the update count returned
+   *          by the executeUpdate execution, the second element being a
+   *          DriverResultSet containing the autogenerated keys
+   * @throws SocketIOException if an error occurs
+   */
+  std::list<ResultSetOrUpdateCount> statementExecuteUpdateWithKeys(
+                                        Request &request)
+                                        throw (SocketIOException,
+                                        BackendException,ControllerException,
+                                        ProtocolException, 
UnexpectedException);
   /**
    * Closes the remote ResultSet given its cursor name.
    * 
@@ -542,7 +557,7 @@
                           UnexpectedException);
   /**
    * Check if the given query already executed or not on the controller we are
-   * currently connected to.
+   * currently connected to. If so, return this query previous result
    * 
    * @param request the request to check
    * @return a <code>List</code> of ResultSetOrUpdateCount
@@ -552,6 +567,18 @@
                           ControllerException, ProtocolException,
                           UnexpectedException);
   /**
+   * Check if the given query already executed or not on the controller we are
+   * currently connected to. If so, return this query previous result
+   * 
+   * @param request the request to check
+   * @return previous result of the given query, 
+   * @throws DriverSQLException if an error occurs
+   */
+  std::list<ResultSetOrUpdateCount> retrieveExecuteUpdateWithKeysResult(
+                          const Request &request) throw (SocketIOException,
+                          BackendException, ControllerException,
+                          ProtocolException, UnexpectedException);
+  /**
    * Fetches multiple results from a query executed with Statement.execute()
    * @return the list of results
    */
Index: carob/src/Connection.cpp
diff -u carob/src/Connection.cpp:1.67 carob/src/Connection.cpp:1.68
--- carob/src/Connection.cpp:1.67       Thu Feb 16 16:07:47 2006
+++ carob/src/Connection.cpp    Fri Feb 17 17:15:45 2006
@@ -685,12 +685,91 @@
   catch (SocketIOException sioe)
   {
     FO_TRY_NTIMES(RECONNECT_RETRIES)
+      // Clean-up old results if any
+      if (results.size() > 0)
+      {
+        for (std::list<ResultSetOrUpdateCount>::iterator iter = 
results.begin();
+            iter != results.end(); iter++)
+        {
+          if (iter->isResultSet)
+          {
+            delete iter->resultSetPtr;
+          }
+        }
+        results.clear();
+      }
+      // Then retrieve results on controller
       results = retrieveExecuteResult(request);
     FO_CATCH_NTIMES
   }
   return results;
 }
 
+std::list<ResultSetOrUpdateCount> Connection::statementExecuteUpdateWithKeys(
+    Request &request) throw (SocketIOException, BackendException,
+    ControllerException, ProtocolException, UnexpectedException)
+{
+  wstring fctName(L"Connection::statementExecuteUpdateWithKeys");
+
+  LockScope ls(&connectionCS);
+
+  std::list<ResultSetOrUpdateCount> result;
+  for (int failuresCnt=0; failuresCnt<RECONNECT_RETRIES; failuresCnt++)
+  { // this for is in the case we were disconnected and the controller did not
+    // get the update request
+    FO_TRY_NTIMES(RECONNECT_RETRIES)
+      checkIfConnected();
+      beginTransactionIfNeeded();
+      setConnectionParametersOnRequest(request);
+      sendCommand(*driverSocketPtr, StatementExecuteUpdateWithKeys);
+      request.sendToStream(*driverSocketPtr);
+      if (isDebugEnabled())
+        logDebug(fctName, L"Executing write request with keys: "
+            + static_cast<wstring>(request));
+      request.setId(receiveLongOrException());
+    FO_CATCH_NTIMES
+    try
+    {
+      // Receive first the update count or an exception
+      ResultSetOrUpdateCount uc;
+      uc.isResultSet = false;
+      uc.updateCount = static_cast<int>(receiveIntOrException());
+      result.push_back(uc);
+      // Then the ResultSet containing the autogenerated keys
+      ResultSetOrUpdateCount rs;
+      rs.isResultSet = true;
+      rs.resultSetPtr = receiveResultSet();
+      result.push_back(rs);
+    }
+    catch (SocketIOException sioe)
+    {
+      FO_TRY_NTIMES(RECONNECT_RETRIES)
+        // Clean-up old result if any
+        if (result.size() > 0)
+        {
+          for (std::list<ResultSetOrUpdateCount>::iterator iter = 
result.begin();
+              iter != result.end(); iter++)
+          {
+            if (iter->isResultSet)
+            {
+              delete iter->resultSetPtr;
+            }
+          }
+          result.clear();
+        }
+        // Then retrieve result on controller
+        result = retrieveExecuteUpdateWithKeysResult(request);
+      FO_CATCH_NTIMES
+      if (result.size() > 1)
+        return result;
+      // otherwise, the update was not done on the controller, we go back at
+      // the beginning of the function, cleaning up results
+      result.clear();
+    }
+  }
+  return result;
+}
+
 void Connection::writeRequestOnStream(const Request& request)
     throw (SocketIOException, UnexpectedException )
 {
@@ -898,15 +977,42 @@
   *driverSocketPtr << request.getId();
   return static_cast<int>(receiveIntOrException());
 }
-std::list<ResultSetOrUpdateCount> Connection::retrieveExecuteResult(const 
Request &request)
-    throw (SocketIOException, BackendException, ControllerException,
-    ProtocolException, UnexpectedException)
+
+std::list<ResultSetOrUpdateCount> Connection::retrieveExecuteResult(
+    const Request &request) throw (SocketIOException, BackendException,
+    ControllerException, ProtocolException, UnexpectedException)
 {
   sendCommand(*driverSocketPtr, RetrieveExecuteResult);
   *driverSocketPtr << request.getId();
   return fetchMultipleResultsFromStream();
 }
 
+std::list<ResultSetOrUpdateCount> 
Connection::retrieveExecuteUpdateWithKeysResult(
+                        const Request &request) throw (SocketIOException,
+                        BackendException, ControllerException,
+                        ProtocolException, UnexpectedException)
+{
+  sendCommand(*driverSocketPtr, RetrieveExecuteUpdateWithKeysResult);
+  *driverSocketPtr << request.getId();
+
+  std::list<ResultSetOrUpdateCount> result;
+  // Receive first the update count or an exception
+  ResultSetOrUpdateCount uc;
+  uc.isResultSet = false;
+  uc.updateCount = static_cast<int>(receiveIntOrException());
+  if (uc.updateCount != -1)
+  {
+    result.push_back(uc);
+    // Then the ResultSet containing the autogenerated keys
+    ResultSetOrUpdateCount rs;
+    rs.isResultSet = true;
+    rs.resultSetPtr = receiveResultSet();
+    result.push_back(rs);
+  }
+  //else return an empty list
+  return result;
+}
+
 std::list<ResultSetOrUpdateCount> Connection::fetchMultipleResultsFromStream()
                         throw (SocketIOException, BackendException,
                         ControllerException, ProtocolException,

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

Reply via email to