diff --git a/Data/Data_VS71.vcproj b/Data/Data_VS71.vcproj
index 39d2916be..2dcae00a9 100644
--- a/Data/Data_VS71.vcproj
+++ b/Data/Data_VS71.vcproj
@@ -270,6 +270,9 @@
+
+
@@ -366,6 +369,9 @@
+
+
@@ -454,6 +460,9 @@
+
+
+
+
@@ -537,10 +541,6 @@
RelativePath=".\src\AbstractPreparator.cpp"
>
-
-
@@ -625,6 +625,10 @@
RelativePath=".\src\Time.cpp"
>
+
+
+
+
@@ -542,10 +546,6 @@
RelativePath=".\src\AbstractPreparator.cpp"
>
-
-
@@ -630,6 +630,10 @@
RelativePath=".\src\Time.cpp"
>
+
+
- /// Implements SessionImpl interface
-{
-public:
-
- SessionImpl(const std::string& connectionString);
- /// Creates the SessionImpl. Opens a connection to the database
- ///
- /// Connection string format:
- /// == | ';'
- /// == '='
- /// == 'host' | 'port' | 'user' | 'password' | 'db' } 'compress' | 'auto-reconnect'
- /// == [~;]*
- ///
- /// 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
+ /// 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:
+ /// == | ';'
+ /// == '='
+ /// == 'host' | 'port' | 'user' | 'password' | 'db' } 'compress' | 'auto-reconnect'
+ /// == [~;]*
+ ///
+ /// 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
+ inline T& getValue(MYSQL_BIND* pResult, T& val)
+ {
+ return val = *((T*) pResult->buffer);
+ }
+
+ template
+ 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(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
diff --git a/Data/MySQL/include/Poco/Data/MySQL/StatementExecutor.h b/Data/MySQL/include/Poco/Data/MySQL/StatementExecutor.h
index b02016cf6..15e4c9beb 100644
--- a/Data/MySQL/include/Poco/Data/MySQL/StatementExecutor.h
+++ b/Data/MySQL/include/Poco/Data/MySQL/StatementExecutor.h
@@ -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;
}
diff --git a/Data/MySQL/src/MySQLStatementImpl.cpp b/Data/MySQL/src/MySQLStatementImpl.cpp
index f119e86d3..2bf08860b 100644
--- a/Data/MySQL/src/MySQLStatementImpl.cpp
+++ b/Data/MySQL/src/MySQLStatementImpl.cpp
@@ -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;
}
diff --git a/Data/MySQL/src/SessionHandle.cpp b/Data/MySQL/src/SessionHandle.cpp
index 78fc6c11b..3c1a0173d 100644
--- a/Data/MySQL/src/SessionHandle.cpp
+++ b/Data/MySQL/src/SessionHandle.cpp
@@ -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);
}
diff --git a/Data/MySQL/src/SessionImpl.cpp b/Data/MySQL/src/SessionImpl.cpp
index 10c025a7b..f5878b84b 100644
--- a/Data/MySQL/src/SessionImpl.cpp
+++ b/Data/MySQL/src/SessionImpl.cpp
@@ -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(toLower(connectionString)),
- _mysql(0),
- _connected(false),
- _inTransaction(0)
-{
- addProperty("insertId",
- &SessionImpl::setInsertId,
- &SessionImpl::getInsertId);
-
- std::map 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(toLower(connectionString)),
+ _handle(0),
+ _connected(false),
+ _inTransaction(false)
+{
+ addProperty("insertId",
+ &SessionImpl::setInsertId,
+ &SessionImpl::getInsertId);
+
+ std::map 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;
+}
+
+
+}}}
diff --git a/Data/MySQL/src/StatementExecutor.cpp b/Data/MySQL/src/StatementExecutor.cpp
index 5da236ed7..47630ff39 100644
--- a/Data/MySQL/src/StatementExecutor.cpp
+++ b/Data/MySQL/src/StatementExecutor.cpp
@@ -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(query.length()));
-
- if (res != 0)
- {
- throw StatementException("mysql_stmt_prepare error", h, query);
- }
+ if (mysql_stmt_prepare(_pHandle, query.c_str(), static_cast(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(n), 0);
+ int res = mysql_stmt_fetch_column(_pHandle, bind, static_cast(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);
diff --git a/Data/MySQL/testsuite/TestSuite_VS90.vcproj b/Data/MySQL/testsuite/TestSuite_VS90.vcproj
index 76e8fa303..42f4624fc 100644
--- a/Data/MySQL/testsuite/TestSuite_VS90.vcproj
+++ b/Data/MySQL/testsuite/TestSuite_VS90.vcproj
@@ -41,7 +41,7 @@
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;
}
diff --git a/Data/MySQL/testsuite/src/MySQLTest.h b/Data/MySQL/testsuite/src/MySQLTest.h
index cf3b55d82..a3b75bff6 100644
--- a/Data/MySQL/testsuite/src/MySQLTest.h
+++ b/Data/MySQL/testsuite/src/MySQLTest.h
@@ -113,6 +113,9 @@ public:
void testNullableString();
void testTupleWithNullable();
+ void testSessionTransaction();
+ void testTransaction();
+
void setUp();
void tearDown();
diff --git a/Data/MySQL/testsuite/src/SQLExecutor.cpp b/Data/MySQL/testsuite/src/SQLExecutor.cpp
index 420830c69..576f5e20a 100644
--- a/Data/MySQL/testsuite/src/SQLExecutor.cpp
+++ b/Data/MySQL/testsuite/src/SQLExecutor.cpp
@@ -1,1520 +1,1805 @@
-//
-// SQLExecutor.cpp
-//
-// $Id: //poco/1.4/Data/MySQL/testsuite/src/SQLExecutor.cpp#1 $
-//
-// 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 "CppUnit/TestCase.h"
-#include "SQLExecutor.h"
-#include "Poco/String.h"
-#include "Poco/Format.h"
-#include "Poco/Tuple.h"
-#include "Poco/Any.h"
-#include "Poco/Exception.h"
-#include "Poco/Data/LOB.h"
-#include "Poco/Data/StatementImpl.h"
-#include "Poco/Data/RecordSet.h"
-#include "Poco/Data/MySQL/Connector.h"
-#include "Poco/Data/MySQL/MySQLException.h"
-
-#ifdef _WIN32
-#include
-#endif
-
-#include
-#include
-
-
-using namespace Poco::Data;
-using namespace Poco::Data::Keywords;
-using Poco::Data::MySQL::ConnectionException;
-using Poco::Data::MySQL::StatementException;
-using Poco::format;
-using Poco::Tuple;
-using Poco::Any;
-using Poco::AnyCast;
-using Poco::NotFoundException;
-using Poco::InvalidAccessException;
-using Poco::BadCastException;
-using Poco::RangeException;
-
-
-struct Person
-{
- std::string lastName;
- std::string firstName;
- std::string address;
- int age;
- Person(){age = 0;}
- Person(const std::string& ln, const std::string& fn, const std::string& adr, int a):lastName(ln), firstName(fn), address(adr), age(a)
- {
- }
- bool operator==(const Person& other) const
- {
- return lastName == other.lastName && firstName == other.firstName && address == other.address && age == other.age;
- }
-
- bool operator < (const Person& p) const
- {
- if (age < p.age)
- return true;
- if (lastName < p.lastName)
- return true;
- if (firstName < p.firstName)
- return true;
- return (address < p.address);
- }
-
- const std::string& operator () () const
- /// This method is required so we can extract data to a map!
- {
- // we choose the lastName as examplary key
- return lastName;
- }
-};
-
-
-namespace Poco {
-namespace Data {
-
-
-template <>
-class TypeHandler
-{
-public:
- static void bind(std::size_t pos, const Person& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
- {
- // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))
- poco_assert_dbg (pBinder != 0);
- pBinder->bind(pos++, obj.lastName, dir);
- pBinder->bind(pos++, obj.firstName, dir);
- pBinder->bind(pos++, obj.address, dir);
- pBinder->bind(pos++, obj.age, dir);
- }
-
- static void prepare(std::size_t pos, Person& obj, AbstractPreparator* pPrepare)
- {
- // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))
- poco_assert_dbg (pPrepare != 0);
- pPrepare->prepare(pos++, obj.lastName);
- pPrepare->prepare(pos++, obj.firstName);
- pPrepare->prepare(pos++, obj.address);
- pPrepare->prepare(pos++, obj.age);
- }
-
- static std::size_t size()
- {
- return 4;
- }
-
- static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor* pExt)
- {
- poco_assert_dbg (pExt != 0);
- if (!pExt->extract(pos++, obj.lastName))
- obj.lastName = defVal.lastName;
- if (!pExt->extract(pos++, obj.firstName))
- obj.firstName = defVal.firstName;
- if (!pExt->extract(pos++, obj.address))
- obj.address = defVal.address;
- if (!pExt->extract(pos++, obj.age))
- obj.age = defVal.age;
- }
-
-private:
- TypeHandler();
- ~TypeHandler();
- TypeHandler(const TypeHandler&);
- TypeHandler& operator=(const TypeHandler&);
-};
-
-
-} } // namespace Poco::Data
-
-
-SQLExecutor::SQLExecutor(const std::string& name, Poco::Data::Session* pSession):
- CppUnit::TestCase(name),
- _pSession(pSession)
-{
-}
-
-
-SQLExecutor::~SQLExecutor()
-{
-}
-
-
-void SQLExecutor::bareboneMySQLTest(const char* host, const char* user, const char* pwd, const char* db, int port, const char* tableCreateString)
-{
- int rc;
- MYSQL* hsession = mysql_init(0);
- assert (hsession != 0);
-
- MYSQL* tmp = mysql_real_connect(hsession, host, user, pwd, db, port, 0, 0);
- assert(tmp == hsession);
-
- MYSQL_STMT* hstmt = mysql_stmt_init(hsession);
- assert(hstmt != 0);
-
- std::string sql = "DROP TABLE Test";
- mysql_real_query(hsession, sql.c_str(), static_cast(sql.length()));
-
- sql = tableCreateString;
- rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast(sql.length()));
- assert(rc == 0);
-
- rc = mysql_stmt_execute(hstmt);
- assert(rc == 0);
-
- sql = "INSERT INTO Test VALUES (?,?,?,?,?)";
- rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast(sql.length()));
- assert(rc == 0);
-
- std::string str[3] = { "111", "222", "333" };
- int fourth = 4;
- float fifth = 1.5;
-
- MYSQL_BIND bind_param[5] = {{0}};
-
- bind_param[0].buffer = const_cast(str[0].c_str());
- bind_param[0].buffer_length = static_cast(str[0].length());
- bind_param[0].buffer_type = MYSQL_TYPE_STRING;
-
- bind_param[1].buffer = const_cast(str[1].c_str());
- bind_param[1].buffer_length = static_cast(str[1].length());
- bind_param[1].buffer_type = MYSQL_TYPE_STRING;
-
- bind_param[2].buffer = const_cast(str[2].c_str());
- bind_param[2].buffer_length = static_cast(str[2].length());
- bind_param[2].buffer_type = MYSQL_TYPE_STRING;
-
- bind_param[3].buffer = &fourth;
- bind_param[3].buffer_type = MYSQL_TYPE_LONG;
-
- bind_param[4].buffer = &fifth;
- bind_param[4].buffer_type = MYSQL_TYPE_FLOAT;
-
- rc = mysql_stmt_bind_param(hstmt, bind_param);
- assert (rc == 0);
-
- rc = mysql_stmt_execute(hstmt);
- assert (rc == 0);
-
- sql = "SELECT * FROM Test";
- rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast(sql.length()));
- assert (rc == 0);
-
- char chr[3][5] = {{ 0 }};
- unsigned long lengths[5] = { 0 };
- fourth = 0;
- fifth = 0.0f;
-
- MYSQL_BIND bind_result[5] = {{0}};
-
- bind_result[0].buffer = chr[0];
- bind_result[0].buffer_length = sizeof(chr[0]);
- bind_result[0].buffer_type = MYSQL_TYPE_STRING;
- bind_result[0].length = &lengths[0];
-
- bind_result[1].buffer = chr[1];
- bind_result[1].buffer_length = sizeof(chr[1]);
- bind_result[1].buffer_type = MYSQL_TYPE_STRING;
- bind_result[1].length = &lengths[1];
-
- bind_result[2].buffer = chr[2];
- bind_result[2].buffer_length = sizeof(chr[2]);
- bind_result[2].buffer_type = MYSQL_TYPE_STRING;
- bind_result[2].length = &lengths[2];
-
- bind_result[3].buffer = &fourth;
- bind_result[3].buffer_type = MYSQL_TYPE_LONG;
- bind_result[3].length = &lengths[3];
-
- bind_result[4].buffer = &fifth;
- bind_result[4].buffer_type = MYSQL_TYPE_FLOAT;
- bind_result[4].length = &lengths[4];
-
- rc = mysql_stmt_bind_result(hstmt, bind_result);
- assert (rc == 0);
-
- rc = mysql_stmt_execute(hstmt);
- assert (rc == 0);
- rc = mysql_stmt_fetch(hstmt);
- assert (rc == 0);
-
- assert (0 == std::strncmp("111", chr[0], 3));
- assert (0 == std::strncmp("222", chr[1], 3));
- assert (0 == std::strncmp("333", chr[2], 3));
- assert (4 == fourth);
- assert (1.5 == fifth);
-
- rc = mysql_stmt_close(hstmt);
- assert(rc == 0);
-
- sql = "DROP TABLE Test";
- rc = mysql_real_query(hsession, sql.c_str(), static_cast(sql.length()));
- assert(rc == 0);
-
- mysql_close(hsession);
-}
-
-
-void SQLExecutor::simpleAccess()
-{
- std::string funct = "simpleAccess()";
- std::string lastName = "lastName";
- std::string firstName("firstName");
- std::string address("Address");
- int age = 133132;
- int count = 0;
- std::string result;
-
- count = 0;
- try
- {
- Statement stmt(*_pSession);
- stmt << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(age);//, now;
- stmt.execute();
- }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- 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);
-
- try { *_pSession << "SELECT LastName FROM Person", into(result), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (lastName == result);
-
- 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);
-}
-
-
-void SQLExecutor::complexType()
-{
- std::string funct = "complexType()";
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(p1), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(p2), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- int 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 == 2);
-
- Person c1;
- Person c2;
- try { *_pSession << "SELECT * FROM Person WHERE LastName = 'LN1'", into(c1), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (c1 == p1);
-}
-
-
-void SQLExecutor::simpleAccessVector()
-{
- std::string funct = "simpleAccessVector()";
- std::vector lastNames;
- std::vector firstNames;
- std::vector addresses;
- std::vector ages;
- std::string tableName("Person");
- lastNames.push_back("LN1");
- lastNames.push_back("LN2");
- firstNames.push_back("FN1");
- firstNames.push_back("FN2");
- addresses.push_back("ADDR1");
- addresses.push_back("ADDR2");
- ages.push_back(1);
- ages.push_back(2);
- int count = 0;
- std::string result;
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- 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 == 2);
-
- std::vector lastNamesR;
- std::vector firstNamesR;
- std::vector addressesR;
- std::vector agesR;
- try { *_pSession << "SELECT * FROM Person", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (ages == agesR);
- assert (lastNames == lastNamesR);
- assert (firstNames == firstNamesR);
- assert (addresses == addressesR);
-}
-
-
-void SQLExecutor::complexTypeVector()
-{
- std::string funct = "complexTypeVector()";
- std::vector people;
- people.push_back(Person("LN1", "FN1", "ADDR1", 1));
- people.push_back(Person("LN2", "FN2", "ADDR2", 2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- int 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 == 2);
-
- std::vector result;
- try { *_pSession << "SELECT * FROM Person", into(result), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (result == people);
-}
-
-
-void SQLExecutor::insertVector()
-{
- std::string funct = "insertVector()";
- std::vector str;
- str.push_back("s1");
- str.push_back("s2");
- str.push_back("s3");
- str.push_back("s3");
- int count = 100;
-
- {
- Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(str)));
- try { *_pSession << "SELECT COUNT(*) FROM Strings", 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 == 0);
-
- try { stmt.execute(); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- try { *_pSession << "SELECT COUNT(*) FROM Strings", 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 == 4);
- }
- count = 0;
- try { *_pSession << "SELECT COUNT(*) FROM Strings", 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 == 4);
-}
-
-
-void SQLExecutor::insertEmptyVector()
-{
- std::string funct = "insertEmptyVector()";
- std::vector str;
-
- try
- {
- *_pSession << "INSERT INTO Strings VALUES (?)", use(str), now;
- fail("empty collections should not work");
- }
- catch (Poco::Exception&)
- {
- }
-}
-
-
-void SQLExecutor::insertSingleBulk()
-{
- std::string funct = "insertSingleBulk()";
- int x = 0;
- Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(x)));
-
- for (x = 0; x < 100; ++x)
- {
- int i = stmt.execute();
- assert (i == 0);
- }
-
- int count = 0;
- try { *_pSession << "SELECT COUNT(*) FROM Strings", 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 == 100);
-
- try { *_pSession << "SELECT SUM(str) FROM Strings", 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 == ((0+99)*100/2));
-}
-
-
-void SQLExecutor::floats()
-{
- std::string funct = "floats()";
- float data = 1.5f;
- float ret = 0.0f;
-
- try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- int count = 0;
- try { *_pSession << "SELECT COUNT(*) FROM Strings", 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);
-
- try { *_pSession << "SELECT str FROM Strings", into(ret), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (ret == data);
-}
-
-
-void SQLExecutor::doubles()
-{
- std::string funct = "floats()";
- double data = 1.5;
- double ret = 0.0;
-
- try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- int count = 0;
- try { *_pSession << "SELECT COUNT(*) FROM Strings", 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);
-
- try { *_pSession << "SELECT str FROM Strings", into(ret), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (ret == data);
-}
-
-
-void SQLExecutor::insertSingleBulkVec()
-{
- std::string funct = "insertSingleBulkVec()";
- std::vector data;
-
- for (int x = 0; x < 100; ++x)
- data.push_back(x);
-
- Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(data)));
- stmt.execute();
-
- int count = 0;
- try { *_pSession << "SELECT COUNT(*) FROM Strings", 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 == 100);
- try { *_pSession << "SELECT SUM(str) FROM Strings", 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 == ((0+99)*100/2));
-}
-
-
-void SQLExecutor::limits()
-{
- std::string funct = "limit()";
- std::vector data;
- for (int x = 0; x < 100; ++x)
- {
- data.push_back(x);
- }
-
- try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- std::vector retData;
- try { *_pSession << "SELECT * FROM Strings", into(retData), limit(50), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (retData.size() == 50);
- for (int x = 0; x < 50; ++x)
- {
- assert(data[x] == retData[x]);
- }
-}
-
-
-void SQLExecutor::limitZero()
-{
- std::string funct = "limitZero()";
- std::vector data;
- for (int x = 0; x < 100; ++x)
- {
- data.push_back(x);
- }
-
- try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- std::vector retData;
- try { *_pSession << "SELECT * FROM Strings", into(retData), limit(0), now; }// stupid test, but at least we shouldn't crash
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (retData.size() == 0);
-}
-
-
-void SQLExecutor::limitOnce()
-{
- std::string funct = "limitOnce()";
- std::vector data;
- for (int x = 0; x < 101; ++x)
- {
- data.push_back(x);
- }
-
- try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- std::vector retData;
- Statement stmt = (*_pSession << "SELECT * FROM Strings", into(retData), limit(50), now);
- assert (!stmt.done());
- assert (retData.size() == 50);
- stmt.execute();
- assert (!stmt.done());
- assert (retData.size() == 100);
- stmt.execute();
- assert (stmt.done());
- assert (retData.size() == 101);
-
- for (int x = 0; x < 101; ++x)
- {
- assert(data[x] == retData[x]);
- }
-}
-
-
-void SQLExecutor::limitPrepare()
-{
- std::string funct = "limitPrepare()";
- std::vector data;
- for (int x = 0; x < 100; ++x)
- {
- data.push_back(x);
- }
-
- try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- std::vector retData;
- Statement stmt = (*_pSession << "SELECT * FROM Strings", into(retData), limit(50));
- assert (retData.size() == 0);
- assert (!stmt.done());
-
- try { stmt.execute(); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (!stmt.done());
- assert (retData.size() == 50);
-
- try { stmt.execute(); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (stmt.done());
- assert (retData.size() == 100);
-
- try { stmt.execute(); }// will restart execution!
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (!stmt.done());
- assert (retData.size() == 150);
- for (int x = 0; x < 150; ++x)
- {
- assert(data[x%100] == retData[x]);
- }
-}
-
-
-
-void SQLExecutor::prepare()
-{
- std::string funct = "prepare()";
- std::vector data;
- for (int x = 0; x < 100; x += 2)
- {
- data.push_back(x);
- }
-
- {
- Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(data)));
- }
- // stmt should not have been executed when destroyed
- int count = 100;
- try { *_pSession << "SELECT COUNT(*) FROM Strings", 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 == 0);
-}
-
-
-void SQLExecutor::setSimple()
-{
- std::string funct = "setSimple()";
- std::set lastNames;
- std::set firstNames;
- std::set addresses;
- std::set ages;
- std::string tableName("Person");
- lastNames.insert("LN1");
- lastNames.insert("LN2");
- firstNames.insert("FN1");
- firstNames.insert("FN2");
- addresses.insert("ADDR1");
- addresses.insert("ADDR2");
- ages.insert(1);
- ages.insert(2);
- int count = 0;
- std::string result;
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- 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 == 2);
-
- std::set lastNamesR;
- std::set firstNamesR;
- std::set addressesR;
- std::set agesR;
- try { *_pSession << "SELECT * FROM Person", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (ages == agesR);
- assert (lastNames == lastNamesR);
- assert (firstNames == firstNamesR);
- assert (addresses == addressesR);
-}
-
-
-void SQLExecutor::setComplex()
-{
- std::string funct = "setComplex()";
- std::set people;
- people.insert(Person("LN1", "FN1", "ADDR1", 1));
- people.insert(Person("LN2", "FN2", "ADDR2", 2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- int 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 == 2);
-
- std::set result;
- try { *_pSession << "SELECT * FROM Person", into(result), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (result == people);
-}
-
-
-void SQLExecutor::setComplexUnique()
-{
- std::string funct = "setComplexUnique()";
- std::vector people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- people.push_back(p1);
- people.push_back(p1);
- people.push_back(p1);
- people.push_back(p1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.push_back(p2);
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- int 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 == 5);
-
- std::set result;
- try { *_pSession << "SELECT * FROM Person", into(result), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (result.size() == 2);
- assert (*result.begin() == p1);
- assert (*++result.begin() == p2);
-}
-
-void SQLExecutor::multiSetSimple()
-{
- std::string funct = "multiSetSimple()";
- std::multiset lastNames;
- std::multiset firstNames;
- std::multiset addresses;
- std::multiset ages;
- std::string tableName("Person");
- lastNames.insert("LN1");
- lastNames.insert("LN2");
- firstNames.insert("FN1");
- firstNames.insert("FN2");
- addresses.insert("ADDR1");
- addresses.insert("ADDR2");
- ages.insert(1);
- ages.insert(2);
- int count = 0;
- std::string result;
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- 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 == 2);
-
- std::multiset lastNamesR;
- std::multiset firstNamesR;
- std::multiset addressesR;
- std::multiset agesR;
- try { *_pSession << "SELECT * FROM Person", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (ages.size() == agesR.size());
- assert (lastNames.size() == lastNamesR.size());
- assert (firstNames.size() == firstNamesR.size());
- assert (addresses.size() == addressesR.size());
-}
-
-
-void SQLExecutor::multiSetComplex()
-{
- std::string funct = "multiSetComplex()";
- std::multiset people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- people.insert(p1);
- people.insert(p1);
- people.insert(p1);
- people.insert(p1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(p2);
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- int 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 == 5);
-
- std::multiset result;
- try { *_pSession << "SELECT * FROM Person", into(result), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (result.size() == people.size());
-}
-
-
-void SQLExecutor::mapComplex()
-{
- std::string funct = "mapComplex()";
- std::map people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN2", p2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- int 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 == 2);
-
- std::map result;
- try { *_pSession << "SELECT * FROM Person", into(result), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (result == people);
-}
-
-
-void SQLExecutor::mapComplexUnique()
-{
- std::string funct = "mapComplexUnique()";
- std::multimap people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN2", p2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- int 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 == 5);
-
- std::map result;
- try { *_pSession << "SELECT * FROM Person", into(result), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (result.size() == 2);
-}
-
-
-void SQLExecutor::multiMapComplex()
-{
- std::string funct = "multiMapComplex()";
- std::multimap people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN2", p2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- int 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 == 5);
-
- std::multimap result;
- try { *_pSession << "SELECT * FROM Person", into(result), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (result.size() == people.size());
-}
-
-
-void SQLExecutor::selectIntoSingle()
-{
- std::string funct = "selectIntoSingle()";
- std::multimap people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- int 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 == 2);
- Person result;
- try { *_pSession << "SELECT * FROM Person", into(result), limit(1), now; }// will return 1 object into one single result
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (result == p1);
-}
-
-
-void SQLExecutor::selectIntoSingleStep()
-{
- std::string funct = "selectIntoSingleStep()";
- std::multimap people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- int 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 == 2);
- Person result;
- Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1));
- stmt.execute();
- assert (result == p1);
- assert (!stmt.done());
- stmt.execute();
- assert (result == p2);
- assert (stmt.done());
-}
-
-
-void SQLExecutor::selectIntoSingleFail()
-{
- std::string funct = "selectIntoSingleFail()";
- std::multimap people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- int count = 0;
- try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), limit(2, true), 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 == 2);
- Person result;
- try
- {
- *_pSession << "SELECT * FROM Person", into(result), limit(1, true), now; // will fail now
- fail("hardLimit is set: must fail");
- }
- catch(Poco::Data::LimitException&)
- {
- }
-}
-
-
-void SQLExecutor::lowerLimitOk()
-{
- std::string funct = "lowerLimitOk()";
- std::multimap people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- int 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 == 2);
- Person result;
- try
- {
- *_pSession << "SELECT * FROM Person", into(result), lowerLimit(2), now; // will return 2 objects into one single result but only room for one!
- fail("Not enough space for results");
- }
- catch(Poco::Exception&)
- {
- }
-}
-
-
-void SQLExecutor::singleSelect()
-{
- std::string funct = "singleSelect()";
- std::multimap people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- int 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 == 2);
- Person result;
- Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1));
- stmt.execute();
- assert (result == p1);
- assert (!stmt.done());
- stmt.execute();
- assert (result == p2);
- assert (stmt.done());
-}
-
-
-void SQLExecutor::lowerLimitFail()
-{
- std::string funct = "lowerLimitFail()";
- std::multimap people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- int 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 == 2);
- Person result;
- try
- {
- *_pSession << "SELECT * FROM Person", into(result), lowerLimit(3), now; // will fail
- fail("should fail. not enough data");
- }
- catch(Poco::Exception&)
- {
- }
-}
-
-
-void SQLExecutor::combinedLimits()
-{
- std::string funct = "combinedLimits()";
- std::multimap people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- int 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 == 2);
- std::vector result;
- try { *_pSession << "SELECT * FROM Person", into(result), lowerLimit(2), upperLimit(2), now; }// will return 2 objects
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (result.size() == 2);
- assert (result[0] == p1);
- assert (result[1] == p2);
-}
-
-
-
-void SQLExecutor::ranges()
-{
- std::string funct = "range()";
- std::multimap people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- int 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 == 2);
- std::vector result;
- try { *_pSession << "SELECT * FROM Person", into(result), range(2, 2), now; }// will return 2 objects
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (result.size() == 2);
- assert (result[0] == p1);
- assert (result[1] == p2);
-}
-
-
-void SQLExecutor::combinedIllegalLimits()
-{
- std::string funct = "combinedIllegalLimits()";
- std::multimap people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- int 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 == 2);
- Person result;
- try
- {
- *_pSession << "SELECT * FROM Person", into(result), lowerLimit(3), upperLimit(2), now;
- fail("lower > upper is not allowed");
- }
- catch(LimitException&)
- {
- }
-}
-
-
-void SQLExecutor::illegalRange()
-{
- std::string funct = "illegalRange()";
- std::multimap people;
- Person p1("LN1", "FN1", "ADDR1", 1);
- Person p2("LN2", "FN2", "ADDR2", 2);
- people.insert(std::make_pair("LN1", p1));
- people.insert(std::make_pair("LN1", p2));
-
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- int 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 == 2);
- Person result;
- try
- {
- *_pSession << "SELECT * FROM Person", into(result), range(3, 2), now;
- fail("lower > upper is not allowed");
- }
- catch(LimitException&)
- {
- }
-}
-
-
-void SQLExecutor::emptyDB()
-{
- std::string funct = "emptyDB()";
- int 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 == 0);
-
- Person result;
- Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1));
- stmt.execute();
- assert (result.firstName.empty());
- assert (stmt.done());
-}
-
-
-void SQLExecutor::blob(int bigSize)
-{
- std::string funct = "blob()";
- std::string lastName("lastname");
- std::string firstName("firstname");
- std::string address("Address");
-
- Poco::Data::CLOB img("0123456789", 10);
- int count = 0;
- try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(img), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- 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);
-
- Poco::Data::CLOB res;
- assert (res.size() == 0);
- try { *_pSession << "SELECT Image FROM Person", into(res), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (res == img);
-
- Poco::Data::CLOB big;
- std::vector v(bigSize, 'x');
- big.assignRaw(&v[0], v.size());
-
- assert (big.size() == (size_t)bigSize);
-
- try { *_pSession << "DELETE FROM Person", now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- try { *_pSession << "INSERT INTO Person VALUES(?,?,?,?)", use(lastName), use(firstName), use(address), use(big), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- try { *_pSession << "SELECT Image FROM Person", into(res), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (res == big);
-}
-
-void SQLExecutor::blobStmt()
-{
- std::string funct = "blobStmt()";
- std::string lastName("lastname");
- std::string firstName("firstname");
- std::string address("Address");
- Poco::Data::CLOB blob("0123456789", 10);
-
- int count = 0;
- Statement ins = (*_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(blob));
- ins.execute();
- 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);
-
- Poco::Data::CLOB res;
- poco_assert (res.size() == 0);
- Statement stmt = (*_pSession << "SELECT Image FROM Person", into(res));
- try { stmt.execute(); }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- poco_assert (res == blob);
-}
-
-void SQLExecutor::tuples()
-{
- typedef Tuple TupleType;
- std::string funct = "tuples()";
- TupleType t(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19);
-
- try { *_pSession << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", use(t), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- TupleType ret(-10,-11,-12,-13,-14,-15,-16,-17,-18,-19);
- assert (ret != t);
- try { *_pSession << "SELECT * FROM Tuples", into(ret), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (ret == t);
-}
-
-void SQLExecutor::tupleVector()
-{
- typedef Tuple TupleType;
- std::string funct = "tupleVector()";
- TupleType t(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19);
- Tuple
- t10(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29);
- TupleType t100(100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119);
- std::vector v;
- v.push_back(t);
- v.push_back(t10);
- v.push_back(t100);
-
- try { *_pSession << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", use(v), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- int count = 0;
- try { *_pSession << "SELECT COUNT(*) FROM Tuples", 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 (v.size() == (size_t)count);
-
- std::vector > ret;
- try { *_pSession << "SELECT * FROM Tuples", into(ret), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- assert (ret == v);
-}
-
-
-void SQLExecutor::internalExtraction()
-{
- /*std::string funct = "internalExtraction()";
- std::vector > v;
- v.push_back(Tuple(1, 1.5f, "3"));
- v.push_back(Tuple(2, 2.5f, "4"));
- v.push_back(Tuple(3, 3.5f, "5"));
- v.push_back(Tuple(4, 4.5f, "6"));
-
- try { *_pSession << "INSERT INTO Vectors VALUES (?,?,?)", use(v), now; }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-
- try
- {
- Statement stmt = (*_pSession << "SELECT * FROM Vectors", now);
- RecordSet rset(stmt);
-
- assert (3 == rset.columnCount());
- assert (4 == rset.rowCount());
-
- int curVal = 3;
- do
- {
- assert (rset["str0"] == curVal);
- ++curVal;
- } while (rset.moveNext());
-
- rset.moveFirst();
- assert (rset["str0"] == "3");
- rset.moveLast();
- assert (rset["str0"] == "6");
-
- RecordSet rset2(rset);
- assert (3 == rset2.columnCount());
- assert (4 == rset2.rowCount());
-
- int i = rset.value(0,0);
- assert (1 == i);
-
- std::string s = rset.value(0,0);
- assert ("1" == s);
-
- int a = rset.value(0,2);
- assert (3 == a);
-
- try
- {
- double d = rset.value(1,1);
- assert (2.5 == d);
- }
- catch (BadCastException&)
- {
- float f = rset.value(1,1);
- assert (2.5 == f);
- }
-
- s = rset.value(2,2);
- assert ("5" == s);
- i = rset.value("str0", 2);
- assert (5 == i);
-
- const Column& col = rset.column(0);
- Column::Iterator it = col.begin();
- Column::Iterator end = col.end();
- for (int i = 1; it != end; ++it, ++i)
- assert (*it == i);
-
- rset = (*_pSession << "SELECT COUNT(*) AS cnt FROM Vectors", now);
-
- //various results for COUNT(*) are received from different drivers
- try
- {
- //this is what most drivers will return
- int i = rset.value(0,0);
- assert (4 == i);
- }
- catch(BadCastException&)
- {
- try
- {
- //this is for Oracle
- double i = rset.value(0,0);
- assert (4 == int(i));
- }
- catch(BadCastException&)
- {
- //this is for PostgreSQL
- Poco::Int64 big = rset.value(0,0);
- assert (4 == big);
- }
- }
-
- s = rset.value("cnt", 0).convert();
- assert ("4" == s);
-
- try { const Column& col1 = rset.column(100); fail ("must fail"); }
- catch (RangeException&) { }
-
- try { rset.value(0,0); fail ("must fail"); }
- catch (BadCastException&) { }
-
- stmt = (*_pSession << "DELETE FROM Vectors", now);
- rset = stmt;
-
- try { const Column& col1 = rset.column(0); fail ("must fail"); }
- catch (RangeException&) { }
- }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
-*/
-}
-
-
-void SQLExecutor::doNull()
-{
- std::string funct = "null()";
-
- *_pSession << "INSERT INTO Vectors VALUES (?, ?, ?)",
- use(Poco::Data::Keywords::null),
- use(Poco::Data::Keywords::null),
- use(Poco::Data::Keywords::null), now;
-
- int count = 0;
- try { *_pSession << "SELECT COUNT(*) FROM Vectors", 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);
-
- int i0 = 0;
- Statement stmt1 = (*_pSession << "SELECT i0 FROM Vectors", into(i0, Poco::Data::Position(0), -1));
- try { stmt1.execute(); }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- poco_assert (i0 == -1);
-
- float flt0 = 0;
- Statement stmt2 = (*_pSession << "SELECT flt0 FROM Vectors", into(flt0, Poco::Data::Position(0), 3.25f));
- try { stmt2.execute(); }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- poco_assert (flt0 == 3.25);
-
- std::string str0("string");
- Statement stmt3 = (*_pSession << "SELECT str0 FROM Vectors", into(str0, Poco::Data::Position(0), std::string("DEFAULT")));
- try { stmt3.execute(); }
- catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
- catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
- poco_assert (str0 == "DEFAULT");
-}
+//
+// SQLExecutor.cpp
+//
+// $Id: //poco/1.4/Data/MySQL/testsuite/src/SQLExecutor.cpp#1 $
+//
+// 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 "CppUnit/TestCase.h"
+#include "SQLExecutor.h"
+#include "Poco/String.h"
+#include "Poco/Format.h"
+#include "Poco/Tuple.h"
+#include "Poco/Any.h"
+#include "Poco/Exception.h"
+#include "Poco/Data/LOB.h"
+#include "Poco/Data/StatementImpl.h"
+#include "Poco/Data/RecordSet.h"
+#include "Poco/Data/Transaction.h"
+#include "Poco/Data/MySQL/Connector.h"
+#include "Poco/Data/MySQL/MySQLException.h"
+
+#ifdef _WIN32
+#include
+#endif
+
+#include
+#include
+
+
+using namespace Poco::Data;
+using namespace Poco::Data::Keywords;
+using Poco::Data::MySQL::ConnectionException;
+using Poco::Data::MySQL::StatementException;
+using Poco::format;
+using Poco::Tuple;
+using Poco::Any;
+using Poco::AnyCast;
+using Poco::NotFoundException;
+using Poco::InvalidAccessException;
+using Poco::BadCastException;
+using Poco::RangeException;
+
+
+struct Person
+{
+ std::string lastName;
+ std::string firstName;
+ std::string address;
+ int age;
+ Person(){age = 0;}
+ Person(const std::string& ln, const std::string& fn, const std::string& adr, int a):lastName(ln), firstName(fn), address(adr), age(a)
+ {
+ }
+ bool operator==(const Person& other) const
+ {
+ return lastName == other.lastName && firstName == other.firstName && address == other.address && age == other.age;
+ }
+
+ bool operator < (const Person& p) const
+ {
+ if (age < p.age)
+ return true;
+ if (lastName < p.lastName)
+ return true;
+ if (firstName < p.firstName)
+ return true;
+ return (address < p.address);
+ }
+
+ const std::string& operator () () const
+ /// This method is required so we can extract data to a map!
+ {
+ // we choose the lastName as examplary key
+ return lastName;
+ }
+};
+
+
+namespace Poco {
+namespace Data {
+
+
+template <>
+class TypeHandler
+{
+public:
+ static void bind(std::size_t pos, const Person& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
+ {
+ // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))
+ poco_assert_dbg (pBinder != 0);
+ pBinder->bind(pos++, obj.lastName, dir);
+ pBinder->bind(pos++, obj.firstName, dir);
+ pBinder->bind(pos++, obj.address, dir);
+ pBinder->bind(pos++, obj.age, dir);
+ }
+
+ static void prepare(std::size_t pos, Person& obj, AbstractPreparator* pPrepare)
+ {
+ // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))
+ poco_assert_dbg (pPrepare != 0);
+ pPrepare->prepare(pos++, obj.lastName);
+ pPrepare->prepare(pos++, obj.firstName);
+ pPrepare->prepare(pos++, obj.address);
+ pPrepare->prepare(pos++, obj.age);
+ }
+
+ static std::size_t size()
+ {
+ return 4;
+ }
+
+ static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor* pExt)
+ {
+ poco_assert_dbg (pExt != 0);
+ if (!pExt->extract(pos++, obj.lastName))
+ obj.lastName = defVal.lastName;
+ if (!pExt->extract(pos++, obj.firstName))
+ obj.firstName = defVal.firstName;
+ if (!pExt->extract(pos++, obj.address))
+ obj.address = defVal.address;
+ if (!pExt->extract(pos++, obj.age))
+ obj.age = defVal.age;
+ }
+
+private:
+ TypeHandler();
+ ~TypeHandler();
+ TypeHandler(const TypeHandler&);
+ TypeHandler& operator=(const TypeHandler&);
+};
+
+
+} } // namespace Poco::Data
+
+
+SQLExecutor::SQLExecutor(const std::string& name, Poco::Data::Session* pSession):
+ CppUnit::TestCase(name),
+ _pSession(pSession)
+{
+}
+
+
+SQLExecutor::~SQLExecutor()
+{
+}
+
+
+void SQLExecutor::bareboneMySQLTest(const char* host, const char* user, const char* pwd, const char* db, int port, const char* tableCreateString)
+{
+ int rc;
+ MYSQL* hsession = mysql_init(0);
+ assert (hsession != 0);
+
+ MYSQL* tmp = mysql_real_connect(hsession, host, user, pwd, db, port, 0, 0);
+ assert(tmp == hsession);
+
+ MYSQL_STMT* hstmt = mysql_stmt_init(hsession);
+ assert(hstmt != 0);
+
+ std::string sql = "DROP TABLE Test";
+ mysql_real_query(hsession, sql.c_str(), static_cast(sql.length()));
+
+ sql = tableCreateString;
+ rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast(sql.length()));
+ assert(rc == 0);
+
+ rc = mysql_stmt_execute(hstmt);
+ assert(rc == 0);
+
+ sql = "INSERT INTO Test VALUES (?,?,?,?,?)";
+ rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast(sql.length()));
+ assert(rc == 0);
+
+ std::string str[3] = { "111", "222", "333" };
+ int fourth = 4;
+ float fifth = 1.5;
+
+ MYSQL_BIND bind_param[5] = {{0}};
+
+ bind_param[0].buffer = const_cast(str[0].c_str());
+ bind_param[0].buffer_length = static_cast(str[0].length());
+ bind_param[0].buffer_type = MYSQL_TYPE_STRING;
+
+ bind_param[1].buffer = const_cast(str[1].c_str());
+ bind_param[1].buffer_length = static_cast(str[1].length());
+ bind_param[1].buffer_type = MYSQL_TYPE_STRING;
+
+ bind_param[2].buffer = const_cast(str[2].c_str());
+ bind_param[2].buffer_length = static_cast(str[2].length());
+ bind_param[2].buffer_type = MYSQL_TYPE_STRING;
+
+ bind_param[3].buffer = &fourth;
+ bind_param[3].buffer_type = MYSQL_TYPE_LONG;
+
+ bind_param[4].buffer = &fifth;
+ bind_param[4].buffer_type = MYSQL_TYPE_FLOAT;
+
+ rc = mysql_stmt_bind_param(hstmt, bind_param);
+ assert (rc == 0);
+
+ rc = mysql_stmt_execute(hstmt);
+ assert (rc == 0);
+
+ sql = "SELECT * FROM Test";
+ rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast(sql.length()));
+ assert (rc == 0);
+
+ char chr[3][5] = {{ 0 }};
+ unsigned long lengths[5] = { 0 };
+ fourth = 0;
+ fifth = 0.0f;
+
+ MYSQL_BIND bind_result[5] = {{0}};
+
+ bind_result[0].buffer = chr[0];
+ bind_result[0].buffer_length = sizeof(chr[0]);
+ bind_result[0].buffer_type = MYSQL_TYPE_STRING;
+ bind_result[0].length = &lengths[0];
+
+ bind_result[1].buffer = chr[1];
+ bind_result[1].buffer_length = sizeof(chr[1]);
+ bind_result[1].buffer_type = MYSQL_TYPE_STRING;
+ bind_result[1].length = &lengths[1];
+
+ bind_result[2].buffer = chr[2];
+ bind_result[2].buffer_length = sizeof(chr[2]);
+ bind_result[2].buffer_type = MYSQL_TYPE_STRING;
+ bind_result[2].length = &lengths[2];
+
+ bind_result[3].buffer = &fourth;
+ bind_result[3].buffer_type = MYSQL_TYPE_LONG;
+ bind_result[3].length = &lengths[3];
+
+ bind_result[4].buffer = &fifth;
+ bind_result[4].buffer_type = MYSQL_TYPE_FLOAT;
+ bind_result[4].length = &lengths[4];
+
+ rc = mysql_stmt_bind_result(hstmt, bind_result);
+ assert (rc == 0);
+
+ rc = mysql_stmt_execute(hstmt);
+ assert (rc == 0);
+ rc = mysql_stmt_fetch(hstmt);
+ assert (rc == 0);
+
+ assert (0 == std::strncmp("111", chr[0], 3));
+ assert (0 == std::strncmp("222", chr[1], 3));
+ assert (0 == std::strncmp("333", chr[2], 3));
+ assert (4 == fourth);
+ assert (1.5 == fifth);
+
+ rc = mysql_stmt_close(hstmt);
+ assert(rc == 0);
+
+ sql = "DROP TABLE Test";
+ rc = mysql_real_query(hsession, sql.c_str(), static_cast(sql.length()));
+ assert(rc == 0);
+
+ mysql_close(hsession);
+}
+
+
+void SQLExecutor::simpleAccess()
+{
+ std::string funct = "simpleAccess()";
+ std::string lastName = "lastName";
+ std::string firstName("firstName");
+ std::string address("Address");
+ int age = 133132;
+ int count = 0;
+ std::string result;
+
+ count = 0;
+ try
+ {
+ Statement stmt(*_pSession);
+ stmt << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(age);//, now;
+ stmt.execute();
+ }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ 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);
+
+ try { *_pSession << "SELECT LastName FROM Person", into(result), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (lastName == result);
+
+ 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);
+}
+
+
+void SQLExecutor::complexType()
+{
+ std::string funct = "complexType()";
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(p1), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(p2), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ int 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 == 2);
+
+ Person c1;
+ Person c2;
+ try { *_pSession << "SELECT * FROM Person WHERE LastName = 'LN1'", into(c1), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (c1 == p1);
+}
+
+
+void SQLExecutor::simpleAccessVector()
+{
+ std::string funct = "simpleAccessVector()";
+ std::vector lastNames;
+ std::vector firstNames;
+ std::vector addresses;
+ std::vector ages;
+ std::string tableName("Person");
+ lastNames.push_back("LN1");
+ lastNames.push_back("LN2");
+ firstNames.push_back("FN1");
+ firstNames.push_back("FN2");
+ addresses.push_back("ADDR1");
+ addresses.push_back("ADDR2");
+ ages.push_back(1);
+ ages.push_back(2);
+ int count = 0;
+ std::string result;
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ 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 == 2);
+
+ std::vector lastNamesR;
+ std::vector firstNamesR;
+ std::vector addressesR;
+ std::vector agesR;
+ try { *_pSession << "SELECT * FROM Person", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (ages == agesR);
+ assert (lastNames == lastNamesR);
+ assert (firstNames == firstNamesR);
+ assert (addresses == addressesR);
+}
+
+
+void SQLExecutor::complexTypeVector()
+{
+ std::string funct = "complexTypeVector()";
+ std::vector people;
+ people.push_back(Person("LN1", "FN1", "ADDR1", 1));
+ people.push_back(Person("LN2", "FN2", "ADDR2", 2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ int 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 == 2);
+
+ std::vector result;
+ try { *_pSession << "SELECT * FROM Person", into(result), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (result == people);
+}
+
+
+void SQLExecutor::insertVector()
+{
+ std::string funct = "insertVector()";
+ std::vector str;
+ str.push_back("s1");
+ str.push_back("s2");
+ str.push_back("s3");
+ str.push_back("s3");
+ int count = 100;
+
+ {
+ Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(str)));
+ try { *_pSession << "SELECT COUNT(*) FROM Strings", 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 == 0);
+
+ try { stmt.execute(); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ try { *_pSession << "SELECT COUNT(*) FROM Strings", 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 == 4);
+ }
+ count = 0;
+ try { *_pSession << "SELECT COUNT(*) FROM Strings", 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 == 4);
+}
+
+
+void SQLExecutor::insertEmptyVector()
+{
+ std::string funct = "insertEmptyVector()";
+ std::vector str;
+
+ try
+ {
+ *_pSession << "INSERT INTO Strings VALUES (?)", use(str), now;
+ fail("empty collections should not work");
+ }
+ catch (Poco::Exception&)
+ {
+ }
+}
+
+
+void SQLExecutor::insertSingleBulk()
+{
+ std::string funct = "insertSingleBulk()";
+ int x = 0;
+ Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(x)));
+
+ for (x = 0; x < 100; ++x)
+ {
+ int i = stmt.execute();
+ assert (i == 0);
+ }
+
+ int count = 0;
+ try { *_pSession << "SELECT COUNT(*) FROM Strings", 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 == 100);
+
+ try { *_pSession << "SELECT SUM(str) FROM Strings", 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 == ((0+99)*100/2));
+}
+
+
+void SQLExecutor::floats()
+{
+ std::string funct = "floats()";
+ float data = 1.5f;
+ float ret = 0.0f;
+
+ try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ int count = 0;
+ try { *_pSession << "SELECT COUNT(*) FROM Strings", 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);
+
+ try { *_pSession << "SELECT str FROM Strings", into(ret), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (ret == data);
+}
+
+
+void SQLExecutor::doubles()
+{
+ std::string funct = "floats()";
+ double data = 1.5;
+ double ret = 0.0;
+
+ try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ int count = 0;
+ try { *_pSession << "SELECT COUNT(*) FROM Strings", 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);
+
+ try { *_pSession << "SELECT str FROM Strings", into(ret), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (ret == data);
+}
+
+
+void SQLExecutor::insertSingleBulkVec()
+{
+ std::string funct = "insertSingleBulkVec()";
+ std::vector data;
+
+ for (int x = 0; x < 100; ++x)
+ data.push_back(x);
+
+ Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(data)));
+ stmt.execute();
+
+ int count = 0;
+ try { *_pSession << "SELECT COUNT(*) FROM Strings", 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 == 100);
+ try { *_pSession << "SELECT SUM(str) FROM Strings", 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 == ((0+99)*100/2));
+}
+
+
+void SQLExecutor::limits()
+{
+ std::string funct = "limit()";
+ std::vector data;
+ for (int x = 0; x < 100; ++x)
+ {
+ data.push_back(x);
+ }
+
+ try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ std::vector retData;
+ try { *_pSession << "SELECT * FROM Strings", into(retData), limit(50), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (retData.size() == 50);
+ for (int x = 0; x < 50; ++x)
+ {
+ assert(data[x] == retData[x]);
+ }
+}
+
+
+void SQLExecutor::limitZero()
+{
+ std::string funct = "limitZero()";
+ std::vector data;
+ for (int x = 0; x < 100; ++x)
+ {
+ data.push_back(x);
+ }
+
+ try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ std::vector retData;
+ try { *_pSession << "SELECT * FROM Strings", into(retData), limit(0), now; }// stupid test, but at least we shouldn't crash
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (retData.size() == 0);
+}
+
+
+void SQLExecutor::limitOnce()
+{
+ std::string funct = "limitOnce()";
+ std::vector data;
+ for (int x = 0; x < 101; ++x)
+ {
+ data.push_back(x);
+ }
+
+ try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ std::vector retData;
+ Statement stmt = (*_pSession << "SELECT * FROM Strings", into(retData), limit(50), now);
+ assert (!stmt.done());
+ assert (retData.size() == 50);
+ stmt.execute();
+ assert (!stmt.done());
+ assert (retData.size() == 100);
+ stmt.execute();
+ assert (stmt.done());
+ assert (retData.size() == 101);
+
+ for (int x = 0; x < 101; ++x)
+ {
+ assert(data[x] == retData[x]);
+ }
+}
+
+
+void SQLExecutor::limitPrepare()
+{
+ std::string funct = "limitPrepare()";
+ std::vector data;
+ for (int x = 0; x < 100; ++x)
+ {
+ data.push_back(x);
+ }
+
+ try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ std::vector retData;
+ Statement stmt = (*_pSession << "SELECT * FROM Strings", into(retData), limit(50));
+ assert (retData.size() == 0);
+ assert (!stmt.done());
+
+ try { stmt.execute(); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (!stmt.done());
+ assert (retData.size() == 50);
+
+ try { stmt.execute(); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (stmt.done());
+ assert (retData.size() == 100);
+
+ try { stmt.execute(); }// will restart execution!
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (!stmt.done());
+ assert (retData.size() == 150);
+ for (int x = 0; x < 150; ++x)
+ {
+ assert(data[x%100] == retData[x]);
+ }
+}
+
+
+
+void SQLExecutor::prepare()
+{
+ std::string funct = "prepare()";
+ std::vector data;
+ for (int x = 0; x < 100; x += 2)
+ {
+ data.push_back(x);
+ }
+
+ {
+ Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(data)));
+ }
+ // stmt should not have been executed when destroyed
+ int count = 100;
+ try { *_pSession << "SELECT COUNT(*) FROM Strings", 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 == 0);
+}
+
+
+void SQLExecutor::setSimple()
+{
+ std::string funct = "setSimple()";
+ std::set lastNames;
+ std::set firstNames;
+ std::set addresses;
+ std::set ages;
+ std::string tableName("Person");
+ lastNames.insert("LN1");
+ lastNames.insert("LN2");
+ firstNames.insert("FN1");
+ firstNames.insert("FN2");
+ addresses.insert("ADDR1");
+ addresses.insert("ADDR2");
+ ages.insert(1);
+ ages.insert(2);
+ int count = 0;
+ std::string result;
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ 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 == 2);
+
+ std::set lastNamesR;
+ std::set firstNamesR;
+ std::set addressesR;
+ std::set agesR;
+ try { *_pSession << "SELECT * FROM Person", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (ages == agesR);
+ assert (lastNames == lastNamesR);
+ assert (firstNames == firstNamesR);
+ assert (addresses == addressesR);
+}
+
+
+void SQLExecutor::setComplex()
+{
+ std::string funct = "setComplex()";
+ std::set people;
+ people.insert(Person("LN1", "FN1", "ADDR1", 1));
+ people.insert(Person("LN2", "FN2", "ADDR2", 2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ int 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 == 2);
+
+ std::set result;
+ try { *_pSession << "SELECT * FROM Person", into(result), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (result == people);
+}
+
+
+void SQLExecutor::setComplexUnique()
+{
+ std::string funct = "setComplexUnique()";
+ std::vector people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ people.push_back(p1);
+ people.push_back(p1);
+ people.push_back(p1);
+ people.push_back(p1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.push_back(p2);
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ int 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 == 5);
+
+ std::set result;
+ try { *_pSession << "SELECT * FROM Person", into(result), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (result.size() == 2);
+ assert (*result.begin() == p1);
+ assert (*++result.begin() == p2);
+}
+
+void SQLExecutor::multiSetSimple()
+{
+ std::string funct = "multiSetSimple()";
+ std::multiset lastNames;
+ std::multiset firstNames;
+ std::multiset addresses;
+ std::multiset ages;
+ std::string tableName("Person");
+ lastNames.insert("LN1");
+ lastNames.insert("LN2");
+ firstNames.insert("FN1");
+ firstNames.insert("FN2");
+ addresses.insert("ADDR1");
+ addresses.insert("ADDR2");
+ ages.insert(1);
+ ages.insert(2);
+ int count = 0;
+ std::string result;
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ 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 == 2);
+
+ std::multiset lastNamesR;
+ std::multiset firstNamesR;
+ std::multiset addressesR;
+ std::multiset agesR;
+ try { *_pSession << "SELECT * FROM Person", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (ages.size() == agesR.size());
+ assert (lastNames.size() == lastNamesR.size());
+ assert (firstNames.size() == firstNamesR.size());
+ assert (addresses.size() == addressesR.size());
+}
+
+
+void SQLExecutor::multiSetComplex()
+{
+ std::string funct = "multiSetComplex()";
+ std::multiset people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ people.insert(p1);
+ people.insert(p1);
+ people.insert(p1);
+ people.insert(p1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(p2);
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ int 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 == 5);
+
+ std::multiset result;
+ try { *_pSession << "SELECT * FROM Person", into(result), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (result.size() == people.size());
+}
+
+
+void SQLExecutor::mapComplex()
+{
+ std::string funct = "mapComplex()";
+ std::map people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN2", p2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ int 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 == 2);
+
+ std::map result;
+ try { *_pSession << "SELECT * FROM Person", into(result), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (result == people);
+}
+
+
+void SQLExecutor::mapComplexUnique()
+{
+ std::string funct = "mapComplexUnique()";
+ std::multimap people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN2", p2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ int 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 == 5);
+
+ std::map result;
+ try { *_pSession << "SELECT * FROM Person", into(result), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (result.size() == 2);
+}
+
+
+void SQLExecutor::multiMapComplex()
+{
+ std::string funct = "multiMapComplex()";
+ std::multimap people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN2", p2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ int 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 == 5);
+
+ std::multimap result;
+ try { *_pSession << "SELECT * FROM Person", into(result), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (result.size() == people.size());
+}
+
+
+void SQLExecutor::selectIntoSingle()
+{
+ std::string funct = "selectIntoSingle()";
+ std::multimap people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ int 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 == 2);
+ Person result;
+ try { *_pSession << "SELECT * FROM Person", into(result), limit(1), now; }// will return 1 object into one single result
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (result == p1);
+}
+
+
+void SQLExecutor::selectIntoSingleStep()
+{
+ std::string funct = "selectIntoSingleStep()";
+ std::multimap people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ int 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 == 2);
+ Person result;
+ Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1));
+ stmt.execute();
+ assert (result == p1);
+ assert (!stmt.done());
+ stmt.execute();
+ assert (result == p2);
+ assert (stmt.done());
+}
+
+
+void SQLExecutor::selectIntoSingleFail()
+{
+ std::string funct = "selectIntoSingleFail()";
+ std::multimap people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ int count = 0;
+ try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), limit(2, true), 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 == 2);
+ Person result;
+ try
+ {
+ *_pSession << "SELECT * FROM Person", into(result), limit(1, true), now; // will fail now
+ fail("hardLimit is set: must fail");
+ }
+ catch(Poco::Data::LimitException&)
+ {
+ }
+}
+
+
+void SQLExecutor::lowerLimitOk()
+{
+ std::string funct = "lowerLimitOk()";
+ std::multimap people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ int 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 == 2);
+ Person result;
+ try
+ {
+ *_pSession << "SELECT * FROM Person", into(result), lowerLimit(2), now; // will return 2 objects into one single result but only room for one!
+ fail("Not enough space for results");
+ }
+ catch(Poco::Exception&)
+ {
+ }
+}
+
+
+void SQLExecutor::singleSelect()
+{
+ std::string funct = "singleSelect()";
+ std::multimap people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ int 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 == 2);
+ Person result;
+ Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1));
+ stmt.execute();
+ assert (result == p1);
+ assert (!stmt.done());
+ stmt.execute();
+ assert (result == p2);
+ assert (stmt.done());
+}
+
+
+void SQLExecutor::lowerLimitFail()
+{
+ std::string funct = "lowerLimitFail()";
+ std::multimap people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ int 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 == 2);
+ Person result;
+ try
+ {
+ *_pSession << "SELECT * FROM Person", into(result), lowerLimit(3), now; // will fail
+ fail("should fail. not enough data");
+ }
+ catch(Poco::Exception&)
+ {
+ }
+}
+
+
+void SQLExecutor::combinedLimits()
+{
+ std::string funct = "combinedLimits()";
+ std::multimap people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ int 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 == 2);
+ std::vector result;
+ try { *_pSession << "SELECT * FROM Person", into(result), lowerLimit(2), upperLimit(2), now; }// will return 2 objects
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (result.size() == 2);
+ assert (result[0] == p1);
+ assert (result[1] == p2);
+}
+
+
+
+void SQLExecutor::ranges()
+{
+ std::string funct = "range()";
+ std::multimap people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ int 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 == 2);
+ std::vector result;
+ try { *_pSession << "SELECT * FROM Person", into(result), range(2, 2), now; }// will return 2 objects
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (result.size() == 2);
+ assert (result[0] == p1);
+ assert (result[1] == p2);
+}
+
+
+void SQLExecutor::combinedIllegalLimits()
+{
+ std::string funct = "combinedIllegalLimits()";
+ std::multimap people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ int 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 == 2);
+ Person result;
+ try
+ {
+ *_pSession << "SELECT * FROM Person", into(result), lowerLimit(3), upperLimit(2), now;
+ fail("lower > upper is not allowed");
+ }
+ catch(LimitException&)
+ {
+ }
+}
+
+
+void SQLExecutor::illegalRange()
+{
+ std::string funct = "illegalRange()";
+ std::multimap people;
+ Person p1("LN1", "FN1", "ADDR1", 1);
+ Person p2("LN2", "FN2", "ADDR2", 2);
+ people.insert(std::make_pair("LN1", p1));
+ people.insert(std::make_pair("LN1", p2));
+
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ int 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 == 2);
+ Person result;
+ try
+ {
+ *_pSession << "SELECT * FROM Person", into(result), range(3, 2), now;
+ fail("lower > upper is not allowed");
+ }
+ catch(LimitException&)
+ {
+ }
+}
+
+
+void SQLExecutor::emptyDB()
+{
+ std::string funct = "emptyDB()";
+ int 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 == 0);
+
+ Person result;
+ Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1));
+ stmt.execute();
+ assert (result.firstName.empty());
+ assert (stmt.done());
+}
+
+
+void SQLExecutor::blob(int bigSize)
+{
+ std::string funct = "blob()";
+ std::string lastName("lastname");
+ std::string firstName("firstname");
+ std::string address("Address");
+
+ Poco::Data::CLOB img("0123456789", 10);
+ int count = 0;
+ try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(img), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ 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);
+
+ Poco::Data::CLOB res;
+ assert (res.size() == 0);
+ try { *_pSession << "SELECT Image FROM Person", into(res), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (res == img);
+
+ Poco::Data::CLOB big;
+ std::vector v(bigSize, 'x');
+ big.assignRaw(&v[0], v.size());
+
+ assert (big.size() == (size_t)bigSize);
+
+ try { *_pSession << "DELETE FROM Person", now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ try { *_pSession << "INSERT INTO Person VALUES(?,?,?,?)", use(lastName), use(firstName), use(address), use(big), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ try { *_pSession << "SELECT Image FROM Person", into(res), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (res == big);
+}
+
+void SQLExecutor::blobStmt()
+{
+ std::string funct = "blobStmt()";
+ std::string lastName("lastname");
+ std::string firstName("firstname");
+ std::string address("Address");
+ Poco::Data::CLOB blob("0123456789", 10);
+
+ int count = 0;
+ Statement ins = (*_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(blob));
+ ins.execute();
+ 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);
+
+ Poco::Data::CLOB res;
+ poco_assert (res.size() == 0);
+ Statement stmt = (*_pSession << "SELECT Image FROM Person", into(res));
+ try { stmt.execute(); }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ poco_assert (res == blob);
+}
+
+void SQLExecutor::tuples()
+{
+ typedef Tuple TupleType;
+ std::string funct = "tuples()";
+ TupleType t(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19);
+
+ try { *_pSession << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", use(t), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ TupleType ret(-10,-11,-12,-13,-14,-15,-16,-17,-18,-19);
+ assert (ret != t);
+ try { *_pSession << "SELECT * FROM Tuples", into(ret), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (ret == t);
+}
+
+void SQLExecutor::tupleVector()
+{
+ typedef Tuple TupleType;
+ std::string funct = "tupleVector()";
+ TupleType t(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19);
+ Tuple
+ t10(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29);
+ TupleType t100(100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119);
+ std::vector v;
+ v.push_back(t);
+ v.push_back(t10);
+ v.push_back(t100);
+
+ try { *_pSession << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", use(v), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ int count = 0;
+ try { *_pSession << "SELECT COUNT(*) FROM Tuples", 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 (v.size() == (size_t)count);
+
+ std::vector > ret;
+ try { *_pSession << "SELECT * FROM Tuples", into(ret), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (ret == v);
+}
+
+
+void SQLExecutor::internalExtraction()
+{
+ /*std::string funct = "internalExtraction()";
+ std::vector > v;
+ v.push_back(Tuple(1, 1.5f, "3"));
+ v.push_back(Tuple(2, 2.5f, "4"));
+ v.push_back(Tuple(3, 3.5f, "5"));
+ v.push_back(Tuple(4, 4.5f, "6"));
+
+ try { *_pSession << "INSERT INTO Vectors VALUES (?,?,?)", use(v), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ try
+ {
+ Statement stmt = (*_pSession << "SELECT * FROM Vectors", now);
+ RecordSet rset(stmt);
+
+ assert (3 == rset.columnCount());
+ assert (4 == rset.rowCount());
+
+ int curVal = 3;
+ do
+ {
+ assert (rset["str0"] == curVal);
+ ++curVal;
+ } while (rset.moveNext());
+
+ rset.moveFirst();
+ assert (rset["str0"] == "3");
+ rset.moveLast();
+ assert (rset["str0"] == "6");
+
+ RecordSet rset2(rset);
+ assert (3 == rset2.columnCount());
+ assert (4 == rset2.rowCount());
+
+ int i = rset.value(0,0);
+ assert (1 == i);
+
+ std::string s = rset.value(0,0);
+ assert ("1" == s);
+
+ int a = rset.value(0,2);
+ assert (3 == a);
+
+ try
+ {
+ double d = rset.value(1,1);
+ assert (2.5 == d);
+ }
+ catch (BadCastException&)
+ {
+ float f = rset.value(1,1);
+ assert (2.5 == f);
+ }
+
+ s = rset.value(2,2);
+ assert ("5" == s);
+ i = rset.value("str0", 2);
+ assert (5 == i);
+
+ const Column& col = rset.column(0);
+ Column::Iterator it = col.begin();
+ Column::Iterator end = col.end();
+ for (int i = 1; it != end; ++it, ++i)
+ assert (*it == i);
+
+ rset = (*_pSession << "SELECT COUNT(*) AS cnt FROM Vectors", now);
+
+ //various results for COUNT(*) are received from different drivers
+ try
+ {
+ //this is what most drivers will return
+ int i = rset.value(0,0);
+ assert (4 == i);
+ }
+ catch(BadCastException&)
+ {
+ try
+ {
+ //this is for Oracle
+ double i = rset.value(0,0);
+ assert (4 == int(i));
+ }
+ catch(BadCastException&)
+ {
+ //this is for PostgreSQL
+ Poco::Int64 big = rset.value(0,0);
+ assert (4 == big);
+ }
+ }
+
+ s = rset.value("cnt", 0).convert();
+ assert ("4" == s);
+
+ try { const Column& col1 = rset.column(100); fail ("must fail"); }
+ catch (RangeException&) { }
+
+ try { rset.value(0,0); fail ("must fail"); }
+ catch (BadCastException&) { }
+
+ stmt = (*_pSession << "DELETE FROM Vectors", now);
+ rset = stmt;
+
+ try { const Column& col1 = rset.column(0); fail ("must fail"); }
+ catch (RangeException&) { }
+ }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+*/
+}
+
+
+void SQLExecutor::doNull()
+{
+ std::string funct = "null()";
+
+ *_pSession << "INSERT INTO Vectors VALUES (?, ?, ?)",
+ use(Poco::Data::Keywords::null),
+ use(Poco::Data::Keywords::null),
+ use(Poco::Data::Keywords::null), now;
+
+ int count = 0;
+ try { *_pSession << "SELECT COUNT(*) FROM Vectors", 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);
+
+ int i0 = 0;
+ Statement stmt1 = (*_pSession << "SELECT i0 FROM Vectors", into(i0, Poco::Data::Position(0), -1));
+ try { stmt1.execute(); }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ poco_assert (i0 == -1);
+
+ float flt0 = 0;
+ Statement stmt2 = (*_pSession << "SELECT flt0 FROM Vectors", into(flt0, Poco::Data::Position(0), 3.25f));
+ try { stmt2.execute(); }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ poco_assert (flt0 == 3.25);
+
+ std::string str0("string");
+ Statement stmt3 = (*_pSession << "SELECT str0 FROM Vectors", into(str0, Poco::Data::Position(0), std::string("DEFAULT")));
+ try { stmt3.execute(); }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ poco_assert (str0 == "DEFAULT");
+}
+
+
+void SQLExecutor::setTransactionIsolation(Session& session, Poco::UInt32 ti)
+{
+ if (session.hasTransactionIsolation(ti))
+ {
+ std::string funct = "setTransactionIsolation()";
+
+ try
+ {
+ Transaction t(session, false);
+ t.setIsolation(ti);
+
+ assert (ti == t.getIsolation());
+ assert (t.isIsolation(ti));
+
+ assert (ti == session.getTransactionIsolation());
+ assert (session.isTransactionIsolation(ti));
+ }
+ catch(Poco::Exception& e){ std::cout << funct << ':' << e.displayText() << std::endl;}
+ }
+ else
+ {
+ std::cout << "Transaction isolation not supported: ";
+ switch (ti)
+ {
+ case Session::TRANSACTION_READ_COMMITTED:
+ std::cout << "READ COMMITTED"; break;
+ case Session::TRANSACTION_READ_UNCOMMITTED:
+ std::cout << "READ UNCOMMITTED"; break;
+ case Session::TRANSACTION_REPEATABLE_READ:
+ std::cout << "REPEATABLE READ"; break;
+ case Session::TRANSACTION_SERIALIZABLE:
+ std::cout << "SERIALIZABLE"; break;
+ default:
+ std::cout << "UNKNOWN"; break;
+ }
+ std::cout << std::endl;
+ }
+}
+
+
+void SQLExecutor::sessionTransaction(const std::string& connect)
+{
+ if (!_pSession->canTransact())
+ {
+ std::cout << "Session not capable of transactions." << std::endl;
+ return;
+ }
+
+ Session local("mysql", connect);
+ local.setFeature("autoCommit", true);
+
+ std::string funct = "transaction()";
+ std::vector lastNames;
+ std::vector firstNames;
+ std::vector addresses;
+ std::vector ages;
+ std::string tableName("Person");
+ lastNames.push_back("LN1");
+ lastNames.push_back("LN2");
+ firstNames.push_back("FN1");
+ firstNames.push_back("FN2");
+ addresses.push_back("ADDR1");
+ addresses.push_back("ADDR2");
+ ages.push_back(1);
+ ages.push_back(2);
+ int count = 0, locCount = 0;
+ std::string result;
+
+ bool autoCommit = _pSession->getFeature("autoCommit");
+
+ _pSession->setFeature("autoCommit", true);
+ assert (!_pSession->isTransaction());
+ _pSession->setFeature("autoCommit", false);
+ assert (!_pSession->isTransaction());
+
+ setTransactionIsolation((*_pSession), Session::TRANSACTION_READ_UNCOMMITTED);
+ setTransactionIsolation((*_pSession), Session::TRANSACTION_REPEATABLE_READ);
+ setTransactionIsolation((*_pSession), Session::TRANSACTION_SERIALIZABLE);
+
+ setTransactionIsolation((*_pSession), Session::TRANSACTION_READ_COMMITTED);
+
+ _pSession->begin();
+ assert (_pSession->isTransaction());
+ try { (*_pSession) << "INSERT INTO PERSON VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (_pSession->isTransaction());
+
+ local << "SELECT COUNT(*) FROM PERSON", into(locCount), now;
+ assert (0 == locCount);
+
+ 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 (2 == count);
+ assert (_pSession->isTransaction());
+ _pSession->rollback();
+ assert (!_pSession->isTransaction());
+
+ local << "SELECT COUNT(*) FROM PERSON", into(locCount), now;
+ assert (0 == locCount);
+
+ 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 (0 == count);
+ assert (!_pSession->isTransaction());
+
+ _pSession->begin();
+ try { (*_pSession) << "INSERT INTO PERSON VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+ assert (_pSession->isTransaction());
+
+ local << "SELECT COUNT(*) FROM PERSON", into(locCount), now;
+ assert (0 == locCount);
+
+ _pSession->commit();
+ assert (!_pSession->isTransaction());
+
+ local << "SELECT COUNT(*) FROM PERSON", into(locCount), now;
+ assert (2 == locCount);
+
+ 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 (2 == count);
+
+ _pSession->setFeature("autoCommit", autoCommit);
+}
+
+
+void SQLExecutor::transaction(const std::string& connect)
+{
+ if (!_pSession->canTransact())
+ {
+ std::cout << "Session not transaction-capable." << std::endl;
+ return;
+ }
+
+ Session local("mysql", connect);
+ local.setFeature("autoCommit", true);
+
+ setTransactionIsolation((*_pSession), Session::TRANSACTION_READ_COMMITTED);
+ setTransactionIsolation(local, Session::TRANSACTION_READ_COMMITTED);
+
+ std::string funct = "transaction()";
+ std::vector lastNames;
+ std::vector firstNames;
+ std::vector addresses;
+ std::vector ages;
+ std::string tableName("Person");
+ lastNames.push_back("LN1");
+ lastNames.push_back("LN2");
+ firstNames.push_back("FN1");
+ firstNames.push_back("FN2");
+ addresses.push_back("ADDR1");
+ addresses.push_back("ADDR2");
+ ages.push_back(1);
+ ages.push_back(2);
+ int count = 0, locCount = 0;
+ std::string result;
+
+ bool autoCommit = _pSession->getFeature("autoCommit");
+
+ _pSession->setFeature("autoCommit", true);
+ assert (!_pSession->isTransaction());
+ _pSession->setFeature("autoCommit", false);
+ assert (!_pSession->isTransaction());
+ _pSession->setTransactionIsolation(Session::TRANSACTION_READ_COMMITTED);
+
+ {
+ Transaction trans((*_pSession));
+ assert (trans.isActive());
+ assert (_pSession->isTransaction());
+
+ try { (*_pSession) << "INSERT INTO PERSON VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ assert (_pSession->isTransaction());
+ assert (trans.isActive());
+
+ 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 (2 == count);
+ assert (_pSession->isTransaction());
+ assert (trans.isActive());
+ }
+ assert (!_pSession->isTransaction());
+
+ 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 (0 == count);
+ assert (!_pSession->isTransaction());
+
+ {
+ Transaction trans((*_pSession));
+ try { (*_pSession) << "INSERT INTO PERSON VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ local << "SELECT COUNT(*) FROM PERSON", into(locCount), now;
+ assert (0 == locCount);
+
+ assert (_pSession->isTransaction());
+ assert (trans.isActive());
+ trans.commit();
+ assert (!_pSession->isTransaction());
+ assert (!trans.isActive());
+ local << "SELECT COUNT(*) FROM PERSON", into(locCount), now;
+ assert (2 == locCount);
+ }
+
+ 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 (2 == count);
+
+ _pSession->begin();
+ try { (*_pSession) << "DELETE FROM PERSON", now; }
+ catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+ catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+
+ local << "SELECT COUNT(*) FROM PERSON", into(locCount), now;
+ assert (2 == locCount);
+
+ 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 (0 == count);
+ _pSession->commit();
+
+ local << "SELECT COUNT(*) FROM PERSON", into(locCount), now;
+ assert (0 == locCount);
+
+ std::string sql1 = format("INSERT INTO PERSON VALUES ('%s','%s','%s',%d)", lastNames[0], firstNames[0], addresses[0], ages[0]);
+ std::string sql2 = format("INSERT INTO PERSON VALUES ('%s','%s','%s',%d)", lastNames[1], firstNames[1], addresses[1], ages[1]);
+ std::vector sql;
+ sql.push_back(sql1);
+ sql.push_back(sql2);
+
+ Transaction trans((*_pSession));
+
+ trans.execute(sql1, false);
+ 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 (1 == count);
+ trans.execute(sql2, false);
+ 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 (2 == count);
+
+ local << "SELECT COUNT(*) FROM PERSON", into(locCount), now;
+ assert (0 == locCount);
+
+ trans.rollback();
+
+ local << "SELECT COUNT(*) FROM PERSON", into(locCount), now;
+ assert (0 == locCount);
+
+ 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 (0 == count);
+
+ trans.execute(sql);
+
+ local << "SELECT COUNT(*) FROM PERSON", into(locCount), now;
+ assert (2 == locCount);
+
+ 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 (2 == count);
+
+ _pSession->setFeature("autoCommit", autoCommit);
+}
diff --git a/Data/MySQL/testsuite/src/SQLExecutor.h b/Data/MySQL/testsuite/src/SQLExecutor.h
index 22449b803..a8cbfc977 100644
--- a/Data/MySQL/testsuite/src/SQLExecutor.h
+++ b/Data/MySQL/testsuite/src/SQLExecutor.h
@@ -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;
};
diff --git a/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h b/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h
index fd3269794..fceb742fe 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h
@@ -47,7 +47,8 @@
#include "Poco/Data/ODBC/Handle.h"
#include "Poco/Data/ODBC/ODBCException.h"
#include "Poco/Data/AbstractSessionImpl.h"
-#include "Poco/SharedPtr.h"
+#include "Poco/SharedPtr.h"
+#include "Poco/Mutex.h"
#ifdef POCO_OS_FAMILY_WINDOWS
#include
#endif
@@ -63,6 +64,13 @@ class ODBC_API SessionImpl: public Poco::Data::AbstractSessionImpl