SF [2643953] Improve Data::Session connection

This commit is contained in:
Aleksandar Fabijanic 2009-02-27 03:14:53 +00:00
parent 9bef44cab6
commit 68a79674c1
50 changed files with 689 additions and 165 deletions

View File

@ -62,7 +62,8 @@ public:
virtual const std::string& name() const;
/// Returns the name associated with this connector.
virtual Poco::AutoPtr<Poco::Data::SessionImpl> createSession(const std::string& connectionString);
virtual Poco::AutoPtr<Poco::Data::SessionImpl> createSession(const std::string& connectionString,
std::size_t timeout = Poco::Data::SessionImpl::CONNECT_TIMEOUT_DEFAULT);
/// Creates a MySQL SessionImpl object and initializes it with the given connectionString.
static void registerConnector();

View File

@ -59,12 +59,18 @@ public:
~SessionHandle();
/// Destroy handle, close connection
void init(MYSQL* mysql = 0);
/// Initializes the handle iff not initialized.
void options(mysql_option opt);
/// Set connection options
void options(mysql_option opt, bool b);
/// Set connection options
void options(mysql_option opt, unsigned int i);
/// Set connection options
void connect(const char* host, const char* user, const char* password, const char* db, unsigned int port);
/// Connect to server

View File

@ -62,7 +62,8 @@ public:
static const std::string MYSQL_REPEATABLE_READ;
static const std::string MYSQL_SERIALIZABLE;
SessionImpl(const std::string& connectionString);
SessionImpl(const std::string& connectionString,
std::size_t timeout = CONNECT_TIMEOUT_DEFAULT);
/// Creates the SessionImpl. Opens a connection to the database
///
/// Connection string format:
@ -81,6 +82,15 @@ public:
Poco::Data::StatementImpl* createStatementImpl();
/// Returns an MySQL StatementImpl
void open(const std::string& connection = "");
/// Opens a connection to the database.
void close();
/// Closes the connection.
bool isConnected();
/// Returns true if connected, false otherwise.
void begin();
/// Starts a transaction
@ -90,12 +100,6 @@ public:
void rollback();
/// Aborts a transaction
void close();
/// Closes the connection
bool isConnected();
/// Returns true if connected, false otherwise.
bool canTransact();
/// Returns true if session has transaction capabilities.
@ -163,10 +167,10 @@ private:
return getValue<T>(pResult, val);
}
std::string _connector;
SessionHandle _handle;
bool _connected;
bool _inTransaction;
std::string _connector;
SessionHandle _handle;
bool _connected;
bool _inTransaction;
Poco::FastMutex _mutex;
};

View File

@ -64,9 +64,10 @@ const std::string& Connector::name() const
return KEY;
}
Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString)
Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString,
std::size_t timeout)
{
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString));
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString, timeout));
}

View File

@ -35,6 +35,7 @@
#include "Poco/Data/MySQL/SessionHandle.h"
#include "Poco/Data/DataException.h"
namespace Poco {
@ -42,10 +43,20 @@ namespace Data {
namespace MySQL {
SessionHandle::SessionHandle(MYSQL* mysql)
SessionHandle::SessionHandle(MYSQL* mysql): _pHandle(0)
{
if (!(_pHandle = mysql_init(mysql)))
throw ConnectionException("mysql_init error");
init(mysql);
}
void SessionHandle::init(MYSQL* mysql)
{
if (!_pHandle)
{
_pHandle = mysql_init(mysql);
if (!_pHandle)
throw ConnectionException("mysql_init error");
}
}
@ -69,11 +80,17 @@ void SessionHandle::options(mysql_option opt, bool b)
throw ConnectionException("mysql_options error", _pHandle);
}
void SessionHandle::options(mysql_option opt, unsigned int i)
{
if (mysql_options(_pHandle, opt, &i) != 0)
throw ConnectionException("mysql_options error", _pHandle);
}
void SessionHandle::connect(const char* host, const char* user, const char* password, const char* db, unsigned int port)
{
if (!mysql_real_connect(_pHandle, host, user, password, db, port, 0, 0))
throw ConnectionException("create session: mysql_real_connect error", _pHandle);
throw ConnectionFailedException("mysql_real_connect error");
}

View File

@ -66,8 +66,8 @@ const std::string SessionImpl::MYSQL_REPEATABLE_READ = "REPEATABLE READ";
const std::string SessionImpl::MYSQL_SERIALIZABLE = "SERIALIZABLE";
SessionImpl::SessionImpl(const std::string& connectionString) :
Poco::Data::AbstractSessionImpl<SessionImpl>(toLower(connectionString)),
SessionImpl::SessionImpl(const std::string& connectionString, std::size_t timeout) :
Poco::Data::AbstractSessionImpl<SessionImpl>(toLower(connectionString), timeout),
_handle(0),
_connected(false),
_inTransaction(false)
@ -76,6 +76,28 @@ SessionImpl::SessionImpl(const std::string& connectionString) :
&SessionImpl::setInsertId,
&SessionImpl::getInsertId);
open();
}
void SessionImpl::open(const std::string& connect)
{
if (connect != connectionString())
{
if (isConnected())
throw InvalidAccessException("Session already connected");
if (!connect.empty())
setConnectionString(connect);
}
poco_assert_dbg (!connectionString().empty());
_handle.init();
unsigned int timeout = static_cast<unsigned int>(getTimeout());
_handle.options(MYSQL_OPT_CONNECT_TIMEOUT, timeout);
std::map<std::string, std::string> options;
// Default values
@ -87,9 +109,10 @@ SessionImpl::SessionImpl(const std::string& connectionString) :
options["compress"] = "";
options["auto-reconnect"] = "";
for (std::string::const_iterator start = connectionString.begin();;)
const std::string& connString = connectionString();
for (std::string::const_iterator start = connString.begin();;)
{
std::string::const_iterator finish = std::find(start, connectionString.end(), ';');
std::string::const_iterator finish = std::find(start, connString.end(), ';');
std::string::const_iterator middle = std::find(start, finish, '=');
if (middle == finish)
@ -97,7 +120,7 @@ SessionImpl::SessionImpl(const std::string& connectionString) :
options[copyStripped(start, middle)] = copyStripped(middle + 1, finish);
if ((finish == connectionString.end()) || (finish + 1 == connectionString.end())) break;
if ((finish == connString.end()) || (finish + 1 == connString.end())) break;
start = finish + 1;
}
@ -127,8 +150,7 @@ SessionImpl::SessionImpl(const std::string& connectionString) :
throw MySQLException("create session: specify correct auto-reconnect option (true or false) or skip it");
// Real connect
_handle.connect(
options["host"].c_str(),
_handle.connect(options["host"].c_str(),
options["user"].c_str(),
options["password"].c_str(),
options["db"].c_str(),

View File

@ -507,6 +507,15 @@ void MySQLTest::testTransaction()
}
void MySQLTest::testReconnect()
{
if (!_pSession) fail ("Test not available.");
recreatePersonTable();
_pExecutor->reconnect();
}
void MySQLTest::testNullableInt()
{
if (!_pSession) fail ("Test not available.");
@ -813,6 +822,7 @@ CppUnit::Test* MySQLTest::suite()
CppUnit_addTest(pSuite, MySQLTest, testTupleWithNullable);
CppUnit_addTest(pSuite, MySQLTest, testSessionTransaction);
CppUnit_addTest(pSuite, MySQLTest, testTransaction);
CppUnit_addTest(pSuite, MySQLTest, testReconnect);
return pSuite;
}

View File

@ -116,6 +116,8 @@ public:
void testSessionTransaction();
void testTransaction();
void testReconnect();
void setUp();
void tearDown();

View File

@ -476,7 +476,7 @@ void SQLExecutor::insertSingleBulk()
for (x = 0; x < 100; ++x)
{
int i = stmt.execute();
std::size_t i = stmt.execute();
assert (i == 0);
}
@ -1803,3 +1803,44 @@ void SQLExecutor::transaction(const std::string& connect)
_pSession->setFeature("autoCommit", autoCommit);
}
void SQLExecutor::reconnect()
{
std::string funct = "reconnect()";
std::string lastName = "lastName";
std::string firstName("firstName");
std::string address("Address");
int age = 133132;
int count = 0;
std::string result;
try { (*_pSession) << "INSERT INTO PERSON VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(age), now; }
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
count = 0;
try { (*_pSession) << "SELECT COUNT(*) FROM PERSON", into(count), now; }
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
assert (count == 1);
assert (_pSession->isConnected());
_pSession->close();
assert (!_pSession->isConnected());
try
{
(*_pSession) << "SELECT LastName FROM PERSON", into(result), now;
fail ("must fail");
}
catch(NotConnectedException&){ }
assert (!_pSession->isConnected());
_pSession->open();
assert (_pSession->isConnected());
try { (*_pSession) << "SELECT Age FROM PERSON", into(count), now; }
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
assert (count == age);
assert (_pSession->isConnected());
}

View File

@ -113,6 +113,8 @@ public:
void sessionTransaction(const std::string& connect);
void transaction(const std::string& connect);
void reconnect();
private:
void setTransactionIsolation(Poco::Data::Session& session, Poco::UInt32 ti);

View File

@ -65,7 +65,8 @@ public:
const std::string& name() const;
/// Returns the name associated with this connector.
Poco::AutoPtr<Poco::Data::SessionImpl> createSession(const std::string& connectionString);
Poco::AutoPtr<Poco::Data::SessionImpl> createSession(const std::string& connectionString,
std::size_t timeout = Poco::Data::SessionImpl::CONNECT_TIMEOUT_DEFAULT);
/// Creates a ODBC SessionImpl object and initializes it with the given connectionString.
static void registerConnector();

View File

@ -64,6 +64,8 @@ class ODBC_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
/// Implements SessionImpl interface
{
public:
static const std::size_t ODBC_MAX_FIELD_SIZE = 1024u;
enum TransactionCapability
{
ODBC_TXN_CAPABILITY_UNKNOWN = -1,
@ -71,12 +73,21 @@ public:
ODBC_TXN_CAPABILITY_TRUE = 1
};
SessionImpl(const std::string& connect,
std::size_t timeout,
std::size_t maxFieldSize = ODBC_MAX_FIELD_SIZE,
bool autoBind = true,
bool autoExtract = true);
/// Creates the SessionImpl. Opens a connection to the database.
/// Throws NotConnectedException if connection was not succesful.
//@ deprecated
SessionImpl(const std::string& connect,
Poco::Any maxFieldSize = std::size_t(1024),
Poco::Any maxFieldSize = ODBC_MAX_FIELD_SIZE,
bool enforceCapability=false,
bool autoBind = true,
bool autoExtract = true);
/// Creates the SessionImpl. Opens a connection to the database
/// Creates the SessionImpl. Opens a connection to the database.
~SessionImpl();
/// Destroys the SessionImpl.
@ -84,6 +95,15 @@ public:
Poco::Data::StatementImpl* createStatementImpl();
/// Returns an ODBC StatementImpl
void open(const std::string& connect = "");
/// Opens a connection to the Database
void close();
/// Closes the connection
bool isConnected();
/// Returns true if session is connected
void begin();
/// Starts a transaction
@ -93,12 +113,6 @@ public:
void rollback();
/// Aborts a transaction
void close();
/// Closes the connection
bool isConnected();
/// Returns true if session is connected
bool isTransaction();
/// Returns true iff a transaction is in progress.
@ -161,24 +175,21 @@ private:
static const int FUNCTIONS = SQL_API_ODBC3_ALL_FUNCTIONS_SIZE;
void open();
/// Opens a connection to the Database
void checkError(SQLRETURN rc, const std::string& msg="");
Poco::UInt32 getDefaultTransactionIsolation();
Poco::UInt32 transactionIsolation(SQLUINTEGER isolation);
std::string _connector;
std::string _connector;
const ConnectionHandle _db;
Poco::Any _maxFieldSize;
bool _autoBind;
bool _autoExtract;
TypeInfo _dataTypes;
char _canTransact;
bool _inTransaction;
Poco::FastMutex _mutex;
Poco::Any _maxFieldSize;
bool _autoBind;
bool _autoExtract;
TypeInfo _dataTypes;
char _canTransact;
bool _inTransaction;
Poco::FastMutex _mutex;
};

View File

@ -57,9 +57,10 @@ Connector::~Connector()
}
Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString)
Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString,
std::size_t timeout)
{
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString));
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString, timeout));
}

View File

@ -49,6 +49,24 @@ namespace Data {
namespace ODBC {
SessionImpl::SessionImpl(const std::string& connect,
std::size_t timeout,
std::size_t maxFieldSize,
bool autoBind,
bool autoExtract):
Poco::Data::AbstractSessionImpl<SessionImpl>(connect, timeout),
_connector(toLower(Connector::KEY)),
_maxFieldSize(maxFieldSize),
_autoBind(autoBind),
_autoExtract(autoExtract),
_canTransact(ODBC_TXN_CAPABILITY_UNKNOWN),
_inTransaction(false)
{
setFeature("bulk", true);
open();
}
SessionImpl::SessionImpl(const std::string& connect,
Poco::Any maxFieldSize,
bool enforceCapability,
@ -85,8 +103,30 @@ Poco::Data::StatementImpl* SessionImpl::createStatementImpl()
}
void SessionImpl::open()
void SessionImpl::open(const std::string& connect)
{
if (connect != connectionString())
{
if (isConnected())
throw InvalidAccessException("Session already connected");
if (!connect.empty())
setConnectionString(connect);
}
poco_assert_dbg (!connectionString().empty());
SQLUINTEGER tout = static_cast<SQLUINTEGER>(getTimeout());
if (Utility::isError(SQLSetConnectAttr(_db, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) tout, 0)))
{
if (Utility::isError(SQLGetConnectAttr(_db, SQL_ATTR_LOGIN_TIMEOUT, &tout, 0, 0)) ||
getTimeout() != tout)
{
ConnectionError e(_db);
throw ConnectionFailedException(e.toString());
}
}
SQLCHAR connectOutput[512] = {0};
SQLSMALLINT result;
@ -99,9 +139,10 @@ void SessionImpl::open()
, &result
, SQL_DRIVER_NOPROMPT)))
{
ConnectionException exc(_db);
ConnectionError err(_db);
std::string errStr = err.toString();
close();
throw exc;
throw ConnectionFailedException(errStr);
}
_dataTypes.fillTypeInfo(_db);

View File

@ -681,6 +681,7 @@ CppUnit::Test* ODBCDB2Test::suite()
CppUnit_addTest(pSuite, ODBCDB2Test, testSessionTransaction);
CppUnit_addTest(pSuite, ODBCDB2Test, testTransaction);
CppUnit_addTest(pSuite, ODBCDB2Test, testTransactor);
CppUnit_addTest(pSuite, ODBCDB2Test, testReconnect);
return pSuite;
}

View File

@ -497,6 +497,7 @@ CppUnit::Test* ODBCMySQLTest::suite()
CppUnit_addTest(pSuite, ODBCMySQLTest, testSessionTransaction);
CppUnit_addTest(pSuite, ODBCMySQLTest, testTransaction);
CppUnit_addTest(pSuite, ODBCMySQLTest, testTransactor);
CppUnit_addTest(pSuite, ODBCMySQLTest, testReconnect);
return pSuite;
}

View File

@ -922,6 +922,7 @@ CppUnit::Test* ODBCOracleTest::suite()
CppUnit_addTest(pSuite, ODBCOracleTest, testSessionTransaction);
CppUnit_addTest(pSuite, ODBCOracleTest, testTransaction);
CppUnit_addTest(pSuite, ODBCOracleTest, testTransactor);
CppUnit_addTest(pSuite, ODBCOracleTest, testReconnect);
return pSuite;
}

View File

@ -659,6 +659,7 @@ CppUnit::Test* ODBCPostgreSQLTest::suite()
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSessionTransaction);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testTransaction);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testTransactor);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testReconnect);
return pSuite;
}

View File

@ -809,6 +809,7 @@ CppUnit::Test* ODBCSQLServerTest::suite()
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSessionTransaction);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testTransaction);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testTransactor);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testReconnect);
return pSuite;
}

View File

@ -400,6 +400,7 @@ CppUnit::Test* ODBCSQLiteTest::suite()
CppUnit_addTest(pSuite, ODBCSQLiteTest, testSessionTransaction);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testTransaction);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testTransactor);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testReconnect);
return pSuite;
}

View File

@ -47,12 +47,14 @@
#include "Poco/Data/ODBC/Diagnostics.h"
#include "Poco/Data/ODBC/ODBCException.h"
#include "Poco/Data/ODBC/ODBCStatementImpl.h"
#include "Poco/Data/DataException.h"
#include <sqltypes.h>
#include <iostream>
using namespace Poco::Data::Keywords;
using Poco::Data::Session;
using Poco::Data::ConnectionFailedException;
using Poco::Data::CLOB;
using Poco::Data::ODBC::Utility;
using Poco::Data::ODBC::ODBCException;
@ -1187,6 +1189,23 @@ void ODBCTest::testTransactor()
}
void ODBCTest::testReconnect()
{
if (!_pSession) fail ("Test not available.");
std::string tableName("Person");
for (int i = 0; i < 8;)
{
recreatePersonTable();
_pSession->setFeature("autoBind", bindValue(i));
_pSession->setFeature("autoExtract", bindValue(i+1));
_pExecutor->reconnect();
i += 2;
}
}
bool ODBCTest::canConnect(const std::string& driver,
std::string& dsn,
std::string& uid,
@ -1262,9 +1281,9 @@ ODBCTest::SessionPtr ODBCTest::init(const std::string& driver,
try
{
return new Session(Poco::Data::ODBC::Connector::KEY, dbConnString);
}catch (ConnectionException& ex)
}catch (ConnectionFailedException& ex)
{
std::cout << ex.toString() << std::endl;
std::cout << ex.displayText() << std::endl;
return 0;
}
}

View File

@ -167,6 +167,8 @@ public:
virtual void testTransaction();
virtual void testTransactor();
virtual void testReconnect();
protected:
typedef Poco::Data::ODBC::Utility::DriverMap Drivers;

View File

@ -85,6 +85,7 @@ using Poco::Data::CLOB;
using Poco::Data::Date;
using Poco::Data::Time;
using Poco::Data::Transaction;
using Poco::Data::NotConnectedException;
using Poco::Data::ODBC::Utility;
using Poco::Data::ODBC::Preparator;
using Poco::Data::ODBC::ConnectionException;
@ -3763,3 +3764,44 @@ void SQLExecutor::transactor()
session().setFeature("autoCommit", autoCommit);
}
void SQLExecutor::reconnect()
{
std::string funct = "reconnect()";
std::string lastName = "lastName";
std::string firstName("firstName");
std::string address("Address");
int age = 133132;
int count = 0;
std::string result;
try { session() << "INSERT INTO PERSON VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(age), now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
count = 0;
try { session() << "SELECT COUNT(*) FROM PERSON", into(count), now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
assert (count == 1);
assert (session().isConnected());
session().close();
assert (!session().isConnected());
try
{
session() << "SELECT LastName FROM PERSON", into(result), now;
fail ("must fail");
}
catch(NotConnectedException&){ }
assert (!session().isConnected());
session().open();
assert (session().isConnected());
try { session() << "SELECT Age FROM PERSON", into(count), now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
assert (count == age);
assert (session().isConnected());
}

View File

@ -518,6 +518,8 @@ public:
void transaction(const std::string& connect);
void transactor();
void reconnect();
private:
static const std::string MULTI_INSERT;
static const std::string MULTI_SELECT;

View File

@ -65,7 +65,8 @@ public:
const std::string& name() const;
/// Returns the name associated with this connector.
Poco::AutoPtr<Poco::Data::SessionImpl> createSession(const std::string& connectionString);
Poco::AutoPtr<Poco::Data::SessionImpl> createSession(const std::string& connectionString,
std::size_t timeout = Poco::Data::SessionImpl::CONNECT_TIMEOUT_DEFAULT);
/// Creates a SQLite SessionImpl object and initializes it with the given connectionString.
static void registerConnector();

View File

@ -59,7 +59,8 @@ class SQLite_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl
/// Implements SessionImpl interface.
{
public:
SessionImpl(const std::string& fileName);
SessionImpl(const std::string& fileName,
std::size_t timeout = CONNECT_TIMEOUT_DEFAULT);
/// Creates the SessionImpl. Opens a connection to the database.
~SessionImpl();
@ -77,6 +78,9 @@ public:
void rollback();
/// Aborts a transaction.
void open(const std::string& connect = "");
/// Opens a connection to the Database.
void close();
/// Closes the session.
@ -107,8 +111,6 @@ public:
/// Returns the name of the connector.
private:
void open();
/// Opens a connection to the Database.
std::string _connector;
sqlite3* _pDB;

View File

@ -58,9 +58,10 @@ Connector::~Connector()
}
Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString)
Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString,
std::size_t timeout)
{
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString));
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString, timeout));
}

View File

@ -38,7 +38,10 @@
#include "Poco/Data/SQLite/Utility.h"
#include "Poco/Data/SQLite/SQLiteStatementImpl.h"
#include "Poco/Data/SQLite/Connector.h"
#include "Poco/Data/SQLite/SQLiteException.h"
#include "Poco/Data/Session.h"
#include "Poco/ActiveMethod.h"
#include "Poco/ActiveResult.h"
#include "Poco/String.h"
#include "Poco/Exception.h"
#include "sqlite3.h"
@ -55,8 +58,8 @@ const std::string SessionImpl::COMMIT_TRANSACTION("COMMIT");
const std::string SessionImpl::ABORT_TRANSACTION("ROLLBACK");
SessionImpl::SessionImpl(const std::string& fileName):
Poco::Data::AbstractSessionImpl<SessionImpl>(fileName),
SessionImpl::SessionImpl(const std::string& fileName, std::size_t timeout):
Poco::Data::AbstractSessionImpl<SessionImpl>(fileName, timeout),
_connector(toLower(Connector::KEY)),
_pDB(0),
_connected(false),
@ -133,14 +136,61 @@ bool SessionImpl::isTransactionIsolation(Poco::UInt32 ti)
}
void SessionImpl::open()
class ActiveConnector
{
int rc = sqlite3_open(connectionString().c_str(), &_pDB);
if (rc != 0)
public:
ActiveConnector(const std::string& connectString, sqlite3** ppDB):
connect(this, &ActiveConnector::connectImpl),
_connectString(connectString),
_ppDB(ppDB)
{
close();
Utility::throwException(rc);
poco_check_ptr(_ppDB);
}
ActiveMethod<int, void, ActiveConnector> connect;
private:
ActiveConnector();
inline int connectImpl()
{
return sqlite3_open(_connectString.c_str(), _ppDB);
}
std::string _connectString;
sqlite3** _ppDB;
};
void SessionImpl::open(const std::string& connect)
{
if (connect != connectionString())
{
if (isConnected())
throw InvalidAccessException("Session already connected");
if (!connect.empty())
setConnectionString(connect);
}
poco_assert_dbg (!connectionString().empty());
try
{
ActiveConnector connector(connectionString(), &_pDB);
ActiveResult<int> result = connector.connect();
if (!result.tryWait(getTimeout() * 1000))
throw ConnectionFailedException("Timed out.");
int rc = result.data();
if (rc != 0)
{
close();
Utility::throwException(rc);
}
} catch (SQLiteException& ex)
{
throw ConnectionFailedException(ex.displayText());
}
_connected = true;

View File

@ -43,6 +43,7 @@
#include "Poco/Data/SQLite/Connector.h"
#include "Poco/Data/SQLite/SQLiteException.h"
#include "Poco/Data/TypeHandler.h"
#include "Poco/Data/DataException.h"
#include "Poco/Tuple.h"
#include "Poco/Any.h"
#include "Poco/SharedPtr.h"
@ -71,6 +72,7 @@ using Poco::Data::Time;
using Poco::Data::AbstractExtractionVec;
using Poco::Data::AbstractExtractionVecVec;
using Poco::Data::AbstractBindingVec;
using Poco::Data::NotConnectedException;
using Poco::Tuple;
using Poco::Any;
using Poco::AnyCast;
@ -2317,6 +2319,48 @@ void SQLiteTest::testMultipleResults()
}
void SQLiteTest::testReconnect()
{
Session session (Poco::Data::SQLite::Connector::KEY, "dummy.db");
session << "DROP TABLE IF EXISTS Person", now;
session << "CREATE TABLE Person (LastName VARCHAR(30),"
"FirstName VARCHAR(30),"
"Address VARCHAR(30),"
"Age INTEGER)", now;
std::string lastName = "lastName";
std::string firstName("firstName");
std::string address("Address");
int age = 133132;
int count = 0;
std::string result;
session << "INSERT INTO PERSON VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(age), now;
count = 0;
session << "SELECT COUNT(*) FROM PERSON", into(count), now;
assert (count == 1);
assert (session.isConnected());
session.close();
assert (!session.isConnected());
try
{
session << "SELECT LastName FROM PERSON", into(result), now;
fail ("must fail");
}
catch(NotConnectedException&){ }
assert (!session.isConnected());
session.open();
assert (session.isConnected());
session << "SELECT Age FROM PERSON", into(count), now;
assert (count == age);
assert (session.isConnected());
}
void SQLiteTest::setUp()
{
}
@ -2404,6 +2448,7 @@ CppUnit::Test* SQLiteTest::suite()
CppUnit_addTest(pSuite, SQLiteTest, testBindingCount);
CppUnit_addTest(pSuite, SQLiteTest, testMultipleResults);
CppUnit_addTest(pSuite, SQLiteTest, testPair);
CppUnit_addTest(pSuite, SQLiteTest, testReconnect);
return pSuite;
}

View File

@ -129,6 +129,8 @@ public:
void testBindingCount();
void testMultipleResults();
void testReconnect();
void setUp();
void tearDown();

View File

@ -72,11 +72,12 @@ public:
typedef Poco::Any (C::*PropertyGetter)(const std::string&);
/// The getter method for a property.
AbstractSessionImpl(const std::string& connectionString): SessionImpl(connectionString),
_storage(std::string("deque")),
_bulk(false),
_emptyStringIsNull(false),
_forceEmptyString(false)
AbstractSessionImpl(const std::string& connectionString,
std::size_t timeout = CONNECT_TIMEOUT_DEFAULT): SessionImpl(connectionString, timeout),
_storage(std::string("deque")),
_bulk(false),
_emptyStringIsNull(false),
_forceEmptyString(false)
/// Creates the AbstractSessionImpl.
///
/// Adds "storage" property and sets the default internal storage container

View File

@ -66,7 +66,8 @@ public:
virtual const std::string& name() const = 0;
/// Returns the name associated with this connector.
virtual Poco::AutoPtr<SessionImpl> createSession(const std::string& connectionString) = 0;
virtual Poco::AutoPtr<SessionImpl> createSession(const std::string& connectionString,
std::size_t timeout = SessionImpl::CONNECT_TIMEOUT_DEFAULT) = 0;
/// Create a SessionImpl object and initialize it with the given connectionString.
};

View File

@ -62,6 +62,8 @@ POCO_DECLARE_EXCEPTION(Data_API, SessionPoolExhaustedException, DataException)
POCO_DECLARE_EXCEPTION(Data_API, SessionPoolExistsException, DataException)
POCO_DECLARE_EXCEPTION(Data_API, NoDataException, DataException)
POCO_DECLARE_EXCEPTION(Data_API, LengthExceededException, DataException)
POCO_DECLARE_EXCEPTION(Data_API, ConnectionFailedException, DataException)
POCO_DECLARE_EXCEPTION(Data_API, NotConnectedException, DataException)
} } // namespace Poco::Data

View File

@ -70,6 +70,7 @@ public:
void begin();
void commit();
void rollback();
void open(const std::string& connect = "");
void close();
bool isConnected();
bool canTransact();

View File

@ -173,6 +173,7 @@ class Data_API Session
/// For complete list of supported data types with their respective specifications, see the documentation for format in Foundation.
{
public:
static const std::size_t CONNECT_TIMEOUT_DEFAULT = SessionImpl::CONNECT_TIMEOUT_DEFAULT;
static const Poco::UInt32 TRANSACTION_READ_UNCOMMITTED = 0x00000001L;
static const Poco::UInt32 TRANSACTION_READ_COMMITTED = 0x00000002L;
static const Poco::UInt32 TRANSACTION_REPEATABLE_READ = 0x00000004L;
@ -181,11 +182,14 @@ public:
Session(Poco::AutoPtr<SessionImpl> ptrImpl);
/// Creates the Session.
Session(const std::string& connector, const std::string& connectionString);
Session(const std::string& connector,
const std::string& connectionString,
std::size_t timeout = CONNECT_TIMEOUT_DEFAULT);
/// Creates a new session, using the given connector (which must have
/// been registered), and connectionString.
Session(const std::string& connection);
Session(const std::string& connection,
std::size_t timeout = CONNECT_TIMEOUT_DEFAULT);
/// Creates a new session, using the given connection (must be in
/// "connection:///connectionString" format).
@ -211,6 +215,29 @@ public:
StatementImpl* createStatementImpl();
/// Creates a StatementImpl.
void open(const std::string& connect = "");
/// Opens the session using the supplied string.
/// Can also be used with default empty string to
/// reconnect a disconnected session.
/// If the connection is not established,
/// a ConnectionFailedException is thrown.
/// Zero timout means indefinite
void close();
/// Closes the session.
bool isConnected();
/// Returns true iff session is connected, false otherwise.
void reconnect();
/// Closes the session and opens it.
void setTimeout(std::size_t timeout);
/// Sets the session timeout value.
std::size_t getTimeout() const;
/// Returns the session timeout value.
void begin();
/// Starts a transaction.
@ -219,12 +246,6 @@ public:
void rollback();
/// Rolls back and ends a transaction.
void close();
/// Closes the session.
bool isConnected();
/// Returns true iff session is connected, false otherwise.
bool canTransact();
/// Returns true if session has transaction capabilities.
@ -296,7 +317,7 @@ public:
private:
Session();
Poco::AutoPtr<SessionImpl> _ptrImpl;
Poco::AutoPtr<SessionImpl> _pImpl;
StatementCreator _statementCreator;
};
@ -306,73 +327,97 @@ private:
//
inline StatementImpl* Session::createStatementImpl()
{
return _ptrImpl->createStatementImpl();
return _pImpl->createStatementImpl();
}
inline void Session::begin()
inline void Session::open(const std::string& connect)
{
return _ptrImpl->begin();
}
inline void Session::commit()
{
return _ptrImpl->commit();
}
inline void Session::rollback()
{
return _ptrImpl->rollback();
_pImpl->open(connect);
}
inline void Session::close()
{
_ptrImpl->close();
_pImpl->close();
}
inline bool Session::isConnected()
{
return _ptrImpl->isConnected();
return _pImpl->isConnected();
}
inline void Session::reconnect()
{
_pImpl->reconnect();
}
inline void Session::setTimeout(std::size_t timeout)
{
_pImpl->setTimeout(timeout);
}
inline std::size_t Session::getTimeout() const
{
return _pImpl->getTimeout();
}
inline void Session::begin()
{
return _pImpl->begin();
}
inline void Session::commit()
{
return _pImpl->commit();
}
inline void Session::rollback()
{
return _pImpl->rollback();
}
inline bool Session::canTransact()
{
return _ptrImpl->canTransact();
return _pImpl->canTransact();
}
inline bool Session::isTransaction()
{
return _ptrImpl->isTransaction();
return _pImpl->isTransaction();
}
inline void Session::setTransactionIsolation(Poco::UInt32 ti)
{
_ptrImpl->setTransactionIsolation(ti);
_pImpl->setTransactionIsolation(ti);
}
inline Poco::UInt32 Session::getTransactionIsolation()
{
return _ptrImpl->getTransactionIsolation();
return _pImpl->getTransactionIsolation();
}
inline bool Session::hasTransactionIsolation(Poco::UInt32 ti)
{
return _ptrImpl->hasTransactionIsolation(ti);
return _pImpl->hasTransactionIsolation(ti);
}
inline bool Session::isTransactionIsolation(Poco::UInt32 ti)
{
return _ptrImpl->isTransactionIsolation(ti);
return _pImpl->isTransactionIsolation(ti);
}
@ -385,37 +430,37 @@ inline std::string Session::uri(const std::string& connector,
inline std::string Session::uri()
{
return _ptrImpl->uri();
return _pImpl->uri();
}
inline void Session::setFeature(const std::string& name, bool state)
{
_ptrImpl->setFeature(name, state);
_pImpl->setFeature(name, state);
}
inline bool Session::getFeature(const std::string& name) const
{
return const_cast<SessionImpl*>(_ptrImpl.get())->getFeature(name);
return const_cast<SessionImpl*>(_pImpl.get())->getFeature(name);
}
inline void Session::setProperty(const std::string& name, const Poco::Any& value)
{
_ptrImpl->setProperty(name, value);
_pImpl->setProperty(name, value);
}
inline Poco::Any Session::getProperty(const std::string& name) const
{
return const_cast<SessionImpl*>(_ptrImpl.get())->getProperty(name);
return const_cast<SessionImpl*>(_pImpl.get())->getProperty(name);
}
inline SessionImpl* Session::impl()
{
return _ptrImpl;
return _pImpl;
}

View File

@ -83,11 +83,14 @@ public:
/// Lowers the reference count for the Connector registered under that key. If the count reaches zero,
/// the object is removed.
Session create(const std::string& key, const std::string& connectionString);
Session create(const std::string& key,
const std::string& connectionString,
std::size_t timeout = Session::CONNECT_TIMEOUT_DEFAULT);
/// Creates a Session for the given key with the connectionString. Throws an Poco:Data::UnknownDataBaseException
/// if no Connector is registered for that key.
Session create(const std::string& uri);
Session create(const std::string& uri,
std::size_t timeout = Session::CONNECT_TIMEOUT_DEFAULT);
/// Creates a Session for the given URI (must be in key:///connectionString format).
/// Throws an Poco:Data::UnknownDataBaseException if no Connector is registered for the key.

View File

@ -59,7 +59,14 @@ class Data_API SessionImpl: public Poco::RefCountedObject
/// SessionImpl objects are noncopyable.
{
public:
SessionImpl(const std::string& connectionString);
static const std::size_t CONNECT_TIMEOUT_INFINITE = 0;
/// Infinite connection/login timeout.
static const std::size_t CONNECT_TIMEOUT_DEFAULT = 30;
/// Default connection/login timeout in seconds.
SessionImpl(const std::string& connectionString,
std::size_t timeout = CONNECT_TIMEOUT_DEFAULT);
/// Creates the SessionImpl.
virtual ~SessionImpl();
@ -68,6 +75,29 @@ public:
virtual StatementImpl* createStatementImpl() = 0;
/// Creates a StatementImpl.
virtual void open(const std::string& connectionString = "") = 0;
/// Opens the session using the supplied string.
/// Can also be used with default empty string to reconnect
/// a disconnected session.
/// If the connection is not established within requested timeout
/// (specified in seconds), a ConnectionFailedException is thrown.
/// Zero timout means indefinite
virtual void close() = 0;
/// Closes the connection.
virtual bool isConnected() = 0;
/// Returns true if session is connected, false otherwise.
void setTimeout(std::size_t timeout);
/// Sets the session timeout value.
std::size_t getTimeout() const;
/// Returns the session timeout value.
void reconnect();
/// Closes the connection and opens it again.
virtual void begin() = 0;
/// Starts a transaction.
@ -77,12 +107,6 @@ public:
virtual void rollback() = 0;
/// Aborts a transaction.
virtual void close() = 0;
/// Closes the connection.
virtual bool isConnected() = 0;
/// Returns true if session is connected, false otherwise.
virtual bool canTransact() = 0;
/// Returns true if session has transaction capabilities.
@ -151,12 +175,19 @@ public:
/// Throws a NotSupportedException if the requested property is
/// not supported by the underlying implementation.
protected:
void setConnectionString(const std::string& connectionString);
/// Sets the connection string. Should only be called on
/// disconnetced sessions. Throws InvalidAccessException when called on
/// a connected session.
private:
SessionImpl();
SessionImpl(const SessionImpl&);
SessionImpl& operator = (const SessionImpl&);
std::string _connectionString;
std::size_t _timeout;
};
@ -169,6 +200,18 @@ inline const std::string& SessionImpl::connectionString()
}
inline void SessionImpl::setTimeout(std::size_t timeout)
{
_timeout = timeout;
}
inline std::size_t SessionImpl::getTimeout() const
{
return _timeout;
}
inline std::string SessionImpl::uri(const std::string& connector,
const std::string& connectionString)
{

View File

@ -76,6 +76,9 @@ public:
Statement operator << (const T& t)
/// Creates a Statement.
{
if (!_ptrImpl->isConnected())
throw NotConnectedException(_ptrImpl->connectionString());
Statement stmt(_ptrImpl->createStatementImpl());
stmt << t;
return stmt;

View File

@ -435,14 +435,14 @@ private:
State _state;
Limit _extrLimit;
std::size_t _lowerLimit;
std::size_t _lowerLimit;
std::vector<int> _columnsExtracted;
SessionImpl& _rSession;
Storage _storage;
std::ostringstream _ostr;
AbstractBindingVec _bindings;
AbstractExtractionVecVec _extractors;
std::size_t _curDataSet;
std::size_t _curDataSet;
BulkType _bulkBinding;
BulkType _bulkExtraction;

View File

@ -56,6 +56,8 @@ POCO_IMPLEMENT_EXCEPTION(SessionPoolExhaustedException, DataException, "No more
POCO_IMPLEMENT_EXCEPTION(SessionPoolExistsException, DataException, "Session already exists in the pool")
POCO_IMPLEMENT_EXCEPTION(NoDataException, DataException, "No data found")
POCO_IMPLEMENT_EXCEPTION(LengthExceededException, DataException, "Data too long")
POCO_IMPLEMENT_EXCEPTION(ConnectionFailedException, DataException, "Connection attempt failed")
POCO_IMPLEMENT_EXCEPTION(NotConnectedException, DataException, "Not connected to data source")
} } // namespace Poco::Data

View File

@ -44,7 +44,8 @@ namespace Data {
PooledSessionImpl::PooledSessionImpl(PooledSessionHolder* pHolder):
SessionImpl(pHolder->session()->connectionString()),
SessionImpl(pHolder->session()->connectionString(),
pHolder->session()->getTimeout()),
_pHolder(pHolder, true)
{
}
@ -122,6 +123,12 @@ void PooledSessionImpl::rollback()
}
void PooledSessionImpl::open(const std::string& connect)
{
access()->open(connect);
}
void PooledSessionImpl::close()
{
if (_pHolder)

View File

@ -45,30 +45,33 @@ namespace Poco {
namespace Data {
Session::Session(Poco::AutoPtr<SessionImpl> ptrImpl):
_ptrImpl(ptrImpl),
_statementCreator(ptrImpl)
Session::Session(Poco::AutoPtr<SessionImpl> pImpl):
_pImpl(pImpl),
_statementCreator(pImpl)
{
poco_check_ptr (ptrImpl.get());
poco_check_ptr (pImpl.get());
}
Session::Session(const std::string& connector, const std::string& connectionString)
Session::Session(const std::string& connector,
const std::string& connectionString,
std::size_t timeout)
{
Session newSession(SessionFactory::instance().create(connector, connectionString));
Session newSession(SessionFactory::instance().create(connector, connectionString, timeout));
swap(newSession);
}
Session::Session(const std::string& connection)
Session::Session(const std::string& connection,
std::size_t timeout)
{
Session newSession(SessionFactory::instance().create(connection));
Session newSession(SessionFactory::instance().create(connection, timeout));
swap(newSession);
}
Session::Session(const Session& other): _ptrImpl(other._ptrImpl),
_statementCreator(other._ptrImpl)
Session::Session(const Session& other): _pImpl(other._pImpl),
_statementCreator(other._pImpl)
{
}
@ -90,7 +93,7 @@ void Session::swap(Session& other)
{
using std::swap;
swap(_statementCreator, other._statementCreator);
swap(_ptrImpl, other._ptrImpl);
swap(_pImpl, other._pImpl);
}

View File

@ -81,21 +81,24 @@ void SessionFactory::remove(const std::string& key)
}
Session SessionFactory::create(const std::string& key, const std::string& connectionString)
Session SessionFactory::create(const std::string& key,
const std::string& connectionString,
std::size_t timeout)
{
Poco::FastMutex::ScopedLock lock(_mutex);
Connectors::iterator it = _connectors.find(toLower(key));
poco_assert (_connectors.end() != it);
return Session(it->second.ptrSI->createSession(connectionString));
return Session(it->second.ptrSI->createSession(connectionString, timeout));
}
Session SessionFactory::create(const std::string& uri)
Session SessionFactory::create(const std::string& uri,
std::size_t timeout)
{
URI u(uri);
poco_assert (!u.getPath().empty());
return create(u.getScheme(), u.getPath().substr(1));
return create(u.getScheme(), u.getPath().substr(1), timeout);
}

View File

@ -35,14 +35,16 @@
#include "Poco/Data/SessionImpl.h"
#include "Poco/Exception.h"
namespace Poco {
namespace Data {
SessionImpl::SessionImpl(const std::string& connectionString):
_connectionString(connectionString)
SessionImpl::SessionImpl(const std::string& connectionString, std::size_t timeout):
_connectionString(connectionString),
_timeout(timeout)
{
}
@ -52,4 +54,21 @@ SessionImpl::~SessionImpl()
}
void SessionImpl::reconnect()
{
close();
open();
}
void SessionImpl::setConnectionString(const std::string& connectionString)
{
if (isConnected())
throw Poco::InvalidAccessException("Can not change connection string on connected session."
" Close the session first.");
_connectionString = connectionString;
}
} } // namespace Poco::Data

View File

@ -45,6 +45,7 @@
#include "Poco/SharedPtr.h"
#include "Poco/DateTime.h"
#include "Poco/Exception.h"
#include "Poco/Data/DataException.h"
using Poco::icompare;
@ -74,6 +75,9 @@ StatementImpl::StatementImpl(SessionImpl& rSession):
_bulkBinding(BULK_UNDEFINED),
_bulkExtraction(BULK_UNDEFINED)
{
if (!_rSession.isConnected())
throw NotConnectedException(_rSession.connectionString());
_extractors.resize(1);
_columnsExtracted.resize(1, 0);
}
@ -87,6 +91,13 @@ StatementImpl::~StatementImpl()
std::size_t StatementImpl::execute()
{
resetExtraction();
if (!_rSession.isConnected())
{
_state = ST_DONE;
throw NotConnectedException(_rSession.connectionString());
}
std::size_t lim = 0;
if (_lowerLimit > _extrLimit.value())
throw LimitException("Illegal Statement state. Upper limit must not be smaller than the lower limit.");

View File

@ -53,9 +53,10 @@ Connector::~Connector()
}
Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString)
Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString,
std::size_t timeout)
{
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString));
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString, timeout));
}

View File

@ -60,7 +60,8 @@ public:
const std::string& name() const;
/// Returns the name associated with this connector.
Poco::AutoPtr<Poco::Data::SessionImpl> createSession(const std::string& connectionString);
Poco::AutoPtr<Poco::Data::SessionImpl> createSession(const std::string& connectionString,
std::size_t timeout = SessionImpl::CONNECT_TIMEOUT_DEFAULT);
/// Creates a test SessionImpl object and initializes it with the given connectionString.
static void addToFactory();

View File

@ -42,6 +42,7 @@
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/Data/SimpleRowFormatter.h"
#include "Poco/Data/DataException.h"
#include "Connector.h"
#include "Poco/BinaryReader.h"
#include "Poco/BinaryWriter.h"
@ -89,6 +90,7 @@ using Poco::Data::AbstractExtractionVec;
using Poco::Data::AbstractExtractionVecVec;
using Poco::Data::AbstractBinding;
using Poco::Data::AbstractBindingVec;
using Poco::Data::NotConnectedException;
DataTest::DataTest(const std::string& name): CppUnit::TestCase(name)
@ -110,6 +112,10 @@ void DataTest::testSession()
assert ("cs" == sess.impl()->connectionString());
assert ("test:///cs" == sess.uri());
assert (sess.getTimeout() == Session::CONNECT_TIMEOUT_DEFAULT);
sess.setTimeout(123);
assert (sess.getTimeout() == 123);
Session sess2(SessionFactory::instance().create("TeSt:///Cs"));
assert ("test" == sess2.impl()->connectorName());
assert ("Cs" == sess2.impl()->connectionString());
@ -122,6 +128,36 @@ void DataTest::testSession()
std::string str;
Statement stmt = (sess << "SELECT * FROM Strings", into(str), limit(50));
stmt.execute();
sess.close();
assert (!sess.getFeature("connected"));
assert (!sess.isConnected());
try
{
stmt.execute();
fail ("must fail");
} catch (NotConnectedException&) { }
try
{
sess << "SELECT * FROM Strings", now;
fail ("must fail");
} catch (NotConnectedException&) { }
sess.open();
assert (sess.getFeature("connected"));
assert (sess.isConnected());
sess << "SELECT * FROM Strings", now;
stmt.execute();
sess.reconnect();
assert (sess.getFeature("connected"));
assert (sess.isConnected());
sess << "SELECT * FROM Strings", now;
stmt.execute();
}

View File

@ -40,8 +40,8 @@ namespace Data {
namespace Test {
SessionImpl::SessionImpl(const std::string& init):
Poco::Data::AbstractSessionImpl<SessionImpl>(init),
SessionImpl::SessionImpl(const std::string& init, std::size_t timeout):
Poco::Data::AbstractSessionImpl<SessionImpl>(init, timeout),
_f(false),
_connected(true)
{
@ -60,6 +60,24 @@ SessionImpl::~SessionImpl()
}
void SessionImpl::open(const std::string& connectionString)
{
_connected = true;
}
void SessionImpl::close()
{
_connected = false;
}
bool SessionImpl::isConnected()
{
return _connected;
}
Poco::Data::StatementImpl* SessionImpl::createStatementImpl()
{
return new TestStatementImpl(*this);
@ -81,18 +99,6 @@ void SessionImpl::rollback()
}
void SessionImpl::close()
{
_connected = false;
}
bool SessionImpl::isConnected()
{
return _connected;
}
bool SessionImpl::canTransact()
{
return false;

View File

@ -50,7 +50,8 @@ class SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
/// A no-op implementation of SessionImpl for testing.
{
public:
SessionImpl(const std::string& init);
SessionImpl(const std::string& init,
std::size_t timeout = CONNECT_TIMEOUT_DEFAULT);
/// Creates the SessionImpl. Opens a connection to the database.
~SessionImpl();
@ -59,6 +60,16 @@ public:
Poco::Data::StatementImpl* createStatementImpl();
/// Returns an test StatementImpl.
void open(const std::string& connectionString = "");
/// Opens the session.
void close();
/// Closes the session.
bool isConnected();
/// Returns true if session is connected to the database,
/// false otherwise.
void begin();
/// Starts a transaction.
@ -67,13 +78,6 @@ public:
void rollback();
/// Aborts a transaction.
void close();
/// Closes the session.
bool isConnected();
/// Returns true if session is connected to the database,
/// false otherwise.
bool canTransact();
/// Returns true if session has transaction capabilities.