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