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