mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-12-20 23:17:18 +01:00
Update POCO to 1.11.0
This commit is contained in:
5
vendor/POCO/Data/MySQL/Makefile
vendored
5
vendor/POCO/Data/MySQL/Makefile
vendored
@@ -6,8 +6,9 @@
|
||||
|
||||
include $(POCO_BASE)/build/rules/global
|
||||
|
||||
SYSLIBS += -L/usr/local/lib -L/usr/local/lib$(LIB64SUFFIX)/mysql -L/usr/lib$(LIB64SUFFIX)/mysql -L/usr/mysql/lib$(LIB64SUFFIX) -L/usr/mysql/lib$(LIB64SUFFIX)/mysql -L/usr/local/mysql/lib$(LIB64SUFFIX) -lmysqlclient
|
||||
INCLUDE += -I/usr/local/include/mysql/ -I/usr/include/mysql/ -I/usr/mysql/include/mysql -I/usr/local/mysql/include
|
||||
include MySQL.make
|
||||
|
||||
SYSLIBS += -lmysqlclient
|
||||
SYSFLAGS += -DTHREADSAFE -DNO_TCL
|
||||
|
||||
objects = Binder Extractor SessionImpl Connector \
|
||||
|
||||
32
vendor/POCO/Data/MySQL/MySQL.make
vendored
Normal file
32
vendor/POCO/Data/MySQL/MySQL.make
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# MySQL.make
|
||||
#
|
||||
# Makefile fragment for finding MySQL library
|
||||
#
|
||||
|
||||
ifndef POCO_MYSQL_INCLUDE
|
||||
ifeq (0, $(shell test -d /usr/local/include/mysql; echo $$?))
|
||||
POCO_MYSQL_INCLUDE = /usr/local/include
|
||||
else
|
||||
ifeq (0, $(shell test -d /usr/local/opt/mysql-client/include; echo $$?))
|
||||
POCO_MYSQL_INCLUDE = /usr/local/opt/mysql-client/include
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef POCO_MYSQL_LIB
|
||||
ifeq (0, $(shell test -d /usr/local/include/mysql; echo $$?))
|
||||
POCO_MYSQL_LIB = /usr/local/lib
|
||||
else
|
||||
ifeq (0, $(shell test -d /usr/local/opt/mysql-client/lib; echo $$?))
|
||||
POCO_MYSQL_LIB = /usr/local/opt/mysql-client/lib
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef POCO_MYSQL_INCLUDE
|
||||
INCLUDE += -I$(POCO_MYSQL_INCLUDE)
|
||||
endif
|
||||
ifdef POCO_MYSQL_LIB
|
||||
SYSLIBS += -L$(POCO_MYSQL_LIB)
|
||||
endif
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "Poco/Data/AbstractBinder.h"
|
||||
#include "Poco/Data/LOB.h"
|
||||
#include "Poco/Data/MySQL/MySQLException.h"
|
||||
#include <mysql.h>
|
||||
#include <mysql/mysql.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
|
||||
virtual void bind(std::size_t pos, const unsigned long& val, Direction dir = PD_IN);
|
||||
/// Binds an unsigned long.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
virtual void bind(std::size_t pos, const bool& val, Direction dir);
|
||||
/// Binds a boolean.
|
||||
@@ -104,6 +104,9 @@ public:
|
||||
virtual void bind(std::size_t pos, const Time& val, Direction dir);
|
||||
/// Binds a Time.
|
||||
|
||||
virtual void bind(std::size_t pos, const UUID& val, Direction dir);
|
||||
/// Binds a UUID.
|
||||
|
||||
virtual void bind(std::size_t pos, const NullData& val, Direction dir);
|
||||
/// Binds a null.
|
||||
|
||||
|
||||
@@ -110,6 +110,9 @@ public:
|
||||
virtual bool extract(std::size_t pos, Time& val);
|
||||
/// Extracts a Time. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, UUID& val);
|
||||
/// Extracts a UUID. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, Any& val);
|
||||
/// Extracts an Any. Returns false if null was received.
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
#include <mysql/mysql.h>
|
||||
|
||||
|
||||
//
|
||||
@@ -54,7 +55,11 @@
|
||||
#if !defined(MySQL_EXPORTS)
|
||||
#pragma comment(lib, "PocoDataMySQL" POCO_LIB_SUFFIX)
|
||||
#endif
|
||||
#pragma comment(lib, "libmysql")
|
||||
#if defined(LIBMARIADB)
|
||||
#pragma comment(lib, "libmariadb")
|
||||
#else
|
||||
#pragma comment(lib, "libmysql")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
|
||||
#include "Poco/Data/MySQL/MySQL.h"
|
||||
#include "Poco/Data/DataException.h"
|
||||
#include <mysql/mysql.h>
|
||||
#include <typeinfo>
|
||||
#include <string>
|
||||
#include <mysql.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
#define Data_MySQL_ResultMetadata_INCLUDED
|
||||
|
||||
|
||||
#include <mysql.h>
|
||||
#include <vector>
|
||||
#include "Poco/Data/MetaColumn.h"
|
||||
#include <mysql/mysql.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#if LIBMYSQL_VERSION_ID >= 80000
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#define Data_MySQL_SessionHandle_INCLUDED
|
||||
|
||||
|
||||
#include <mysql.h>
|
||||
#include "Poco/Data/MySQL/MySQLException.h"
|
||||
#include <mysql/mysql.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#define Data_MySQL_StatementHandle_INCLUDED
|
||||
|
||||
|
||||
#include <mysql.h>
|
||||
#include "Poco/Data/MySQL/MySQLException.h"
|
||||
#include <mysql/mysql.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
/// Fetches the column.
|
||||
|
||||
int getAffectedRowCount() const;
|
||||
|
||||
|
||||
operator MYSQL_STMT* ();
|
||||
/// Cast operator to native handle type.
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "Poco/Data/MySQL/MySQL.h"
|
||||
#include "Poco/Data/Session.h"
|
||||
#include <mysql.h>
|
||||
#include <mysql/mysql.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
7
vendor/POCO/Data/MySQL/src/Binder.cpp
vendored
7
vendor/POCO/Data/MySQL/src/Binder.cpp
vendored
@@ -211,6 +211,13 @@ void Binder::bind(std::size_t pos, const Time& val, Direction dir)
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const UUID& val, Direction dir)
|
||||
{
|
||||
std::string str = val.toString();
|
||||
bind(pos, str, dir);
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const NullData&, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
|
||||
4
vendor/POCO/Data/MySQL/src/Connector.cpp
vendored
4
vendor/POCO/Data/MySQL/src/Connector.cpp
vendored
@@ -16,7 +16,7 @@
|
||||
#include "Poco/Data/MySQL/SessionImpl.h"
|
||||
#include "Poco/Data/SessionFactory.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <mysql.h>
|
||||
#include <mysql/mysql.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@@ -46,7 +46,7 @@ const std::string& Connector::name() const
|
||||
Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString,
|
||||
std::size_t timeout)
|
||||
{
|
||||
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString, timeout));
|
||||
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString, timeout));
|
||||
}
|
||||
|
||||
|
||||
|
||||
12
vendor/POCO/Data/MySQL/src/Extractor.cpp
vendored
12
vendor/POCO/Data/MySQL/src/Extractor.cpp
vendored
@@ -204,6 +204,18 @@ bool Extractor::extract(std::size_t pos, Time& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, UUID& val)
|
||||
{
|
||||
std::string str;
|
||||
if (extract(pos, str))
|
||||
{
|
||||
val.parse(str);
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Any& val)
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -12,8 +12,13 @@
|
||||
//
|
||||
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
|
||||
#include "Poco/Data/MySQL/MySQLException.h"
|
||||
#include <mysql.h>
|
||||
#include <mysql/mysql.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
1
vendor/POCO/Data/MySQL/src/SessionHandle.cpp
vendored
1
vendor/POCO/Data/MySQL/src/SessionHandle.cpp
vendored
@@ -183,6 +183,7 @@ void SessionHandle::rollback()
|
||||
|
||||
void SessionHandle::reset()
|
||||
{
|
||||
//#if ((defined (MYSQL_VERSION_ID)) && (MYSQL_VERSION_ID >= 50700)) || ((defined (MARIADB_PACKAGE_VERSION_ID)) && (MARIADB_PACKAGE_VERSION_ID >= 30000))
|
||||
#if ((POCO_OS == POCO_OS_LINUX) && defined (HAVE_MYSQL_RESET_CONNECTION)) && (((defined (MYSQL_VERSION_ID)) && (MYSQL_VERSION_ID >= 50700)) || ((defined (MARIADB_PACKAGE_VERSION_ID)) && (MARIADB_PACKAGE_VERSION_ID >= 30000)))
|
||||
if (mysql_reset_connection(_pHandle) != 0)
|
||||
#else
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
//
|
||||
|
||||
|
||||
#include <mysql.h>
|
||||
#include "Poco/Data/MySQL/StatementExecutor.h"
|
||||
#include "Poco/Format.h"
|
||||
#include <mysql/mysql.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@@ -52,7 +52,7 @@ void StatementExecutor::prepare(const std::string& query)
|
||||
_state = STMT_COMPILED;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int rc = mysql_stmt_prepare(_pHandle, query.c_str(), static_cast<unsigned int>(query.length()));
|
||||
if (rc != 0)
|
||||
{
|
||||
@@ -119,7 +119,7 @@ bool StatementExecutor::fetch()
|
||||
int res = mysql_stmt_fetch(_pHandle);
|
||||
|
||||
// we have specified zero buffers for BLOBs, so DATA_TRUNCATED is normal in this case
|
||||
if ((res != 0) && (res != MYSQL_NO_DATA) && (res != MYSQL_DATA_TRUNCATED))
|
||||
if ((res != 0) && (res != MYSQL_NO_DATA) && (res != MYSQL_DATA_TRUNCATED))
|
||||
throw StatementException("mysql_stmt_fetch error", _pHandle, _query);
|
||||
|
||||
return (res == 0) || (res == MYSQL_DATA_TRUNCATED);
|
||||
|
||||
2
vendor/POCO/Data/MySQL/src/Utility.cpp
vendored
2
vendor/POCO/Data/MySQL/src/Utility.cpp
vendored
@@ -15,7 +15,7 @@
|
||||
|
||||
|
||||
#include "Poco/Data/MySQL/Utility.h"
|
||||
#include <mysql.h>
|
||||
#include <mysql/mysql.h>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
4
vendor/POCO/Data/MySQL/testsuite/Makefile
vendored
4
vendor/POCO/Data/MySQL/testsuite/Makefile
vendored
@@ -6,10 +6,10 @@
|
||||
|
||||
include $(POCO_BASE)/build/rules/global
|
||||
|
||||
INCLUDE += -I./../include -I/usr/local/include/mysql -I/usr/include/mysql/ -I/usr/mysql/include/mysql -I/usr/local/mysql/include
|
||||
include $(POCO_BASE)/Data/MySQL/MySQL.make
|
||||
|
||||
# Note: linking order is important, do not change it.
|
||||
SYSLIBS += -L/usr/local/lib -L/usr/local/lib$(LIB64SUFFIX)/mysql -L/usr/lib$(LIB64SUFFIX)/mysql -L/usr/mysql/lib$(LIB64SUFFIX) -L/usr/mysql/lib$(LIB64SUFFIX)/mysql -L/usr/local/mysql/lib$(LIB64SUFFIX) -lmysqlclient -lz -lpthread -ldl
|
||||
SYSLIBS += -lmysqlclient -lz -lpthread -ldl
|
||||
|
||||
objects = MySQLTestSuite Driver MySQLTest SQLExecutor
|
||||
|
||||
|
||||
@@ -45,7 +45,9 @@ Poco::SharedPtr<SQLExecutor> MySQLTest::_pExecutor = 0;
|
||||
#define MYSQL_USER "pocotest"
|
||||
#define MYSQL_PWD "pocotest"
|
||||
#define MYSQL_HOST "127.0.0.1"
|
||||
#ifndef MYSQL_PORT
|
||||
#define MYSQL_PORT 3306
|
||||
#endif
|
||||
#define MYSQL_DB "pocotest"
|
||||
|
||||
//
|
||||
@@ -494,6 +496,15 @@ void MySQLTest::testDouble()
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testUUID()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateUUIDsTable();
|
||||
_pExecutor->uuids();
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::testTuple()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
@@ -777,6 +788,15 @@ void MySQLTest::recreateFloatsTable()
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::recreateUUIDsTable()
|
||||
{
|
||||
dropTable("Strings");
|
||||
try { *_pSession << "CREATE TABLE Strings (str CHAR(36))", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateUUIDsTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateUUIDsTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void MySQLTest::recreateTuplesTable()
|
||||
{
|
||||
dropTable("Tuples");
|
||||
@@ -902,6 +922,7 @@ CppUnit::Test* MySQLTest::suite()
|
||||
CppUnit_addTest(pSuite, MySQLTest, testUnsignedInts);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testFloat);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testDouble);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testUUID);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testTuple);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testTupleVector);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testInternalExtraction);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
class MySQLTest: public CppUnit::TestCase
|
||||
/// MySQL test class
|
||||
/// Tested:
|
||||
///
|
||||
///
|
||||
/// Driver | DB | OS
|
||||
/// ----------------+---------------------------+------------------------------------------
|
||||
/// 03.51.12.00 | MySQL 5.0.27-community-nt | MS Windows XP Professional x64 v.2003/SP1
|
||||
@@ -84,6 +84,8 @@ public:
|
||||
void testFloat();
|
||||
void testDouble();
|
||||
|
||||
void testUUID();
|
||||
|
||||
void testTuple();
|
||||
void testTupleVector();
|
||||
|
||||
@@ -119,6 +121,7 @@ private:
|
||||
void recreateIntsTable();
|
||||
void recreateUnsignedIntsTable();
|
||||
void recreateFloatsTable();
|
||||
void recreateUUIDsTable();
|
||||
void recreateTuplesTable();
|
||||
void recreateVectorsTable();
|
||||
void recreateNullableIntTable();
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "MySQLTestSuite.h"
|
||||
#include "MySQLTest.h"
|
||||
|
||||
|
||||
CppUnit::Test* MySQLTestSuite::suite()
|
||||
{
|
||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("MySQLTestSuite");
|
||||
|
||||
109
vendor/POCO/Data/MySQL/testsuite/src/SQLExecutor.cpp
vendored
109
vendor/POCO/Data/MySQL/testsuite/src/SQLExecutor.cpp
vendored
@@ -27,9 +27,9 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Winsock2.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <mysql.h>
|
||||
#include <mysql/mysql.h>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
@@ -141,7 +141,7 @@ private:
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
SQLExecutor::SQLExecutor(const std::string& name, Poco::Data::Session* pSession):
|
||||
SQLExecutor::SQLExecutor(const std::string& name, Poco::Data::Session* pSession):
|
||||
CppUnit::TestCase(name),
|
||||
_pSession(pSession)
|
||||
{
|
||||
@@ -161,22 +161,22 @@ void SQLExecutor::bareboneMySQLTest(const char* host, const char* user, const ch
|
||||
|
||||
MYSQL* tmp = mysql_real_connect(hsession, host, user, pwd, db, port, 0, 0);
|
||||
assertTrue (tmp == hsession);
|
||||
|
||||
|
||||
MYSQL_STMT* hstmt = mysql_stmt_init(hsession);
|
||||
assertTrue (hstmt != 0);
|
||||
|
||||
|
||||
std::string sql = "DROP TABLE Test";
|
||||
mysql_real_query(hsession, sql.c_str(), static_cast<unsigned long>(sql.length()));
|
||||
|
||||
|
||||
sql = tableCreateString;
|
||||
rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast<unsigned long>(sql.length()));
|
||||
rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast<unsigned long>(sql.length()));
|
||||
assertTrue (rc == 0);
|
||||
|
||||
rc = mysql_stmt_execute(hstmt);
|
||||
assertTrue (rc == 0);
|
||||
|
||||
sql = "INSERT INTO Test VALUES (?,?,?,?,?)";
|
||||
rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast<unsigned long>(sql.length()));
|
||||
rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast<unsigned long>(sql.length()));
|
||||
assertTrue (rc == 0);
|
||||
|
||||
std::string str[3] = { "111", "222", "333" };
|
||||
@@ -219,7 +219,7 @@ void SQLExecutor::bareboneMySQLTest(const char* host, const char* user, const ch
|
||||
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;
|
||||
@@ -279,15 +279,15 @@ void SQLExecutor::simpleAccess()
|
||||
std::string result;
|
||||
|
||||
count = 0;
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
Statement stmt(*_pSession);
|
||||
stmt << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(age);//, now;
|
||||
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); }
|
||||
@@ -545,11 +545,34 @@ void SQLExecutor::doubles()
|
||||
}
|
||||
|
||||
|
||||
void SQLExecutor::uuids()
|
||||
{
|
||||
std::string funct = "uuids()";
|
||||
Poco::UUID data("da8b9c4d-faa0-44e1-b834-ece1e7d31cd5");
|
||||
Poco::UUID ret;
|
||||
|
||||
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); }
|
||||
assertTrue (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); }
|
||||
assertTrue (ret == data);
|
||||
}
|
||||
|
||||
|
||||
void SQLExecutor::insertSingleBulkVec()
|
||||
{
|
||||
std::string funct = "insertSingleBulkVec()";
|
||||
std::vector<int> data;
|
||||
|
||||
|
||||
for (int x = 0; x < 100; ++x)
|
||||
data.push_back(x);
|
||||
|
||||
@@ -938,7 +961,7 @@ void SQLExecutor::multiMapComplex()
|
||||
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); }
|
||||
@@ -1000,7 +1023,7 @@ void SQLExecutor::selectIntoSingleStep()
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
|
||||
assertTrue (count == 2);
|
||||
Person result;
|
||||
Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1));
|
||||
Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1));
|
||||
stmt.execute();
|
||||
assertTrue (result == p1);
|
||||
assertTrue (!stmt.done());
|
||||
@@ -1264,7 +1287,7 @@ void SQLExecutor::dateTime()
|
||||
std::string firstName("Simpson");
|
||||
std::string address("Springfield");
|
||||
DateTime birthday(1980, 4, 1, 5, 45, 12, 354, 879);
|
||||
|
||||
|
||||
int count = 0;
|
||||
try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(birthday), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
|
||||
@@ -1273,14 +1296,14 @@ void SQLExecutor::dateTime()
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
|
||||
assertTrue (count == 1);
|
||||
|
||||
|
||||
DateTime bd;
|
||||
assertTrue (bd != birthday);
|
||||
try { *_pSession << "SELECT Birthday FROM Person", into(bd), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
|
||||
assertTrue (bd == birthday);
|
||||
|
||||
|
||||
std::cout << std::endl << RecordSet(*_pSession, "SELECT * FROM Person");
|
||||
}
|
||||
|
||||
@@ -1292,7 +1315,7 @@ void SQLExecutor::date()
|
||||
std::string firstName("Simpson");
|
||||
std::string address("Springfield");
|
||||
Date birthday(1980, 4, 1);
|
||||
|
||||
|
||||
int count = 0;
|
||||
try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(birthday), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
|
||||
@@ -1301,14 +1324,14 @@ void SQLExecutor::date()
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
|
||||
assertTrue (count == 1);
|
||||
|
||||
|
||||
Date bd;
|
||||
assertTrue (bd != birthday);
|
||||
try { *_pSession << "SELECT Birthday FROM Person", into(bd), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
|
||||
assertTrue (bd == birthday);
|
||||
|
||||
|
||||
std::cout << std::endl << RecordSet(*_pSession, "SELECT * FROM Person");
|
||||
}
|
||||
|
||||
@@ -1320,7 +1343,7 @@ void SQLExecutor::time()
|
||||
std::string firstName("Simpson");
|
||||
std::string address("Springfield");
|
||||
Time birthday(1, 2, 3);
|
||||
|
||||
|
||||
int count = 0;
|
||||
try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(birthday), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
|
||||
@@ -1329,14 +1352,14 @@ void SQLExecutor::time()
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
|
||||
assertTrue (count == 1);
|
||||
|
||||
|
||||
Time bd;
|
||||
assertTrue (bd != birthday);
|
||||
try { *_pSession << "SELECT Birthday FROM Person", into(bd), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
|
||||
assertTrue (bd == birthday);
|
||||
|
||||
|
||||
std::cout << std::endl << RecordSet(*_pSession, "SELECT * FROM Person");
|
||||
}
|
||||
|
||||
@@ -1436,7 +1459,7 @@ void SQLExecutor::tupleVector()
|
||||
typedef Tuple<int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int> 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<int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int>
|
||||
Tuple<int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int>
|
||||
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<TupleType> v;
|
||||
@@ -1475,8 +1498,8 @@ void SQLExecutor::internalExtraction()
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
Statement stmt = (*_pSession << "SELECT * FROM Vectors", now);
|
||||
RecordSet rset(stmt);
|
||||
|
||||
@@ -1523,7 +1546,7 @@ void SQLExecutor::internalExtraction()
|
||||
assertTrue ("5" == s);
|
||||
i = rset.value("str0", 2);
|
||||
assertTrue (5 == i);
|
||||
|
||||
|
||||
const Column<int>& col = rset.column<int>(0);
|
||||
Column<int>::Iterator it = col.begin();
|
||||
Column<int>::Iterator end = col.end();
|
||||
@@ -1563,7 +1586,7 @@ void SQLExecutor::internalExtraction()
|
||||
|
||||
try { rset.value<std::string>(0,0); fail ("must fail"); }
|
||||
catch (BadCastException&) { }
|
||||
|
||||
|
||||
stmt = (*_pSession << "DELETE FROM Vectors", now);
|
||||
rset = stmt;
|
||||
|
||||
@@ -1579,10 +1602,10 @@ void SQLExecutor::internalExtraction()
|
||||
void SQLExecutor::doNull()
|
||||
{
|
||||
std::string funct = "null()";
|
||||
|
||||
*_pSession << "INSERT INTO Vectors VALUES (?, ?, ?)",
|
||||
use(Poco::Data::Keywords::null),
|
||||
use(Poco::Data::Keywords::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;
|
||||
@@ -1615,19 +1638,19 @@ void SQLExecutor::doNull()
|
||||
|
||||
|
||||
void SQLExecutor::setTransactionIsolation(Session& session, Poco::UInt32 ti)
|
||||
{
|
||||
{
|
||||
if (session.hasTransactionIsolation(ti))
|
||||
{
|
||||
std::string funct = "setTransactionIsolation()";
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
Transaction t(session, false);
|
||||
t.setIsolation(ti);
|
||||
|
||||
|
||||
assertTrue (ti == t.getIsolation());
|
||||
assertTrue (t.isIsolation(ti));
|
||||
|
||||
|
||||
assertTrue (ti == session.getTransactionIsolation());
|
||||
assertTrue (session.isTransactionIsolation(ti));
|
||||
}
|
||||
@@ -1789,11 +1812,11 @@ void SQLExecutor::transaction(const std::string& connect)
|
||||
Transaction trans((*_pSession));
|
||||
assertTrue (trans.isActive());
|
||||
assertTrue (_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); }
|
||||
|
||||
|
||||
assertTrue (_pSession->isTransaction());
|
||||
assertTrue (trans.isActive());
|
||||
|
||||
@@ -1885,7 +1908,7 @@ void SQLExecutor::transaction(const std::string& connect)
|
||||
assertTrue (0 == count);
|
||||
|
||||
trans.execute(sql);
|
||||
|
||||
|
||||
local << "SELECT COUNT(*) FROM Person", into(locCount), now;
|
||||
assertTrue (2 == locCount);
|
||||
|
||||
@@ -1921,9 +1944,9 @@ void SQLExecutor::reconnect()
|
||||
assertTrue (_pSession->isConnected());
|
||||
_pSession->close();
|
||||
assertTrue (!_pSession->isConnected());
|
||||
try
|
||||
try
|
||||
{
|
||||
(*_pSession) << "SELECT LastName FROM Person", into(result), now;
|
||||
(*_pSession) << "SELECT LastName FROM Person", into(result), now;
|
||||
fail ("must fail");
|
||||
}
|
||||
catch(NotConnectedException&){ }
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
PB_IMMEDIATE,
|
||||
PB_AT_EXEC
|
||||
};
|
||||
|
||||
|
||||
enum DataExtraction
|
||||
{
|
||||
DE_MANUAL,
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
~SQLExecutor();
|
||||
|
||||
void bareboneMySQLTest(const char* host, const char* user, const char* pwd, const char* db, int port, const char* tableCreateString);
|
||||
/// This function uses "bare bone" MySQL API calls (i.e. calls are not
|
||||
/// This function uses "bare bone" MySQL API calls (i.e. calls are not
|
||||
/// "wrapped" in PocoData framework structures).
|
||||
/// The purpose of the function is to verify that driver behaves
|
||||
/// correctly. If this test passes, subsequent tests failures are likely ours.
|
||||
@@ -86,6 +86,7 @@ public:
|
||||
void unsignedInts();
|
||||
void floats();
|
||||
void doubles();
|
||||
void uuids();
|
||||
void tuples();
|
||||
void tupleVector();
|
||||
|
||||
|
||||
3
vendor/POCO/Data/ODBC/ODBC.make
vendored
3
vendor/POCO/Data/ODBC/ODBC.make
vendored
@@ -56,9 +56,6 @@ else ifeq (0, $(shell test -e $(POCO_ODBC_LIB)/libiodbc$(LIBLINKEXT); echo $$?))
|
||||
SYSLIBS += -liodbc -liodbcinst
|
||||
COMMONFLAGS += -DPOCO_IODBC -I/usr/include/iodbc
|
||||
|
||||
# TODO: OSX >= 10.8 deprecated non-Unicode ODBC API functions, silence warnings until iODBC Unicode support
|
||||
COMMONFLAGS += -Wno-deprecated-declarations
|
||||
|
||||
else
|
||||
$(error No ODBC library found. Please install unixODBC or iODBC or specify POCO_ODBC_LIB and try again)
|
||||
endif
|
||||
|
||||
@@ -322,6 +322,9 @@ public:
|
||||
void bind(std::size_t pos, const std::list<DateTime>& val, Direction dir);
|
||||
/// Binds a DateTime list.
|
||||
|
||||
void bind(std::size_t pos, const UUID& val, Direction dir);
|
||||
/// Binds a UUID.
|
||||
|
||||
void bind(std::size_t pos, const NullData& val, Direction dir);
|
||||
/// Binds a null. In-bound only.
|
||||
|
||||
@@ -367,6 +370,7 @@ private:
|
||||
typedef std::vector<AnyVec> AnyVecVec;
|
||||
typedef std::map<char*, std::string*> StringMap;
|
||||
typedef std::map<UTF16String::value_type*, UTF16String*> UTF16StringMap;
|
||||
typedef std::map<char*, UUID*> UUIDMap;
|
||||
typedef std::map<SQL_DATE_STRUCT*, Date*> DateMap;
|
||||
typedef std::map<SQL_TIME_STRUCT*, Time*> TimeMap;
|
||||
typedef std::map<SQL_TIMESTAMP_STRUCT*, DateTime*> TimestampMap;
|
||||
@@ -998,6 +1002,7 @@ private:
|
||||
TimestampMap _timestamps;
|
||||
StringMap _strings;
|
||||
UTF16StringMap _utf16Strings;
|
||||
UUIDMap _uuids;
|
||||
|
||||
DateVecVec _dateVecVec;
|
||||
TimeVecVec _timeVecVec;
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
#define Data_ODBC_Extractor_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Data/Constants.h"
|
||||
#include "Poco/Data/ODBC/ODBC.h"
|
||||
#include "Poco/Data/AbstractExtractor.h"
|
||||
#include "Poco/Data/ODBC/Preparator.h"
|
||||
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
|
||||
#include "Poco/Data/ODBC/Error.h"
|
||||
#include "Poco/Data/ODBC/Utility.h"
|
||||
#include "Poco/Data/AbstractExtractor.h"
|
||||
#include "Poco/Data/Constants.h"
|
||||
#include "Poco/Data/Date.h"
|
||||
#include "Poco/Data/Time.h"
|
||||
#include "Poco/DateTime.h"
|
||||
@@ -32,6 +32,8 @@
|
||||
#include "Poco/Dynamic/Var.h"
|
||||
#include "Poco/Nullable.h"
|
||||
#include "Poco/UTFString.h"
|
||||
#include "Poco/TextEncoding.h"
|
||||
#include "Poco/TextConverter.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <map>
|
||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||
@@ -52,8 +54,9 @@ class ODBC_API Extractor: public Poco::Data::AbstractExtractor
|
||||
public:
|
||||
typedef Preparator::Ptr PreparatorPtr;
|
||||
|
||||
Extractor(const StatementHandle& rStmt,
|
||||
Preparator::Ptr pPreparator);
|
||||
Extractor(const StatementHandle& rStmt,
|
||||
Preparator::Ptr pPreparator,
|
||||
Poco::TextEncoding::Ptr pDBEncoding = nullptr);
|
||||
/// Creates the Extractor.
|
||||
|
||||
~Extractor();
|
||||
@@ -304,7 +307,10 @@ public:
|
||||
|
||||
bool extract(std::size_t pos, std::list<Poco::DateTime>& val);
|
||||
/// Extracts a DateTime list.
|
||||
|
||||
|
||||
bool extract(std::size_t pos, Poco::UUID& val);
|
||||
/// Extracts a UUID.
|
||||
|
||||
bool extract(std::size_t pos, Poco::Any& val);
|
||||
/// Extracts an Any.
|
||||
|
||||
@@ -339,7 +345,7 @@ public:
|
||||
/// Returns true if the value at [col,row] is null.
|
||||
|
||||
void reset();
|
||||
/// Resets the internally cached length indicators.
|
||||
/// Resets the internally cached length indicators.
|
||||
|
||||
private:
|
||||
static const int CHUNK_SIZE = 1024;
|
||||
@@ -365,7 +371,7 @@ private:
|
||||
{
|
||||
if (isNull(pos)) return false;
|
||||
poco_assert_dbg (typeid(T) == _pPreparator->at(pos).type());
|
||||
val = *AnyCast<T>(&_pPreparator->at(pos));
|
||||
val = *AnyCast<T>(&_pPreparator->at(pos));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -384,7 +390,7 @@ private:
|
||||
|
||||
bool extractBoundImplContainer(std::size_t pos, std::vector<std::string>& values);
|
||||
bool extractBoundImplContainer(std::size_t pos, std::deque<std::string>& values);
|
||||
bool extractBoundImplContainer(std::size_t pos, std::list<std::string>& values);
|
||||
bool extractBoundImplContainer(std::size_t pos, std::list<std::string>& values);
|
||||
bool extractBoundImplContainer(std::size_t pos, std::vector<Poco::UTF16String>& values);
|
||||
bool extractBoundImplContainer(std::size_t pos, std::deque<Poco::UTF16String>& values);
|
||||
bool extractBoundImplContainer(std::size_t pos, std::list<Poco::UTF16String>& values);
|
||||
@@ -462,12 +468,12 @@ private:
|
||||
bool extractManualImpl(std::size_t pos, T& val, SQLSMALLINT cType)
|
||||
{
|
||||
SQLRETURN rc = 0;
|
||||
T value = (T) 0;
|
||||
T value{};
|
||||
|
||||
resizeLengths(pos);
|
||||
|
||||
rc = SQLGetData(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
rc = SQLGetData(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
cType, //C data type
|
||||
&value, //returned value
|
||||
0, //buffer length (ignored)
|
||||
@@ -475,10 +481,10 @@ private:
|
||||
|
||||
if (Utility::isError(rc))
|
||||
throw StatementException(_rStmt, "SQLGetData()");
|
||||
|
||||
if (isNullLengthIndicator(_lengths[pos]))
|
||||
|
||||
if (isNullLengthIndicator(_lengths[pos]))
|
||||
return false;
|
||||
else
|
||||
else
|
||||
{
|
||||
//for fixed-length data, buffer must be large enough
|
||||
//otherwise, driver may write past the end
|
||||
@@ -567,16 +573,53 @@ private:
|
||||
case MetaColumn::FDT_TIMESTAMP:
|
||||
{ return extAny<T, Poco::DateTime>(pos, val); }
|
||||
|
||||
default:
|
||||
case MetaColumn::FDT_UUID:
|
||||
{ return extAny<T, Poco::UUID>(pos, val); }
|
||||
|
||||
default:
|
||||
throw DataFormatException("Unsupported data type.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
bool stringContainerExtractConvert(std::size_t pos, C& val)
|
||||
{
|
||||
bool ret = false;
|
||||
C res;
|
||||
ret = extractBoundImplContainer(pos, res);
|
||||
val.clear();
|
||||
if (ret)
|
||||
{
|
||||
Poco::TextConverter conv(*_pDBEncoding, *_pToEncoding);
|
||||
val.resize(res.size());
|
||||
typename C::iterator vIt = val.begin();
|
||||
typename C::iterator it = res.begin();
|
||||
for (; it != res.end(); ++it, ++vIt) conv.convert(*it, *vIt);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
bool stringContainerExtract(std::size_t pos, C& val)
|
||||
{
|
||||
bool ret = false;
|
||||
if (Preparator::DE_BOUND == _dataExtraction)
|
||||
{
|
||||
if (!_transcode)
|
||||
ret = extractBoundImplContainer(pos, val);
|
||||
else
|
||||
ret = stringContainerExtractConvert(pos, val);
|
||||
}
|
||||
else
|
||||
throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool isNullLengthIndicator(SQLLEN val) const;
|
||||
/// The reason for this utility wrapper are platforms where
|
||||
/// SQLLEN macro (a.k.a. SQLINTEGER) yields 64-bit value,
|
||||
/// The reason for this utility wrapper are platforms where
|
||||
/// SQLLEN macro (a.k.a. SQLINTEGER) yields 64-bit value,
|
||||
/// while SQL_NULL_DATA (#define'd as -1 literal) remains 32-bit.
|
||||
|
||||
SQLINTEGER columnSize(std::size_t pos) const;
|
||||
@@ -585,6 +628,9 @@ private:
|
||||
PreparatorPtr _pPreparator;
|
||||
Preparator::DataExtraction _dataExtraction;
|
||||
std::vector<SQLLEN> _lengths;
|
||||
Poco::TextEncoding::Ptr _pDBEncoding;
|
||||
bool _transcode;
|
||||
Poco::TextEncoding::Ptr _pToEncoding;
|
||||
};
|
||||
|
||||
|
||||
@@ -640,42 +686,42 @@ inline bool Extractor::extractBoundImplContainer(std::size_t pos, std::list<Poco
|
||||
}
|
||||
|
||||
|
||||
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
|
||||
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
|
||||
std::vector<Poco::Data::CLOB>& values)
|
||||
{
|
||||
return extractBoundImplContainerLOB(pos, values);
|
||||
}
|
||||
|
||||
|
||||
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
|
||||
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
|
||||
std::deque<Poco::Data::CLOB>& values)
|
||||
{
|
||||
return extractBoundImplContainerLOB(pos, values);
|
||||
}
|
||||
|
||||
|
||||
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
|
||||
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
|
||||
std::list<Poco::Data::CLOB>& values)
|
||||
{
|
||||
return extractBoundImplContainerLOB(pos, values);
|
||||
}
|
||||
|
||||
|
||||
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
|
||||
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
|
||||
std::vector<Poco::Data::BLOB>& values)
|
||||
{
|
||||
return extractBoundImplContainerLOB(pos, values);
|
||||
}
|
||||
|
||||
|
||||
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
|
||||
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
|
||||
std::deque<Poco::Data::BLOB>& values)
|
||||
{
|
||||
return extractBoundImplContainerLOB(pos, values);
|
||||
}
|
||||
|
||||
|
||||
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
|
||||
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
|
||||
std::list<Poco::Data::BLOB>& values)
|
||||
{
|
||||
return extractBoundImplContainerLOB(pos, values);
|
||||
@@ -702,7 +748,7 @@ inline void Extractor::reset()
|
||||
|
||||
inline void Extractor::resizeLengths(std::size_t pos)
|
||||
{
|
||||
if (pos >= _lengths.size())
|
||||
if (pos >= _lengths.size())
|
||||
_lengths.resize(pos + 1, (SQLLEN) 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -136,8 +136,6 @@ private:
|
||||
/// Called whenever SQLExecute returns SQL_NEED_DATA. This is expected
|
||||
/// behavior for PB_AT_EXEC binding mode.
|
||||
|
||||
void getData();
|
||||
|
||||
void addPreparator();
|
||||
void fillColumns();
|
||||
void checkError(SQLRETURN rc, const std::string& msg="");
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
#define Data_ODBC_Preparator_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Data/Constants.h"
|
||||
#include "Poco/Data/ODBC/ODBC.h"
|
||||
#include "Poco/Data/ODBC/Handle.h"
|
||||
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
|
||||
#include "Poco/Data/ODBC/Utility.h"
|
||||
#include "Poco/Data/AbstractPreparator.h"
|
||||
#include "Poco/Data/Constants.h"
|
||||
#include "Poco/Data/LOB.h"
|
||||
#include "Poco/Any.h"
|
||||
#include "Poco/DynamicAny.h"
|
||||
@@ -49,13 +49,13 @@ namespace ODBC {
|
||||
|
||||
|
||||
class ODBC_API Preparator : public AbstractPreparator
|
||||
/// Class used for database preparation where we first have to register all data types
|
||||
/// with respective memory output locations before extracting data.
|
||||
/// Class used for database preparation where we first have to register all data types
|
||||
/// with respective memory output locations before extracting data.
|
||||
/// Extraction works in two-phases: first prepare is called once, then extract n-times.
|
||||
/// In ODBC, SQLBindCol/SQLFetch is the preferred method of data retrieval (SQLGetData is available,
|
||||
/// however with numerous driver implementation dependent limitations and inferior performance).
|
||||
/// In order to fit this functionality into Poco DataConnectors framework, every ODBC SQL statement
|
||||
/// instantiates its own Preparator object.
|
||||
/// In ODBC, SQLBindCol/SQLFetch is the preferred method of data retrieval (SQLGetData is available,
|
||||
/// however with numerous driver implementation dependent limitations and inferior performance).
|
||||
/// In order to fit this functionality into Poco DataConnectors framework, every ODBC SQL statement
|
||||
/// instantiates its own Preparator object.
|
||||
/// This is done once per statement execution (from StatementImpl::bindImpl()).
|
||||
///
|
||||
/// Preparator object is used to :
|
||||
@@ -69,7 +69,7 @@ class ODBC_API Preparator : public AbstractPreparator
|
||||
/// - Value datatypes in this interface prepare() calls serve only for the purpose of type distinction.
|
||||
/// - Preparator keeps its own std::vector<Any> buffer for fetched data to be later retrieved by Extractor.
|
||||
/// - prepare() methods should not be called when extraction mode is DE_MANUAL
|
||||
///
|
||||
///
|
||||
{
|
||||
public:
|
||||
typedef std::vector<char*> CharArray;
|
||||
@@ -96,8 +96,8 @@ public:
|
||||
DT_DATETIME
|
||||
};
|
||||
|
||||
Preparator(const StatementHandle& rStmt,
|
||||
const std::string& statement,
|
||||
Preparator(const StatementHandle& rStmt,
|
||||
const std::string& statement,
|
||||
std::size_t maxFieldSize,
|
||||
DataExtraction dataExtraction = DE_BOUND);
|
||||
/// Creates the Preparator.
|
||||
@@ -353,6 +353,9 @@ public:
|
||||
void prepare(std::size_t pos, const std::list<Poco::DateTime>& val);
|
||||
/// Prepares a DateTime list.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::UUID& val);
|
||||
/// Prepares a UUID.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::Any& val);
|
||||
/// Prepares an Any.
|
||||
|
||||
@@ -395,12 +398,12 @@ public:
|
||||
|
||||
std::size_t maxDataSize(std::size_t pos) const;
|
||||
/// Returns max supported size for column at position pos.
|
||||
/// Returned length for variable length fields is the one
|
||||
/// Returned length for variable length fields is the one
|
||||
/// supported by this implementation, not the underlying DB.
|
||||
|
||||
std::size_t actualDataSize(std::size_t col, std::size_t row = POCO_DATA_INVALID_ROW) const;
|
||||
/// Returns the returned length for the column and row specified.
|
||||
/// This is usually equal to the column size, except for
|
||||
/// Returns the returned length for the column and row specified.
|
||||
/// This is usually equal to the column size, except for
|
||||
/// variable length fields (BLOB and variable length strings).
|
||||
/// For null values, the return value is -1 (SQL_NO_DATA)
|
||||
|
||||
@@ -435,7 +438,7 @@ private:
|
||||
if (pVal)
|
||||
return prepareFixedSize<Poco::Int8>(pos, SQL_C_STINYINT, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<Poco::Int8>(pos, SQL_C_STINYINT);
|
||||
return prepareFixedSize<Poco::Int8>(pos, SQL_C_STINYINT);
|
||||
|
||||
case MetaColumn::FDT_UINT8:
|
||||
if (pVal)
|
||||
@@ -548,7 +551,13 @@ private:
|
||||
else
|
||||
return prepareFixedSize<DateTime>(pos, SQL_C_TYPE_TIMESTAMP);
|
||||
|
||||
default:
|
||||
case MetaColumn::FDT_UUID:
|
||||
if (pVal)
|
||||
return prepareFixedSize<DateTime>(pos, SQL_C_BINARY, 16);
|
||||
else
|
||||
return prepareFixedSize<DateTime>(pos, SQL_C_BINARY);
|
||||
|
||||
default:
|
||||
throw DataFormatException("Unsupported data type.");
|
||||
}
|
||||
}
|
||||
@@ -567,11 +576,11 @@ private:
|
||||
_values[pos] = Poco::Any(T());
|
||||
|
||||
T* pVal = AnyCast<T>(&_values[pos]);
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) pVal,
|
||||
(SQLINTEGER) dataSize,
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) pVal,
|
||||
(SQLINTEGER) dataSize,
|
||||
&_lengths[pos])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindCol()");
|
||||
@@ -596,11 +605,11 @@ private:
|
||||
std::vector<T>& cache = RefAnyCast<std::vector<T> >(_values[pos]);
|
||||
cache.resize(length);
|
||||
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) &cache[0],
|
||||
(SQLINTEGER) dataSize,
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) &cache[0],
|
||||
(SQLINTEGER) dataSize,
|
||||
&_lenLengths[pos][0])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindCol()");
|
||||
@@ -614,18 +623,18 @@ private:
|
||||
poco_assert (DE_BOUND == _dataExtraction);
|
||||
poco_assert (pos < _values.size());
|
||||
|
||||
T* pCache = new T[size];
|
||||
T* pCache = new T[size];
|
||||
std::memset(pCache, 0, size);
|
||||
|
||||
_values[pos] = Any(pCache);
|
||||
_lengths[pos] = (SQLLEN) size;
|
||||
_varLengthArrays.insert(IndexMap::value_type(pos, dt));
|
||||
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) pCache,
|
||||
(SQLINTEGER) size*sizeof(T),
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) pCache,
|
||||
(SQLINTEGER) size*sizeof(T),
|
||||
&_lengths[pos])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindCol()");
|
||||
@@ -648,11 +657,11 @@ private:
|
||||
_lenLengths[pos].resize(length);
|
||||
_varLengthArrays.insert(IndexMap::value_type(pos, DT));
|
||||
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) pArray,
|
||||
(SQLINTEGER) size,
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) pArray,
|
||||
(SQLINTEGER) size,
|
||||
&_lenLengths[pos][0])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindCol()");
|
||||
@@ -1173,6 +1182,12 @@ inline void Preparator::prepare(std::size_t pos, const std::list<Poco::DateTime>
|
||||
}
|
||||
|
||||
|
||||
inline void Preparator::prepare(std::size_t pos, const Poco::UUID&)
|
||||
{
|
||||
prepareCharArray<char, DT_CHAR_ARRAY>(pos, SQL_C_BINARY, 16, 16);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparator::prepare(std::size_t pos, const Poco::Any& val)
|
||||
{
|
||||
prepareImpl<std::vector<Poco::Any> >(pos);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "Poco/Data/ODBC/Handle.h"
|
||||
#include "Poco/Data/ODBC/ODBCException.h"
|
||||
#include "Poco/Data/AbstractSessionImpl.h"
|
||||
#include "Poco/TextEncoding.h"
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include "Poco/Mutex.h"
|
||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||
@@ -162,6 +163,16 @@ public:
|
||||
/// Returns the timeout (in seconds) for queries,
|
||||
/// or -1 if no timeout has been set.
|
||||
|
||||
void setDBEncoding(const std::string&, const Poco::Any& value);
|
||||
/// Sets the database encoding.
|
||||
/// Value must be of type std::string.
|
||||
|
||||
Poco::Any getDBEncoding(const std::string&) const;
|
||||
/// Returns the database encoding.
|
||||
|
||||
const std::string& dbEncoding() const;
|
||||
/// Returns the database encoding.
|
||||
|
||||
const ConnectionHandle& dbc() const;
|
||||
/// Returns the connection handle.
|
||||
|
||||
@@ -193,6 +204,7 @@ private:
|
||||
mutable char _canTransact;
|
||||
bool _inTransaction;
|
||||
int _queryTimeout;
|
||||
std::string _dbEncoding;
|
||||
Poco::FastMutex _mutex;
|
||||
};
|
||||
|
||||
@@ -291,6 +303,18 @@ inline int SessionImpl::queryTimeout() const
|
||||
}
|
||||
|
||||
|
||||
inline Poco::Any SessionImpl::getDBEncoding(const std::string&) const
|
||||
{
|
||||
return _dbEncoding;
|
||||
}
|
||||
|
||||
|
||||
inline const std::string& SessionImpl::dbEncoding() const
|
||||
{
|
||||
return _dbEncoding;
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::ODBC
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,14 @@ inline void makeUTF8(Poco::Buffer<wchar_t>& buffer, SQLINTEGER length, SQLPOINTE
|
||||
UnicodeConverter::toUTF8(buffer.begin(), length, result);
|
||||
|
||||
std::memset(pTarget, 0, targetLength);
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4996) // deprecation warnings
|
||||
#endif
|
||||
std::strncpy((char*) pTarget, result.c_str(), result.size() < targetLength ? result.size() : targetLength);
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
149
vendor/POCO/Data/ODBC/src/Binder.cpp
vendored
149
vendor/POCO/Data/ODBC/src/Binder.cpp
vendored
@@ -80,6 +80,10 @@ void Binder::freeMemory()
|
||||
UTF16CharPtrVec::iterator endUTF16Chr = _utf16CharPtrs.end();
|
||||
for (; itUTF16Chr != endUTF16Chr; ++itUTF16Chr) std::free(*itUTF16Chr);
|
||||
|
||||
UUIDMap::iterator itUUID = _uuids.begin();
|
||||
UUIDMap::iterator itUUIDEnd = _uuids.end();
|
||||
for(; itUUID != itUUIDEnd; ++itUUID) std::free(itUUID->first);
|
||||
|
||||
BoolPtrVec::iterator itBool = _boolPtrs.begin();
|
||||
BoolPtrVec::iterator endBool = _boolPtrs.end();
|
||||
for (; itBool != endBool; ++itBool) delete [] *itBool;
|
||||
@@ -129,15 +133,15 @@ void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
|
||||
|
||||
_lengthIndicator.push_back(pLenIn);
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
SQL_C_CHAR,
|
||||
Connector::stringBoundToLongVarChar() ? SQL_LONGVARCHAR : SQL_VARCHAR,
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
SQL_C_CHAR,
|
||||
Connector::stringBoundToLongVarChar() ? SQL_LONGVARCHAR : SQL_VARCHAR,
|
||||
(SQLUINTEGER) colSize,
|
||||
0,
|
||||
pVal,
|
||||
(SQLINTEGER) size,
|
||||
pVal,
|
||||
(SQLINTEGER) size,
|
||||
_lengthIndicator.back())))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter(std::string)");
|
||||
@@ -206,22 +210,22 @@ void Binder::bind(std::size_t pos, const Date& val, Direction dir)
|
||||
|
||||
SQL_DATE_STRUCT* pDS = new SQL_DATE_STRUCT;
|
||||
Utility::dateSync(*pDS, val);
|
||||
|
||||
|
||||
_dates.insert(DateMap::value_type(pDS, const_cast<Date*>(&val)));
|
||||
|
||||
SQLINTEGER colSize = 0;
|
||||
SQLSMALLINT decDigits = 0;
|
||||
getColSizeAndPrecision(pos, SQL_TYPE_DATE, colSize, decDigits);
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
SQL_C_TYPE_DATE,
|
||||
SQL_TYPE_DATE,
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
SQL_C_TYPE_DATE,
|
||||
SQL_TYPE_DATE,
|
||||
colSize,
|
||||
decDigits,
|
||||
(SQLPOINTER) pDS,
|
||||
0,
|
||||
(SQLPOINTER) pDS,
|
||||
0,
|
||||
_lengthIndicator.back())))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter(Date)");
|
||||
@@ -239,22 +243,22 @@ void Binder::bind(std::size_t pos, const Time& val, Direction dir)
|
||||
|
||||
SQL_TIME_STRUCT* pTS = new SQL_TIME_STRUCT;
|
||||
Utility::timeSync(*pTS, val);
|
||||
|
||||
|
||||
_times.insert(TimeMap::value_type(pTS, const_cast<Time*>(&val)));
|
||||
|
||||
SQLINTEGER colSize = 0;
|
||||
SQLSMALLINT decDigits = 0;
|
||||
getColSizeAndPrecision(pos, SQL_TYPE_TIME, colSize, decDigits);
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
SQL_C_TYPE_TIME,
|
||||
SQL_TYPE_TIME,
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
SQL_C_TYPE_TIME,
|
||||
SQL_TYPE_TIME,
|
||||
colSize,
|
||||
decDigits,
|
||||
(SQLPOINTER) pTS,
|
||||
0,
|
||||
(SQLPOINTER) pTS,
|
||||
0,
|
||||
_lengthIndicator.back())))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter(Time)");
|
||||
@@ -279,15 +283,15 @@ void Binder::bind(std::size_t pos, const Poco::DateTime& val, Direction dir)
|
||||
SQLSMALLINT decDigits = 0;
|
||||
getColSizeAndPrecision(pos, SQL_TYPE_TIMESTAMP, colSize, decDigits);
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
SQL_C_TYPE_TIMESTAMP,
|
||||
SQL_TYPE_TIMESTAMP,
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
SQL_C_TYPE_TIMESTAMP,
|
||||
SQL_TYPE_TIMESTAMP,
|
||||
colSize,
|
||||
decDigits,
|
||||
(SQLPOINTER) pTS,
|
||||
0,
|
||||
(SQLPOINTER) pTS,
|
||||
0,
|
||||
_lengthIndicator.back())))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter(DateTime)");
|
||||
@@ -295,6 +299,38 @@ void Binder::bind(std::size_t pos, const Poco::DateTime& val, Direction dir)
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const UUID& val, Direction dir)
|
||||
{
|
||||
SQLINTEGER size = (SQLINTEGER) 16;
|
||||
SQLLEN* pLenIn = new SQLLEN;
|
||||
*pLenIn = size;
|
||||
|
||||
_lengthIndicator.push_back(pLenIn);
|
||||
|
||||
char* pUUID = new char[16];
|
||||
val.copyTo(pUUID);
|
||||
|
||||
_uuids.insert(UUIDMap::value_type(pUUID, const_cast<UUID*>(&val)));
|
||||
|
||||
SQLINTEGER colSize = 0;
|
||||
SQLSMALLINT decDigits = 0;
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
SQL_C_BINARY,
|
||||
SQL_GUID,
|
||||
colSize,
|
||||
decDigits,
|
||||
(SQLPOINTER) pUUID,
|
||||
0,
|
||||
_lengthIndicator.back())))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter(UUID)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
|
||||
{
|
||||
if (isOutBound(dir) || !isInBound(dir))
|
||||
@@ -311,15 +347,15 @@ void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
|
||||
SQLSMALLINT decDigits = 0;
|
||||
getColSizeAndPrecision(pos, SQL_C_STINYINT, colSize, decDigits);
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
SQL_PARAM_INPUT,
|
||||
SQL_C_STINYINT,
|
||||
Utility::sqlDataType(SQL_C_STINYINT),
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
SQL_PARAM_INPUT,
|
||||
SQL_C_STINYINT,
|
||||
Utility::sqlDataType(SQL_C_STINYINT),
|
||||
colSize,
|
||||
decDigits,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
_lengthIndicator.back())))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter()");
|
||||
@@ -334,7 +370,7 @@ std::size_t Binder::parameterSize(SQLPOINTER pAddr) const
|
||||
|
||||
it = _outParams.find(pAddr);
|
||||
if (it != _outParams.end()) return it->second;
|
||||
|
||||
|
||||
throw NotFoundException("Requested data size not found.");
|
||||
}
|
||||
|
||||
@@ -350,7 +386,7 @@ SQLSMALLINT Binder::toODBCDirection(Direction dir) const
|
||||
bool in = isInBound(dir);
|
||||
bool out = isOutBound(dir);
|
||||
SQLSMALLINT ioType = SQL_PARAM_TYPE_UNKNOWN;
|
||||
if (in && out) ioType = SQL_PARAM_INPUT_OUTPUT;
|
||||
if (in && out) ioType = SQL_PARAM_INPUT_OUTPUT;
|
||||
else if(in) ioType = SQL_PARAM_INPUT;
|
||||
else if(out) ioType = SQL_PARAM_OUTPUT;
|
||||
else throw Poco::IllegalStateException("Binder not bound (must be [in] OR [out]).");
|
||||
@@ -365,7 +401,7 @@ void Binder::synchronize()
|
||||
{
|
||||
DateMap::iterator it = _dates.begin();
|
||||
DateMap::iterator end = _dates.end();
|
||||
for(; it != end; ++it)
|
||||
for(; it != end; ++it)
|
||||
Utility::dateSync(*it->second, *it->first);
|
||||
}
|
||||
|
||||
@@ -373,7 +409,7 @@ void Binder::synchronize()
|
||||
{
|
||||
TimeMap::iterator it = _times.begin();
|
||||
TimeMap::iterator end = _times.end();
|
||||
for(; it != end; ++it)
|
||||
for(; it != end; ++it)
|
||||
Utility::timeSync(*it->second, *it->first);
|
||||
}
|
||||
|
||||
@@ -381,7 +417,7 @@ void Binder::synchronize()
|
||||
{
|
||||
TimestampMap::iterator it = _timestamps.begin();
|
||||
TimestampMap::iterator end = _timestamps.end();
|
||||
for(; it != end; ++it)
|
||||
for(; it != end; ++it)
|
||||
Utility::dateTimeSync(*it->second, *it->first);
|
||||
}
|
||||
|
||||
@@ -392,6 +428,14 @@ void Binder::synchronize()
|
||||
for(; it != end; ++it)
|
||||
it->second->assign(it->first, std::strlen(it->first));
|
||||
}
|
||||
|
||||
if (_uuids.size())
|
||||
{
|
||||
UUIDMap::iterator it = _uuids.begin();
|
||||
UUIDMap::iterator end = _uuids.end();
|
||||
for(; it != end; ++it)
|
||||
it->second->copyFrom(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -405,6 +449,7 @@ void Binder::reset()
|
||||
_times.clear();
|
||||
_timestamps.clear();
|
||||
_strings.clear();
|
||||
_uuids.clear();
|
||||
_dateVecVec.clear();
|
||||
_timeVecVec.clear();
|
||||
_dateTimeVecVec.clear();
|
||||
@@ -415,9 +460,9 @@ void Binder::reset()
|
||||
}
|
||||
|
||||
|
||||
void Binder::getColSizeAndPrecision(std::size_t pos,
|
||||
SQLSMALLINT cDataType,
|
||||
SQLINTEGER& colSize,
|
||||
void Binder::getColSizeAndPrecision(std::size_t pos,
|
||||
SQLSMALLINT cDataType,
|
||||
SQLINTEGER& colSize,
|
||||
SQLSMALLINT& decDigits,
|
||||
std::size_t actualSize)
|
||||
{
|
||||
@@ -448,9 +493,9 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
|
||||
colSize = (SQLINTEGER) p.columnSize();
|
||||
decDigits = (SQLSMALLINT) p.decimalDigits();
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (StatementException&)
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
@@ -459,9 +504,9 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
|
||||
colSize = (SQLINTEGER) c.length();
|
||||
decDigits = (SQLSMALLINT) c.precision();
|
||||
return;
|
||||
}
|
||||
catch (StatementException&)
|
||||
{
|
||||
}
|
||||
catch (StatementException&)
|
||||
{
|
||||
}
|
||||
|
||||
// last check, just in case
|
||||
@@ -505,7 +550,7 @@ void Binder::getColumnOrParameterSize(std::size_t pos, SQLINTEGER& size)
|
||||
if (!Utility::isError(SQLGetStmtAttr(_rStmt, SQL_ATTR_IMP_PARAM_DESC, &hIPD, SQL_IS_POINTER, 0)))
|
||||
{
|
||||
SQLUINTEGER sz = 0;
|
||||
if (!Utility::isError(SQLGetDescField(hIPD, (SQLSMALLINT) pos + 1, SQL_DESC_LENGTH, &sz, SQL_IS_UINTEGER, 0)) &&
|
||||
if (!Utility::isError(SQLGetDescField(hIPD, (SQLSMALLINT) pos + 1, SQL_DESC_LENGTH, &sz, SQL_IS_UINTEGER, 0)) &&
|
||||
sz > 0)
|
||||
{
|
||||
size = sz;
|
||||
@@ -529,7 +574,7 @@ void Binder::setParamSetSize(std::size_t length)
|
||||
{
|
||||
if (0 == _paramSetSize)
|
||||
{
|
||||
if (Utility::isError(Poco::Data::ODBC::SQLSetStmtAttr(_rStmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, SQL_IS_UINTEGER)) ||
|
||||
if (Utility::isError(Poco::Data::ODBC::SQLSetStmtAttr(_rStmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, SQL_IS_UINTEGER)) ||
|
||||
Utility::isError(Poco::Data::ODBC::SQLSetStmtAttr(_rStmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER) length, SQL_IS_UINTEGER)))
|
||||
throw StatementException(_rStmt, "SQLSetStmtAttr()");
|
||||
|
||||
|
||||
200
vendor/POCO/Data/ODBC/src/Extractor.cpp
vendored
200
vendor/POCO/Data/ODBC/src/Extractor.cpp
vendored
@@ -12,13 +12,13 @@
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/ODBC/ODBC.h"
|
||||
#include "Poco/Data/ODBC/Extractor.h"
|
||||
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
|
||||
#include "Poco/Data/ODBC/Utility.h"
|
||||
#include "Poco/Data/ODBC/ODBCException.h"
|
||||
#include "Poco/Data/LOB.h"
|
||||
#include "Poco/Buffer.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <typeinfo>
|
||||
|
||||
|
||||
@@ -33,11 +33,15 @@ const std::string Extractor::FLD_SIZE_EXCEEDED_FMT = "Specified data size (%z by
|
||||
"to increase the maximum allowed data size\n";
|
||||
|
||||
|
||||
Extractor::Extractor(const StatementHandle& rStmt,
|
||||
Preparator::Ptr pPreparator):
|
||||
_rStmt(rStmt),
|
||||
Extractor::Extractor(const StatementHandle& rStmt,
|
||||
Preparator::Ptr pPreparator,
|
||||
TextEncoding::Ptr pDBEncoding):
|
||||
_rStmt(rStmt),
|
||||
_pPreparator(pPreparator),
|
||||
_dataExtraction(pPreparator->getDataExtraction())
|
||||
_dataExtraction(pPreparator->getDataExtraction()),
|
||||
_pDBEncoding(pDBEncoding),
|
||||
_transcode(_pDBEncoding && !_pDBEncoding->isA("UTF-8")),
|
||||
_pToEncoding(_transcode ? Poco::TextEncoding::find("UTF-8") : nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -106,7 +110,7 @@ bool Extractor::extractBoundImpl<Poco::Data::Date>(std::size_t pos, Poco::Data::
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImplContainer<std::vector<Poco::Data::Date> >(std::size_t pos,
|
||||
bool Extractor::extractBoundImplContainer<std::vector<Poco::Data::Date> >(std::size_t pos,
|
||||
std::vector<Poco::Data::Date>& val)
|
||||
{
|
||||
std::vector<SQL_DATE_STRUCT>& ds = RefAnyCast<std::vector<SQL_DATE_STRUCT> >(_pPreparator->at(pos));
|
||||
@@ -116,7 +120,7 @@ bool Extractor::extractBoundImplContainer<std::vector<Poco::Data::Date> >(std::s
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImplContainer<std::deque<Poco::Data::Date> >(std::size_t pos,
|
||||
bool Extractor::extractBoundImplContainer<std::deque<Poco::Data::Date> >(std::size_t pos,
|
||||
std::deque<Poco::Data::Date>& val)
|
||||
{
|
||||
std::vector<SQL_DATE_STRUCT>& ds = RefAnyCast<std::vector<SQL_DATE_STRUCT> >(_pPreparator->at(pos));
|
||||
@@ -126,7 +130,7 @@ bool Extractor::extractBoundImplContainer<std::deque<Poco::Data::Date> >(std::si
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImplContainer<std::list<Poco::Data::Date> >(std::size_t pos,
|
||||
bool Extractor::extractBoundImplContainer<std::list<Poco::Data::Date> >(std::size_t pos,
|
||||
std::list<Poco::Data::Date>& val)
|
||||
{
|
||||
std::vector<SQL_DATE_STRUCT>& ds = RefAnyCast<std::vector<SQL_DATE_STRUCT> >(_pPreparator->at(pos));
|
||||
@@ -150,7 +154,7 @@ bool Extractor::extractBoundImpl<Poco::Data::Time>(std::size_t pos, Poco::Data::
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImplContainer<std::vector<Poco::Data::Time> >(std::size_t pos,
|
||||
bool Extractor::extractBoundImplContainer<std::vector<Poco::Data::Time> >(std::size_t pos,
|
||||
std::vector<Poco::Data::Time>& val)
|
||||
{
|
||||
std::vector<SQL_TIME_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIME_STRUCT> >(_pPreparator->at(pos));
|
||||
@@ -160,7 +164,7 @@ bool Extractor::extractBoundImplContainer<std::vector<Poco::Data::Time> >(std::s
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImplContainer<std::deque<Poco::Data::Time> >(std::size_t pos,
|
||||
bool Extractor::extractBoundImplContainer<std::deque<Poco::Data::Time> >(std::size_t pos,
|
||||
std::deque<Poco::Data::Time>& val)
|
||||
{
|
||||
std::vector<SQL_TIME_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIME_STRUCT> >(_pPreparator->at(pos));
|
||||
@@ -170,7 +174,7 @@ bool Extractor::extractBoundImplContainer<std::deque<Poco::Data::Time> >(std::si
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImplContainer<std::list<Poco::Data::Time> >(std::size_t pos,
|
||||
bool Extractor::extractBoundImplContainer<std::list<Poco::Data::Time> >(std::size_t pos,
|
||||
std::list<Poco::Data::Time>& val)
|
||||
{
|
||||
std::vector<SQL_TIME_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIME_STRUCT> >(_pPreparator->at(pos));
|
||||
@@ -194,7 +198,7 @@ bool Extractor::extractBoundImpl<Poco::DateTime>(std::size_t pos, Poco::DateTime
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImplContainer<std::vector<Poco::DateTime> >(std::size_t pos,
|
||||
bool Extractor::extractBoundImplContainer<std::vector<Poco::DateTime> >(std::size_t pos,
|
||||
std::vector<Poco::DateTime>& val)
|
||||
{
|
||||
std::vector<SQL_TIMESTAMP_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIMESTAMP_STRUCT> >(_pPreparator->at(pos));
|
||||
@@ -204,7 +208,7 @@ bool Extractor::extractBoundImplContainer<std::vector<Poco::DateTime> >(std::siz
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImplContainer<std::deque<Poco::DateTime> >(std::size_t pos,
|
||||
bool Extractor::extractBoundImplContainer<std::deque<Poco::DateTime> >(std::size_t pos,
|
||||
std::deque<Poco::DateTime>& val)
|
||||
{
|
||||
std::vector<SQL_TIMESTAMP_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIMESTAMP_STRUCT> >(_pPreparator->at(pos));
|
||||
@@ -214,7 +218,7 @@ bool Extractor::extractBoundImplContainer<std::deque<Poco::DateTime> >(std::size
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImplContainer<std::list<Poco::DateTime> >(std::size_t pos,
|
||||
bool Extractor::extractBoundImplContainer<std::list<Poco::DateTime> >(std::size_t pos,
|
||||
std::list<Poco::DateTime>& val)
|
||||
{
|
||||
std::vector<SQL_TIMESTAMP_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIMESTAMP_STRUCT> >(_pPreparator->at(pos));
|
||||
@@ -224,7 +228,21 @@ bool Extractor::extractBoundImplContainer<std::list<Poco::DateTime> >(std::size_
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImplContainer<std::vector<bool> >(std::size_t pos,
|
||||
bool Extractor::extractBoundImpl<Poco::UUID>(std::size_t pos, Poco::UUID& val)
|
||||
{
|
||||
if (isNull(pos)) return false;
|
||||
|
||||
std::size_t dataSize = _pPreparator->actualDataSize(pos);
|
||||
checkDataSize(dataSize);
|
||||
char* pBuffer = *AnyCast<char*>(&_pPreparator->at(pos));
|
||||
val.copyFrom(pBuffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImplContainer<std::vector<bool> >(std::size_t pos,
|
||||
std::vector<bool>& val)
|
||||
{
|
||||
std::size_t length = _pPreparator->getLength();
|
||||
@@ -235,7 +253,7 @@ bool Extractor::extractBoundImplContainer<std::vector<bool> >(std::size_t pos,
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImplContainer<std::deque<bool> >(std::size_t pos,
|
||||
bool Extractor::extractBoundImplContainer<std::deque<bool> >(std::size_t pos,
|
||||
std::deque<bool>& val)
|
||||
{
|
||||
std::size_t length = _pPreparator->getLength();
|
||||
@@ -246,7 +264,7 @@ bool Extractor::extractBoundImplContainer<std::deque<bool> >(std::size_t pos,
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImplContainer<std::list<bool> >(std::size_t pos,
|
||||
bool Extractor::extractBoundImplContainer<std::list<bool> >(std::size_t pos,
|
||||
std::list<bool>& val)
|
||||
{
|
||||
std::size_t length = _pPreparator->getLength();
|
||||
@@ -262,13 +280,13 @@ bool Extractor::extractManualImpl<std::string>(std::size_t pos, std::string& val
|
||||
std::size_t maxSize = _pPreparator->getMaxFieldSize();
|
||||
std::size_t fetchedSize = 0;
|
||||
std::size_t totalSize = 0;
|
||||
|
||||
|
||||
SQLLEN len;
|
||||
const int bufSize = CHUNK_SIZE;
|
||||
Poco::Buffer<char> apChar(bufSize);
|
||||
char* pChar = apChar.begin();
|
||||
SQLRETURN rc = 0;
|
||||
|
||||
|
||||
val.clear();
|
||||
resizeLengths(pos);
|
||||
|
||||
@@ -276,8 +294,8 @@ bool Extractor::extractManualImpl<std::string>(std::size_t pos, std::string& val
|
||||
{
|
||||
std::memset(pChar, 0, bufSize);
|
||||
len = 0;
|
||||
rc = SQLGetData(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
rc = SQLGetData(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
cType, //C data type
|
||||
pChar, //returned value
|
||||
bufSize, //buffer length
|
||||
@@ -301,9 +319,9 @@ bool Extractor::extractManualImpl<std::string>(std::size_t pos, std::string& val
|
||||
_lengths[pos] += len;
|
||||
fetchedSize = _lengths[pos] > CHUNK_SIZE ? CHUNK_SIZE : _lengths[pos];
|
||||
totalSize += fetchedSize;
|
||||
if (totalSize <= maxSize)
|
||||
if (totalSize <= maxSize)
|
||||
val.append(pChar, fetchedSize);
|
||||
else
|
||||
else
|
||||
throw DataException(format(FLD_SIZE_EXCEEDED_FMT, fetchedSize, maxSize));
|
||||
}while (true);
|
||||
|
||||
@@ -367,8 +385,8 @@ bool Extractor::extractManualImpl<UTF16String>(std::size_t pos, UTF16String& val
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractManualImpl<Poco::Data::CLOB>(std::size_t pos,
|
||||
Poco::Data::CLOB& val,
|
||||
bool Extractor::extractManualImpl<Poco::Data::CLOB>(std::size_t pos,
|
||||
Poco::Data::CLOB& val,
|
||||
SQLSMALLINT cType)
|
||||
{
|
||||
std::size_t maxSize = _pPreparator->getMaxFieldSize();
|
||||
@@ -380,7 +398,7 @@ bool Extractor::extractManualImpl<Poco::Data::CLOB>(std::size_t pos,
|
||||
Poco::Buffer<char> apChar(bufSize);
|
||||
char* pChar = apChar.begin();
|
||||
SQLRETURN rc = 0;
|
||||
|
||||
|
||||
val.clear();
|
||||
resizeLengths(pos);
|
||||
|
||||
@@ -388,13 +406,13 @@ bool Extractor::extractManualImpl<Poco::Data::CLOB>(std::size_t pos,
|
||||
{
|
||||
std::memset(pChar, 0, bufSize);
|
||||
len = 0;
|
||||
rc = SQLGetData(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
rc = SQLGetData(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
cType, //C data type
|
||||
pChar, //returned value
|
||||
bufSize, //buffer length
|
||||
&len); //length indicator
|
||||
|
||||
|
||||
_lengths[pos] += len;
|
||||
|
||||
if (SQL_NO_DATA != rc && Utility::isError(rc))
|
||||
@@ -411,9 +429,9 @@ bool Extractor::extractManualImpl<Poco::Data::CLOB>(std::size_t pos,
|
||||
|
||||
fetchedSize = len > CHUNK_SIZE ? CHUNK_SIZE : len;
|
||||
totalSize += fetchedSize;
|
||||
if (totalSize <= maxSize)
|
||||
if (totalSize <= maxSize)
|
||||
val.appendRaw(pChar, fetchedSize);
|
||||
else
|
||||
else
|
||||
throw DataException(format(FLD_SIZE_EXCEEDED_FMT, fetchedSize, maxSize));
|
||||
|
||||
}while (true);
|
||||
@@ -423,26 +441,26 @@ bool Extractor::extractManualImpl<Poco::Data::CLOB>(std::size_t pos,
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractManualImpl<Poco::Data::Date>(std::size_t pos,
|
||||
Poco::Data::Date& val,
|
||||
bool Extractor::extractManualImpl<Poco::Data::Date>(std::size_t pos,
|
||||
Poco::Data::Date& val,
|
||||
SQLSMALLINT cType)
|
||||
{
|
||||
SQL_DATE_STRUCT ds;
|
||||
resizeLengths(pos);
|
||||
|
||||
SQLRETURN rc = SQLGetData(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
SQLRETURN rc = SQLGetData(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
cType, //C data type
|
||||
&ds, //returned value
|
||||
sizeof(ds), //buffer length
|
||||
&_lengths[pos]); //length indicator
|
||||
|
||||
|
||||
if (Utility::isError(rc))
|
||||
throw StatementException(_rStmt, "SQLGetData()");
|
||||
|
||||
if (isNullLengthIndicator(_lengths[pos]))
|
||||
if (isNullLengthIndicator(_lengths[pos]))
|
||||
return false;
|
||||
else
|
||||
else
|
||||
Utility::dateSync(val, ds);
|
||||
|
||||
return true;
|
||||
@@ -450,26 +468,26 @@ bool Extractor::extractManualImpl<Poco::Data::Date>(std::size_t pos,
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractManualImpl<Poco::Data::Time>(std::size_t pos,
|
||||
Poco::Data::Time& val,
|
||||
bool Extractor::extractManualImpl<Poco::Data::Time>(std::size_t pos,
|
||||
Poco::Data::Time& val,
|
||||
SQLSMALLINT cType)
|
||||
{
|
||||
SQL_TIME_STRUCT ts;
|
||||
resizeLengths(pos);
|
||||
|
||||
SQLRETURN rc = SQLGetData(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
SQLRETURN rc = SQLGetData(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
cType, //C data type
|
||||
&ts, //returned value
|
||||
sizeof(ts), //buffer length
|
||||
&_lengths[pos]); //length indicator
|
||||
|
||||
|
||||
if (Utility::isError(rc))
|
||||
throw StatementException(_rStmt, "SQLGetData()");
|
||||
|
||||
if (isNullLengthIndicator(_lengths[pos]))
|
||||
if (isNullLengthIndicator(_lengths[pos]))
|
||||
return false;
|
||||
else
|
||||
else
|
||||
Utility::timeSync(val, ts);
|
||||
|
||||
return true;
|
||||
@@ -477,32 +495,59 @@ bool Extractor::extractManualImpl<Poco::Data::Time>(std::size_t pos,
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractManualImpl<Poco::DateTime>(std::size_t pos,
|
||||
Poco::DateTime& val,
|
||||
bool Extractor::extractManualImpl<Poco::DateTime>(std::size_t pos,
|
||||
Poco::DateTime& val,
|
||||
SQLSMALLINT cType)
|
||||
{
|
||||
SQL_TIMESTAMP_STRUCT ts;
|
||||
resizeLengths(pos);
|
||||
|
||||
SQLRETURN rc = SQLGetData(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
SQLRETURN rc = SQLGetData(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
cType, //C data type
|
||||
&ts, //returned value
|
||||
sizeof(ts), //buffer length
|
||||
&_lengths[pos]); //length indicator
|
||||
|
||||
|
||||
if (Utility::isError(rc))
|
||||
throw StatementException(_rStmt, "SQLGetData()");
|
||||
|
||||
if (isNullLengthIndicator(_lengths[pos]))
|
||||
if (isNullLengthIndicator(_lengths[pos]))
|
||||
return false;
|
||||
else
|
||||
else
|
||||
Utility::dateTimeSync(val, ts);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractManualImpl<Poco::UUID>(std::size_t pos,
|
||||
Poco::UUID& val,
|
||||
SQLSMALLINT cType)
|
||||
{
|
||||
char buffer[16];
|
||||
resizeLengths(pos);
|
||||
|
||||
SQLRETURN rc = SQLGetData(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
cType, //C data type
|
||||
&buffer, //returned value
|
||||
sizeof(buffer), //buffer length
|
||||
&_lengths[pos]); //length indicator
|
||||
|
||||
if (Utility::isError(rc))
|
||||
throw StatementException(_rStmt, "SQLGetData()");
|
||||
|
||||
if (isNullLengthIndicator(_lengths[pos]))
|
||||
return false;
|
||||
else
|
||||
val.copyFrom(buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Int32& val)
|
||||
{
|
||||
if (Preparator::DE_MANUAL == _dataExtraction)
|
||||
@@ -660,37 +705,45 @@ bool Extractor::extract(std::size_t pos, std::list<double>& val)
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::string& val)
|
||||
{
|
||||
if (Preparator::DE_MANUAL == _dataExtraction)
|
||||
return extractManualImpl(pos, val, SQL_C_CHAR);
|
||||
bool ret = false;
|
||||
|
||||
if (!_transcode)
|
||||
{
|
||||
if (Preparator::DE_MANUAL == _dataExtraction)
|
||||
ret = extractManualImpl(pos, val, SQL_C_CHAR);
|
||||
else
|
||||
ret = extractBoundImpl(pos, val);
|
||||
}
|
||||
else
|
||||
return extractBoundImpl(pos, val);
|
||||
{
|
||||
std::string result;
|
||||
if (Preparator::DE_MANUAL == _dataExtraction)
|
||||
ret = extractManualImpl(pos, result, SQL_C_CHAR);
|
||||
else
|
||||
ret = extractBoundImpl(pos, result);
|
||||
Poco::TextConverter converter(*_pDBEncoding, *_pToEncoding);
|
||||
converter.convert(result, val);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<std::string>& val)
|
||||
{
|
||||
if (Preparator::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplContainer(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
|
||||
return stringContainerExtract(pos, val);
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::deque<std::string>& val)
|
||||
{
|
||||
if (Preparator::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplContainer(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
|
||||
return stringContainerExtract(pos, val);
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::list<std::string>& val)
|
||||
{
|
||||
if (Preparator::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplContainer(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
|
||||
return stringContainerExtract(pos, val);
|
||||
}
|
||||
|
||||
|
||||
@@ -910,6 +963,15 @@ bool Extractor::extract(std::size_t pos, std::list<Poco::DateTime>& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::UUID& val)
|
||||
{
|
||||
if (Preparator::DE_MANUAL == _dataExtraction)
|
||||
return extractManualImpl(pos, val, SQL_C_BINARY);
|
||||
else
|
||||
return extractBoundImpl(pos, val);
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Int8& val)
|
||||
{
|
||||
if (Preparator::DE_MANUAL == _dataExtraction)
|
||||
@@ -1307,10 +1369,10 @@ bool Extractor::isNull(std::size_t col, std::size_t row)
|
||||
try
|
||||
{
|
||||
return isNullLengthIndicator(_lengths.at(col));
|
||||
}
|
||||
}
|
||||
catch (std::out_of_range& ex)
|
||||
{
|
||||
throw RangeException(ex.what());
|
||||
throw RangeException(ex.what());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
6
vendor/POCO/Data/ODBC/src/ODBCMetaColumn.cpp
vendored
6
vendor/POCO/Data/ODBC/src/ODBCMetaColumn.cpp
vendored
@@ -102,9 +102,6 @@ void ODBCMetaColumn::init()
|
||||
case SQL_CHAR:
|
||||
case SQL_VARCHAR:
|
||||
case SQL_LONGVARCHAR:
|
||||
#ifdef SQL_GUID
|
||||
case SQL_GUID:
|
||||
#endif
|
||||
setType(MetaColumn::FDT_STRING); break;
|
||||
|
||||
case SQL_WCHAR:
|
||||
@@ -168,6 +165,9 @@ void ODBCMetaColumn::init()
|
||||
case SQL_TYPE_TIMESTAMP:
|
||||
setType(MetaColumn::FDT_TIMESTAMP); break;
|
||||
|
||||
case SQL_GUID:
|
||||
setType(MetaColumn::FDT_UUID); break;
|
||||
|
||||
default:
|
||||
throw DataFormatException("Unsupported data type.");
|
||||
}
|
||||
|
||||
@@ -145,7 +145,8 @@ void ODBCStatementImpl::addPreparator()
|
||||
else
|
||||
_preparations.push_back(new Preparator(*_preparations[0]));
|
||||
|
||||
_extractors.push_back(new Extractor(_stmt, _preparations.back()));
|
||||
_extractors.push_back(new Extractor(_stmt, _preparations.back(),
|
||||
TextEncoding::find(Poco::RefAnyCast<std::string>(session().getProperty("dbEncoding")))));
|
||||
}
|
||||
|
||||
|
||||
|
||||
22
vendor/POCO/Data/ODBC/src/Preparator.cpp
vendored
22
vendor/POCO/Data/ODBC/src/Preparator.cpp
vendored
@@ -25,10 +25,10 @@ namespace Data {
|
||||
namespace ODBC {
|
||||
|
||||
|
||||
Preparator::Preparator(const StatementHandle& rStmt,
|
||||
const std::string& statement,
|
||||
Preparator::Preparator(const StatementHandle& rStmt,
|
||||
const std::string& statement,
|
||||
std::size_t maxFieldSize,
|
||||
DataExtraction dataExtraction):
|
||||
DataExtraction dataExtraction):
|
||||
_rStmt(rStmt),
|
||||
_maxFieldSize(maxFieldSize),
|
||||
_dataExtraction(dataExtraction)
|
||||
@@ -39,7 +39,7 @@ Preparator::Preparator(const StatementHandle& rStmt,
|
||||
}
|
||||
|
||||
|
||||
Preparator::Preparator(const Preparator& other):
|
||||
Preparator::Preparator(const Preparator& other):
|
||||
_rStmt(other._rStmt),
|
||||
_maxFieldSize(other._maxFieldSize),
|
||||
_dataExtraction(other._dataExtraction)
|
||||
@@ -151,14 +151,14 @@ std::size_t Preparator::maxDataSize(std::size_t pos) const
|
||||
std::size_t sz = 0;
|
||||
std::size_t maxsz = getMaxFieldSize();
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
ODBCMetaColumn mc(_rStmt, pos);
|
||||
sz = mc.length();
|
||||
|
||||
// accomodate for terminating zero (non-bulk only!)
|
||||
MetaColumn::ColumnDataType type = mc.type();
|
||||
if (!isBulk() && ((ODBCMetaColumn::FDT_WSTRING == type) || (ODBCMetaColumn::FDT_STRING == type))) ++sz;
|
||||
if (sz && !isBulk() && ((ODBCMetaColumn::FDT_WSTRING == type) || (ODBCMetaColumn::FDT_STRING == type))) ++sz;
|
||||
}
|
||||
catch (StatementException&) { }
|
||||
|
||||
@@ -194,11 +194,11 @@ void Preparator::prepareBoolArray(std::size_t pos, SQLSMALLINT valueType, std::s
|
||||
_lenLengths[pos].resize(length);
|
||||
_varLengthArrays.insert(IndexMap::value_type(pos, DT_BOOL_ARRAY));
|
||||
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) pArray,
|
||||
(SQLINTEGER) sizeof(bool),
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) pArray,
|
||||
(SQLINTEGER) sizeof(bool),
|
||||
&_lenLengths[pos][0])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindCol()");
|
||||
|
||||
18
vendor/POCO/Data/ODBC/src/SessionImpl.cpp
vendored
18
vendor/POCO/Data/ODBC/src/SessionImpl.cpp
vendored
@@ -39,7 +39,8 @@ SessionImpl::SessionImpl(const std::string& connect,
|
||||
_autoExtract(autoExtract),
|
||||
_canTransact(ODBC_TXN_CAPABILITY_UNKNOWN),
|
||||
_inTransaction(false),
|
||||
_queryTimeout(-1)
|
||||
_queryTimeout(-1),
|
||||
_dbEncoding("UTF-8")
|
||||
{
|
||||
setFeature("bulk", true);
|
||||
open();
|
||||
@@ -58,7 +59,8 @@ SessionImpl::SessionImpl(const std::string& connect,
|
||||
_autoExtract(autoExtract),
|
||||
_canTransact(ODBC_TXN_CAPABILITY_UNKNOWN),
|
||||
_inTransaction(false),
|
||||
_queryTimeout(-1)
|
||||
_queryTimeout(-1),
|
||||
_dbEncoding("UTF-8")
|
||||
{
|
||||
setFeature("bulk", true);
|
||||
open();
|
||||
@@ -158,12 +160,24 @@ void SessionImpl::open(const std::string& connect)
|
||||
&SessionImpl::setQueryTimeout,
|
||||
&SessionImpl::getQueryTimeout);
|
||||
|
||||
addProperty("dbEncoding",
|
||||
&SessionImpl::setDBEncoding,
|
||||
&SessionImpl::getDBEncoding);
|
||||
|
||||
Poco::Data::ODBC::SQLSetConnectAttr(_db, SQL_ATTR_QUIET_MODE, 0, 0);
|
||||
|
||||
if (!canTransact()) autoCommit("", true);
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::setDBEncoding(const std::string&, const Poco::Any& value)
|
||||
{
|
||||
const std::string& enc = Poco::RefAnyCast<std::string>(value);
|
||||
Poco::TextEncoding::byName(enc); // throws if not found
|
||||
_dbEncoding = enc;
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::isConnected() const
|
||||
{
|
||||
SQLULEN value = 0;
|
||||
|
||||
@@ -612,6 +612,15 @@ void ODBCSQLServerTest::recreateFloatsTable()
|
||||
}
|
||||
|
||||
|
||||
void ODBCSQLServerTest::recreateUUIDsTable()
|
||||
{
|
||||
dropObject("TABLE", "Strings");
|
||||
try { session() << "CREATE TABLE Strings (str UNIQUEIDENTIFIER)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateUUIDsTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateUUIDsTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void ODBCSQLServerTest::recreateTuplesTable()
|
||||
{
|
||||
dropObject("TABLE", "Tuples");
|
||||
@@ -787,6 +796,7 @@ CppUnit::Test* ODBCSQLServerTest::suite()
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testDateTime);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testFloat);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testDouble);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testUUID);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testTuple);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testTupleVector);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredProcedure);
|
||||
|
||||
@@ -64,6 +64,7 @@ private:
|
||||
void recreateStringsTable();
|
||||
void recreateIntsTable();
|
||||
void recreateFloatsTable();
|
||||
void recreateUUIDsTable();
|
||||
void recreateTuplesTable();
|
||||
void recreateVectorTable();
|
||||
void recreateVectorsTable();
|
||||
|
||||
15
vendor/POCO/Data/ODBC/testsuite/src/ODBCTest.cpp
vendored
15
vendor/POCO/Data/ODBC/testsuite/src/ODBCTest.cpp
vendored
@@ -917,6 +917,21 @@ void ODBCTest::testDouble()
|
||||
}
|
||||
|
||||
|
||||
void ODBCTest::testUUID()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
for (int i = 0; i < 8;)
|
||||
{
|
||||
recreateUUIDsTable();
|
||||
_pSession->setFeature("autoBind", bindValue(i));
|
||||
_pSession->setFeature("autoExtract", bindValue(i+1));
|
||||
_pExecutor->uuids();
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ODBCTest::testTuple()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
@@ -113,6 +113,8 @@ public:
|
||||
virtual void testFloat();
|
||||
virtual void testDouble();
|
||||
|
||||
virtual void testUUID();
|
||||
|
||||
virtual void testTuple();
|
||||
virtual void testTupleVector();
|
||||
|
||||
@@ -166,6 +168,7 @@ protected:
|
||||
virtual void recreateStringsTable();
|
||||
virtual void recreateIntsTable();
|
||||
virtual void recreateFloatsTable();
|
||||
virtual void recreateUUIDsTable();
|
||||
virtual void recreateTuplesTable();
|
||||
virtual void recreateVectorsTable();
|
||||
virtual void recreateAnysTable();
|
||||
@@ -317,6 +320,12 @@ inline void ODBCTest::recreateFloatsTable()
|
||||
}
|
||||
|
||||
|
||||
inline void ODBCTest::recreateUUIDsTable()
|
||||
{
|
||||
throw Poco::NotImplementedException("ODBCTest::recreateUUIDsTable()");
|
||||
}
|
||||
|
||||
|
||||
inline void ODBCTest::recreateTuplesTable()
|
||||
{
|
||||
throw Poco::NotImplementedException("ODBCTest::recreateTuplesTable()");
|
||||
|
||||
@@ -1540,6 +1540,29 @@ void SQLExecutor::doubles()
|
||||
}
|
||||
|
||||
|
||||
void SQLExecutor::uuids()
|
||||
{
|
||||
std::string funct = "uuids()";
|
||||
Poco::UUID data("49cf6461-9b62-4163-9659-5472ef73153d");
|
||||
Poco::UUID ret;
|
||||
|
||||
try { session() << "INSERT INTO Strings VALUES (?)", use(data), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
|
||||
int count = 0;
|
||||
try { session() << "SELECT COUNT(*) FROM Strings", into(count), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
assertTrue (count == 1);
|
||||
|
||||
try { session() << "SELECT str FROM Strings", into(ret), now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
assertTrue (ret == data);
|
||||
}
|
||||
|
||||
|
||||
void SQLExecutor::insertSingleBulkVec()
|
||||
{
|
||||
std::string funct = "insertSingleBulkVec()";
|
||||
|
||||
@@ -469,6 +469,7 @@ public:
|
||||
void time();
|
||||
void floats();
|
||||
void doubles();
|
||||
void uuids();
|
||||
void tuples();
|
||||
void tupleVector();
|
||||
|
||||
|
||||
3
vendor/POCO/Data/PostgreSQL/Makefile
vendored
3
vendor/POCO/Data/PostgreSQL/Makefile
vendored
@@ -37,6 +37,9 @@ endif
|
||||
ifeq (0, $(shell test -e /opt/postgresql/lib$(LIB64SUFFIX); echo $$?))
|
||||
SYSLIBS += -L/opt/postgresql/lib$(LIB64SUFFIX)
|
||||
endif
|
||||
ifeq (0, $(shell test -e /usr/local/opt/libpq/lib; echo $$?))
|
||||
SYSLIBS += -L/usr/local/opt/libpq/lib$(LIB64SUFFIX)
|
||||
endif
|
||||
SYSLIBS += -lpq
|
||||
|
||||
objects = Extractor Binder SessionImpl Connector \
|
||||
|
||||
@@ -108,6 +108,9 @@ public:
|
||||
virtual void bind(std::size_t pos, const Time& val, Direction dir = PD_IN);
|
||||
/// Binds a Time.
|
||||
|
||||
virtual void bind(std::size_t pos, const UUID& val, Direction dir = PD_IN);
|
||||
/// Binds a UUID.
|
||||
|
||||
virtual void bind(std::size_t pos, const NullData& val, Direction dir = PD_IN);
|
||||
/// Binds a null.
|
||||
|
||||
|
||||
@@ -109,6 +109,9 @@ public:
|
||||
virtual bool extract(std::size_t pos, Time& val);
|
||||
/// Extracts a Time. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, UUID& val);
|
||||
/// Extracts a UUID. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, Any& val);
|
||||
/// Extracts an Any. Returns false if null was received.
|
||||
|
||||
@@ -326,15 +329,10 @@ private:
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if (isColumnNull(outputParameter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (isColumnNull(outputParameter)) return false;
|
||||
|
||||
std::string tempString; // since the postgreSQL API in use is all about strings...
|
||||
|
||||
bool returnValue = extract(pos, tempString);
|
||||
|
||||
if (returnValue)
|
||||
{
|
||||
val = tempString;
|
||||
@@ -343,9 +341,10 @@ private:
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
bool extractToDynamic(std::size_t pos, Dynamic::Var& val);
|
||||
|
||||
// Prevent VC8 warning "operator= could not be generated"
|
||||
Extractor& operator=(const Extractor&);
|
||||
Extractor& operator = (const Extractor&);
|
||||
|
||||
private:
|
||||
StatementExecutor& _statementExecutor;
|
||||
|
||||
@@ -271,6 +271,7 @@ inline const void* InputParameter::pInternalRepresentation() const
|
||||
case Poco::Data::MetaColumn::FDT_DATE:
|
||||
case Poco::Data::MetaColumn::FDT_TIME:
|
||||
case Poco::Data::MetaColumn::FDT_TIMESTAMP:
|
||||
case Poco::Data::MetaColumn::FDT_UUID:
|
||||
return _stringVersionRepresentation.c_str();
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_BLOB:
|
||||
@@ -278,7 +279,8 @@ inline const void* InputParameter::pInternalRepresentation() const
|
||||
return _pNonStringVersionRepresentation;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_UNKNOWN:
|
||||
default: return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,8 +89,7 @@ public:
|
||||
|
||||
void connect(const char* aConnectionString);
|
||||
|
||||
void connect(const char* aHost, const char* aUser, const char* aPassword,
|
||||
const char* aDatabase, unsigned short aPort, unsigned int aConnectionTimeout);
|
||||
void connect(const char* aHost, const char* aUser, const char* aPassword, const char* aDatabase, unsigned short aPort, unsigned int aConnectionTimeout);
|
||||
|
||||
bool isConnected() const;
|
||||
/// is a connection established?
|
||||
|
||||
19
vendor/POCO/Data/PostgreSQL/src/Binder.cpp
vendored
19
vendor/POCO/Data/PostgreSQL/src/Binder.cpp
vendored
@@ -176,6 +176,13 @@ void Binder::bind(std::size_t pos, const Time& val, Direction dir)
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const UUID& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_UUID, &val, sizeof(UUID));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const NullData&, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
@@ -198,8 +205,8 @@ Binder::bindVector() const
|
||||
|
||||
void Binder::updateBindVectorToCurrentValues()
|
||||
{
|
||||
InputParameterVector::iterator itr = _bindVector.begin();
|
||||
InputParameterVector::iterator itrEnd = _bindVector.end();
|
||||
InputParameterVector::iterator itr = _bindVector.begin();
|
||||
InputParameterVector::iterator itrEnd = _bindVector.end();
|
||||
|
||||
for (; itr != itrEnd; ++itr)
|
||||
{
|
||||
@@ -293,6 +300,14 @@ void Binder::updateBindVectorToCurrentValues()
|
||||
const Poco::Data::CLOB& clob = * static_cast<const Poco::Data::CLOB*>(itr->pData());
|
||||
itr->setNonStringVersionRepresentation(static_cast<const void*> (clob.rawContent()), clob.size());
|
||||
}
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_UUID:
|
||||
{
|
||||
const Poco::UUID& uuid = * static_cast<const Poco::UUID*>(itr->pData());
|
||||
itr->setStringVersionRepresentation(uuid.toString());
|
||||
}
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_UNKNOWN:
|
||||
default:
|
||||
|
||||
399
vendor/POCO/Data/PostgreSQL/src/Extractor.cpp
vendored
399
vendor/POCO/Data/PostgreSQL/src/Extractor.cpp
vendored
@@ -17,6 +17,8 @@
|
||||
#include "Poco/Data/Time.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/DateTimeParser.h"
|
||||
#include "Poco/MemoryStream.h"
|
||||
#include "Poco/HexBinaryDecoder.h"
|
||||
#include <limits>
|
||||
|
||||
|
||||
@@ -42,14 +44,10 @@ bool Extractor::extract(std::size_t pos, Poco::Int8& val)
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
int tempVal = 0;
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParse(outputParameter.pData(), tempVal)
|
||||
)
|
||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParse(outputParameter.pData(), tempVal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = static_cast<Int8>(tempVal);
|
||||
|
||||
return true;
|
||||
@@ -61,15 +59,11 @@ bool Extractor::extract(std::size_t pos, Poco::UInt8& val)
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
unsigned int tempVal = 0;
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), tempVal)
|
||||
)
|
||||
if (isColumnNull(outputParameter)|| !Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), tempVal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = static_cast<Int8>(tempVal);
|
||||
val = static_cast<UInt8>(tempVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -80,15 +74,11 @@ bool Extractor::extract(std::size_t pos, Poco::Int16& val)
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
int tempVal = 0;
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParse(outputParameter.pData(), tempVal)
|
||||
)
|
||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParse(outputParameter.pData(), tempVal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = static_cast<Int8>(tempVal);
|
||||
val = static_cast<Int16>(tempVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -99,15 +89,11 @@ bool Extractor::extract(std::size_t pos, Poco::UInt16& val)
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
unsigned int tempVal = 0;
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), tempVal)
|
||||
)
|
||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), tempVal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = static_cast<Int8>(tempVal);
|
||||
val = static_cast<UInt16>(tempVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -117,9 +103,7 @@ bool Extractor::extract(std::size_t pos, Poco::Int32& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParse(outputParameter.pData(), val)
|
||||
)
|
||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParse(outputParameter.pData(), val))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -132,9 +116,7 @@ bool Extractor::extract(std::size_t pos, Poco::UInt32& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), val)
|
||||
)
|
||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), val))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -147,9 +129,7 @@ bool Extractor::extract(std::size_t pos, Poco::Int64& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParse64(outputParameter.pData(), val)
|
||||
)
|
||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParse64(outputParameter.pData(), val))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -162,9 +142,7 @@ bool Extractor::extract(std::size_t pos, Poco::UInt64& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseUnsigned64(outputParameter.pData(), val)
|
||||
)
|
||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParseUnsigned64(outputParameter.pData(), val))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -179,13 +157,10 @@ bool Extractor::extract(std::size_t pos, long& val)
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
Poco::Int64 tempVal = 0;
|
||||
|
||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParse64(outputParameter.pData(), tempVal)
|
||||
)
|
||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParse64(outputParameter.pData(), tempVal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = (long)tempVal;
|
||||
|
||||
return true;
|
||||
@@ -197,14 +172,10 @@ bool Extractor::extract(std::size_t pos, unsigned long& val)
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
Poco::UInt64 tempVal = 0;
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseUnsigned64(outputParameter.pData(), tempVal)
|
||||
)
|
||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParseUnsigned64(outputParameter.pData(), tempVal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = (unsigned long)tempVal;
|
||||
|
||||
return true;
|
||||
@@ -216,19 +187,12 @@ bool Extractor::extract(std::size_t pos, bool& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if ( isColumnNull(outputParameter))
|
||||
if (isColumnNull(outputParameter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ('t' == *outputParameter.pData())
|
||||
{
|
||||
val = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = false;
|
||||
}
|
||||
val = 't' == *outputParameter.pData();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -239,15 +203,11 @@ bool Extractor::extract(std::size_t pos, float& val)
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
double tempVal = 0.0;
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseFloat(outputParameter.pData(), tempVal)
|
||||
)
|
||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParseFloat(outputParameter.pData(), tempVal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = (float)tempVal;
|
||||
val = static_cast<float>(tempVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -257,9 +217,7 @@ bool Extractor::extract(std::size_t pos, double& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseFloat(outputParameter.pData(), val)
|
||||
)
|
||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParseFloat(outputParameter.pData(), val))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -272,11 +230,10 @@ bool Extractor::extract(std::size_t pos, char& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if (isColumnNull(outputParameter))
|
||||
if (isColumnNull(outputParameter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = *outputParameter.pData();
|
||||
|
||||
return true;
|
||||
@@ -291,7 +248,6 @@ bool Extractor::extract(std::size_t pos, std::string& val)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val.assign(outputParameter.pData(), outputParameter.size());
|
||||
|
||||
return true;
|
||||
@@ -309,31 +265,24 @@ bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
|
||||
|
||||
// convert the PostgreSQL text format to binary and append to the BLOB
|
||||
// Format: \x10843029479abcf ... two characters for every byte
|
||||
//
|
||||
// The code below can be made more efficient by converting more than one byte at a time
|
||||
// also if BLOB had a resize method it would be useful to allocate memory in one
|
||||
// attempt.
|
||||
//
|
||||
|
||||
const char * pBLOB = reinterpret_cast<const char*>(outputParameter.pData());
|
||||
std::size_t BLOBSize = outputParameter.size();
|
||||
std::size_t blobSize = outputParameter.size();
|
||||
val = Poco::Data::BLOB(); // don't share contents with _default
|
||||
|
||||
if ( '\\' == pBLOB[0]
|
||||
&& 'x' == pBLOB[1] // preamble to BYTEA data format in text form is \x
|
||||
)
|
||||
if (blobSize > 2 && '\\' == pBLOB[0] && 'x' == pBLOB[1]) // preamble to BYTEA data format in text form is \x
|
||||
{
|
||||
BLOBSize -= 2; // lose the preamble
|
||||
BLOBSize /= 2; // each byte is encoded as two text characters
|
||||
blobSize -= 2; // lose the preamble
|
||||
|
||||
for (int i = 0; i < BLOBSize * 2; i += 2)
|
||||
Poco::MemoryInputStream mistr(pBLOB + 2, blobSize);
|
||||
Poco::HexBinaryDecoder decoder(mistr);
|
||||
auto* pDecoderBuf = decoder.rdbuf();
|
||||
blobSize /= 2;
|
||||
val.resize(blobSize);
|
||||
char* pData = reinterpret_cast<char*>(val.rawContent());
|
||||
while (blobSize-- > 0)
|
||||
{
|
||||
std::string buffer(&pBLOB[i + 2], 2);
|
||||
unsigned int binaryBuffer = 0;
|
||||
if (Poco::NumberParser::tryParseHex(buffer, binaryBuffer))
|
||||
{
|
||||
UInt8 finalBinaryBuffer = static_cast<UInt8>(binaryBuffer); // downsize
|
||||
val.appendRaw(&finalBinaryBuffer, 1);
|
||||
}
|
||||
*pData++ = pDecoderBuf->sbumpc();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -348,7 +297,6 @@ bool Extractor::extract(std::size_t pos, Poco::Data::CLOB& val)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val.assignRaw(outputParameter.pData(), outputParameter.size());
|
||||
|
||||
return true;
|
||||
@@ -366,14 +314,11 @@ bool Extractor::extract(std::size_t pos, DateTime& val)
|
||||
|
||||
int tzd = -1;
|
||||
DateTime dateTime;
|
||||
|
||||
if (! DateTimeParser::tryParse(outputParameter.pData(), dateTime, tzd))
|
||||
if (!DateTimeParser::tryParse(outputParameter.pData(), dateTime, tzd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
dateTime.makeUTC(tzd);
|
||||
|
||||
val = dateTime;
|
||||
|
||||
return true;
|
||||
@@ -388,17 +333,13 @@ bool Extractor::extract(std::size_t pos, Date& val)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int tzd = -1;
|
||||
DateTime dateTime;
|
||||
|
||||
if (! DateTimeParser::tryParse(outputParameter.pData(), dateTime, tzd))
|
||||
if (!DateTimeParser::tryParse(outputParameter.pData(), dateTime, tzd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
dateTime.makeUTC(tzd);
|
||||
|
||||
val.assign(dateTime.year(), dateTime.month(), dateTime.day());
|
||||
|
||||
return true;
|
||||
@@ -413,10 +354,8 @@ bool Extractor::extract(std::size_t pos, Time& val)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int tzd = -1;
|
||||
DateTime dateTime;
|
||||
|
||||
if (! DateTimeParser::tryParse("%H:%M:%s%z", outputParameter.pData(), dateTime, tzd))
|
||||
{
|
||||
return false;
|
||||
@@ -431,15 +370,28 @@ bool Extractor::extract(std::size_t pos, Time& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, UUID& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if (isColumnNull(outputParameter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return val.tryParse(outputParameter.pData());
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Any& val)
|
||||
{
|
||||
return extractStringImpl (pos, val);
|
||||
return extractStringImpl(pos, val);
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Dynamic::Var& val)
|
||||
{
|
||||
return extractStringImpl (pos, val);
|
||||
return extractToDynamic(pos, val);
|
||||
}
|
||||
|
||||
|
||||
@@ -462,8 +414,7 @@ void Extractor::reset()
|
||||
}
|
||||
|
||||
|
||||
const OutputParameter&
|
||||
Extractor::extractPreamble(std::size_t aPosition) const
|
||||
const OutputParameter& Extractor::extractPreamble(std::size_t aPosition) const
|
||||
{
|
||||
if (_statementExecutor.columnsReturned() <= aPosition)
|
||||
{
|
||||
@@ -474,11 +425,125 @@ Extractor::extractPreamble(std::size_t aPosition) const
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Extractor::isColumnNull (const OutputParameter& anOutputParameter) const
|
||||
bool Extractor::isColumnNull(const OutputParameter& anOutputParameter) const
|
||||
{
|
||||
return anOutputParameter.isNull()
|
||||
|| 0 == anOutputParameter.pData();
|
||||
return anOutputParameter.isNull() || 0 == anOutputParameter.pData();
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extractToDynamic(std::size_t pos, Dynamic::Var& val)
|
||||
{
|
||||
OutputParameter outputParameter = _statementExecutor.resultColumn(pos);
|
||||
|
||||
if (isColumnNull(outputParameter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string tempString{outputParameter.pData(), outputParameter.size()};
|
||||
const Oid oid = outputParameter.internalFieldType();
|
||||
|
||||
bool success = false;
|
||||
|
||||
switch (oid)
|
||||
{
|
||||
case BOOLOID:
|
||||
{
|
||||
success = true;
|
||||
if (tempString[0] == 't')
|
||||
val = true;
|
||||
else
|
||||
val = false;
|
||||
break;
|
||||
}
|
||||
case INT2OID:
|
||||
case INT4OID:
|
||||
case INT8OID:
|
||||
{
|
||||
Poco::Int64 tempValue = 0;
|
||||
success = Poco::NumberParser::tryParse64(tempString, tempValue);
|
||||
if (success)
|
||||
val = tempValue;
|
||||
break;
|
||||
}
|
||||
// floating point
|
||||
case FLOAT8OID:
|
||||
case FLOAT4OID:
|
||||
case NUMERICOID:
|
||||
{
|
||||
double tempValue = 0;
|
||||
success = Poco::NumberParser::tryParseFloat(tempString, tempValue);
|
||||
if (success)
|
||||
val = tempValue;
|
||||
break;
|
||||
}
|
||||
// character strings
|
||||
case CHAROID:
|
||||
case BPCHAROID:
|
||||
case VARCHAROID:
|
||||
default:
|
||||
{
|
||||
success = true;
|
||||
val = tempString;
|
||||
break;
|
||||
}
|
||||
// BLOB, CLOB
|
||||
case BYTEAOID:
|
||||
{
|
||||
Poco::Data::BLOB blob;
|
||||
success = extract(pos, blob);
|
||||
if (success)
|
||||
val = blob;
|
||||
break;
|
||||
}
|
||||
case TEXTOID:
|
||||
{
|
||||
Poco::Data::CLOB clob;
|
||||
success = extract(pos, clob);
|
||||
if (success)
|
||||
val = clob;
|
||||
break;
|
||||
}
|
||||
// date
|
||||
case DATEOID:
|
||||
{
|
||||
Date d;
|
||||
success = extract(pos, d);
|
||||
if (success)
|
||||
val = d;
|
||||
break;
|
||||
}
|
||||
// time
|
||||
case TIMEOID:
|
||||
case TIMETZOID:
|
||||
{
|
||||
Time t;
|
||||
success = extract(pos, t);
|
||||
if (success)
|
||||
val = t;
|
||||
break;
|
||||
}
|
||||
//timestamp
|
||||
case TIMESTAMPOID:
|
||||
case TIMESTAMPZOID:
|
||||
{
|
||||
DateTime dt;
|
||||
success = extract(pos, dt);
|
||||
if (success)
|
||||
val = dt;
|
||||
break;
|
||||
}
|
||||
case UUIDOID:
|
||||
{
|
||||
UUID uuid;
|
||||
success = extract(pos, uuid);
|
||||
if (success)
|
||||
val = uuid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@@ -487,381 +552,381 @@ Extractor::isColumnNull (const OutputParameter& anOutputParameter) const
|
||||
//////////////
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::Int8>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<Poco::Int8>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::Int8>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<Poco::Int8>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::Int8>&)
|
||||
bool Extractor::extract(std::size_t, std::list<Poco::Int8>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::UInt8>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<Poco::UInt8>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::UInt8>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<Poco::UInt8>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::UInt8>&)
|
||||
bool Extractor::extract(std::size_t, std::list<Poco::UInt8>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::Int16>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<Poco::Int16>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::Int16>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<Poco::Int16>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::Int16>&)
|
||||
bool Extractor::extract(std::size_t, std::list<Poco::Int16>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::UInt16>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<Poco::UInt16>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::UInt16>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<Poco::UInt16>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::UInt16>&)
|
||||
bool Extractor::extract(std::size_t, std::list<Poco::UInt16>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::Int32>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<Poco::Int32>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::Int32>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<Poco::Int32>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::Int32>&)
|
||||
bool Extractor::extract(std::size_t, std::list<Poco::Int32>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::UInt32>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<Poco::UInt32>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::UInt32>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<Poco::UInt32>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::UInt32>&)
|
||||
bool Extractor::extract(std::size_t, std::list<Poco::UInt32>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::Int64>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<Poco::Int64>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::Int64>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<Poco::Int64>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::Int64>&)
|
||||
bool Extractor::extract(std::size_t, std::list<Poco::Int64>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::UInt64>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<Poco::UInt64>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::UInt64>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<Poco::UInt64>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::UInt64>&)
|
||||
bool Extractor::extract(std::size_t, std::list<Poco::UInt64>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
#ifndef POCO_INT64_IS_LONG
|
||||
bool Extractor::extract(std::size_t , std::vector<long>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<long>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<long>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<long>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<long>&)
|
||||
bool Extractor::extract(std::size_t, std::list<long>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<bool>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<bool>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<bool>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<bool>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<bool>&)
|
||||
bool Extractor::extract(std::size_t, std::list<bool>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<float>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<float>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<float>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<float>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<float>&)
|
||||
bool Extractor::extract(std::size_t, std::list<float>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<double>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<double>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<double>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<double>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<double>&)
|
||||
bool Extractor::extract(std::size_t, std::list<double>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<char>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<char>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<char>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<char>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<char>&)
|
||||
bool Extractor::extract(std::size_t, std::list<char>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<std::string>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<std::string>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<std::string>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<std::string>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<std::string>&)
|
||||
bool Extractor::extract(std::size_t, std::list<std::string>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<BLOB>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<BLOB>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<BLOB>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<BLOB>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<BLOB>&)
|
||||
bool Extractor::extract(std::size_t, std::list<BLOB>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<CLOB>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<CLOB>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<CLOB>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<CLOB>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<CLOB>&)
|
||||
bool Extractor::extract(std::size_t, std::list<CLOB>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<DateTime>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<DateTime>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<DateTime>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<DateTime>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<DateTime>&)
|
||||
bool Extractor::extract(std::size_t, std::list<DateTime>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Date>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<Date>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Date>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<Date>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Date>&)
|
||||
bool Extractor::extract(std::size_t, std::list<Date>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Time>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<Time>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Time>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<Time>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Time>&)
|
||||
bool Extractor::extract(std::size_t, std::list<Time>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Any>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<Any>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Any>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<Any>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Any>&)
|
||||
bool Extractor::extract(std::size_t, std::list<Any>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Dynamic::Var>&)
|
||||
bool Extractor::extract(std::size_t, std::vector<Dynamic::Var>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Dynamic::Var>&)
|
||||
bool Extractor::extract(std::size_t, std::deque<Dynamic::Var>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Dynamic::Var>&)
|
||||
bool Extractor::extract(std::size_t, std::list<Dynamic::Var>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
@@ -108,8 +108,7 @@ bool PostgreSQLStatementImpl::canBind() const
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if ((_statementExecutor.state() >= StatementExecutor::STMT_COMPILED)
|
||||
&& !bindings().empty())
|
||||
if ((_statementExecutor.state() >= StatementExecutor::STMT_COMPILED) && !bindings().empty())
|
||||
{
|
||||
ret = (*bindings().begin())->canBind();
|
||||
}
|
||||
|
||||
@@ -94,6 +94,11 @@ Poco::Data::MetaColumn::ColumnDataType oidToColumnDataType(const Oid anOID)
|
||||
cdt = Poco::Data::MetaColumn::FDT_TIMESTAMP;
|
||||
break;
|
||||
|
||||
//uuid
|
||||
case UUIDOID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_BLOB;
|
||||
break;
|
||||
|
||||
// everything else is a string
|
||||
default:
|
||||
cdt = Poco::Data::MetaColumn::FDT_STRING;
|
||||
|
||||
@@ -86,7 +86,7 @@ void SessionHandle::connect(const std::string& aConnectionString)
|
||||
|
||||
_pConnection = PQconnectdb(aConnectionString.c_str());
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
if (!isConnectedNoLock())
|
||||
{
|
||||
throw ConnectionFailedException(std::string("Connection Error: ") + lastErrorNoLock());
|
||||
}
|
||||
@@ -151,6 +151,7 @@ void SessionHandle::disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: Figure out what happens if a connection is reset with a pending transaction
|
||||
bool SessionHandle::reset()
|
||||
{
|
||||
@@ -174,7 +175,7 @@ std::string SessionHandle::lastError() const
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
if (!isConnectedNoLock())
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
@@ -196,7 +197,7 @@ void SessionHandle::startTransaction()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
if (!isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
@@ -223,7 +224,7 @@ void SessionHandle::commit()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
if (!isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
@@ -247,7 +248,7 @@ void SessionHandle::rollback()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
if (!isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
@@ -291,7 +292,7 @@ void SessionHandle::setAsynchronousCommit(bool aShouldAsynchronousCommit)
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
if (!isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
@@ -318,7 +319,7 @@ void SessionHandle::cancel()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
if (!isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
@@ -335,7 +336,7 @@ void SessionHandle::setTransactionIsolation(Poco::UInt32 aTI)
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
if (!isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
@@ -345,7 +346,7 @@ void SessionHandle::setTransactionIsolation(Poco::UInt32 aTI)
|
||||
return;
|
||||
}
|
||||
|
||||
if (! hasTransactionIsolation(aTI))
|
||||
if (!hasTransactionIsolation(aTI))
|
||||
{
|
||||
throw Poco::InvalidArgumentException("setTransactionIsolation()");
|
||||
}
|
||||
@@ -354,12 +355,12 @@ void SessionHandle::setTransactionIsolation(Poco::UInt32 aTI)
|
||||
|
||||
switch (aTI)
|
||||
{
|
||||
case Session::TRANSACTION_READ_COMMITTED:
|
||||
isolationLevel = POSTGRESQL_READ_COMMITTED; break;
|
||||
case Session::TRANSACTION_REPEATABLE_READ:
|
||||
isolationLevel = POSTGRESQL_REPEATABLE_READ; break;
|
||||
case Session::TRANSACTION_SERIALIZABLE:
|
||||
isolationLevel = POSTGRESQL_SERIALIZABLE; break;
|
||||
case Session::TRANSACTION_READ_COMMITTED:
|
||||
isolationLevel = POSTGRESQL_READ_COMMITTED; break;
|
||||
case Session::TRANSACTION_REPEATABLE_READ:
|
||||
isolationLevel = POSTGRESQL_REPEATABLE_READ; break;
|
||||
case Session::TRANSACTION_SERIALIZABLE:
|
||||
isolationLevel = POSTGRESQL_SERIALIZABLE; break;
|
||||
}
|
||||
|
||||
PGresult* pPQResult = PQexec(_pConnection, Poco::format("SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL %s", isolationLevel).c_str());
|
||||
@@ -393,12 +394,12 @@ void SessionHandle::deallocatePreparedStatement(const std::string& aPreparedStat
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
if (!isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
if (! _inTransaction)
|
||||
if (!_inTransaction)
|
||||
{
|
||||
deallocatePreparedStatementNoLock(aPreparedStatementToDeAllocate);
|
||||
}
|
||||
@@ -431,7 +432,7 @@ void SessionHandle::deallocatePreparedStatementNoLock(const std::string& aPrepar
|
||||
void SessionHandle::deallocateStoredPreparedStatements()
|
||||
{
|
||||
// DO NOT ACQUIRE THE MUTEX IN PRIVATE METHODS
|
||||
while (! _preparedStatementsToBeDeallocated.empty())
|
||||
while (!_preparedStatementsToBeDeallocated.empty())
|
||||
{
|
||||
deallocatePreparedStatementNoLock(_preparedStatementsToBeDeallocated.back());
|
||||
|
||||
@@ -444,7 +445,7 @@ int SessionHandle::serverVersion() const
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
if (!isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
@@ -457,7 +458,7 @@ int SessionHandle::serverProcessID() const
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
if (!isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
@@ -470,7 +471,7 @@ int SessionHandle::protocoVersion() const
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
if (!isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
@@ -483,7 +484,7 @@ std::string SessionHandle::clientEncoding() const
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
if (!isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
@@ -502,7 +503,7 @@ SessionParametersMap SessionHandle::setConnectionInfoParameters(PQconninfoOption
|
||||
{
|
||||
SessionParametersMap sessionParametersMap;
|
||||
|
||||
while (0 != pConnInfOpt->keyword)
|
||||
while (pConnInfOpt->keyword)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -542,7 +543,7 @@ SessionParametersMap SessionHandle::connectionDefaultParameters()
|
||||
|
||||
SessionParametersMap SessionHandle::connectionParameters() const
|
||||
{
|
||||
if (! isConnected())
|
||||
if (!isConnected())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace
|
||||
{
|
||||
std::string connectionString;
|
||||
|
||||
for (std::map<std::string, std::string>::const_iterator citr = anOptionsMap.begin(); citr != anOptionsMap.end(); ++citr)
|
||||
for (auto citr = anOptionsMap.begin(); citr != anOptionsMap.end(); ++citr)
|
||||
{
|
||||
connectionString.append(citr->first);
|
||||
connectionString.append("=");
|
||||
@@ -57,7 +57,8 @@ namespace PostgreSQL {
|
||||
|
||||
|
||||
SessionImpl::SessionImpl(const std::string& aConnectionString, std::size_t aLoginTimeout):
|
||||
Poco::Data::AbstractSessionImpl<SessionImpl>(aConnectionString, aLoginTimeout)
|
||||
Poco::Data::AbstractSessionImpl<SessionImpl>(aConnectionString, aLoginTimeout),
|
||||
_connectorName("postgresql")
|
||||
{
|
||||
setProperty("handle", static_cast<SessionHandle*>(&_sessionHandle));
|
||||
setConnectionTimeout(CONNECTION_TIMEOUT_DEFAULT);
|
||||
@@ -92,7 +93,7 @@ void SessionImpl::open(const std::string& aConnectionString)
|
||||
throw ConnectionException("Session already connected");
|
||||
}
|
||||
|
||||
if (! aConnectionString.empty())
|
||||
if (!aConnectionString.empty())
|
||||
{
|
||||
setConnectionString(aConnectionString);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ namespace
|
||||
Poco::RegularExpression::Match match = { 0 , 0 }; // Match is a struct, not a class :-(
|
||||
|
||||
std::size_t startingPosition = 0;
|
||||
|
||||
while (match.offset != std::string::npos)
|
||||
{
|
||||
try
|
||||
@@ -110,7 +109,7 @@ StatementExecutor::State StatementExecutor::state() const
|
||||
|
||||
void StatementExecutor::prepare(const std::string& aSQLStatement)
|
||||
{
|
||||
if (! _sessionHandle.isConnected()) throw NotConnectedException();
|
||||
if (!_sessionHandle.isConnected()) throw NotConnectedException();
|
||||
if (_state >= STMT_COMPILED) return;
|
||||
|
||||
// clear out the metadata. One way or another it is now obsolete.
|
||||
@@ -160,7 +159,7 @@ void StatementExecutor::prepare(const std::string& aSQLStatement)
|
||||
|
||||
{
|
||||
PQResultClear resultClearer(ptrPGResult);
|
||||
if (! ptrPGResult || PQresultStatus(ptrPGResult) != PGRES_COMMAND_OK)
|
||||
if (!ptrPGResult || PQresultStatus(ptrPGResult) != PGRES_COMMAND_OK)
|
||||
{
|
||||
throw StatementException(std::string("postgresql_stmt_describe error: ") +
|
||||
PQresultErrorMessage (ptrPGResult) + " " + aSQLStatement);
|
||||
@@ -186,7 +185,7 @@ void StatementExecutor::prepare(const std::string& aSQLStatement)
|
||||
|
||||
void StatementExecutor::bindParams(const InputParameterVector& anInputParameterVector)
|
||||
{
|
||||
if (! _sessionHandle.isConnected()) throw NotConnectedException();
|
||||
if (!_sessionHandle.isConnected()) throw NotConnectedException();
|
||||
|
||||
if (_state < STMT_COMPILED) throw StatementException("Statement is not compiled yet");
|
||||
|
||||
@@ -203,7 +202,7 @@ void StatementExecutor::bindParams(const InputParameterVector& anInputParameterV
|
||||
|
||||
void StatementExecutor::execute()
|
||||
{
|
||||
if (! _sessionHandle.isConnected()) throw NotConnectedException();
|
||||
if (!_sessionHandle.isConnected()) throw NotConnectedException();
|
||||
|
||||
if (_state < STMT_COMPILED) throw StatementException("Statement is not compiled yet");
|
||||
|
||||
@@ -225,8 +224,8 @@ void StatementExecutor::execute()
|
||||
std::vector<int> parameterLengthVector;
|
||||
std::vector<int> parameterFormatVector;
|
||||
|
||||
InputParameterVector::const_iterator cItr = _inputParameterVector.begin();
|
||||
InputParameterVector::const_iterator cItrEnd = _inputParameterVector.end();
|
||||
InputParameterVector::const_iterator cItr = _inputParameterVector.begin();
|
||||
InputParameterVector::const_iterator cItrEnd = _inputParameterVector.end();
|
||||
|
||||
for (; cItr != cItrEnd; ++cItr)
|
||||
{
|
||||
@@ -315,7 +314,7 @@ void StatementExecutor::execute()
|
||||
|
||||
bool StatementExecutor::fetch()
|
||||
{
|
||||
if (! _sessionHandle.isConnected())
|
||||
if (!_sessionHandle.isConnected())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
5
vendor/POCO/Data/PostgreSQL/src/Utility.cpp
vendored
5
vendor/POCO/Data/PostgreSQL/src/Utility.cpp
vendored
@@ -27,13 +27,9 @@ namespace PostgreSQL {
|
||||
std::string Utility::serverInfo(SessionHandle* aHandlePtr)
|
||||
{
|
||||
std::string srvrInfo = "Process ID: ";
|
||||
|
||||
srvrInfo.append(Poco::NumberFormatter::format(aHandlePtr->serverProcessID()));
|
||||
|
||||
srvrInfo.append(" Protocol Version: ");
|
||||
|
||||
srvrInfo.append(Poco::NumberFormatter::format(aHandlePtr->protocoVersion()));
|
||||
|
||||
return srvrInfo;
|
||||
}
|
||||
|
||||
@@ -61,7 +57,6 @@ std::string Utility::hostInfo(SessionHandle* aHandlePtr)
|
||||
SessionParametersMap parametersMap = aHandlePtr->connectionParameters();
|
||||
|
||||
SessionParametersMap::const_iterator cItr = parametersMap.find("host");
|
||||
|
||||
if (parametersMap.end() == cItr)
|
||||
{
|
||||
return std::string();
|
||||
|
||||
@@ -37,6 +37,9 @@ endif
|
||||
ifeq (0, $(shell test -e /opt/postgresql/lib$(LIB64SUFFIX); echo $$?))
|
||||
SYSLIBS += -L/opt/postgresql/lib$(LIB64SUFFIX)
|
||||
endif
|
||||
ifeq (0, $(shell test -e /usr/local/opt/libpq/lib; echo $$?))
|
||||
SYSLIBS += -L/usr/local/opt/libpq/lib$(LIB64SUFFIX)
|
||||
endif
|
||||
|
||||
# Note: linking order is important, do not change it.
|
||||
SYSLIBS += -lpq -lz -lpthread -ldl
|
||||
|
||||
@@ -690,6 +690,14 @@ void PostgreSQLTest::testDouble()
|
||||
}
|
||||
|
||||
|
||||
void PostgreSQLTest::testUUID()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
recreateUUIDsTable();
|
||||
_pExecutor->uuids();
|
||||
}
|
||||
|
||||
void PostgreSQLTest::testTuple()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
@@ -986,6 +994,15 @@ void PostgreSQLTest::recreateFloatsTable()
|
||||
}
|
||||
|
||||
|
||||
void PostgreSQLTest::recreateUUIDsTable()
|
||||
{
|
||||
dropTable("Strings");
|
||||
try { *_pSession << "CREATE TABLE Strings (str UUID)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateUUIDsTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateUUIDsTable()"); }
|
||||
}
|
||||
|
||||
|
||||
void PostgreSQLTest::recreateTuplesTable()
|
||||
{
|
||||
dropTable("Tuples");
|
||||
@@ -1110,6 +1127,7 @@ CppUnit::Test* PostgreSQLTest::suite()
|
||||
CppUnit_addTest(pSuite, PostgreSQLTest, testUnsignedInts);
|
||||
CppUnit_addTest(pSuite, PostgreSQLTest, testFloat);
|
||||
CppUnit_addTest(pSuite, PostgreSQLTest, testDouble);
|
||||
CppUnit_addTest(pSuite, PostgreSQLTest, testUUID);
|
||||
CppUnit_addTest(pSuite, PostgreSQLTest, testTuple);
|
||||
CppUnit_addTest(pSuite, PostgreSQLTest, testTupleVector);
|
||||
CppUnit_addTest(pSuite, PostgreSQLTest, testInternalExtraction);
|
||||
|
||||
@@ -82,6 +82,7 @@ public:
|
||||
void testUnsignedInts();
|
||||
void testFloat();
|
||||
void testDouble();
|
||||
void testUUID();
|
||||
|
||||
void testTuple();
|
||||
void testTupleVector();
|
||||
@@ -118,6 +119,7 @@ private:
|
||||
void recreateIntsTable();
|
||||
void recreateUnsignedIntsTable();
|
||||
void recreateFloatsTable();
|
||||
void recreateUUIDsTable();
|
||||
void recreateTuplesTable();
|
||||
void recreateVectorsTable();
|
||||
void recreateNullableIntTable();
|
||||
|
||||
@@ -712,6 +712,29 @@ void SQLExecutor::floats()
|
||||
}
|
||||
|
||||
|
||||
void SQLExecutor::uuids()
|
||||
{
|
||||
std::string funct = "uuids()";
|
||||
Poco::UUID data("264a1c6f-7af5-43a5-a593-377aff3d2d7d");
|
||||
Poco::UUID ret;
|
||||
|
||||
try { *_pSession << "INSERT INTO Strings VALUES ($1)", 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); }
|
||||
assertTrue (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); }
|
||||
assertTrue (ret == data);
|
||||
}
|
||||
|
||||
|
||||
void SQLExecutor::doubles()
|
||||
{
|
||||
std::string funct = "floats()";
|
||||
@@ -1611,7 +1634,7 @@ void SQLExecutor::blobStmt()
|
||||
std::string lastName("lastname");
|
||||
std::string firstName("firstname");
|
||||
std::string address("Address");
|
||||
unsigned char BLOBData[ 10 ] = { 0,1,2,3,4,5,6,7,14,15 };
|
||||
unsigned char BLOBData[ 10 ] = { 0,1,2,3,4,5,6,7,14,15 };
|
||||
Poco::Data::BLOB blob(BLOBData, 10);
|
||||
|
||||
int count = 0;
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
PB_IMMEDIATE,
|
||||
PB_AT_EXEC
|
||||
};
|
||||
|
||||
|
||||
enum DataExtraction
|
||||
{
|
||||
DE_MANUAL,
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
|
||||
void oidPostgreSQLTest(std::string host, std::string user, std::string pwd, std::string db, std::string port, const char* tableCreateString, const Oid anOIDArray[]);
|
||||
/// This function verifies the PostgreSQL Column type OIDs are consistent between releases
|
||||
|
||||
|
||||
void barebonePostgreSQLTest(std::string host, std::string user, std::string pwd, std::string db, std::string port, const char* tableCreateString);
|
||||
/// This function uses "bare bone" API calls (i.e. calls are not
|
||||
/// "wrapped" in PocoSQL framework structures).
|
||||
@@ -89,6 +89,7 @@ public:
|
||||
void unsignedInts();
|
||||
void floats();
|
||||
void doubles();
|
||||
void uuids();
|
||||
void tuples();
|
||||
void tupleVector();
|
||||
|
||||
|
||||
4
vendor/POCO/Data/SQLite/CMakeLists.txt
vendored
4
vendor/POCO/Data/SQLite/CMakeLists.txt
vendored
@@ -60,10 +60,6 @@ else()
|
||||
SQLITE_OMIT_COMPLETE
|
||||
SQLITE_OMIT_TCL_VARIABLE
|
||||
SQLITE_OMIT_DEPRECATED
|
||||
SQLITE_ENABLE_RTREE
|
||||
SQLITE_ENABLE_JSON1
|
||||
SQLITE_ENABLE_SESSION
|
||||
SQLITE_ENABLE_MATH_FUNCTIONS
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -106,6 +106,9 @@ public:
|
||||
void bind(std::size_t pos, const DateTime& val, Direction dir);
|
||||
/// Binds a DateTime.
|
||||
|
||||
void bind(std::size_t pos, const UUID& val, Direction dir);
|
||||
/// Binds a UUID.
|
||||
|
||||
void bind(std::size_t pos, const NullData& val, Direction dir);
|
||||
/// Binds a null.
|
||||
|
||||
|
||||
@@ -116,6 +116,9 @@ public:
|
||||
bool extract(std::size_t pos, Poco::DateTime& val);
|
||||
/// Extracts a DateTime.
|
||||
|
||||
bool extract(std::size_t pos, Poco::UUID& val);
|
||||
/// Extracts a Time.
|
||||
|
||||
bool extract(std::size_t pos, Poco::Any& val);
|
||||
/// Extracts an Any.
|
||||
|
||||
@@ -264,6 +267,13 @@ private:
|
||||
val = dt;
|
||||
break;
|
||||
}
|
||||
case MetaColumn::FDT_UUID:
|
||||
{
|
||||
UUID uuid;
|
||||
ret = extract(pos, uuid);
|
||||
val = uuid;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw Poco::Data::UnknownTypeException("Unknown type during extraction");
|
||||
}
|
||||
|
||||
7
vendor/POCO/Data/SQLite/src/Binder.cpp
vendored
7
vendor/POCO/Data/SQLite/src/Binder.cpp
vendored
@@ -111,6 +111,13 @@ void Binder::bind(std::size_t pos, const DateTime& val, Direction dir)
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const UUID& val, Direction dir)
|
||||
{
|
||||
std::string str(val.toString());
|
||||
bind(pos, str, dir);
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const NullData&, Direction)
|
||||
{
|
||||
sqlite3_bind_null(_pStmt, static_cast<int>(pos));
|
||||
|
||||
10
vendor/POCO/Data/SQLite/src/Extractor.cpp
vendored
10
vendor/POCO/Data/SQLite/src/Extractor.cpp
vendored
@@ -208,6 +208,16 @@ bool Extractor::extract(std::size_t pos, DateTime& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, UUID& val)
|
||||
{
|
||||
if (isNull(pos)) return false;
|
||||
std::string str;
|
||||
extract(pos, str);
|
||||
val.parse(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Any& val)
|
||||
{
|
||||
return extractImpl(pos, val);
|
||||
|
||||
6
vendor/POCO/Data/SQLite/src/Utility.cpp
vendored
6
vendor/POCO/Data/SQLite/src/Utility.cpp
vendored
@@ -134,6 +134,8 @@ Utility::Utility()
|
||||
_types.insert(TypeMap::value_type("TIME", MetaColumn::FDT_TIME));
|
||||
_types.insert(TypeMap::value_type("DATETIME", MetaColumn::FDT_TIMESTAMP));
|
||||
_types.insert(TypeMap::value_type("TIMESTAMP", MetaColumn::FDT_TIMESTAMP));
|
||||
_types.insert(TypeMap::value_type("UUID", MetaColumn::FDT_UUID));
|
||||
_types.insert(TypeMap::value_type("GUID", MetaColumn::FDT_UUID));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,7 +250,9 @@ bool Utility::fileToMemory(sqlite3* pInMemory, const std::string& fileName)
|
||||
sqlite3* pFile;
|
||||
sqlite3_backup* pBackup;
|
||||
|
||||
rc = sqlite3_open_v2(fileName.c_str(), &pFile, SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, NULL);
|
||||
// Note: SQLITE_OPEN_READWRITE is required to correctly handle an existing hot journal.
|
||||
// See #3135
|
||||
rc = sqlite3_open_v2(fileName.c_str(), &pFile, SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI, NULL);
|
||||
if(rc == SQLITE_OK )
|
||||
{
|
||||
pBackup = sqlite3_backup_init(pInMemory, "main", pFile, "main");
|
||||
|
||||
7247
vendor/POCO/Data/SQLite/src/sqlite3.c
vendored
7247
vendor/POCO/Data/SQLite/src/sqlite3.c
vendored
File diff suppressed because it is too large
Load Diff
133
vendor/POCO/Data/SQLite/src/sqlite3.h
vendored
133
vendor/POCO/Data/SQLite/src/sqlite3.h
vendored
@@ -123,9 +123,9 @@ extern "C" {
|
||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.35.3"
|
||||
#define SQLITE_VERSION_NUMBER 3035003
|
||||
#define SQLITE_SOURCE_ID "2021-03-26 12:12:52 4c5e6c200adc8afe0814936c67a971efc516d1bd739cb620235592f18f40be2a"
|
||||
#define SQLITE_VERSION "3.36.0"
|
||||
#define SQLITE_VERSION_NUMBER 3036000
|
||||
#define SQLITE_SOURCE_ID "2021-06-18 18:36:39 5c9a6c06871cb9fe42814af9c039eb6da5427a6ec28f187af7ebfb62eafa66e5"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
@@ -1128,6 +1128,23 @@ struct sqlite3_io_methods {
|
||||
** file to the database file, but before the *-shm file is updated to
|
||||
** record the fact that the pages have been checkpointed.
|
||||
** </ul>
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_EXTERNAL_READER]]
|
||||
** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect
|
||||
** whether or not there is a database client in another process with a wal-mode
|
||||
** transaction open on the database or not. It is only available on unix.The
|
||||
** (void*) argument passed with this file-control should be a pointer to a
|
||||
** value of type (int). The integer value is set to 1 if the database is a wal
|
||||
** mode database and there exists at least one client in another process that
|
||||
** currently has an SQL transaction open on the database. It is set to 0 if
|
||||
** the database is not a wal-mode db, or if there is no such connection in any
|
||||
** other process. This opcode cannot be used to detect transactions opened
|
||||
** by clients within the current process, only within other processes.
|
||||
** </ul>
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_CKSM_FILE]]
|
||||
** Used by the cksmvfs VFS module only.
|
||||
** </ul>
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
|
||||
@@ -1167,6 +1184,8 @@ struct sqlite3_io_methods {
|
||||
#define SQLITE_FCNTL_CKPT_DONE 37
|
||||
#define SQLITE_FCNTL_RESERVE_BYTES 38
|
||||
#define SQLITE_FCNTL_CKPT_START 39
|
||||
#define SQLITE_FCNTL_EXTERNAL_READER 40
|
||||
#define SQLITE_FCNTL_CKSM_FILE 41
|
||||
|
||||
/* deprecated names */
|
||||
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
||||
@@ -4179,6 +4198,15 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
|
||||
** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
|
||||
** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
|
||||
** sqlite3_stmt_readonly() returns false for those commands.
|
||||
**
|
||||
** ^This routine returns false if there is any possibility that the
|
||||
** statement might change the database file. ^A false return does
|
||||
** not guarantee that the statement will change the database file.
|
||||
** ^For example, an UPDATE statement might have a WHERE clause that
|
||||
** makes it a no-op, but the sqlite3_stmt_readonly() result would still
|
||||
** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
|
||||
** read-only no-op if the table already exists, but
|
||||
** sqlite3_stmt_readonly() still returns false for such a statement.
|
||||
*/
|
||||
SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
|
||||
|
||||
@@ -4348,18 +4376,22 @@ typedef struct sqlite3_context sqlite3_context;
|
||||
** contain embedded NULs. The result of expressions involving strings
|
||||
** with embedded NULs is undefined.
|
||||
**
|
||||
** ^The fifth argument to the BLOB and string binding interfaces
|
||||
** is a destructor used to dispose of the BLOB or
|
||||
** string after SQLite has finished with it. ^The destructor is called
|
||||
** to dispose of the BLOB or string even if the call to the bind API fails,
|
||||
** except the destructor is not called if the third parameter is a NULL
|
||||
** pointer or the fourth parameter is negative.
|
||||
** ^If the fifth argument is
|
||||
** the special value [SQLITE_STATIC], then SQLite assumes that the
|
||||
** information is in static, unmanaged space and does not need to be freed.
|
||||
** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
|
||||
** SQLite makes its own private copy of the data immediately, before
|
||||
** the sqlite3_bind_*() routine returns.
|
||||
** ^The fifth argument to the BLOB and string binding interfaces controls
|
||||
** or indicates the lifetime of the object referenced by the third parameter.
|
||||
** These three options exist:
|
||||
** ^ (1) A destructor to dispose of the BLOB or string after SQLite has finished
|
||||
** with it may be passed. ^It is called to dispose of the BLOB or string even
|
||||
** if the call to the bind API fails, except the destructor is not called if
|
||||
** the third parameter is a NULL pointer or the fourth parameter is negative.
|
||||
** ^ (2) The special constant, [SQLITE_STATIC], may be passsed to indicate that
|
||||
** the application remains responsible for disposing of the object. ^In this
|
||||
** case, the object and the provided pointer to it must remain valid until
|
||||
** either the prepared statement is finalized or the same SQL parameter is
|
||||
** bound to something else, whichever occurs sooner.
|
||||
** ^ (3) The constant, [SQLITE_TRANSIENT], may be passed to indicate that the
|
||||
** object is to be copied prior to the return from sqlite3_bind_*(). ^The
|
||||
** object and pointer to it must remain valid until then. ^SQLite will then
|
||||
** manage the lifetime of its private copy.
|
||||
**
|
||||
** ^The sixth argument to sqlite3_bind_text64() must be one of
|
||||
** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
|
||||
@@ -5101,7 +5133,6 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
|
||||
** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions,
|
||||
** index expressions, or the WHERE clause of partial indexes.
|
||||
**
|
||||
** <span style="background-color:#ffff90;">
|
||||
** For best security, the [SQLITE_DIRECTONLY] flag is recommended for
|
||||
** all application-defined SQL functions that do not need to be
|
||||
** used inside of triggers, view, CHECK constraints, or other elements of
|
||||
@@ -5111,7 +5142,6 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
|
||||
** a database file to include invocations of the function with parameters
|
||||
** chosen by the attacker, which the application will then execute when
|
||||
** the database file is opened and read.
|
||||
** </span>
|
||||
**
|
||||
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
|
||||
** function can gain access to this pointer using [sqlite3_user_data()].)^
|
||||
@@ -7779,7 +7809,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
|
||||
#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
|
||||
#define SQLITE_TESTCTRL_SEEK_COUNT 30
|
||||
#define SQLITE_TESTCTRL_TRACEFLAGS 31
|
||||
#define SQLITE_TESTCTRL_LAST 31 /* Largest TESTCTRL */
|
||||
#define SQLITE_TESTCTRL_TUNE 32
|
||||
#define SQLITE_TESTCTRL_LAST 32 /* Largest TESTCTRL */
|
||||
|
||||
/*
|
||||
** CAPI3REF: SQL Keyword Checking
|
||||
@@ -9531,6 +9562,15 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
|
||||
** triggers; or 2 for changes resulting from triggers called by top-level
|
||||
** triggers; and so forth.
|
||||
**
|
||||
** When the [sqlite3_blob_write()] API is used to update a blob column,
|
||||
** the pre-update hook is invoked with SQLITE_DELETE. This is because the
|
||||
** in this case the new values are not available. In this case, when a
|
||||
** callback made with op==SQLITE_DELETE is actuall a write using the
|
||||
** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns
|
||||
** the index of the column being written. In other cases, where the
|
||||
** pre-update hook is being invoked for some other reason, including a
|
||||
** regular DELETE, sqlite3_preupdate_blobwrite() returns -1.
|
||||
**
|
||||
** See also: [sqlite3_update_hook()]
|
||||
*/
|
||||
#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
|
||||
@@ -9551,6 +9591,7 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
|
||||
SQLITE_API int sqlite3_preupdate_count(sqlite3 *);
|
||||
SQLITE_API int sqlite3_preupdate_depth(sqlite3 *);
|
||||
SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
|
||||
SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -9789,8 +9830,8 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c
|
||||
** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
|
||||
** allocation error occurs.
|
||||
**
|
||||
** This interface is only available if SQLite is compiled with the
|
||||
** [SQLITE_ENABLE_DESERIALIZE] option.
|
||||
** This interface is omitted if SQLite is compiled with the
|
||||
** [SQLITE_OMIT_DESERIALIZE] option.
|
||||
*/
|
||||
SQLITE_API unsigned char *sqlite3_serialize(
|
||||
sqlite3 *db, /* The database connection */
|
||||
@@ -9841,8 +9882,8 @@ SQLITE_API unsigned char *sqlite3_serialize(
|
||||
** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
|
||||
** [sqlite3_free()] is invoked on argument P prior to returning.
|
||||
**
|
||||
** This interface is only available if SQLite is compiled with the
|
||||
** [SQLITE_ENABLE_DESERIALIZE] option.
|
||||
** This interface is omitted if SQLite is compiled with the
|
||||
** [SQLITE_OMIT_DESERIALIZE] option.
|
||||
*/
|
||||
SQLITE_API int sqlite3_deserialize(
|
||||
sqlite3 *db, /* The database connection */
|
||||
@@ -10091,6 +10132,38 @@ SQLITE_API int sqlite3session_create(
|
||||
*/
|
||||
SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
|
||||
|
||||
/*
|
||||
** CAPIREF: Conigure a Session Object
|
||||
** METHOD: sqlite3_session
|
||||
**
|
||||
** This method is used to configure a session object after it has been
|
||||
** created. At present the only valid value for the second parameter is
|
||||
** [SQLITE_SESSION_OBJCONFIG_SIZE].
|
||||
**
|
||||
** Arguments for sqlite3session_object_config()
|
||||
**
|
||||
** The following values may passed as the the 4th parameter to
|
||||
** sqlite3session_object_config().
|
||||
**
|
||||
** <dt>SQLITE_SESSION_OBJCONFIG_SIZE <dd>
|
||||
** This option is used to set, clear or query the flag that enables
|
||||
** the [sqlite3session_changeset_size()] API. Because it imposes some
|
||||
** computational overhead, this API is disabled by default. Argument
|
||||
** pArg must point to a value of type (int). If the value is initially
|
||||
** 0, then the sqlite3session_changeset_size() API is disabled. If it
|
||||
** is greater than 0, then the same API is enabled. Or, if the initial
|
||||
** value is less than zero, no change is made. In all cases the (int)
|
||||
** variable is set to 1 if the sqlite3session_changeset_size() API is
|
||||
** enabled following the current call, or 0 otherwise.
|
||||
**
|
||||
** It is an error (SQLITE_MISUSE) to attempt to modify this setting after
|
||||
** the first table has been attached to the session object.
|
||||
*/
|
||||
SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
|
||||
|
||||
/*
|
||||
*/
|
||||
#define SQLITE_SESSION_OBJCONFIG_SIZE 1
|
||||
|
||||
/*
|
||||
** CAPI3REF: Enable Or Disable A Session Object
|
||||
@@ -10335,6 +10408,22 @@ SQLITE_API int sqlite3session_changeset(
|
||||
void **ppChangeset /* OUT: Buffer containing changeset */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Return An Upper-limit For The Size Of The Changeset
|
||||
** METHOD: sqlite3_session
|
||||
**
|
||||
** By default, this function always returns 0. For it to return
|
||||
** a useful result, the sqlite3_session object must have been configured
|
||||
** to enable this API using sqlite3session_object_config() with the
|
||||
** SQLITE_SESSION_OBJCONFIG_SIZE verb.
|
||||
**
|
||||
** When enabled, this function returns an upper limit, in bytes, for the size
|
||||
** of the changeset that might be produced if sqlite3session_changeset() were
|
||||
** called. The final changeset size might be equal to or smaller than the
|
||||
** size in bytes returned by this function.
|
||||
*/
|
||||
SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Load The Difference Between Tables Into A Session
|
||||
** METHOD: sqlite3_session
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "Poco/Data/SQLite/SQLiteException.h"
|
||||
#include "Poco/Tuple.h"
|
||||
#include "Poco/Any.h"
|
||||
#include "Poco/UUIDGenerator.h"
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include "Poco/DynamicAny.h"
|
||||
#include "Poco/DateTime.h"
|
||||
@@ -1916,6 +1917,21 @@ void SQLiteTest::testDateTime()
|
||||
}
|
||||
|
||||
|
||||
void SQLiteTest::testUUID()
|
||||
{
|
||||
Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
|
||||
tmp << "DROP TABLE IF EXISTS Ids", now;
|
||||
tmp << "CREATE TABLE Ids (id0 UUID)", now;
|
||||
|
||||
Poco::UUID uuid = Poco::UUIDGenerator::defaultGenerator().createRandom();
|
||||
tmp << "INSERT INTO Ids VALUES (?)", use(uuid), now;
|
||||
|
||||
Poco::UUID ruuid;
|
||||
tmp << "SELECT * FROM Ids", into(ruuid), now;
|
||||
assertTrue (ruuid == uuid);
|
||||
}
|
||||
|
||||
|
||||
void SQLiteTest::testInternalExtraction()
|
||||
{
|
||||
Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
|
||||
@@ -3453,6 +3469,7 @@ CppUnit::Test* SQLiteTest::suite()
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testTuple1);
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testTupleVector1);
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testDateTime);
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testUUID);
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testInternalExtraction);
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testPrimaryKeyConstraint);
|
||||
CppUnit_addTest(pSuite, SQLiteTest, testNullable);
|
||||
|
||||
@@ -100,6 +100,8 @@ public:
|
||||
|
||||
void testDateTime();
|
||||
|
||||
void testUUID();
|
||||
|
||||
void testInternalExtraction();
|
||||
void testPrimaryKeyConstraint();
|
||||
void testNullable();
|
||||
|
||||
175
vendor/POCO/Data/doc/00200-DataUserManual.page
vendored
175
vendor/POCO/Data/doc/00200-DataUserManual.page
vendored
@@ -5,8 +5,9 @@ POCO Data Library
|
||||
|
||||
POCO Data is POCO's database abstraction layer which allows users to
|
||||
easily send/retrieve data to/from various databases. Currently supported
|
||||
database connectors are SQLite, MySQL and ODBC. Framework is opened
|
||||
for extension, so additional native connectors (Oracle, PostgreSQL, ...)
|
||||
database connectors are SQLite, MySQL/MariaDB, PostgreSQL and ODBC (which
|
||||
covers SQL Server and other databases).
|
||||
Framework is opened for extension, so additional native connectors (Oracle, Db2, ...)
|
||||
can be added. The intent behind the Poco::Data framework is to produce the
|
||||
integration between C++ and relational databses in a simple and natural way.
|
||||
|
||||
@@ -16,54 +17,54 @@ The following complete example shows how to use POCO Data:
|
||||
#include "Poco/Data/SQLite/Connector.h"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
using Poco::Data::Session;
|
||||
using Poco::Data::Statement;
|
||||
|
||||
|
||||
struct Person
|
||||
{
|
||||
std::string name;
|
||||
std::string address;
|
||||
int age;
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// register SQLite connector
|
||||
Poco::Data::SQLite::Connector::registerConnector();
|
||||
|
||||
|
||||
// create a session
|
||||
Session session("SQLite", "sample.db");
|
||||
|
||||
|
||||
// drop sample table, if it exists
|
||||
session << "DROP TABLE IF EXISTS Person", now;
|
||||
|
||||
|
||||
// (re)create table
|
||||
session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now;
|
||||
|
||||
|
||||
// insert some rows
|
||||
Person person =
|
||||
Person person =
|
||||
{
|
||||
"Bart Simpson",
|
||||
"Springfield",
|
||||
12
|
||||
};
|
||||
|
||||
|
||||
Statement insert(session);
|
||||
insert << "INSERT INTO Person VALUES(?, ?, ?)",
|
||||
use(person.name),
|
||||
use(person.address),
|
||||
use(person.age);
|
||||
|
||||
|
||||
insert.execute();
|
||||
|
||||
|
||||
person.name = "Lisa Simpson";
|
||||
person.address = "Springfield";
|
||||
person.age = 10;
|
||||
|
||||
|
||||
insert.execute();
|
||||
|
||||
|
||||
// a simple query
|
||||
Statement select(session);
|
||||
select << "SELECT Name, Address, Age FROM Person",
|
||||
@@ -71,24 +72,24 @@ The following complete example shows how to use POCO Data:
|
||||
into(person.address),
|
||||
into(person.age),
|
||||
range(0, 1); // iterate over result set one row at a time
|
||||
|
||||
|
||||
while (!select.done())
|
||||
{
|
||||
select.execute();
|
||||
std::cout << person.name << " " << person.address << " " << person.age << std::endl;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
----
|
||||
|
||||
The above example is pretty much self explanatory.
|
||||
The above example is pretty much self explanatory.
|
||||
|
||||
The <[using namespace Poco::Data ]> is for convenience only but highly
|
||||
recommended for good readable code. While <[ses << "SELECT COUNT(*)
|
||||
FROM PERSON", Poco::Data::Keywords::into(count), Poco::Data::Keywords::now;]>
|
||||
FROM PERSON", Poco::Data::Keywords::into(count), Poco::Data::Keywords::now;]>
|
||||
is valid, the aesthetic aspect of the code is improved by eliminating the need
|
||||
for full namespace qualification; this document uses convention introduced in
|
||||
for full namespace qualification; this document uses convention introduced in
|
||||
the example above.
|
||||
|
||||
The remainder of this tutorial is split up into the following parts:
|
||||
@@ -117,20 +118,23 @@ parameter contains the connection string.
|
||||
|
||||
In the case of SQLite, the path of the database file is sufficient as connection string.
|
||||
|
||||
For ODBC, the connection string may be a simple "DSN=MyDSNName" when a DSN is configured or
|
||||
a complete ODBC driver-specific connection string defining all the necessary connection parameters
|
||||
(for details, consult your ODBC driver documentation).
|
||||
For ODBC, the connection string may be a simple "DSN=MyDSNName" when a DSN is configured or
|
||||
a complete ODBC driver-specific connection string defining all the necessary connection parameters
|
||||
(for details, consult your ODBC driver documentation).
|
||||
|
||||
For MySQL, the connection string is a semicolon-delimited list of name-value pairs
|
||||
specifying various parameters like host, port, user, password, database, compression and
|
||||
automatic reconnect. Example: <["host=localhost;port=3306;db=mydb;user=alice;password=s3cr3t;compress=true;auto-reconnect=true"]>
|
||||
For MySQL, the connection string is a semicolon-delimited list of name-value pairs
|
||||
specifying various parameters like host, port, user, password, database, compression and
|
||||
automatic reconnect. Example:
|
||||
|
||||
"host=localhost;port=3306;db=mydb;user=alice;password=s3cr3t;compress=true;auto-reconnect=true"
|
||||
----
|
||||
|
||||
|
||||
!!!Inserting and Retrieving Data
|
||||
|
||||
!!Single Data Sets
|
||||
|
||||
Inserting data works by <[using]> the content of other variables.
|
||||
Inserting data works by <[using]> the content of other variables.
|
||||
Assume we have a table that stores only forenames:
|
||||
|
||||
ForeName (Name VARCHAR(30))
|
||||
@@ -139,17 +143,17 @@ Assume we have a table that stores only forenames:
|
||||
If we want to insert one single forename we could simply write:
|
||||
|
||||
std::string aName("Peter");
|
||||
session << "INSERT INTO FORENAME VALUES(" << aName << ")", now;
|
||||
session << "INSERT INTO FORENAME VALUES('" << aName << "')", now;
|
||||
----
|
||||
|
||||
However, a better solution is to use <*placeholders*> and connect each
|
||||
placeholder via a <[use]> expression with a variable that will provide
|
||||
placeholder via a `use` expression with a variable that will provide
|
||||
the value during execution. Placeholders, depending on your database are
|
||||
recognized by having either a colon(<[:]>) in front of the name or
|
||||
simply by a question mark (<[?]>) as a placeholder. While having the
|
||||
recognized by having either a colon (`:`) in front of the name or
|
||||
simply by a question mark (`?`) as a placeholder. While having the
|
||||
placeholders marked with a colon followed by a human-readable name is
|
||||
very convenient due to readability, not all SQL dialects support this and
|
||||
universally accepted standard placeholder is (<[?]>). Consult your database
|
||||
universally accepted standard placeholder is `?`. Consult your database
|
||||
SQL documentation to determine the valid placeholder syntax.
|
||||
|
||||
Rewriting the above code now simply gives:
|
||||
@@ -159,8 +163,8 @@ Rewriting the above code now simply gives:
|
||||
----
|
||||
|
||||
In this example the <[use]> expression matches the placeholder with the
|
||||
<[Peter]> value. Note that apart from the nicer syntax, the real benefits of
|
||||
placeholders -- which are performance and protection against SQL injection
|
||||
<[Peter]> value. Note that apart from the nicer syntax, the real benefits of
|
||||
placeholders -- which are performance and protection against SQL injection
|
||||
attacks -- don't show here. Check the <[Statements]> section to find out more.
|
||||
|
||||
Retrieving data from the Database works similar. The <[into]>
|
||||
@@ -172,14 +176,14 @@ database:
|
||||
ses << "SELECT NAME FROM FORENAME", into(aName), now;
|
||||
ses << "SELECT NAME FROM FORENAME", into(aName, 0, "default"), now;
|
||||
|
||||
You'll note the integer zero argument in the second into() call. The reason for
|
||||
that is that Poco::Data supports multiple result sets for those databases/drivers
|
||||
that have such capbility and we have to indicate the resultset we are referring to.
|
||||
Attempting to create sufficient overloads of <[into()]> creates more trouble than
|
||||
what it's worth and null values can effectively be dealt with through use of either
|
||||
Poco::Nullable wrapper (see Handling Null Entries later in this document) or
|
||||
Poco::Dynamic::Var, which will be set as empty for null values when used as query
|
||||
output target.
|
||||
You'll note the integer zero argument in the second into() call. The reason for
|
||||
that is that Poco::Data supports multiple result sets for those databases/drivers
|
||||
that have such capbility and we have to indicate the resultset we are referring to.
|
||||
Attempting to create sufficient overloads of <[into()]> creates more trouble than
|
||||
what it's worth and null values can effectively be dealt with through use of either
|
||||
Poco::Nullable wrapper (see Handling Null Entries later in this document) or
|
||||
Poco::Dynamic::Var, which will be set as empty for null values when used as query
|
||||
output target.
|
||||
----
|
||||
|
||||
It is also possible to combine into and use expressions:
|
||||
@@ -224,18 +228,18 @@ To accomodate for NULL, use the Poco::Nullable template:
|
||||
if (!lastName.isNull()) { ... }
|
||||
----
|
||||
|
||||
The above used Poco::Nullable is a lightweight template class, wrapping any type
|
||||
The above used Poco::Nullable is a lightweight template class, wrapping any type
|
||||
for the purpose of allowing it to have null value.
|
||||
|
||||
If the returned value was null, age.isNull() will return true. Whether empty
|
||||
string is null or not is more of a philosophical question (a topic for discussion
|
||||
in some other time and place); for the purpose of this document, suffice it to say
|
||||
that different databases handle it differently and Poco::Data provides a way to
|
||||
in some other time and place); for the purpose of this document, suffice it to say
|
||||
that different databases handle it differently and Poco::Data provides a way to
|
||||
tweak it to user's needs through folowing <[Session]> features:
|
||||
|
||||
*emptyStringIsNull
|
||||
*forceEmptyString
|
||||
|
||||
|
||||
So, if your database does not treat empty strings as null but you want Poco::Data
|
||||
to emulate such behavior, modify the session like this:
|
||||
|
||||
@@ -259,7 +263,7 @@ set it belongs to:
|
||||
std::vector<Person> people;
|
||||
Person pHomer, pLisa;
|
||||
int aHomer(42), aLisa(10), aBart(0);
|
||||
|
||||
|
||||
session << "SELECT * FROM Person WHERE Age = ?; "
|
||||
"SELECT Age FROM Person WHERE FirstName = 'Bart'; "
|
||||
"SELECT * FROM Person WHERE Age = ?",
|
||||
@@ -293,7 +297,7 @@ More on statements and manipulators in the chapters that follow.
|
||||
Most of the modern database systems support stored procedures and/or
|
||||
functions. Does Poco::Data provide any support there? You bet.
|
||||
While the specifics on what exactly is possible (e.g. the data types
|
||||
passed in and out, automatic or manual data binding, binding direction,
|
||||
passed in and out, automatic or manual data binding, binding direction,
|
||||
etc.) is ultimately database dependent, POCO Data does it's
|
||||
best to provide reasonable access to such functionality through <[in]>,
|
||||
<[out]> and <[io]> binding functions. As their names imply, these
|
||||
@@ -306,7 +310,7 @@ here's an Oracle ODBC example:
|
||||
" temp NUMBER := param1; "
|
||||
" BEGIN param1 := param2; param2 := temp; RETURN(param1+param2); "
|
||||
" END storedFunction;" , now;
|
||||
|
||||
|
||||
int i = 1, j = 2, result = 0;
|
||||
session << "{? = call storedFunction(?, ?)}", out(result), io(i), io(j), now; // i = 2, j = 1, result = 3
|
||||
----
|
||||
@@ -322,10 +326,10 @@ Stored procedures are allowed to return data sets (a.k.a. cursors):
|
||||
" ret SYS_REFCURSOR; "
|
||||
"BEGIN "
|
||||
" OPEN ret FOR "
|
||||
" SELECT * FROM Person WHERE Age < ageLimit; "
|
||||
" SELECT * FROM Person WHERE Age < ageLimit; "
|
||||
" RETURN ret; "
|
||||
"END storedCursorFunction;" , now;
|
||||
|
||||
|
||||
session << "{call storedCursorFunction(?)}", in(age), into(people), now;
|
||||
----
|
||||
|
||||
@@ -387,8 +391,8 @@ Here's how we control when to actually execute the statement:
|
||||
----
|
||||
|
||||
By calling <[execute]> we asserted that our query was executed and that
|
||||
the value was inserted. The check to <[stmt.done()]> simply guarantees that the
|
||||
statement was fully completed.
|
||||
the value was inserted. The check to <[stmt.done()]> simply guarantees that the
|
||||
statement was fully completed.
|
||||
|
||||
|
||||
|
||||
@@ -479,7 +483,7 @@ return value is because, for asynchronous statements, <[execute()]>
|
||||
always returns zero. This makes sense, because it does not know the
|
||||
number of returned rows (remember, asynchronous <[execute()]> call
|
||||
returns <[immediately]> and does not wait for the completion of the
|
||||
execution).
|
||||
execution).
|
||||
|
||||
!A Word of Warning
|
||||
|
||||
@@ -513,7 +517,7 @@ later during execution. Thus, one should never pass temporaries to <[use()]>:
|
||||
----
|
||||
|
||||
It is possible to use <[bind()]> instead of <[use()]>. The <[bind()]> call will always create a
|
||||
copy of the supplied argument. Also, it is possible to execute a statement returning
|
||||
copy of the supplied argument. Also, it is possible to execute a statement returning
|
||||
data without supplying the storage and have the statement itself store the returned
|
||||
data for later retrieval through <[RecordSet]>. For details, see <[RecordSet]> chapter.
|
||||
|
||||
@@ -538,7 +542,7 @@ well-known source of many security problems in C and C++ code, do not
|
||||
worry. Poco::format() family of functions is <[safe]> (and, admittedly,
|
||||
slower than printf).
|
||||
|
||||
For cases where this type of formatting is used with queries containing
|
||||
For cases where this type of formatting is used with queries containing
|
||||
the percent sign, use double percent ("%%"):
|
||||
|
||||
Statement stmt = (ses << "SELECT * FROM %s WHERE Name LIKE 'Simp%%'", "Person");
|
||||
@@ -609,8 +613,8 @@ not!> be used in conjunction with <[out]> and <[io]> under any
|
||||
circumstances: <[std::vector<bool>]> . The details are beyond the scope
|
||||
of this manual. For those interested to learn more about it, there is an
|
||||
excellent explanation in S. Meyers book "Efective STL", Item 18 or Gotw
|
||||
#50, [[http://www.gotw.ca/gotw/050.htm When Is a Container Not a
|
||||
Container]] paragraph.
|
||||
#50, [[http://www.gotw.ca/gotw/050.htm When Is a Container Not a Container]]
|
||||
paragraph.
|
||||
|
||||
|
||||
!!!Tuples
|
||||
@@ -696,13 +700,13 @@ object until <[statement.done()]> returns true.
|
||||
For the next example, we assume that our system knows about 101 forenames:
|
||||
|
||||
std::vector<std::string> names;
|
||||
Statement stmt = (ses << "SELECT NAME FROM FORENAME", into(names), limit(50));
|
||||
Statement stmt = (ses << "SELECT NAME FROM FORENAME", into(names), limit(50));
|
||||
stmt.execute(); //names.size() == 50
|
||||
poco_assert (!stmt.done());
|
||||
stmt.execute(); //names.size() == 100
|
||||
poco_assert (!stmt.done());
|
||||
stmt.execute(); //names.size() == 101
|
||||
poco_assert (stmt.done());
|
||||
poco_assert (stmt.done());
|
||||
----
|
||||
|
||||
We previously stated that if no data is returned this is valid too. Thus, executing the following statement on an
|
||||
@@ -750,14 +754,14 @@ off.
|
||||
|
||||
The <[bulk]> keyword allows to boost performance for the connectors that
|
||||
support column-wise operation and arrays of values and/or parameters
|
||||
(e.g. ODBC).
|
||||
(e.g. ODBC).
|
||||
Here's how to signal bulk insertion to the statement:
|
||||
|
||||
std::vector<int> ints(100, 1);
|
||||
session << "INSERT INTO Test VALUES (?)", use(ints, bulk), now;
|
||||
----
|
||||
|
||||
The above code will execute a "one-shot" insertion into the target table.
|
||||
The above code will execute a "one-shot" insertion into the target table.
|
||||
|
||||
|
||||
Selection in bulk mode looks like this:
|
||||
@@ -771,8 +775,8 @@ size of data set we want to fetch, either explicitly as in the code
|
||||
above or implicitly, through size of the supplied container as in
|
||||
following example:
|
||||
|
||||
std::vector<int> ints(100, 1);
|
||||
session << "SELECT * FROM Test", into(ints, bulk), now;
|
||||
std::vector<int> ints(100, 1);
|
||||
session << "SELECT * FROM Test", into(ints, bulk), now;
|
||||
----
|
||||
|
||||
For statements that generate their ow internal extraction storage (see
|
||||
@@ -827,7 +831,7 @@ feature.
|
||||
!!! RecordSets, Iterators and Rows
|
||||
|
||||
In all the examples so far the programmer had to supply the storage for
|
||||
data to be inserted or retrieved from a database.
|
||||
data to be inserted or retrieved from a database.
|
||||
|
||||
It is usually desirable to avoid that and let the framework take care of
|
||||
it, something like this:
|
||||
@@ -840,16 +844,16 @@ No worries -- that's what the RecordSet class does:
|
||||
Statement select(session); // we need a Statement for later RecordSet creation
|
||||
select << "SELECT * FROM Person", now;
|
||||
|
||||
// create a RecordSet
|
||||
// create a RecordSet
|
||||
RecordSet rs(select);
|
||||
std::size_t cols = rs.columnCount();
|
||||
|
||||
// print all column names
|
||||
for (std::size_t col = 0; col < cols; ++col)
|
||||
std::cout << rs.columnName(col) << std::endl;
|
||||
|
||||
|
||||
// iterate over all rows and columns
|
||||
for (RecordSet::Iterator it = rs.begin(); it != rs.end(); ++it)
|
||||
for (RecordSet::Iterator it = rs.begin(); it != rs.end(); ++it)
|
||||
std::cout << *it << " ";
|
||||
----
|
||||
|
||||
@@ -889,7 +893,7 @@ used for sorting purposes. However, the sort criteria can be modified at
|
||||
runtime. For example, an additional field may be added to sort fields
|
||||
(think "... ORDER BY Name ASC, Age DESC"):
|
||||
|
||||
row.addSortField("Field1"); // now Field0 and Field1 are used for sorting
|
||||
row.addSortField("Field1"); // now Field0 and Field1 are used for sorting
|
||||
row.replaceSortField("Field0", "Field2");// now Field1 and Field2 are used for sorting
|
||||
----
|
||||
|
||||
@@ -914,7 +918,7 @@ Valid storage type manipulators are:
|
||||
|
||||
So, if neither data storage, nor storage type are explicitly specified,
|
||||
the data will internally be kept in standard deques. This can be changed
|
||||
through use of storage type manipulators.
|
||||
through use of storage type manipulators.
|
||||
|
||||
|
||||
!!!Complex Data Types
|
||||
@@ -930,19 +934,19 @@ Assume you have a class Person:
|
||||
// default constructor+destr.
|
||||
// getter and setter methods for all members
|
||||
// ...
|
||||
|
||||
|
||||
bool operator <(const Person& p) const
|
||||
/// we need this for set and multiset support
|
||||
{
|
||||
return _socialSecNr < p._socialSecNr;
|
||||
}
|
||||
|
||||
|
||||
Poco::UInt64 operator()() const
|
||||
/// we need this operator to return the key for the map and multimap
|
||||
{
|
||||
return _socialSecNr;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::string _firstName;
|
||||
std::string _lastName;
|
||||
@@ -953,12 +957,12 @@ Assume you have a class Person:
|
||||
Ideally, one would like to use a Person as simple as one used a string.
|
||||
All that is needed is a template specialization of the <[TypeHandler]>
|
||||
template. Note that template specializations must be declared in the
|
||||
<*same namespace*> as the original template, i.e. <[Poco::Data]>.
|
||||
<*same namespace*> as the original template, i.e. <[Poco::Data]>.
|
||||
The template specialization must implement the following methods:
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
template <>
|
||||
class TypeHandler<class Person>
|
||||
{
|
||||
@@ -972,12 +976,12 @@ The template specialization must implement the following methods:
|
||||
TypeHandler<std::string>::bind(pos++, obj.getLastName(), pBinder, dir);
|
||||
TypeHandler<Poco::UInt64>::bind(pos++, obj.getSocialSecNr(), pBinder, dir);
|
||||
}
|
||||
|
||||
|
||||
static std::size_t size()
|
||||
{
|
||||
return 3; // we handle three columns of the Table!
|
||||
}
|
||||
|
||||
|
||||
static void prepare(std::size_t pos, const Person& obj, AbstractPreparator::Ptr pPrepare)
|
||||
{
|
||||
poco_assert_dbg (!pPrepare.isNull());
|
||||
@@ -987,7 +991,7 @@ The template specialization must implement the following methods:
|
||||
TypeHandler<std::string>::prepare(pos++, obj.getLastName(), pPrepare);
|
||||
TypeHandler<Poco::UInt64>::prepare(pos++, obj.getSocialSecNr(), pPrepare);
|
||||
}
|
||||
|
||||
|
||||
static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor::Ptr pExt)
|
||||
/// obj will contain the result, defVal contains values we should use when one column is NULL
|
||||
{
|
||||
@@ -1002,14 +1006,14 @@ The template specialization must implement the following methods:
|
||||
obj.setLastName(lastName);
|
||||
obj.setSocialSecNr(socialSecNr);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
----
|
||||
|
||||
@@ -1022,8 +1026,9 @@ working with a string:
|
||||
|
||||
|
||||
!!!Session Pooling
|
||||
|
||||
Creating a connection to a database is often a time consuming
|
||||
operation. Therefore it makes sense to save a session object for
|
||||
operation. Therefore it makes sense to save a session object for
|
||||
later reuse once it is no longer needed.
|
||||
|
||||
A Poco::Data::SessionPool manages a collection of sessions.
|
||||
@@ -1046,7 +1051,7 @@ Pooled sessions are automatically returned to the pool when the
|
||||
Session variable holding them is destroyed.
|
||||
|
||||
One session pool, of course, holds sessions for one database
|
||||
connection. For sessions to multiple databases, there is
|
||||
connection. For sessions to multiple databases, there is
|
||||
SessionPoolContainer:
|
||||
|
||||
SessionPoolContainer spc;
|
||||
@@ -1060,15 +1065,15 @@ SessionPoolContainer:
|
||||
|
||||
This document provides an overview of the most important features
|
||||
offered by the POCO Data framework. The framework also supports LOB
|
||||
(specialized to BLOB and CLOB) type as well as Poco::DateTime binding.
|
||||
The usage of these data types is no different than any C++ type, so we
|
||||
(specialized to BLOB and CLOB) type as well as Poco::DateTime binding.
|
||||
The usage of these data types is no different than any C++ type, so we
|
||||
did not go into details here.
|
||||
|
||||
The great deal of <[RecordSet]> and <[Row]> runtime "magic" is achieved
|
||||
through employment of Poco::Dynamic::Var, which is the POCO
|
||||
equivalent of dynamic language data type. Obviously, due to its nature,
|
||||
there is a run time performance penalty associated with Poco::Dynamic::Var,
|
||||
but the internal details are beyond the scope of this document.
|
||||
but the internal details are beyond the scope of this document.
|
||||
|
||||
POCO Data tries to provide a broad spectrum of functionality,
|
||||
with configurable efficiency/convenience ratio, providing a solid
|
||||
|
||||
63
vendor/POCO/Data/doc/99100-DataReleaseNotes.page
vendored
63
vendor/POCO/Data/doc/99100-DataReleaseNotes.page
vendored
@@ -1,63 +0,0 @@
|
||||
POCO Data Release Notes
|
||||
POCO Data Library
|
||||
|
||||
!!!Release 1.5.0
|
||||
|
||||
The Data library has been available since the 1.2 release. For the 1.5.0 release, a few things have been changed in an incompatible way that requires changes
|
||||
to existing code.
|
||||
|
||||
!!Summary of Changes
|
||||
|
||||
- Poco::Data::RowFormatter class for convenient output formatting.
|
||||
- Stored procedures support (for databases and ODBC drivers that support it).
|
||||
- Improved transaction support (for databases that support it).
|
||||
- Bulk execution (for ODBC drivers that support it).
|
||||
- Batch queries and multiple results (for databases and ODBC drivers that support it).
|
||||
- Stored procedures/functions support (for databases that support it)
|
||||
- New Poco::Data::SessionPoolContainer class.
|
||||
|
||||
|
||||
!!Incompatible Changes and Possible Transition Issues
|
||||
|
||||
Keywords (use, into, limit, etc) now reside in Poco::Data::Keywords namespace.
|
||||
|
||||
|
||||
!!!Release 1.5.2
|
||||
|
||||
!!Summary of Changes
|
||||
|
||||
- framework-wide refactoring to use SharedPtr-based garbage collection
|
||||
|
||||
!!Incompatible Changes and Possible Transition Issues
|
||||
|
||||
Internally, (Abstract)Binder, Extracion nas (where applicable) Preparator are garbage collected.
|
||||
While old way of passing pointers to TypeHandler may still work, it is strongly recommended
|
||||
to pass SharedPtr to handler functions, e.g. :
|
||||
|
||||
template <>
|
||||
class TypeHandler<Person>
|
||||
{
|
||||
public:
|
||||
static std::size_t size()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
static void bind(std::size_t pos, const Person& person, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
|
||||
{
|
||||
TypeHandler<std::string>::bind(pos++, person.name, pBinder, dir);
|
||||
// ...
|
||||
}
|
||||
|
||||
static void extract(std::size_t pos, Person& person, const Person& deflt, AbstractExtractor::Ptr pExtr)
|
||||
{
|
||||
TypeHandler<std::string>::extract(pos++, person.name, deflt.name, pExtr);
|
||||
// ...
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, const Person& person, AbstractPreparator::Ptr pPrep)
|
||||
{
|
||||
TypeHandler<std::string>::prepare(pos++, person.name, pPrep);
|
||||
// ...
|
||||
}
|
||||
};
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "Poco/Data/LOB.h"
|
||||
#include "Poco/DateTime.h"
|
||||
#include "Poco/Nullable.h"
|
||||
#include "Poco/UUID.h"
|
||||
#include "Poco/Any.h"
|
||||
#include "Poco/Dynamic/Var.h"
|
||||
#include "Poco/UTFString.h"
|
||||
@@ -317,6 +318,18 @@ public:
|
||||
virtual void bind(std::size_t pos, const std::list<Time>& val, Direction dir = PD_IN);
|
||||
/// Binds a Time list.
|
||||
|
||||
virtual void bind(std::size_t pos, const UUID& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds a UUID.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<UUID>& val, Direction dir = PD_IN);
|
||||
/// Binds a UUID vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::deque<UUID>& val, Direction dir = PD_IN);
|
||||
/// Binds a UUID deque.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::list<UUID>& val, Direction dir = PD_IN);
|
||||
/// Binds a UUID list.
|
||||
|
||||
virtual void bind(std::size_t pos, const NullData& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds a null.
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "Poco/Data/Data.h"
|
||||
#include "Poco/Data/Constants.h"
|
||||
#include "Poco/Data/LOB.h"
|
||||
#include "Poco/UUID.h"
|
||||
#include "Poco/UTFString.h"
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
@@ -304,6 +305,18 @@ public:
|
||||
virtual bool extract(std::size_t pos, std::list<Time>& val);
|
||||
/// Extracts a Time list.
|
||||
|
||||
virtual bool extract(std::size_t pos, UUID& val) = 0;
|
||||
/// Extracts a UUID. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<UUID>& val);
|
||||
/// Extracts a UUID vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::deque<UUID>& val);
|
||||
/// Extracts a UUID deque.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::list<UUID>& val);
|
||||
/// Extracts a UUID list.
|
||||
|
||||
virtual bool extract(std::size_t pos, Any& val) = 0;
|
||||
/// Extracts an Any. Returns false if null was received.
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "Poco/Data/Data.h"
|
||||
#include "Poco/RefCountedObject.h"
|
||||
#include "Poco/Data/LOB.h"
|
||||
#include "Poco/UUID.h"
|
||||
#include "Poco/UTFString.h"
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
@@ -310,6 +311,18 @@ public:
|
||||
virtual void prepare(std::size_t pos, const std::list<Time>& val);
|
||||
/// Prepares a Time list.
|
||||
|
||||
virtual void prepare(std::size_t pos, const UUID&) = 0;
|
||||
/// Prepares a UUID.
|
||||
|
||||
virtual void prepare(std::size_t pos, const std::vector<UUID>& val);
|
||||
/// Prepares a UUID vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, const std::deque<UUID>& val);
|
||||
/// Prepares a UUID deque.
|
||||
|
||||
virtual void prepare(std::size_t pos, const std::list<UUID>& val);
|
||||
/// Prepares a UUID list.
|
||||
|
||||
virtual void prepare(std::size_t pos, const Any&) = 0;
|
||||
/// Prepares an Any.
|
||||
|
||||
|
||||
31
vendor/POCO/Data/include/Poco/Data/LOB.h
vendored
31
vendor/POCO/Data/include/Poco/Data/LOB.h
vendored
@@ -130,7 +130,18 @@ public:
|
||||
if (_pContent->empty())
|
||||
return 0;
|
||||
else
|
||||
return &(*_pContent)[0];
|
||||
return _pContent->data();
|
||||
}
|
||||
|
||||
T* rawContent()
|
||||
/// Returns the raw content.
|
||||
///
|
||||
/// If the LOB is empty, returns NULL.
|
||||
{
|
||||
if (_pContent->empty())
|
||||
return 0;
|
||||
else
|
||||
return _pContent->data();
|
||||
}
|
||||
|
||||
void assignVal(std::size_t count, const T& val)
|
||||
@@ -155,6 +166,18 @@ public:
|
||||
_pContent->insert(_pContent->end(), pChar, pChar+count);
|
||||
}
|
||||
|
||||
void reserve(std::size_t size)
|
||||
/// Sets the capacity of the internal buffer.
|
||||
{
|
||||
_pContent->reserve(size);
|
||||
}
|
||||
|
||||
void resize(std::size_t size)
|
||||
/// Resizes the internal buffer.
|
||||
{
|
||||
_pContent->resize(size);
|
||||
}
|
||||
|
||||
void clear(bool doCompact = false)
|
||||
/// Clears the content of the blob.
|
||||
/// If doCompact is true, trims the excess capacity.
|
||||
@@ -185,6 +208,12 @@ public:
|
||||
return static_cast<std::size_t>(_pContent->size());
|
||||
}
|
||||
|
||||
std::size_t capacity() const
|
||||
/// Returns the capacity of the underlying buffer.
|
||||
{
|
||||
return static_cast<std::size_t>(_pContent->capacity());
|
||||
}
|
||||
|
||||
private:
|
||||
ContentPtr _pContent;
|
||||
};
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
FDT_DATE,
|
||||
FDT_TIME,
|
||||
FDT_TIMESTAMP,
|
||||
FDT_UUID,
|
||||
FDT_UNKNOWN
|
||||
};
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class Data_API SQLChannel: public Poco::Channel
|
||||
/// To provide as non-intrusive operation as possbile, the log entries are cached and
|
||||
/// inserted into the target database asynchronously by default. The blocking, however, will occur
|
||||
/// before the next entry insertion with default timeout of 1 second. The default settings can be
|
||||
/// overriden (see async, timeout and throw properties for details).
|
||||
/// overridden (see async, timeout and throw properties for details).
|
||||
/// If throw property is false, insertion timeouts are ignored, otherwise a TimeoutException is thrown.
|
||||
/// To force insertion of every entry, set timeout to 0. This setting, however, introduces
|
||||
/// a risk of long blocking periods in case of remote server communication delays.
|
||||
|
||||
@@ -70,19 +70,19 @@ public:
|
||||
|
||||
enum BulkType
|
||||
{
|
||||
BULK_UNDEFINED,
|
||||
BULK_UNDEFINED,
|
||||
/// Bulk mode not defined yet.
|
||||
BULK_BINDING,
|
||||
BULK_BINDING,
|
||||
/// Binding in bulk mode.
|
||||
/// If extraction is present in the same statement,
|
||||
/// If extraction is present in the same statement,
|
||||
/// it must also be bulk.
|
||||
BULK_EXTRACTION,
|
||||
BULK_EXTRACTION,
|
||||
/// Extraction in bulk mode.
|
||||
/// If binding is present in the same statement,
|
||||
/// If binding is present in the same statement,
|
||||
/// it must also be bulk.
|
||||
BULK_FORBIDDEN
|
||||
/// Bulk forbidden.
|
||||
/// Happens when the statement has already been
|
||||
BULK_FORBIDDEN
|
||||
/// Bulk forbidden.
|
||||
/// Happens when the statement has already been
|
||||
/// configured as non-bulk.
|
||||
};
|
||||
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
virtual ~StatementImpl();
|
||||
/// Destroys the StatementImpl.
|
||||
|
||||
template <typename T>
|
||||
template <typename T>
|
||||
void add(const T& t)
|
||||
/// Appends SQL statement (fragments).
|
||||
{
|
||||
@@ -117,15 +117,15 @@ public:
|
||||
/// Registers objects used for extracting data with the StatementImpl.
|
||||
|
||||
void setExtractionLimit(const Limit& extrLimit);
|
||||
/// Changes the extractionLimit to extrLimit.
|
||||
/// Changes the extractionLimit to extrLimit.
|
||||
/// Per default no limit (EXTRACT_UNLIMITED) is set.
|
||||
|
||||
std::string toString() const;
|
||||
/// Create a string version of the SQL statement.
|
||||
|
||||
std::size_t execute(const bool& reset = true);
|
||||
/// Executes a statement. Returns the number of rows
|
||||
/// extracted for statements returning data or number of rows
|
||||
/// Executes a statement. Returns the number of rows
|
||||
/// extracted for statements returning data or number of rows
|
||||
/// affected for all other statements (insert, update, delete).
|
||||
/// If reset is true (default), the underlying bound storage is
|
||||
/// reset and reused. In case of containers, this means they are
|
||||
@@ -154,15 +154,15 @@ public:
|
||||
|
||||
std::size_t dataSetCount() const;
|
||||
/// Returns the number of data sets associated with the statement.
|
||||
|
||||
|
||||
protected:
|
||||
virtual std::size_t columnsReturned() const = 0;
|
||||
/// Returns number of columns returned by query.
|
||||
/// Returns number of columns returned by query.
|
||||
|
||||
virtual int affectedRowCount() const = 0;
|
||||
/// Returns the number of affected rows.
|
||||
/// Used to find out the number of rows affected by insert, delete or update.
|
||||
///
|
||||
///
|
||||
/// Some back-ends may return a negative number in certain circumstances (e.g.
|
||||
/// some ODBC drivers when this function is called after a select statement
|
||||
/// execution).
|
||||
@@ -174,10 +174,10 @@ protected:
|
||||
/// Returns column meta data.
|
||||
|
||||
virtual bool hasNext() = 0;
|
||||
/// Returns true if a call to next() will return data.
|
||||
/// Returns true if a call to next() will return data.
|
||||
///
|
||||
/// Note that the implementation must support
|
||||
/// several consecutive calls to hasNext without data getting lost,
|
||||
/// several consecutive calls to hasNext without data getting lost,
|
||||
/// ie. hasNext(); hasNext(); next() must be equal to hasNext(); next();
|
||||
|
||||
virtual std::size_t next() = 0;
|
||||
@@ -232,8 +232,8 @@ protected:
|
||||
/// Determines the type of the internal extraction container and
|
||||
/// calls the extraction creation function (addInternalExtract)
|
||||
/// with appropriate data type and container type arguments.
|
||||
///
|
||||
/// This function is only called in cases when there is data
|
||||
///
|
||||
/// This function is only called in cases when there is data
|
||||
/// returned by query, but no data storage supplied by user.
|
||||
///
|
||||
/// The type of the internal container is determined in the
|
||||
@@ -273,24 +273,24 @@ protected:
|
||||
/// Used as a help to determine whether to automatically create the
|
||||
/// internal extractions when no outside extraction is supplied.
|
||||
/// The reason for this function is to prevent unnecessary internal
|
||||
/// extraction creation in cases (behavior exhibited by some ODBC drivers)
|
||||
/// when there is data available from the stored procedure call
|
||||
/// statement execution but no external extraction is supplied (as is
|
||||
/// extraction creation in cases (behavior exhibited by some ODBC drivers)
|
||||
/// when there is data available from the stored procedure call
|
||||
/// statement execution but no external extraction is supplied (as is
|
||||
/// usually the case when stored procedures are called). In such cases
|
||||
/// no storage is needed because output parameters serve as storage.
|
||||
/// At the Data framework level, this function always returns false.
|
||||
/// When connector-specific behavior is desired, it should be overriden
|
||||
/// When connector-specific behavior is desired, it should be overridden
|
||||
/// by the statement implementation.
|
||||
|
||||
std::size_t currentDataSet() const;
|
||||
/// Returns the current data set.
|
||||
|
||||
std::size_t activateNextDataSet();
|
||||
/// Returns the next data set index, or throws NoDataException if the last
|
||||
/// Returns the next data set index, or throws NoDataException if the last
|
||||
/// data set was reached.
|
||||
|
||||
std::size_t activatePreviousDataSet();
|
||||
/// Returns the previous data set index, or throws NoDataException if the last
|
||||
/// Returns the previous data set index, or throws NoDataException if the last
|
||||
/// data set was reached.
|
||||
|
||||
bool hasMoreDataSets() const;
|
||||
@@ -304,13 +304,13 @@ private:
|
||||
/// Binds the statement, if not yet bound.
|
||||
|
||||
std::size_t executeWithLimit();
|
||||
/// Executes with an upper limit set. Returns the number of rows
|
||||
/// extracted for statements returning data or number of rows
|
||||
/// Executes with an upper limit set. Returns the number of rows
|
||||
/// extracted for statements returning data or number of rows
|
||||
/// affected for all other statements (insert, update, delete).
|
||||
|
||||
std::size_t executeWithoutLimit();
|
||||
/// Executes without an upper limit set. Returns the number of rows
|
||||
/// extracted for statements returning data or number of rows
|
||||
/// Executes without an upper limit set. Returns the number of rows
|
||||
/// extracted for statements returning data or number of rows
|
||||
/// affected for all other statements (insert, update, delete).
|
||||
|
||||
void resetExtraction();
|
||||
@@ -339,7 +339,7 @@ private:
|
||||
void addInternalExtract(const MetaColumn& mc)
|
||||
/// Creates and adds the internal extraction.
|
||||
///
|
||||
/// The decision about internal extraction container is done
|
||||
/// The decision about internal extraction container is done
|
||||
/// in a following way:
|
||||
///
|
||||
/// If this statement has _storage member set, that setting
|
||||
@@ -349,17 +349,17 @@ private:
|
||||
/// type set, std::vector is the default container type used.
|
||||
{
|
||||
std::string storage;
|
||||
|
||||
|
||||
switch (_storage)
|
||||
{
|
||||
case STORAGE_DEQUE_IMPL:
|
||||
case STORAGE_DEQUE_IMPL:
|
||||
storage = DEQUE; break;
|
||||
case STORAGE_VECTOR_IMPL:
|
||||
case STORAGE_VECTOR_IMPL:
|
||||
storage = VECTOR; break;
|
||||
case STORAGE_LIST_IMPL:
|
||||
case STORAGE_LIST_IMPL:
|
||||
storage = LIST; break;
|
||||
case STORAGE_UNKNOWN_IMPL:
|
||||
storage = AnyCast<std::string>(session().getProperty("storage"));
|
||||
storage = AnyCast<std::string>(session().getProperty("storage"));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -390,7 +390,7 @@ private:
|
||||
|
||||
bool isNull(std::size_t col, std::size_t row) const;
|
||||
/// Returns true if the value in [col, row] is null.
|
||||
|
||||
|
||||
void forbidBulk();
|
||||
/// Forbids bulk operations.
|
||||
|
||||
@@ -399,7 +399,7 @@ private:
|
||||
|
||||
void setBulkExtraction(const Bulk& l);
|
||||
/// Sets the bulk extraction flag and extraction limit.
|
||||
|
||||
|
||||
void resetBulk();
|
||||
/// Resets the bulk extraction and binding flag.
|
||||
|
||||
@@ -446,7 +446,7 @@ private:
|
||||
BulkType _bulkExtraction;
|
||||
CountVec _subTotalRowCount;
|
||||
|
||||
friend class Statement;
|
||||
friend class Statement;
|
||||
};
|
||||
|
||||
|
||||
@@ -538,13 +538,13 @@ inline bool StatementImpl::isStoredProcedure() const
|
||||
|
||||
inline bool StatementImpl::isNull(std::size_t col, std::size_t row) const
|
||||
{
|
||||
try
|
||||
try
|
||||
{
|
||||
return extractions().at(col)->isNull(row);
|
||||
}
|
||||
catch (std::out_of_range& ex)
|
||||
{
|
||||
throw RangeException(ex.what());
|
||||
{
|
||||
throw RangeException(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -605,7 +605,7 @@ inline bool StatementImpl::isBulkExtraction() const
|
||||
return BULK_EXTRACTION == _bulkExtraction;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void StatementImpl::resetBulk()
|
||||
{
|
||||
_bulkExtraction = BULK_UNDEFINED;
|
||||
|
||||
342
vendor/POCO/Data/include/Poco/Data/TypeHandler.h
vendored
342
vendor/POCO/Data/include/Poco/Data/TypeHandler.h
vendored
@@ -34,7 +34,7 @@ namespace Data {
|
||||
|
||||
|
||||
class AbstractTypeHandler
|
||||
/// Parent class for type handlers.
|
||||
/// Parent class for type handlers.
|
||||
/// The reason for this class is to prevent instantiations of type handlers.
|
||||
/// For documentation on type handlers, see TypeHandler class.
|
||||
{
|
||||
@@ -59,12 +59,12 @@ class TypeHandler: public AbstractTypeHandler
|
||||
/// int _age;
|
||||
/// public:
|
||||
/// const std::string& getLastName();
|
||||
/// [...] // other set/get methods (returning const reference), a default constructor,
|
||||
/// [...] // other set/get methods (returning const reference), a default constructor,
|
||||
/// [...] // optional < operator (for set, multiset) or function operator (for map, multimap)
|
||||
/// };
|
||||
///
|
||||
/// The TypeHandler must provide a custom bind, size, prepare and extract method:
|
||||
///
|
||||
///
|
||||
/// template <>
|
||||
/// class TypeHandler<struct Person>
|
||||
/// {
|
||||
@@ -73,7 +73,7 @@ class TypeHandler: public AbstractTypeHandler
|
||||
/// {
|
||||
/// return 3; // lastName + firstname + age occupy three columns
|
||||
/// }
|
||||
///
|
||||
///
|
||||
/// static void bind(std::size_t pos, const Person& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
|
||||
/// {
|
||||
/// // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))
|
||||
@@ -83,7 +83,7 @@ class TypeHandler: public AbstractTypeHandler
|
||||
/// TypeHandler<std::string>::bind(pos++, obj.getFirstName(), pBinder, dir);
|
||||
/// TypeHandler<int>::bind(pos++, obj.getAge(), pBinder, dir);
|
||||
/// }
|
||||
///
|
||||
///
|
||||
/// static void prepare(std::size_t pos, const Person& obj, AbstractPreparator::Ptr pPreparator)
|
||||
/// {
|
||||
/// // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))
|
||||
@@ -92,7 +92,7 @@ class TypeHandler: public AbstractTypeHandler
|
||||
/// TypeHandler<std::string>::prepare(pos++, obj.getFirstName(), pPreparator);
|
||||
/// TypeHandler<int>::prepare(pos++, obj.getAge(), pPreparator);
|
||||
/// }
|
||||
///
|
||||
///
|
||||
/// static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor::Ptr pExt)
|
||||
/// {
|
||||
/// // defVal is the default person we should use if we encunter NULL entries, so we take the individual fields
|
||||
@@ -249,52 +249,52 @@ private:
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TypeHandler<Nullable<T>>
|
||||
class TypeHandler<Nullable<T>>
|
||||
/// Specialization of type handler for Nullable.
|
||||
{
|
||||
public:
|
||||
|
||||
static void bind(std::size_t pos, const Nullable<T>& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
|
||||
static void bind(std::size_t pos, const Nullable<T>& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
|
||||
{
|
||||
poco_assert_dbg (!pBinder.isNull());
|
||||
if (obj.isNull())
|
||||
if (obj.isNull())
|
||||
{
|
||||
pBinder->bind(pos++, Poco::Data::Keywords::null, dir);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
pBinder->bind(pos++, obj.value(), dir);
|
||||
}
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, const Nullable<T>& obj, AbstractPreparator::Ptr pPreparator)
|
||||
|
||||
static void prepare(std::size_t pos, const Nullable<T>& obj, AbstractPreparator::Ptr pPreparator)
|
||||
{
|
||||
poco_assert_dbg (!pPreparator.isNull());
|
||||
if (obj.isNull())
|
||||
if (obj.isNull())
|
||||
{
|
||||
pPreparator->prepare(pos++, Poco::Data::Keywords::null);
|
||||
pPreparator->prepare(pos++, T());
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
pPreparator->prepare(pos++, obj.value());
|
||||
}
|
||||
}
|
||||
|
||||
static std::size_t size()
|
||||
static std::size_t size()
|
||||
{
|
||||
return 1u;
|
||||
}
|
||||
|
||||
static void extract(std::size_t pos, Nullable<T>& obj, const Nullable<T>& , AbstractExtractor::Ptr pExt)
|
||||
static void extract(std::size_t pos, Nullable<T>& obj, const Nullable<T>& , AbstractExtractor::Ptr pExt)
|
||||
{
|
||||
poco_assert_dbg (!pExt.isNull());
|
||||
T val;
|
||||
|
||||
if (pExt->extract(pos++, val))
|
||||
|
||||
if (pExt->extract(pos++, val))
|
||||
{
|
||||
obj = val;
|
||||
obj = std::move(val);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
obj.clear();
|
||||
}
|
||||
@@ -343,25 +343,25 @@ void tupleExtract(std::size_t& pos, TupleType tuple, DefValType defVal, Abstract
|
||||
}
|
||||
|
||||
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
class T13,
|
||||
class T14,
|
||||
class T15,
|
||||
class T16,
|
||||
class T17,
|
||||
class T18,
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
class T13,
|
||||
class T14,
|
||||
class T15,
|
||||
class T16,
|
||||
class T17,
|
||||
class T18,
|
||||
class T19>
|
||||
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19>>
|
||||
{
|
||||
@@ -474,24 +474,24 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
class T13,
|
||||
class T14,
|
||||
class T15,
|
||||
class T16,
|
||||
class T17,
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
class T13,
|
||||
class T14,
|
||||
class T15,
|
||||
class T16,
|
||||
class T17,
|
||||
class T18>
|
||||
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18>>
|
||||
{
|
||||
@@ -600,23 +600,23 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
class T13,
|
||||
class T14,
|
||||
class T15,
|
||||
class T16,
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
class T13,
|
||||
class T14,
|
||||
class T15,
|
||||
class T16,
|
||||
class T17>
|
||||
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17>>
|
||||
{
|
||||
@@ -721,22 +721,22 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
class T13,
|
||||
class T14,
|
||||
class T15,
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
class T13,
|
||||
class T14,
|
||||
class T15,
|
||||
class T16>
|
||||
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16>>
|
||||
{
|
||||
@@ -837,21 +837,21 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
class T13,
|
||||
class T14,
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
class T13,
|
||||
class T14,
|
||||
class T15>
|
||||
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15>>
|
||||
{
|
||||
@@ -948,20 +948,20 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
class T13,
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
class T13,
|
||||
class T14>
|
||||
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14>>
|
||||
{
|
||||
@@ -1054,19 +1054,19 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12,
|
||||
class T13>
|
||||
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13>>
|
||||
{
|
||||
@@ -1155,18 +1155,18 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11,
|
||||
class T12>
|
||||
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12>>
|
||||
{
|
||||
@@ -1251,17 +1251,17 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10,
|
||||
class T11>
|
||||
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>>
|
||||
{
|
||||
@@ -1342,16 +1342,16 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
template <class T0,
|
||||
class T1,
|
||||
class T2,
|
||||
class T3,
|
||||
class T4,
|
||||
class T5,
|
||||
class T6,
|
||||
class T7,
|
||||
class T8,
|
||||
class T9,
|
||||
class T10>
|
||||
class TypeHandler<Poco::Tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>>
|
||||
{
|
||||
@@ -1956,7 +1956,7 @@ public:
|
||||
return TypeHandler<T0>::size();
|
||||
}
|
||||
|
||||
static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal,
|
||||
static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal,
|
||||
AbstractExtractor::Ptr pExt)
|
||||
{
|
||||
poco_assert_dbg (!pExt.isNull());
|
||||
@@ -2013,7 +2013,7 @@ public:
|
||||
static void bind(std::size_t pos, const Poco::AutoPtr<T>& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
|
||||
{
|
||||
// *obj will trigger a nullpointer exception if empty: this is on purpose
|
||||
TypeHandler<T>::bind(pos, *obj, pBinder, dir);
|
||||
TypeHandler<T>::bind(pos, *obj, pBinder, dir);
|
||||
}
|
||||
|
||||
static std::size_t size()
|
||||
@@ -2024,7 +2024,7 @@ public:
|
||||
static void extract(std::size_t pos, Poco::AutoPtr<T>& obj, const Poco::AutoPtr<T>& defVal, AbstractExtractor::Ptr pExt)
|
||||
{
|
||||
poco_assert_dbg (!pExt.isNull());
|
||||
|
||||
|
||||
obj = Poco::AutoPtr<T>(new T());
|
||||
if (defVal)
|
||||
TypeHandler<T>::extract(pos, *obj, *defVal, pExt);
|
||||
@@ -2053,7 +2053,7 @@ public:
|
||||
static void bind(std::size_t pos, const Poco::SharedPtr<T>& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
|
||||
{
|
||||
// *obj will trigger a nullpointer exception if empty
|
||||
TypeHandler<T>::bind(pos, *obj, pBinder, dir);
|
||||
TypeHandler<T>::bind(pos, *obj, pBinder, dir);
|
||||
}
|
||||
|
||||
static std::size_t size()
|
||||
@@ -2064,7 +2064,7 @@ public:
|
||||
static void extract(std::size_t pos, Poco::SharedPtr<T>& obj, const Poco::SharedPtr<T>& defVal, AbstractExtractor::Ptr pExt)
|
||||
{
|
||||
poco_assert_dbg (!pExt.isNull());
|
||||
|
||||
|
||||
obj = Poco::SharedPtr<T>(new T());
|
||||
if (defVal)
|
||||
TypeHandler<T>::extract(pos, *obj, *defVal, pExt);
|
||||
|
||||
18
vendor/POCO/Data/src/AbstractBinder.cpp
vendored
18
vendor/POCO/Data/src/AbstractBinder.cpp
vendored
@@ -404,6 +404,24 @@ void AbstractBinder::bind(std::size_t pos, const std::list<Time>& val, Direction
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<UUID>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::deque<UUID>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::deque binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::list<UUID>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::list binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<NullData>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
|
||||
18
vendor/POCO/Data/src/AbstractExtractor.cpp
vendored
18
vendor/POCO/Data/src/AbstractExtractor.cpp
vendored
@@ -398,6 +398,24 @@ bool AbstractExtractor::extract(std::size_t pos, std::list<Time>& val)
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<UUID>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::deque<UUID>& val)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::list<UUID>& val)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<Any>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
|
||||
18
vendor/POCO/Data/src/AbstractPreparator.cpp
vendored
18
vendor/POCO/Data/src/AbstractPreparator.cpp
vendored
@@ -399,6 +399,24 @@ void AbstractPreparator::prepare(std::size_t pos, const std::list<Time>& val)
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparator::prepare(std::size_t pos, const std::vector<UUID>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparator must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparator::prepare(std::size_t pos, const std::deque<UUID>& val)
|
||||
{
|
||||
throw NotImplementedException("std::deque preparator must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparator::prepare(std::size_t pos, const std::list<UUID>& val)
|
||||
{
|
||||
throw NotImplementedException("std::list preparator must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparator::prepare(std::size_t pos, const std::vector<Any>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparator must be implemented.");
|
||||
|
||||
19
vendor/POCO/Data/src/RecordSet.cpp
vendored
19
vendor/POCO/Data/src/RecordSet.cpp
vendored
@@ -34,7 +34,7 @@ const std::size_t RecordSet::UNKNOWN_TOTAL_ROW_COUNT = std::numeric_limits<std::
|
||||
|
||||
|
||||
RecordSet::RecordSet(const Statement& rStatement,
|
||||
RowFormatter::Ptr pRowFormatter):
|
||||
RowFormatter::Ptr pRowFormatter):
|
||||
Statement(rStatement),
|
||||
_currentRow(0),
|
||||
_pBegin(new RowIterator(this, 0 == rowsExtracted())),
|
||||
@@ -45,9 +45,9 @@ RecordSet::RecordSet(const Statement& rStatement,
|
||||
}
|
||||
|
||||
|
||||
RecordSet::RecordSet(Session& rSession,
|
||||
const std::string& query,
|
||||
RowFormatter::Ptr pRowFormatter):
|
||||
RecordSet::RecordSet(Session& rSession,
|
||||
const std::string& query,
|
||||
RowFormatter::Ptr pRowFormatter):
|
||||
Statement((rSession << query, now)),
|
||||
_currentRow(0),
|
||||
_pBegin(new RowIterator(this, 0 == rowsExtracted())),
|
||||
@@ -119,7 +119,7 @@ void RecordSet::reset(const Statement& stmt)
|
||||
_pEnd = 0;
|
||||
_currentRow = 0;
|
||||
_totalRowCount = UNKNOWN_TOTAL_ROW_COUNT;
|
||||
|
||||
|
||||
RowMap::iterator it = _rowMap.begin();
|
||||
RowMap::iterator end = _rowMap.end();
|
||||
for (; it != end; ++it) delete it->second;
|
||||
@@ -159,6 +159,7 @@ Poco::Dynamic::Var RecordSet::value(std::size_t col, std::size_t row, bool useFi
|
||||
case MetaColumn::FDT_DATE: return value<Date>(col, row, useFilter);
|
||||
case MetaColumn::FDT_TIME: return value<Time>(col, row, useFilter);
|
||||
case MetaColumn::FDT_TIMESTAMP: return value<DateTime>(col, row);
|
||||
case MetaColumn::FDT_UUID: return value<UUID>(col, row);
|
||||
default:
|
||||
throw UnknownTypeException("Data type not supported.");
|
||||
}
|
||||
@@ -188,9 +189,11 @@ Poco::Dynamic::Var RecordSet::value(const std::string& name, std::size_t row, bo
|
||||
case MetaColumn::FDT_STRING: return value<std::string>(name, row, useFilter);
|
||||
case MetaColumn::FDT_WSTRING: return value<UTF16String>(name, row, useFilter);
|
||||
case MetaColumn::FDT_BLOB: return value<BLOB>(name, row, useFilter);
|
||||
case MetaColumn::FDT_CLOB: return value<CLOB>(name, row, useFilter);
|
||||
case MetaColumn::FDT_DATE: return value<Date>(name, row, useFilter);
|
||||
case MetaColumn::FDT_TIME: return value<Time>(name, row, useFilter);
|
||||
case MetaColumn::FDT_TIMESTAMP: return value<DateTime>(name, row, useFilter);
|
||||
case MetaColumn::FDT_UUID: return value<UUID>(name, row, useFilter);
|
||||
default:
|
||||
throw UnknownTypeException("Data type not supported.");
|
||||
}
|
||||
@@ -210,7 +213,7 @@ Row& RecordSet::row(std::size_t pos)
|
||||
{
|
||||
if (_rowMap.size())
|
||||
{
|
||||
//reuse first row column names and sorting fields to save some memory
|
||||
//reuse first row column names and sorting fields to save some memory
|
||||
pRow = new Row(_rowMap.begin()->second->names(),
|
||||
_rowMap.begin()->second->getSortMap(),
|
||||
getRowFormatter());
|
||||
@@ -218,7 +221,7 @@ Row& RecordSet::row(std::size_t pos)
|
||||
for (std::size_t col = 0; col < columns; ++col)
|
||||
pRow->set(col, value(col, pos));
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
pRow = new Row;
|
||||
pRow->setFormatter(getRowFormatter());
|
||||
@@ -228,7 +231,7 @@ Row& RecordSet::row(std::size_t pos)
|
||||
|
||||
_rowMap.insert(RowMap::value_type(pos, pRow));
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
pRow = it->second;
|
||||
poco_check_ptr (pRow);
|
||||
|
||||
83
vendor/POCO/Data/src/SessionPool.cpp
vendored
83
vendor/POCO/Data/src/SessionPool.cpp
vendored
@@ -65,7 +65,7 @@ Session SessionPool::get()
|
||||
{
|
||||
Poco::Mutex::ScopedLock lock(_mutex);
|
||||
if (_shutdown) throw InvalidAccessException("Session pool has been shut down.");
|
||||
|
||||
|
||||
purgeDeadSessions();
|
||||
|
||||
if (_idleSessions.empty())
|
||||
@@ -85,7 +85,7 @@ Session SessionPool::get()
|
||||
|
||||
PooledSessionHolderPtr pHolder(_idleSessions.front());
|
||||
PooledSessionImplPtr pPSI(new PooledSessionImpl(pHolder));
|
||||
|
||||
|
||||
_activeSessions.push_front(pHolder);
|
||||
_idleSessions.pop_front();
|
||||
return Session(pPSI);
|
||||
@@ -115,14 +115,14 @@ int SessionPool::capacity() const
|
||||
return _maxSessions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int SessionPool::used() const
|
||||
{
|
||||
Poco::Mutex::ScopedLock lock(_mutex);
|
||||
return (int) _activeSessions.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
int SessionPool::idle() const
|
||||
{
|
||||
Poco::Mutex::ScopedLock lock(_mutex);
|
||||
@@ -153,7 +153,7 @@ int SessionPool::allocated() const
|
||||
return _nSessions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int SessionPool::available() const
|
||||
{
|
||||
if (_shutdown) return 0;
|
||||
@@ -233,28 +233,43 @@ void SessionPool::putBack(PooledSessionHolderPtr pHolder)
|
||||
SessionList::iterator it = std::find(_activeSessions.begin(), _activeSessions.end(), pHolder);
|
||||
if (it != _activeSessions.end())
|
||||
{
|
||||
if (pHolder->session()->isGood())
|
||||
try
|
||||
{
|
||||
pHolder->session()->reset();
|
||||
if (pHolder->session()->isGood())
|
||||
{
|
||||
pHolder->session()->reset();
|
||||
|
||||
// reverse settings applied at acquisition time, if any
|
||||
AddPropertyMap::iterator pIt = _addPropertyMap.find(pHolder->session());
|
||||
if (pIt != _addPropertyMap.end())
|
||||
pHolder->session()->setProperty(pIt->second.first, pIt->second.second);
|
||||
// reverse settings applied at acquisition time, if any
|
||||
AddPropertyMap::iterator pIt = _addPropertyMap.find(pHolder->session());
|
||||
if (pIt != _addPropertyMap.end())
|
||||
pHolder->session()->setProperty(pIt->second.first, pIt->second.second);
|
||||
|
||||
AddFeatureMap::iterator fIt = _addFeatureMap.find(pHolder->session());
|
||||
if (fIt != _addFeatureMap.end())
|
||||
pHolder->session()->setFeature(fIt->second.first, fIt->second.second);
|
||||
AddFeatureMap::iterator fIt = _addFeatureMap.find(pHolder->session());
|
||||
if (fIt != _addFeatureMap.end())
|
||||
pHolder->session()->setFeature(fIt->second.first, fIt->second.second);
|
||||
|
||||
// re-apply the default pool settings
|
||||
applySettings(pHolder->session());
|
||||
// re-apply the default pool settings
|
||||
applySettings(pHolder->session());
|
||||
|
||||
pHolder->access();
|
||||
_idleSessions.push_front(pHolder);
|
||||
pHolder->access();
|
||||
_idleSessions.push_front(pHolder);
|
||||
}
|
||||
else --_nSessions;
|
||||
|
||||
_activeSessions.erase(it);
|
||||
}
|
||||
catch (const Poco::Exception& e)
|
||||
{
|
||||
--_nSessions;
|
||||
_activeSessions.erase(it);
|
||||
poco_bugcheck_msg(format("Exception in SessionPool::putBack(): %s", e.displayText()).c_str());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
--_nSessions;
|
||||
_activeSessions.erase(it);
|
||||
poco_bugcheck_msg("Unknown exception in SessionPool::putBack()");
|
||||
}
|
||||
else --_nSessions;
|
||||
|
||||
_activeSessions.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -268,13 +283,18 @@ void SessionPool::onJanitorTimer(Poco::Timer&)
|
||||
Poco::Mutex::ScopedLock lock(_mutex);
|
||||
if (_shutdown) return;
|
||||
|
||||
SessionList::iterator it = _idleSessions.begin();
|
||||
SessionList::iterator it = _idleSessions.begin();
|
||||
while (_nSessions > _minSessions && it != _idleSessions.end())
|
||||
{
|
||||
if ((*it)->idle() > _idleTime || !(*it)->session()->isGood())
|
||||
{
|
||||
try { (*it)->session()->close(); }
|
||||
catch (...) { }
|
||||
{
|
||||
try
|
||||
{
|
||||
(*it)->session()->close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
it = _idleSessions.erase(it);
|
||||
--_nSessions;
|
||||
}
|
||||
@@ -296,15 +316,20 @@ void SessionPool::shutdown()
|
||||
|
||||
void SessionPool::closeAll(SessionList& sessionList)
|
||||
{
|
||||
SessionList::iterator it = sessionList.begin();
|
||||
SessionList::iterator it = sessionList.begin();
|
||||
for (; it != sessionList.end();)
|
||||
{
|
||||
try { (*it)->session()->close(); }
|
||||
catch (...) { }
|
||||
try
|
||||
{
|
||||
(*it)->session()->close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
it = sessionList.erase(it);
|
||||
if (_nSessions > 0) --_nSessions;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
} } // namespace Poco::Data
|
||||
48
vendor/POCO/Data/src/StatementImpl.cpp
vendored
48
vendor/POCO/Data/src/StatementImpl.cpp
vendored
@@ -131,15 +131,15 @@ std::size_t StatementImpl::executeWithLimit()
|
||||
do
|
||||
{
|
||||
bind();
|
||||
while (count < limit && hasNext())
|
||||
while (count < limit && hasNext())
|
||||
count += next();
|
||||
} while (count < limit && canBind());
|
||||
|
||||
if (!canBind() && (!hasNext() || limit == 0))
|
||||
if (!canBind() && (!hasNext() || limit == 0))
|
||||
_state = ST_DONE;
|
||||
else if (hasNext() && limit == count && _extrLimit.isHardLimit())
|
||||
throw LimitException("HardLimit reached (retrieved more data than requested).");
|
||||
else
|
||||
else
|
||||
_state = ST_PAUSED;
|
||||
|
||||
int affectedRows = affectedRowCount();
|
||||
@@ -177,8 +177,8 @@ std::size_t StatementImpl::executeWithoutLimit()
|
||||
|
||||
void StatementImpl::compile()
|
||||
{
|
||||
if (_state == ST_INITIALIZED ||
|
||||
_state == ST_RESET ||
|
||||
if (_state == ST_INITIALIZED ||
|
||||
_state == ST_RESET ||
|
||||
_state == ST_BOUND)
|
||||
{
|
||||
compileImpl();
|
||||
@@ -298,7 +298,7 @@ void StatementImpl::setStorage(const std::string& storage)
|
||||
if (0 == icompare(DEQUE, storage))
|
||||
_storage = STORAGE_DEQUE_IMPL;
|
||||
else if (0 == icompare(VECTOR, storage))
|
||||
_storage = STORAGE_VECTOR_IMPL;
|
||||
_storage = STORAGE_VECTOR_IMPL;
|
||||
else if (0 == icompare(LIST, storage))
|
||||
_storage = STORAGE_LIST_IMPL;
|
||||
else if (0 == icompare(UNKNOWN, storage))
|
||||
@@ -317,38 +317,42 @@ void StatementImpl::makeExtractors(std::size_t count)
|
||||
{
|
||||
case MetaColumn::FDT_BOOL:
|
||||
addInternalExtract<bool>(mc); break;
|
||||
case MetaColumn::FDT_INT8:
|
||||
case MetaColumn::FDT_INT8:
|
||||
addInternalExtract<Int8>(mc); break;
|
||||
case MetaColumn::FDT_UINT8:
|
||||
case MetaColumn::FDT_UINT8:
|
||||
addInternalExtract<UInt8>(mc); break;
|
||||
case MetaColumn::FDT_INT16:
|
||||
case MetaColumn::FDT_INT16:
|
||||
addInternalExtract<Int16>(mc); break;
|
||||
case MetaColumn::FDT_UINT16:
|
||||
case MetaColumn::FDT_UINT16:
|
||||
addInternalExtract<UInt16>(mc); break;
|
||||
case MetaColumn::FDT_INT32:
|
||||
case MetaColumn::FDT_INT32:
|
||||
addInternalExtract<Int32>(mc); break;
|
||||
case MetaColumn::FDT_UINT32:
|
||||
case MetaColumn::FDT_UINT32:
|
||||
addInternalExtract<UInt32>(mc); break;
|
||||
case MetaColumn::FDT_INT64:
|
||||
case MetaColumn::FDT_INT64:
|
||||
addInternalExtract<Int64>(mc); break;
|
||||
case MetaColumn::FDT_UINT64:
|
||||
case MetaColumn::FDT_UINT64:
|
||||
addInternalExtract<UInt64>(mc); break;
|
||||
case MetaColumn::FDT_FLOAT:
|
||||
case MetaColumn::FDT_FLOAT:
|
||||
addInternalExtract<float>(mc); break;
|
||||
case MetaColumn::FDT_DOUBLE:
|
||||
case MetaColumn::FDT_DOUBLE:
|
||||
addInternalExtract<double>(mc); break;
|
||||
case MetaColumn::FDT_STRING:
|
||||
case MetaColumn::FDT_STRING:
|
||||
addInternalExtract<std::string>(mc); break;
|
||||
case MetaColumn::FDT_WSTRING:
|
||||
addInternalExtract<Poco::UTF16String>(mc); break;
|
||||
case MetaColumn::FDT_BLOB:
|
||||
case MetaColumn::FDT_BLOB:
|
||||
addInternalExtract<BLOB>(mc); break;
|
||||
case MetaColumn::FDT_CLOB:
|
||||
addInternalExtract<CLOB>(mc); break;
|
||||
case MetaColumn::FDT_DATE:
|
||||
addInternalExtract<Date>(mc); break;
|
||||
case MetaColumn::FDT_TIME:
|
||||
addInternalExtract<Time>(mc); break;
|
||||
case MetaColumn::FDT_TIMESTAMP:
|
||||
addInternalExtract<DateTime>(mc); break;
|
||||
case MetaColumn::FDT_UUID:
|
||||
addInternalExtract<UUID>(mc); break;
|
||||
default:
|
||||
throw Poco::InvalidArgumentException("Data type not supported.");
|
||||
}
|
||||
@@ -391,7 +395,7 @@ void StatementImpl::addExtract(AbstractExtraction::Ptr pExtraction)
|
||||
{
|
||||
poco_check_ptr (pExtraction);
|
||||
std::size_t pos = pExtraction->position();
|
||||
if (pos >= _extractors.size())
|
||||
if (pos >= _extractors.size())
|
||||
_extractors.resize(pos + 1);
|
||||
|
||||
pExtraction->setEmptyStringIsNull(
|
||||
@@ -411,7 +415,7 @@ void StatementImpl::removeBind(const std::string& name)
|
||||
AbstractBindingVec::iterator it = _bindings.begin();
|
||||
for (; it != _bindings.end();)
|
||||
{
|
||||
if ((*it)->name() == name)
|
||||
if ((*it)->name() == name)
|
||||
{
|
||||
it = _bindings.erase(it);
|
||||
found = true;
|
||||
@@ -446,7 +450,7 @@ std::size_t StatementImpl::rowsExtracted(int dataSet) const
|
||||
if (_extractors[dataSet].size() > 0)
|
||||
return _extractors[dataSet][0]->numOfRowsHandled();
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -459,7 +463,7 @@ std::size_t StatementImpl::subTotalRowCount(int dataSet) const
|
||||
poco_assert (dataSet >= 0 && dataSet < _subTotalRowCount.size());
|
||||
return _subTotalRowCount[dataSet];
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
5
vendor/POCO/Data/testsuite/src/Binder.cpp
vendored
5
vendor/POCO/Data/testsuite/src/Binder.cpp
vendored
@@ -140,6 +140,11 @@ void Binder::bind(std::size_t pos, const DateTime& val, Direction dir)
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const UUID& val, Direction dir)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
|
||||
{
|
||||
}
|
||||
|
||||
5
vendor/POCO/Data/testsuite/src/Binder.h
vendored
5
vendor/POCO/Data/testsuite/src/Binder.h
vendored
@@ -100,8 +100,11 @@ public:
|
||||
void bind(std::size_t pos, const DateTime& val, Direction dir);
|
||||
/// Binds a DateTime.
|
||||
|
||||
void bind(std::size_t pos, const UUID& val, Direction dir);
|
||||
/// Binds a UUID.
|
||||
|
||||
void bind(std::size_t pos, const NullData& val, Direction dir);
|
||||
/// Binds a DateTime.
|
||||
/// Binds a NullData.
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
7
vendor/POCO/Data/testsuite/src/Extractor.cpp
vendored
7
vendor/POCO/Data/testsuite/src/Extractor.cpp
vendored
@@ -166,13 +166,18 @@ bool Extractor::extract(std::size_t pos, Poco::Data::Time& val)
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::DateTime& val)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::UUID& val)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Any& val)
|
||||
{
|
||||
return true;
|
||||
|
||||
5
vendor/POCO/Data/testsuite/src/Extractor.h
vendored
5
vendor/POCO/Data/testsuite/src/Extractor.h
vendored
@@ -100,9 +100,12 @@ public:
|
||||
bool extract(std::size_t pos, Time& val);
|
||||
/// Extracts a Time.
|
||||
|
||||
bool extract(std::size_t pos, Poco::DateTime& val);
|
||||
bool extract(std::size_t pos, DateTime& val);
|
||||
/// Extracts a DateTime.
|
||||
|
||||
bool extract(std::size_t pos, UUID& val);
|
||||
/// Extracts a UUID.
|
||||
|
||||
bool isNull(std::size_t col, std::size_t row = -1);
|
||||
/// Returns true if the current row value at pos column is null.
|
||||
|
||||
|
||||
@@ -135,6 +135,11 @@ void Preparator::prepare(std::size_t pos, const Poco::DateTime&)
|
||||
}
|
||||
|
||||
|
||||
void Preparator::prepare(std::size_t pos, const Poco::UUID&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Preparator::prepare(std::size_t pos, const Poco::Any&)
|
||||
{
|
||||
}
|
||||
|
||||
3
vendor/POCO/Data/testsuite/src/Preparator.h
vendored
3
vendor/POCO/Data/testsuite/src/Preparator.h
vendored
@@ -98,6 +98,9 @@ public:
|
||||
void prepare(std::size_t pos, const Poco::DateTime&);
|
||||
/// Prepares a DateTime.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::UUID&);
|
||||
/// Prepares a UUID.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::Any&);
|
||||
/// Prepares an Any.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user