mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-14 06:55:49 +02:00
[SF 2580108] Improve transaction handling
This commit is contained in:
@@ -4,6 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MySQL", "MySQL_VS90.vcproj", "{D9C692A6-D089-4269-B444-C445ED192F0D}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSuite", "testsuite\TestSuite_VS90.vcproj", "{1B30A91B-375F-11DB-837B-00123FC423B5}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{D9C692A6-D089-4269-B444-C445ED192F0D} = {D9C692A6-D089-4269-B444-C445ED192F0D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@@ -41,7 +41,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=".\include;.\src;..\..\Foundation\include;..\..\Data\include"
|
||||
AdditionalIncludeDirectories=".\include;.\src;..\..\Foundation\include;..\..\Data\include;.\include\Poco\Data\MySQL\mysql"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MYSQL_EXPORTS;POCO_DLL;NO_TCL;THREADSAFE;__LCC__"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
|
@@ -89,7 +89,7 @@ private:
|
||||
|
||||
private:
|
||||
|
||||
MYSQL* h;
|
||||
MYSQL* _pHandle;
|
||||
};
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ private:
|
||||
|
||||
inline SessionHandle::operator MYSQL* ()
|
||||
{
|
||||
return h;
|
||||
return _pHandle;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,146 +1,221 @@
|
||||
//
|
||||
// SessionImpl.h
|
||||
//
|
||||
// $Id: //poco/1.4/Data/MySQL/include/Poco/Data/MySQL/SessionImpl.h#1 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: MySQL
|
||||
// Module: SessionImpl
|
||||
//
|
||||
// Definition of the SessionImpl class.
|
||||
//
|
||||
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#ifndef Data_MySQL_SessionImpl_INCLUDED
|
||||
#define Data_MySQL_SessionImpl_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Data/MySQL/MySQL.h"
|
||||
#include "Poco/Data/AbstractSessionImpl.h"
|
||||
#include "Poco/Data/MySQL/SessionHandle.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace MySQL {
|
||||
|
||||
|
||||
class MySQL_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
|
||||
/// Implements SessionImpl interface
|
||||
{
|
||||
public:
|
||||
|
||||
SessionImpl(const std::string& connectionString);
|
||||
/// Creates the SessionImpl. Opens a connection to the database
|
||||
///
|
||||
/// Connection string format:
|
||||
/// <str> == <assignment> | <assignment> ';' <str>
|
||||
/// <assignment> == <name> '=' <value>
|
||||
/// <name> == 'host' | 'port' | 'user' | 'password' | 'db' } 'compress' | 'auto-reconnect'
|
||||
/// <value> == [~;]*
|
||||
///
|
||||
/// for compress and auto-reconnect correct values are true/false
|
||||
/// for port - numeric in decimal notation
|
||||
///
|
||||
|
||||
~SessionImpl();
|
||||
/// Destroys the SessionImpl.
|
||||
|
||||
virtual Poco::Data::StatementImpl* createStatementImpl();
|
||||
/// Returns an MySQL StatementImpl
|
||||
|
||||
virtual void begin();
|
||||
/// Starts a transaction
|
||||
|
||||
virtual void commit();
|
||||
/// Commits and ends a transaction
|
||||
|
||||
virtual void rollback();
|
||||
/// Aborts a transaction
|
||||
|
||||
virtual void close();
|
||||
/// Closes the connection
|
||||
|
||||
virtual bool isConnected();
|
||||
/// Returns true iff session is connected.
|
||||
|
||||
virtual bool isTransaction();
|
||||
/// Returns true iff a transaction is in progress.
|
||||
|
||||
void setInsertId(const std::string&, const Poco::Any&);
|
||||
/// Try to set insert id - do nothing.
|
||||
|
||||
Poco::Any getInsertId(const std::string&);
|
||||
/// Get insert id
|
||||
|
||||
SessionHandle& handle();
|
||||
// Get handle
|
||||
|
||||
//
|
||||
// SessionImpl.h
|
||||
//
|
||||
// $Id: //poco/1.4/Data/MySQL/include/Poco/Data/MySQL/SessionImpl.h#1 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: MySQL
|
||||
// Module: SessionImpl
|
||||
//
|
||||
// Definition of the SessionImpl class.
|
||||
//
|
||||
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#ifndef Data_MySQL_SessionImpl_INCLUDED
|
||||
#define Data_MySQL_SessionImpl_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Data/MySQL/MySQL.h"
|
||||
#include "Poco/Data/AbstractSessionImpl.h"
|
||||
#include "Poco/Data/MySQL/SessionHandle.h"
|
||||
#include "Poco/Mutex.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace MySQL {
|
||||
|
||||
|
||||
class MySQL_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
|
||||
/// Implements SessionImpl interface
|
||||
{
|
||||
public:
|
||||
static const std::string MYSQL_READ_UNCOMMITTED;
|
||||
static const std::string MYSQL_READ_COMMITTED;
|
||||
static const std::string MYSQL_REPEATABLE_READ;
|
||||
static const std::string MYSQL_SERIALIZABLE;
|
||||
|
||||
SessionImpl(const std::string& connectionString);
|
||||
/// Creates the SessionImpl. Opens a connection to the database
|
||||
///
|
||||
/// Connection string format:
|
||||
/// <str> == <assignment> | <assignment> ';' <str>
|
||||
/// <assignment> == <name> '=' <value>
|
||||
/// <name> == 'host' | 'port' | 'user' | 'password' | 'db' } 'compress' | 'auto-reconnect'
|
||||
/// <value> == [~;]*
|
||||
///
|
||||
/// for compress and auto-reconnect correct values are true/false
|
||||
/// for port - numeric in decimal notation
|
||||
///
|
||||
|
||||
~SessionImpl();
|
||||
/// Destroys the SessionImpl.
|
||||
|
||||
Poco::Data::StatementImpl* createStatementImpl();
|
||||
/// Returns an MySQL StatementImpl
|
||||
|
||||
void begin();
|
||||
/// Starts a transaction
|
||||
|
||||
void commit();
|
||||
/// Commits and ends a transaction
|
||||
|
||||
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.
|
||||
|
||||
bool isTransaction();
|
||||
/// Returns true iff a transaction is a transaction is in progress, false otherwise.
|
||||
|
||||
void setTransactionIsolation(Poco::UInt32 ti);
|
||||
/// Sets the transaction isolation level.
|
||||
|
||||
Poco::UInt32 getTransactionIsolation();
|
||||
/// Returns the transaction isolation level.
|
||||
|
||||
bool hasTransactionIsolation(Poco::UInt32 ti);
|
||||
/// Returns true iff the transaction isolation level corresponding
|
||||
/// to the supplied bitmask is supported.
|
||||
|
||||
bool isTransactionIsolation(Poco::UInt32 ti);
|
||||
/// Returns true iff the transaction isolation level corresponds
|
||||
/// to the supplied bitmask.
|
||||
|
||||
void autoCommit(const std::string&, bool val);
|
||||
/// Sets autocommit property for the session.
|
||||
|
||||
bool isAutoCommit(const std::string& name="");
|
||||
/// Returns autocommit property value.
|
||||
|
||||
void setInsertId(const std::string&, const Poco::Any&);
|
||||
/// Try to set insert id - do nothing.
|
||||
|
||||
Poco::Any getInsertId(const std::string&);
|
||||
/// Get insert id
|
||||
|
||||
SessionHandle& handle();
|
||||
// Get handle
|
||||
|
||||
const std::string& connectorName();
|
||||
/// Returns the name of the connector.
|
||||
|
||||
private:
|
||||
|
||||
std::string _connector;
|
||||
SessionHandle _mysql;
|
||||
bool _connected;
|
||||
int _inTransaction;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
|
||||
inline void SessionImpl::setInsertId(const std::string&, const Poco::Any&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
inline Poco::Any SessionImpl::getInsertId(const std::string&)
|
||||
{
|
||||
return Poco::Any(Poco::UInt64(mysql_insert_id(_mysql)));
|
||||
}
|
||||
|
||||
|
||||
inline SessionHandle& SessionImpl::handle()
|
||||
{
|
||||
return _mysql;
|
||||
|
||||
private:
|
||||
|
||||
template <typename T>
|
||||
inline T& getValue(MYSQL_BIND* pResult, T& val)
|
||||
{
|
||||
return val = *((T*) pResult->buffer);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& getSetting(const std::string& name, T& val)
|
||||
/// Returns required setting.
|
||||
/// Limited to one setting at a time.
|
||||
{
|
||||
StatementExecutor ex(_handle);
|
||||
ResultMetadata metadata;
|
||||
metadata.reset();
|
||||
ex.prepare(Poco::format("SELECT @@%s", name));
|
||||
metadata.init(ex);
|
||||
|
||||
if (metadata.columnsReturned() > 0)
|
||||
ex.bindResult(metadata.row());
|
||||
else
|
||||
throw InvalidArgumentException("No data returned.");
|
||||
|
||||
ex.execute(); ex.fetch();
|
||||
MYSQL_BIND* pResult = metadata.row();
|
||||
return getValue<T>(pResult, val);
|
||||
}
|
||||
|
||||
std::string _connector;
|
||||
SessionHandle _handle;
|
||||
bool _connected;
|
||||
bool _inTransaction;
|
||||
Poco::FastMutex _mutex;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
inline bool SessionImpl::canTransact()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline void SessionImpl::setInsertId(const std::string&, const Poco::Any&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
inline Poco::Any SessionImpl::getInsertId(const std::string&)
|
||||
{
|
||||
return Poco::Any(Poco::UInt64(mysql_insert_id(_handle)));
|
||||
}
|
||||
|
||||
|
||||
inline SessionHandle& SessionImpl::handle()
|
||||
{
|
||||
return _handle;
|
||||
}
|
||||
|
||||
|
||||
inline const std::string& SessionImpl::connectorName()
|
||||
{
|
||||
return _connector;
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::MySQL
|
||||
|
||||
|
||||
#endif // Data_MySQL_SessionImpl_INCLUDED
|
||||
}
|
||||
|
||||
|
||||
inline bool SessionImpl::isTransactionIsolation(Poco::UInt32 ti)
|
||||
{
|
||||
return getTransactionIsolation() == ti;
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
inline std::string& SessionImpl::getValue(MYSQL_BIND* pResult, std::string& val)
|
||||
{
|
||||
val.assign((char*) pResult->buffer, pResult->buffer_length);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::MySQL
|
||||
|
||||
|
||||
#endif // Data_MySQL_SessionImpl_INCLUDED
|
||||
|
@@ -96,7 +96,7 @@ private:
|
||||
|
||||
private:
|
||||
|
||||
MYSQL_STMT* h;
|
||||
MYSQL_STMT* _pHandle;
|
||||
int _state;
|
||||
std::string _query;
|
||||
};
|
||||
@@ -108,7 +108,7 @@ private:
|
||||
|
||||
inline StatementExecutor::operator MYSQL_STMT* ()
|
||||
{
|
||||
return h;
|
||||
return _pHandle;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -144,43 +144,24 @@ void MySQLStatementImpl::compileImpl()
|
||||
_metadata.init(_stmt);
|
||||
|
||||
if (_metadata.columnsReturned() > 0)
|
||||
{
|
||||
_stmt.bindResult(_metadata.row());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MySQLStatementImpl::bindImpl()
|
||||
{
|
||||
//
|
||||
// Bind all bindings
|
||||
//
|
||||
|
||||
Poco::Data::AbstractBindingVec& binds = bindings();
|
||||
size_t pos = 0;
|
||||
Poco::Data::AbstractBindingVec::iterator it = binds.begin();
|
||||
Poco::Data::AbstractBindingVec::iterator itEnd = binds.end();
|
||||
for (; it != itEnd && (*it)->canBind(); ++it)
|
||||
{
|
||||
Poco::Data::AbstractBindingVec& binds = bindings();
|
||||
size_t pos = 0;
|
||||
Poco::Data::AbstractBindingVec::iterator it = binds.begin();
|
||||
Poco::Data::AbstractBindingVec::iterator itEnd = binds.end();
|
||||
|
||||
for (; it != itEnd && (*it)->canBind(); ++it)
|
||||
{
|
||||
(*it)->bind(pos);
|
||||
pos += (*it)->numOfColumnsHandled();
|
||||
}
|
||||
(*it)->bind(pos);
|
||||
pos += (*it)->numOfColumnsHandled();
|
||||
}
|
||||
|
||||
//
|
||||
// And bind them to statement
|
||||
//
|
||||
|
||||
_stmt.bindParams(_binder.getBindArray(), _binder.size());
|
||||
|
||||
//
|
||||
// And execute
|
||||
//
|
||||
|
||||
_stmt.execute();
|
||||
|
||||
_hasNext = NEXT_DONTKNOW;
|
||||
}
|
||||
|
||||
|
@@ -44,12 +44,8 @@ namespace MySQL {
|
||||
|
||||
SessionHandle::SessionHandle(MYSQL* mysql)
|
||||
{
|
||||
h = mysql_init(mysql);
|
||||
|
||||
if (!h)
|
||||
{
|
||||
if (!(_pHandle = mysql_init(mysql)))
|
||||
throw ConnectionException("mysql_init error");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,74 +57,54 @@ SessionHandle::~SessionHandle()
|
||||
|
||||
void SessionHandle::options(mysql_option opt)
|
||||
{
|
||||
int res = mysql_options(h, opt, 0);
|
||||
|
||||
if (res != 0)
|
||||
{
|
||||
throw ConnectionException("mysql_options error", h);
|
||||
}
|
||||
if (mysql_options(_pHandle, opt, 0) != 0)
|
||||
throw ConnectionException("mysql_options error", _pHandle);
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::options(mysql_option opt, bool b)
|
||||
{
|
||||
my_bool tmp = b;
|
||||
int res = mysql_options(h, opt, &tmp);
|
||||
|
||||
if (res != 0)
|
||||
{
|
||||
throw ConnectionException("mysql_options error", h);
|
||||
}
|
||||
if (mysql_options(_pHandle, opt, &tmp) != 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(h, host, user, password, db, port, 0, 0))
|
||||
{
|
||||
throw ConnectionException("create session: mysql_real_connect error", h);
|
||||
}
|
||||
if (!mysql_real_connect(_pHandle, host, user, password, db, port, 0, 0))
|
||||
throw ConnectionException("create session: mysql_real_connect error", _pHandle);
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::close()
|
||||
{
|
||||
if (h)
|
||||
if (_pHandle)
|
||||
{
|
||||
mysql_close(h);
|
||||
h = 0;
|
||||
mysql_close(_pHandle);
|
||||
_pHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::startTransaction()
|
||||
{
|
||||
int res = mysql_autocommit(h, false);
|
||||
|
||||
if (res != 0)
|
||||
{
|
||||
throw TransactionException("Start transaction failed.", h);
|
||||
}
|
||||
if (mysql_autocommit(_pHandle, false) != 0)
|
||||
throw TransactionException("Start transaction failed.", _pHandle);
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::commit()
|
||||
{
|
||||
int res = mysql_commit(h);
|
||||
|
||||
if (res != 0)
|
||||
{
|
||||
throw TransactionException("Commit failed.", h);
|
||||
}
|
||||
if (mysql_commit(_pHandle) != 0)
|
||||
throw TransactionException("Commit failed.", _pHandle);
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::rollback()
|
||||
{
|
||||
int res = mysql_rollback(h);
|
||||
|
||||
if (res != 0)
|
||||
{
|
||||
throw TransactionException("Rollback failed.", h);
|
||||
}
|
||||
if (mysql_rollback(_pHandle) != 0)
|
||||
throw TransactionException("Rollback failed.", _pHandle);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,233 +1,271 @@
|
||||
//
|
||||
// MySQLException.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/Data/MySQL/src/SessionImpl.cpp#1 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: MySQL
|
||||
// Module: SessionImpl
|
||||
//
|
||||
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/MySQL/SessionImpl.h"
|
||||
#include "Poco/Data/MySQL/MySQLStatementImpl.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/String.h"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string copyStripped(std::string::const_iterator from, std::string::const_iterator to)
|
||||
{
|
||||
// skip leading spaces
|
||||
while ((from != to) && isspace(*from)) from++;
|
||||
// skip trailing spaces
|
||||
while ((from != to) && isspace(*(to - 1))) to--;
|
||||
|
||||
return std::string(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace MySQL {
|
||||
|
||||
|
||||
SessionImpl::SessionImpl(const std::string& connectionString) :
|
||||
Poco::Data::AbstractSessionImpl<SessionImpl>(toLower(connectionString)),
|
||||
_mysql(0),
|
||||
_connected(false),
|
||||
_inTransaction(0)
|
||||
{
|
||||
addProperty("insertId",
|
||||
&SessionImpl::setInsertId,
|
||||
&SessionImpl::getInsertId);
|
||||
|
||||
std::map<std::string, std::string> options;
|
||||
|
||||
// Default values
|
||||
options["host"] = "localhost";
|
||||
options["port"] = "3306";
|
||||
options["user"] = "";
|
||||
options["password"] = "";
|
||||
options["db"] = "";
|
||||
options["compress"] = "";
|
||||
options["auto-reconnect"] = "";
|
||||
|
||||
//
|
||||
// Parse string
|
||||
//
|
||||
|
||||
for (std::string::const_iterator start = connectionString.begin();;)
|
||||
{
|
||||
// find next ';'
|
||||
std::string::const_iterator finish = std::find(start, connectionString.end(), ';');
|
||||
|
||||
// find '='
|
||||
std::string::const_iterator middle = std::find(start, finish, '=');
|
||||
|
||||
if (middle == finish)
|
||||
{
|
||||
throw MySQLException("create session: bad connection string format, can not find '='");
|
||||
}
|
||||
|
||||
// Parse name and value, skip all spaces
|
||||
options[copyStripped(start, middle)] = copyStripped(middle + 1, finish);
|
||||
|
||||
if ((finish == connectionString.end()) || (finish + 1 == connectionString.end()))
|
||||
{
|
||||
// end of parse
|
||||
break;
|
||||
}
|
||||
|
||||
// move start position after ';'
|
||||
start = finish + 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Checking
|
||||
//
|
||||
|
||||
if (options["user"] == "")
|
||||
{
|
||||
throw MySQLException("create session: specify user name");
|
||||
}
|
||||
|
||||
if (options["db"] == "")
|
||||
{
|
||||
throw MySQLException("create session: specify database");
|
||||
}
|
||||
|
||||
unsigned int port = 0;
|
||||
if (!NumberParser::tryParseUnsigned(options["port"], port) || 0 == port || port > 65535)
|
||||
{
|
||||
throw MySQLException("create session: specify correct port (numeric in decimal notation)");
|
||||
}
|
||||
|
||||
//
|
||||
// Options
|
||||
//
|
||||
|
||||
if (options["compress"] == "true")
|
||||
{
|
||||
_mysql.options(MYSQL_OPT_COMPRESS);
|
||||
}
|
||||
else if (options["compress"] == "false")
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
else if (options["compress"] != "")
|
||||
{
|
||||
throw MySQLException("create session: specify correct compress option (true or false) or skip it");
|
||||
}
|
||||
|
||||
if (options["auto-reconnect"] == "true")
|
||||
{
|
||||
_mysql.options(MYSQL_OPT_RECONNECT, true);
|
||||
}
|
||||
else if (options["auto-reconnect"] == "false")
|
||||
{
|
||||
_mysql.options(MYSQL_OPT_RECONNECT, false);
|
||||
}
|
||||
else if (options["auto-reconnect"] != "")
|
||||
{
|
||||
throw MySQLException("create session: specify correct auto-reconnect option (true or false) or skip it");
|
||||
}
|
||||
|
||||
//
|
||||
// Real connect
|
||||
//
|
||||
|
||||
_mysql.connect(
|
||||
options["host"].c_str(),
|
||||
options["user"].c_str(),
|
||||
options["password"].c_str(),
|
||||
options["db"].c_str(),
|
||||
port);
|
||||
|
||||
_connected = true;
|
||||
}
|
||||
|
||||
|
||||
SessionImpl::~SessionImpl()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
Poco::Data::StatementImpl* SessionImpl::createStatementImpl()
|
||||
{
|
||||
return new MySQLStatementImpl(*this);
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::begin()
|
||||
{
|
||||
_mysql.startTransaction();
|
||||
_inTransaction++;
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::commit()
|
||||
{
|
||||
_mysql.commit();
|
||||
_inTransaction--;
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::rollback()
|
||||
{
|
||||
_mysql.rollback();
|
||||
_inTransaction--;
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::close()
|
||||
{
|
||||
if (_connected)
|
||||
{
|
||||
_mysql.close();
|
||||
_connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::isConnected()
|
||||
{
|
||||
return _connected;
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::isTransaction()
|
||||
{
|
||||
return (_inTransaction > 0);
|
||||
}
|
||||
|
||||
|
||||
}}}
|
||||
//
|
||||
// MySQLException.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/Data/MySQL/src/SessionImpl.cpp#1 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: MySQL
|
||||
// Module: SessionImpl
|
||||
//
|
||||
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/MySQL/SessionImpl.h"
|
||||
#include "Poco/Data/MySQL/MySQLStatementImpl.h"
|
||||
#include "Poco/Data/MySQL/StatementExecutor.h"
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/String.h"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string copyStripped(std::string::const_iterator from, std::string::const_iterator to)
|
||||
{
|
||||
// skip leading spaces
|
||||
while ((from != to) && isspace(*from)) from++;
|
||||
// skip trailing spaces
|
||||
while ((from != to) && isspace(*(to - 1))) to--;
|
||||
|
||||
return std::string(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace MySQL {
|
||||
|
||||
|
||||
const std::string SessionImpl::MYSQL_READ_UNCOMMITTED = "READ UNCOMMITTED";
|
||||
const std::string SessionImpl::MYSQL_READ_COMMITTED = "READ COMMITTED";
|
||||
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)),
|
||||
_handle(0),
|
||||
_connected(false),
|
||||
_inTransaction(false)
|
||||
{
|
||||
addProperty("insertId",
|
||||
&SessionImpl::setInsertId,
|
||||
&SessionImpl::getInsertId);
|
||||
|
||||
std::map<std::string, std::string> options;
|
||||
|
||||
// Default values
|
||||
options["host"] = "localhost";
|
||||
options["port"] = "3306";
|
||||
options["user"] = "";
|
||||
options["password"] = "";
|
||||
options["db"] = "";
|
||||
options["compress"] = "";
|
||||
options["auto-reconnect"] = "";
|
||||
|
||||
for (std::string::const_iterator start = connectionString.begin();;)
|
||||
{
|
||||
std::string::const_iterator finish = std::find(start, connectionString.end(), ';');
|
||||
std::string::const_iterator middle = std::find(start, finish, '=');
|
||||
|
||||
if (middle == finish)
|
||||
throw MySQLException("create session: bad connection string format, can not find '='");
|
||||
|
||||
options[copyStripped(start, middle)] = copyStripped(middle + 1, finish);
|
||||
|
||||
if ((finish == connectionString.end()) || (finish + 1 == connectionString.end())) break;
|
||||
|
||||
start = finish + 1;
|
||||
}
|
||||
|
||||
if (options["user"] == "")
|
||||
throw MySQLException("create session: specify user name");
|
||||
|
||||
if (options["db"] == "")
|
||||
throw MySQLException("create session: specify database");
|
||||
|
||||
unsigned int port = 0;
|
||||
if (!NumberParser::tryParseUnsigned(options["port"], port) || 0 == port || port > 65535)
|
||||
throw MySQLException("create session: specify correct port (numeric in decimal notation)");
|
||||
|
||||
if (options["compress"] == "true")
|
||||
_handle.options(MYSQL_OPT_COMPRESS);
|
||||
else if (options["compress"] == "false")
|
||||
;
|
||||
else if (options["compress"] != "")
|
||||
throw MySQLException("create session: specify correct compress option (true or false) or skip it");
|
||||
|
||||
if (options["auto-reconnect"] == "true")
|
||||
_handle.options(MYSQL_OPT_RECONNECT, true);
|
||||
else if (options["auto-reconnect"] == "false")
|
||||
_handle.options(MYSQL_OPT_RECONNECT, false);
|
||||
else if (options["auto-reconnect"] != "")
|
||||
throw MySQLException("create session: specify correct auto-reconnect option (true or false) or skip it");
|
||||
|
||||
// Real connect
|
||||
_handle.connect(
|
||||
options["host"].c_str(),
|
||||
options["user"].c_str(),
|
||||
options["password"].c_str(),
|
||||
options["db"].c_str(),
|
||||
port);
|
||||
|
||||
addFeature("autoCommit",
|
||||
&SessionImpl::autoCommit,
|
||||
&SessionImpl::isAutoCommit);
|
||||
|
||||
_connected = true;
|
||||
}
|
||||
|
||||
|
||||
SessionImpl::~SessionImpl()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
Poco::Data::StatementImpl* SessionImpl::createStatementImpl()
|
||||
{
|
||||
return new MySQLStatementImpl(*this);
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::begin()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock l(_mutex);
|
||||
|
||||
if (_inTransaction)
|
||||
throw Poco::InvalidAccessException("Already in transaction.");
|
||||
|
||||
_handle.startTransaction();
|
||||
_inTransaction = true;
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::commit()
|
||||
{
|
||||
_handle.commit();
|
||||
_inTransaction = false;
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::rollback()
|
||||
{
|
||||
_handle.rollback();
|
||||
_inTransaction = false;
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::autoCommit(const std::string&, bool val)
|
||||
{
|
||||
StatementExecutor ex(_handle);
|
||||
ex.prepare(Poco::format("SET autocommit=%d", val ? 1 : 0));
|
||||
ex.execute();
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::isAutoCommit(const std::string&)
|
||||
{
|
||||
int ac = 0;
|
||||
return 1 == getSetting("autocommit", ac);
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::setTransactionIsolation(Poco::UInt32 ti)
|
||||
{
|
||||
std::string isolation;
|
||||
switch (ti)
|
||||
{
|
||||
case Session::TRANSACTION_READ_UNCOMMITTED:
|
||||
isolation = MYSQL_READ_UNCOMMITTED; break;
|
||||
case Session::TRANSACTION_READ_COMMITTED:
|
||||
isolation = MYSQL_READ_COMMITTED; break;
|
||||
case Session::TRANSACTION_REPEATABLE_READ:
|
||||
isolation = MYSQL_REPEATABLE_READ; break;
|
||||
case Session::TRANSACTION_SERIALIZABLE:
|
||||
isolation = MYSQL_SERIALIZABLE; break;
|
||||
default:
|
||||
throw Poco::InvalidArgumentException("setTransactionIsolation()");
|
||||
}
|
||||
|
||||
StatementExecutor ex(_handle);
|
||||
ex.prepare(Poco::format("SET SESSION TRANSACTION ISOLATION LEVEL %s", isolation));
|
||||
ex.execute();
|
||||
}
|
||||
|
||||
|
||||
Poco::UInt32 SessionImpl::getTransactionIsolation()
|
||||
{
|
||||
std::string isolation;
|
||||
getSetting("tx_isolation", isolation);
|
||||
Poco::replaceInPlace(isolation, "-", " ");
|
||||
if (MYSQL_READ_UNCOMMITTED == isolation)
|
||||
return Session::TRANSACTION_READ_UNCOMMITTED;
|
||||
else if (MYSQL_READ_COMMITTED == isolation)
|
||||
return Session::TRANSACTION_READ_COMMITTED;
|
||||
else if (MYSQL_REPEATABLE_READ == isolation)
|
||||
return Session::TRANSACTION_REPEATABLE_READ;
|
||||
else if (MYSQL_SERIALIZABLE == isolation)
|
||||
return Session::TRANSACTION_SERIALIZABLE;
|
||||
|
||||
throw InvalidArgumentException("getTransactionIsolation()");
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::hasTransactionIsolation(Poco::UInt32 ti)
|
||||
{
|
||||
return Session::TRANSACTION_READ_UNCOMMITTED == ti ||
|
||||
Session::TRANSACTION_READ_COMMITTED == ti ||
|
||||
Session::TRANSACTION_REPEATABLE_READ == ti ||
|
||||
Session::TRANSACTION_SERIALIZABLE == ti;
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::close()
|
||||
{
|
||||
if (_connected)
|
||||
{
|
||||
_handle.close();
|
||||
_connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::isConnected()
|
||||
{
|
||||
return _connected;
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::isTransaction()
|
||||
{
|
||||
return _inTransaction;
|
||||
}
|
||||
|
||||
|
||||
}}}
|
||||
|
@@ -46,12 +46,8 @@ namespace MySQL {
|
||||
|
||||
StatementExecutor::StatementExecutor(MYSQL* mysql)
|
||||
{
|
||||
h = mysql_stmt_init(mysql);
|
||||
|
||||
if (!h)
|
||||
{
|
||||
if (!(_pHandle = mysql_stmt_init(mysql)))
|
||||
throw StatementException("mysql_stmt_init error");
|
||||
}
|
||||
|
||||
_state = STMT_INITED;
|
||||
}
|
||||
@@ -59,7 +55,7 @@ StatementExecutor::StatementExecutor(MYSQL* mysql)
|
||||
|
||||
StatementExecutor::~StatementExecutor()
|
||||
{
|
||||
mysql_stmt_close(h);
|
||||
mysql_stmt_close(_pHandle);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,16 +71,10 @@ void StatementExecutor::prepare(const std::string& query)
|
||||
{
|
||||
_state = STMT_COMPILED;
|
||||
return;
|
||||
//throw StatementException("Satement is already compiled");
|
||||
}
|
||||
|
||||
// compile
|
||||
int res = mysql_stmt_prepare(h, query.c_str(), static_cast<unsigned int>(query.length()));
|
||||
|
||||
if (res != 0)
|
||||
{
|
||||
throw StatementException("mysql_stmt_prepare error", h, query);
|
||||
}
|
||||
if (mysql_stmt_prepare(_pHandle, query.c_str(), static_cast<unsigned int>(query.length())) != 0)
|
||||
throw StatementException("mysql_stmt_prepare error", _pHandle, query);
|
||||
|
||||
_query = query;
|
||||
_state = STMT_COMPILED;
|
||||
@@ -94,58 +84,35 @@ void StatementExecutor::prepare(const std::string& query)
|
||||
void StatementExecutor::bindParams(MYSQL_BIND* params, size_t count)
|
||||
{
|
||||
if (_state < STMT_COMPILED)
|
||||
{
|
||||
throw StatementException("Satement is not compiled yet");
|
||||
}
|
||||
|
||||
if (count != mysql_stmt_param_count(h))
|
||||
{
|
||||
if (count != mysql_stmt_param_count(_pHandle))
|
||||
throw StatementException("wrong bind parameters count", 0, _query);
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (count == 0) return;
|
||||
|
||||
int res = mysql_stmt_bind_param(h, params);
|
||||
|
||||
if (res != 0)
|
||||
{
|
||||
throw StatementException("mysql_stmt_bind_param() error ", h, _query);
|
||||
}
|
||||
if (mysql_stmt_bind_param(_pHandle, params) != 0)
|
||||
throw StatementException("mysql_stmt_bind_param() error ", _pHandle, _query);
|
||||
}
|
||||
|
||||
|
||||
void StatementExecutor::bindResult(MYSQL_BIND* result)
|
||||
{
|
||||
if (_state < STMT_COMPILED)
|
||||
{
|
||||
throw StatementException("Satement is not compiled yet");
|
||||
}
|
||||
|
||||
int res = mysql_stmt_bind_result(h, result);
|
||||
|
||||
if (res != 0)
|
||||
{
|
||||
throw StatementException("mysql_stmt_bind_result error ", h, _query);
|
||||
}
|
||||
if (mysql_stmt_bind_result(_pHandle, result) != 0)
|
||||
throw StatementException("mysql_stmt_bind_result error ", _pHandle, _query);
|
||||
}
|
||||
|
||||
|
||||
void StatementExecutor::execute()
|
||||
{
|
||||
if (_state < STMT_COMPILED)
|
||||
{
|
||||
throw StatementException("Satement is not compiled yet");
|
||||
}
|
||||
|
||||
int res = mysql_stmt_execute(h);
|
||||
|
||||
if (res != 0)
|
||||
{
|
||||
throw StatementException("mysql_stmt_execute error", h, _query);
|
||||
}
|
||||
if (mysql_stmt_execute(_pHandle) != 0)
|
||||
throw StatementException("mysql_stmt_execute error", _pHandle, _query);
|
||||
|
||||
_state = STMT_EXECUTED;
|
||||
}
|
||||
@@ -154,16 +121,12 @@ void StatementExecutor::execute()
|
||||
bool StatementExecutor::fetch()
|
||||
{
|
||||
if (_state < STMT_EXECUTED)
|
||||
{
|
||||
throw StatementException("Satement is not executed yet");
|
||||
}
|
||||
|
||||
int res = mysql_stmt_fetch(h);
|
||||
int res = mysql_stmt_fetch(_pHandle);
|
||||
|
||||
if ((res != 0) && (res != MYSQL_NO_DATA))
|
||||
{
|
||||
throw StatementException("mysql_stmt_fetch error", h, _query);
|
||||
}
|
||||
throw StatementException("mysql_stmt_fetch error", _pHandle, _query);
|
||||
|
||||
return (res == 0);
|
||||
}
|
||||
@@ -172,17 +135,15 @@ bool StatementExecutor::fetch()
|
||||
bool StatementExecutor::fetchColumn(size_t n, MYSQL_BIND *bind)
|
||||
{
|
||||
if (_state < STMT_EXECUTED)
|
||||
{
|
||||
throw StatementException("Satement is not executed yet");
|
||||
}
|
||||
|
||||
int res = mysql_stmt_fetch_column(h, bind, static_cast<unsigned int>(n), 0);
|
||||
int res = mysql_stmt_fetch_column(_pHandle, bind, static_cast<unsigned int>(n), 0);
|
||||
|
||||
if ((res != 0) && (res != MYSQL_NO_DATA))
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg << "mysql_stmt_fetch_column(" << n << ") error";
|
||||
throw StatementException(msg.str(), h, _query);
|
||||
throw StatementException(msg.str(), _pHandle, _query);
|
||||
}
|
||||
|
||||
return (res == 0);
|
||||
|
@@ -41,7 +41,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\include;..\..\..\Foundation\include;..\..\..\CppUnit\include;..\..\..\CppUnit\WinTestRunner\include;..\..\..\Data\include"
|
||||
AdditionalIncludeDirectories="..\include;..\..\..\Foundation\include;..\..\..\CppUnit\include;..\..\..\CppUnit\WinTestRunner\include;..\..\..\Data\include;..\..\MySQL\include\Poco\Data\MySQL\mysql"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;POCO_DLL;WINVER=0x0500"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
|
@@ -79,27 +79,6 @@ MySQLTest::MySQLTest(const std::string& name):
|
||||
CppUnit::TestCase(name)
|
||||
{
|
||||
MySQL::Connector::registerConnector();
|
||||
|
||||
/*static bool beenHere = false;
|
||||
|
||||
|
||||
if (!beenHere)
|
||||
{
|
||||
try
|
||||
{
|
||||
_pSession = new Session(SessionFactory::instance().create(MySQL::Connector::KEY, _dbConnString));
|
||||
}catch (ConnectionException& ex)
|
||||
{
|
||||
std::cout << "!!! WARNING: Connection failed. MySQL tests will fail !!!" << std::endl;
|
||||
std::cout << ex.toString() << std::endl;
|
||||
}
|
||||
|
||||
if (_pSession && _pSession->isConnected())
|
||||
std::cout << "*** Connected to " << '(' << _dbConnString << ')' << std::endl;
|
||||
if (!_pExecutor) _pExecutor = new SQLExecutor("MySQL SQL Executor", _pSession);
|
||||
}
|
||||
|
||||
beenHere = true;*/
|
||||
}
|
||||
|
||||
|
||||
@@ -510,6 +489,24 @@ void MySQLTest::testNull()
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testSessionTransaction()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonBLOBTable();
|
||||
_pExecutor->sessionTransaction(_dbConnString);
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testTransaction()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreatePersonBLOBTable();
|
||||
_pExecutor->transaction(_dbConnString);
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testNullableInt()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
@@ -814,6 +811,8 @@ CppUnit::Test* MySQLTest::suite()
|
||||
CppUnit_addTest(pSuite, MySQLTest, testNullableInt);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testNullableString);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testTupleWithNullable);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testSessionTransaction);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testTransaction);
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@@ -113,6 +113,9 @@ public:
|
||||
void testNullableString();
|
||||
void testTupleWithNullable();
|
||||
|
||||
void testSessionTransaction();
|
||||
void testTransaction();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -110,7 +110,12 @@ public:
|
||||
void internalExtraction();
|
||||
void doNull();
|
||||
|
||||
void sessionTransaction(const std::string& connect);
|
||||
void transaction(const std::string& connect);
|
||||
|
||||
private:
|
||||
void setTransactionIsolation(Poco::Data::Session& session, Poco::UInt32 ti);
|
||||
|
||||
Poco::Data::Session* _pSession;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user