mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-12 18:20:26 +01:00
#3318: Data: Support Poco::UUID for data binding
This commit is contained in:
parent
a95c591e0a
commit
7569ccf82b
@ -19,7 +19,6 @@
|
|||||||
#include "Poco/ActiveRecord/ActiveRecordLib.h"
|
#include "Poco/ActiveRecord/ActiveRecordLib.h"
|
||||||
#include "Poco/ActiveRecord/Context.h"
|
#include "Poco/ActiveRecord/Context.h"
|
||||||
#include "Poco/ActiveRecord/IDTraits.h"
|
#include "Poco/ActiveRecord/IDTraits.h"
|
||||||
#include "Poco/ActiveRecord/TypeHandler.h"
|
|
||||||
#include "Poco/DateTime.h"
|
#include "Poco/DateTime.h"
|
||||||
#include "Poco/RefCountedObject.h"
|
#include "Poco/RefCountedObject.h"
|
||||||
#include "Poco/AutoPtr.h"
|
#include "Poco/AutoPtr.h"
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
//
|
|
||||||
// TypeHandler.h
|
|
||||||
//
|
|
||||||
// Library: ActiveRecord
|
|
||||||
// Package: ActiveRecord
|
|
||||||
// Module: TypeHandler
|
|
||||||
//
|
|
||||||
// Copyright (c) 2020, Applied Informatics Software Engineering GmbH.
|
|
||||||
// and Contributors.
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: BSL-1.0
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ActiveRecord_TypeHandler_INCLUDED
|
|
||||||
#define ActiveRecord_TypeHandler_INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/TypeHandler.h"
|
|
||||||
#include "Poco/ThreadLocal.h"
|
|
||||||
#include "Poco/UUID.h"
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class TypeHandler<Poco::UUID>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using UUIDMap = std::map<std::size_t, std::string>;
|
|
||||||
|
|
||||||
static std::size_t size()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bind(std::size_t pos, const Poco::UUID& uuid, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
|
|
||||||
{
|
|
||||||
static Poco::ThreadLocal<UUIDMap> uuidMap;
|
|
||||||
std::string& uuidString = (*uuidMap)[pos];
|
|
||||||
uuidString = uuid.toString();
|
|
||||||
TypeHandler<std::string>::bind(pos++, uuidString, pBinder, dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void extract(std::size_t pos, Poco::UUID& uuid, const Poco::UUID& deflt, AbstractExtractor::Ptr pExtr)
|
|
||||||
{
|
|
||||||
std::string defltString = deflt.toString();
|
|
||||||
std::string uuidString;
|
|
||||||
TypeHandler<std::string>::extract(pos++, uuidString, defltString, pExtr);
|
|
||||||
uuid.parse(uuidString);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void prepare(std::size_t pos, const Poco::UUID& uuid, AbstractPreparator::Ptr pPrep)
|
|
||||||
{
|
|
||||||
static Poco::ThreadLocal<UUIDMap> uuidMap;
|
|
||||||
std::string& uuidString = (*uuidMap)[pos];
|
|
||||||
uuidString = uuid.toString();
|
|
||||||
TypeHandler<std::string>::prepare(pos++, uuidString, pPrep);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // ActiveRecord_TypeHandler_INCLUDED
|
|
||||||
|
|
@ -104,6 +104,9 @@ public:
|
|||||||
virtual void bind(std::size_t pos, const Time& val, Direction dir);
|
virtual void bind(std::size_t pos, const Time& val, Direction dir);
|
||||||
/// Binds a Time.
|
/// 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);
|
virtual void bind(std::size_t pos, const NullData& val, Direction dir);
|
||||||
/// Binds a null.
|
/// Binds a null.
|
||||||
|
|
||||||
|
@ -110,6 +110,9 @@ public:
|
|||||||
virtual bool extract(std::size_t pos, Time& val);
|
virtual bool extract(std::size_t pos, Time& val);
|
||||||
/// Extracts a Time. Returns false if null was received.
|
/// 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);
|
virtual bool extract(std::size_t pos, Any& val);
|
||||||
/// Extracts an Any. Returns false if null was received.
|
/// Extracts an Any. Returns false if null was received.
|
||||||
|
|
||||||
|
@ -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)
|
void Binder::bind(std::size_t pos, const NullData&, Direction dir)
|
||||||
{
|
{
|
||||||
poco_assert(dir == PD_IN);
|
poco_assert(dir == PD_IN);
|
||||||
|
@ -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)
|
bool Extractor::extract(std::size_t pos, Any& val)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -496,6 +496,15 @@ void MySQLTest::testDouble()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MySQLTest::testUUID()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
recreateUUIDsTable();
|
||||||
|
_pExecutor->uuids();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MySQLTest::testTuple()
|
void MySQLTest::testTuple()
|
||||||
{
|
{
|
||||||
if (!_pSession) fail ("Test not available.");
|
if (!_pSession) fail ("Test not available.");
|
||||||
@ -779,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()
|
void MySQLTest::recreateTuplesTable()
|
||||||
{
|
{
|
||||||
dropTable("Tuples");
|
dropTable("Tuples");
|
||||||
@ -904,6 +922,7 @@ CppUnit::Test* MySQLTest::suite()
|
|||||||
CppUnit_addTest(pSuite, MySQLTest, testUnsignedInts);
|
CppUnit_addTest(pSuite, MySQLTest, testUnsignedInts);
|
||||||
CppUnit_addTest(pSuite, MySQLTest, testFloat);
|
CppUnit_addTest(pSuite, MySQLTest, testFloat);
|
||||||
CppUnit_addTest(pSuite, MySQLTest, testDouble);
|
CppUnit_addTest(pSuite, MySQLTest, testDouble);
|
||||||
|
CppUnit_addTest(pSuite, MySQLTest, testUUID);
|
||||||
CppUnit_addTest(pSuite, MySQLTest, testTuple);
|
CppUnit_addTest(pSuite, MySQLTest, testTuple);
|
||||||
CppUnit_addTest(pSuite, MySQLTest, testTupleVector);
|
CppUnit_addTest(pSuite, MySQLTest, testTupleVector);
|
||||||
CppUnit_addTest(pSuite, MySQLTest, testInternalExtraction);
|
CppUnit_addTest(pSuite, MySQLTest, testInternalExtraction);
|
||||||
|
@ -84,6 +84,8 @@ public:
|
|||||||
void testFloat();
|
void testFloat();
|
||||||
void testDouble();
|
void testDouble();
|
||||||
|
|
||||||
|
void testUUID();
|
||||||
|
|
||||||
void testTuple();
|
void testTuple();
|
||||||
void testTupleVector();
|
void testTupleVector();
|
||||||
|
|
||||||
@ -119,6 +121,7 @@ private:
|
|||||||
void recreateIntsTable();
|
void recreateIntsTable();
|
||||||
void recreateUnsignedIntsTable();
|
void recreateUnsignedIntsTable();
|
||||||
void recreateFloatsTable();
|
void recreateFloatsTable();
|
||||||
|
void recreateUUIDsTable();
|
||||||
void recreateTuplesTable();
|
void recreateTuplesTable();
|
||||||
void recreateVectorsTable();
|
void recreateVectorsTable();
|
||||||
void recreateNullableIntTable();
|
void recreateNullableIntTable();
|
||||||
|
@ -545,6 +545,29 @@ 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()
|
void SQLExecutor::insertSingleBulkVec()
|
||||||
{
|
{
|
||||||
std::string funct = "insertSingleBulkVec()";
|
std::string funct = "insertSingleBulkVec()";
|
||||||
|
@ -86,6 +86,7 @@ public:
|
|||||||
void unsignedInts();
|
void unsignedInts();
|
||||||
void floats();
|
void floats();
|
||||||
void doubles();
|
void doubles();
|
||||||
|
void uuids();
|
||||||
void tuples();
|
void tuples();
|
||||||
void tupleVector();
|
void tupleVector();
|
||||||
|
|
||||||
|
@ -322,6 +322,9 @@ public:
|
|||||||
void bind(std::size_t pos, const std::list<DateTime>& val, Direction dir);
|
void bind(std::size_t pos, const std::list<DateTime>& val, Direction dir);
|
||||||
/// Binds a DateTime list.
|
/// 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);
|
void bind(std::size_t pos, const NullData& val, Direction dir);
|
||||||
/// Binds a null. In-bound only.
|
/// Binds a null. In-bound only.
|
||||||
|
|
||||||
@ -367,6 +370,7 @@ private:
|
|||||||
typedef std::vector<AnyVec> AnyVecVec;
|
typedef std::vector<AnyVec> AnyVecVec;
|
||||||
typedef std::map<char*, std::string*> StringMap;
|
typedef std::map<char*, std::string*> StringMap;
|
||||||
typedef std::map<UTF16String::value_type*, UTF16String*> UTF16StringMap;
|
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_DATE_STRUCT*, Date*> DateMap;
|
||||||
typedef std::map<SQL_TIME_STRUCT*, Time*> TimeMap;
|
typedef std::map<SQL_TIME_STRUCT*, Time*> TimeMap;
|
||||||
typedef std::map<SQL_TIMESTAMP_STRUCT*, DateTime*> TimestampMap;
|
typedef std::map<SQL_TIMESTAMP_STRUCT*, DateTime*> TimestampMap;
|
||||||
@ -998,6 +1002,7 @@ private:
|
|||||||
TimestampMap _timestamps;
|
TimestampMap _timestamps;
|
||||||
StringMap _strings;
|
StringMap _strings;
|
||||||
UTF16StringMap _utf16Strings;
|
UTF16StringMap _utf16Strings;
|
||||||
|
UUIDMap _uuids;
|
||||||
|
|
||||||
DateVecVec _dateVecVec;
|
DateVecVec _dateVecVec;
|
||||||
TimeVecVec _timeVecVec;
|
TimeVecVec _timeVecVec;
|
||||||
|
@ -305,6 +305,9 @@ public:
|
|||||||
bool extract(std::size_t pos, std::list<Poco::DateTime>& val);
|
bool extract(std::size_t pos, std::list<Poco::DateTime>& val);
|
||||||
/// Extracts a DateTime list.
|
/// 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);
|
bool extract(std::size_t pos, Poco::Any& val);
|
||||||
/// Extracts an Any.
|
/// Extracts an Any.
|
||||||
|
|
||||||
@ -567,6 +570,9 @@ private:
|
|||||||
case MetaColumn::FDT_TIMESTAMP:
|
case MetaColumn::FDT_TIMESTAMP:
|
||||||
{ return extAny<T, Poco::DateTime>(pos, val); }
|
{ return extAny<T, Poco::DateTime>(pos, val); }
|
||||||
|
|
||||||
|
case MetaColumn::FDT_UUID:
|
||||||
|
{ return extAny<T, Poco::UUID>(pos, val); }
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw DataFormatException("Unsupported data type.");
|
throw DataFormatException("Unsupported data type.");
|
||||||
}
|
}
|
||||||
|
@ -353,6 +353,9 @@ public:
|
|||||||
void prepare(std::size_t pos, const std::list<Poco::DateTime>& val);
|
void prepare(std::size_t pos, const std::list<Poco::DateTime>& val);
|
||||||
/// Prepares a DateTime list.
|
/// 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);
|
void prepare(std::size_t pos, const Poco::Any& val);
|
||||||
/// Prepares an Any.
|
/// Prepares an Any.
|
||||||
|
|
||||||
@ -548,6 +551,12 @@ private:
|
|||||||
else
|
else
|
||||||
return prepareFixedSize<DateTime>(pos, SQL_C_TYPE_TIMESTAMP);
|
return prepareFixedSize<DateTime>(pos, SQL_C_TYPE_TIMESTAMP);
|
||||||
|
|
||||||
|
case MetaColumn::FDT_UUID:
|
||||||
|
if (pVal)
|
||||||
|
return prepareFixedSize<DateTime>(pos, SQL_C_BINARY, 16);
|
||||||
|
else
|
||||||
|
return prepareFixedSize<DateTime>(pos, SQL_C_BINARY);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw DataFormatException("Unsupported data type.");
|
throw DataFormatException("Unsupported data type.");
|
||||||
}
|
}
|
||||||
@ -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)
|
inline void Preparator::prepare(std::size_t pos, const Poco::Any& val)
|
||||||
{
|
{
|
||||||
prepareImpl<std::vector<Poco::Any> >(pos);
|
prepareImpl<std::vector<Poco::Any> >(pos);
|
||||||
|
@ -80,6 +80,10 @@ void Binder::freeMemory()
|
|||||||
UTF16CharPtrVec::iterator endUTF16Chr = _utf16CharPtrs.end();
|
UTF16CharPtrVec::iterator endUTF16Chr = _utf16CharPtrs.end();
|
||||||
for (; itUTF16Chr != endUTF16Chr; ++itUTF16Chr) std::free(*itUTF16Chr);
|
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 itBool = _boolPtrs.begin();
|
||||||
BoolPtrVec::iterator endBool = _boolPtrs.end();
|
BoolPtrVec::iterator endBool = _boolPtrs.end();
|
||||||
for (; itBool != endBool; ++itBool) delete [] *itBool;
|
for (; itBool != endBool; ++itBool) delete [] *itBool;
|
||||||
@ -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)
|
void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
|
||||||
{
|
{
|
||||||
if (isOutBound(dir) || !isInBound(dir))
|
if (isOutBound(dir) || !isInBound(dir))
|
||||||
@ -392,6 +428,14 @@ void Binder::synchronize()
|
|||||||
for(; it != end; ++it)
|
for(; it != end; ++it)
|
||||||
it->second->assign(it->first, std::strlen(it->first));
|
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();
|
_times.clear();
|
||||||
_timestamps.clear();
|
_timestamps.clear();
|
||||||
_strings.clear();
|
_strings.clear();
|
||||||
|
_uuids.clear();
|
||||||
_dateVecVec.clear();
|
_dateVecVec.clear();
|
||||||
_timeVecVec.clear();
|
_timeVecVec.clear();
|
||||||
_dateTimeVecVec.clear();
|
_dateTimeVecVec.clear();
|
||||||
|
@ -224,6 +224,20 @@ bool Extractor::extractBoundImplContainer<std::list<Poco::DateTime> >(std::size_
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
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<>
|
template<>
|
||||||
bool Extractor::extractBoundImplContainer<std::vector<bool> >(std::size_t pos,
|
bool Extractor::extractBoundImplContainer<std::vector<bool> >(std::size_t pos,
|
||||||
std::vector<bool>& val)
|
std::vector<bool>& val)
|
||||||
@ -504,6 +518,33 @@ bool Extractor::extractManualImpl<Poco::DateTime>(std::size_t pos,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
bool Extractor::extract(std::size_t pos, Poco::Int32& val)
|
||||||
{
|
{
|
||||||
if (Preparator::DE_MANUAL == _dataExtraction)
|
if (Preparator::DE_MANUAL == _dataExtraction)
|
||||||
@ -911,6 +952,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)
|
bool Extractor::extract(std::size_t pos, Poco::Int8& val)
|
||||||
{
|
{
|
||||||
if (Preparator::DE_MANUAL == _dataExtraction)
|
if (Preparator::DE_MANUAL == _dataExtraction)
|
||||||
|
@ -102,9 +102,6 @@ void ODBCMetaColumn::init()
|
|||||||
case SQL_CHAR:
|
case SQL_CHAR:
|
||||||
case SQL_VARCHAR:
|
case SQL_VARCHAR:
|
||||||
case SQL_LONGVARCHAR:
|
case SQL_LONGVARCHAR:
|
||||||
#ifdef SQL_GUID
|
|
||||||
case SQL_GUID:
|
|
||||||
#endif
|
|
||||||
setType(MetaColumn::FDT_STRING); break;
|
setType(MetaColumn::FDT_STRING); break;
|
||||||
|
|
||||||
case SQL_WCHAR:
|
case SQL_WCHAR:
|
||||||
@ -168,6 +165,9 @@ void ODBCMetaColumn::init()
|
|||||||
case SQL_TYPE_TIMESTAMP:
|
case SQL_TYPE_TIMESTAMP:
|
||||||
setType(MetaColumn::FDT_TIMESTAMP); break;
|
setType(MetaColumn::FDT_TIMESTAMP); break;
|
||||||
|
|
||||||
|
case SQL_GUID:
|
||||||
|
setType(MetaColumn::FDT_UUID); break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw DataFormatException("Unsupported data type.");
|
throw DataFormatException("Unsupported data type.");
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,9 @@ endif
|
|||||||
ifeq (0, $(shell test -e /opt/postgresql/lib$(LIB64SUFFIX); echo $$?))
|
ifeq (0, $(shell test -e /opt/postgresql/lib$(LIB64SUFFIX); echo $$?))
|
||||||
SYSLIBS += -L/opt/postgresql/lib$(LIB64SUFFIX)
|
SYSLIBS += -L/opt/postgresql/lib$(LIB64SUFFIX)
|
||||||
endif
|
endif
|
||||||
|
ifeq (0, $(shell test -e /usr/local/opt/libpq/lib; echo $$?))
|
||||||
|
SYSLIBS += -L/usr/local/opt/libpq/lib$(LIB64SUFFIX)
|
||||||
|
endif
|
||||||
SYSLIBS += -lpq
|
SYSLIBS += -lpq
|
||||||
|
|
||||||
objects = Extractor Binder SessionImpl Connector \
|
objects = Extractor Binder SessionImpl Connector \
|
||||||
|
@ -108,6 +108,9 @@ public:
|
|||||||
virtual void bind(std::size_t pos, const Time& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const Time& val, Direction dir = PD_IN);
|
||||||
/// Binds a Time.
|
/// 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);
|
virtual void bind(std::size_t pos, const NullData& val, Direction dir = PD_IN);
|
||||||
/// Binds a null.
|
/// Binds a null.
|
||||||
|
|
||||||
|
@ -109,6 +109,9 @@ public:
|
|||||||
virtual bool extract(std::size_t pos, Time& val);
|
virtual bool extract(std::size_t pos, Time& val);
|
||||||
/// Extracts a Time. Returns false if null was received.
|
/// 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);
|
virtual bool extract(std::size_t pos, Any& val);
|
||||||
/// Extracts an Any. Returns false if null was received.
|
/// Extracts an Any. Returns false if null was received.
|
||||||
|
|
||||||
|
@ -271,6 +271,7 @@ inline const void* InputParameter::pInternalRepresentation() const
|
|||||||
case Poco::Data::MetaColumn::FDT_DATE:
|
case Poco::Data::MetaColumn::FDT_DATE:
|
||||||
case Poco::Data::MetaColumn::FDT_TIME:
|
case Poco::Data::MetaColumn::FDT_TIME:
|
||||||
case Poco::Data::MetaColumn::FDT_TIMESTAMP:
|
case Poco::Data::MetaColumn::FDT_TIMESTAMP:
|
||||||
|
case Poco::Data::MetaColumn::FDT_UUID:
|
||||||
return _stringVersionRepresentation.c_str();
|
return _stringVersionRepresentation.c_str();
|
||||||
|
|
||||||
case Poco::Data::MetaColumn::FDT_BLOB:
|
case Poco::Data::MetaColumn::FDT_BLOB:
|
||||||
|
@ -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)
|
void Binder::bind(std::size_t pos, const NullData&, Direction dir)
|
||||||
{
|
{
|
||||||
poco_assert(dir == PD_IN);
|
poco_assert(dir == PD_IN);
|
||||||
@ -293,6 +300,14 @@ void Binder::updateBindVectorToCurrentValues()
|
|||||||
const Poco::Data::CLOB& clob = * static_cast<const Poco::Data::CLOB*>(itr->pData());
|
const Poco::Data::CLOB& clob = * static_cast<const Poco::Data::CLOB*>(itr->pData());
|
||||||
itr->setNonStringVersionRepresentation(static_cast<const void*> (clob.rawContent()), clob.size());
|
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:
|
case Poco::Data::MetaColumn::FDT_UNKNOWN:
|
||||||
default:
|
default:
|
||||||
|
@ -432,6 +432,19 @@ 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)
|
bool Extractor::extract(std::size_t pos, Any& val)
|
||||||
{
|
{
|
||||||
return extractStringImpl(pos, val);
|
return extractStringImpl(pos, val);
|
||||||
@ -583,6 +596,14 @@ bool Extractor::extractToDynamic(std::size_t pos, Dynamic::Var& val)
|
|||||||
val = dt;
|
val = dt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case UUIDOID:
|
||||||
|
{
|
||||||
|
UUID uuid;
|
||||||
|
success = extract(pos, uuid);
|
||||||
|
if (success)
|
||||||
|
val = uuid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
@ -94,6 +94,11 @@ Poco::Data::MetaColumn::ColumnDataType oidToColumnDataType(const Oid anOID)
|
|||||||
cdt = Poco::Data::MetaColumn::FDT_TIMESTAMP;
|
cdt = Poco::Data::MetaColumn::FDT_TIMESTAMP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//uuid
|
||||||
|
case UUIDOID:
|
||||||
|
cdt = Poco::Data::MetaColumn::FDT_BLOB;
|
||||||
|
break;
|
||||||
|
|
||||||
// everything else is a string
|
// everything else is a string
|
||||||
default:
|
default:
|
||||||
cdt = Poco::Data::MetaColumn::FDT_STRING;
|
cdt = Poco::Data::MetaColumn::FDT_STRING;
|
||||||
|
@ -37,6 +37,9 @@ endif
|
|||||||
ifeq (0, $(shell test -e /opt/postgresql/lib$(LIB64SUFFIX); echo $$?))
|
ifeq (0, $(shell test -e /opt/postgresql/lib$(LIB64SUFFIX); echo $$?))
|
||||||
SYSLIBS += -L/opt/postgresql/lib$(LIB64SUFFIX)
|
SYSLIBS += -L/opt/postgresql/lib$(LIB64SUFFIX)
|
||||||
endif
|
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.
|
# Note: linking order is important, do not change it.
|
||||||
SYSLIBS += -lpq -lz -lpthread -ldl
|
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()
|
void PostgreSQLTest::testTuple()
|
||||||
{
|
{
|
||||||
if (!_pSession) fail ("Test not available.");
|
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()
|
void PostgreSQLTest::recreateTuplesTable()
|
||||||
{
|
{
|
||||||
dropTable("Tuples");
|
dropTable("Tuples");
|
||||||
@ -1110,6 +1127,7 @@ CppUnit::Test* PostgreSQLTest::suite()
|
|||||||
CppUnit_addTest(pSuite, PostgreSQLTest, testUnsignedInts);
|
CppUnit_addTest(pSuite, PostgreSQLTest, testUnsignedInts);
|
||||||
CppUnit_addTest(pSuite, PostgreSQLTest, testFloat);
|
CppUnit_addTest(pSuite, PostgreSQLTest, testFloat);
|
||||||
CppUnit_addTest(pSuite, PostgreSQLTest, testDouble);
|
CppUnit_addTest(pSuite, PostgreSQLTest, testDouble);
|
||||||
|
CppUnit_addTest(pSuite, PostgreSQLTest, testUUID);
|
||||||
CppUnit_addTest(pSuite, PostgreSQLTest, testTuple);
|
CppUnit_addTest(pSuite, PostgreSQLTest, testTuple);
|
||||||
CppUnit_addTest(pSuite, PostgreSQLTest, testTupleVector);
|
CppUnit_addTest(pSuite, PostgreSQLTest, testTupleVector);
|
||||||
CppUnit_addTest(pSuite, PostgreSQLTest, testInternalExtraction);
|
CppUnit_addTest(pSuite, PostgreSQLTest, testInternalExtraction);
|
||||||
|
@ -82,6 +82,7 @@ public:
|
|||||||
void testUnsignedInts();
|
void testUnsignedInts();
|
||||||
void testFloat();
|
void testFloat();
|
||||||
void testDouble();
|
void testDouble();
|
||||||
|
void testUUID();
|
||||||
|
|
||||||
void testTuple();
|
void testTuple();
|
||||||
void testTupleVector();
|
void testTupleVector();
|
||||||
@ -118,6 +119,7 @@ private:
|
|||||||
void recreateIntsTable();
|
void recreateIntsTable();
|
||||||
void recreateUnsignedIntsTable();
|
void recreateUnsignedIntsTable();
|
||||||
void recreateFloatsTable();
|
void recreateFloatsTable();
|
||||||
|
void recreateUUIDsTable();
|
||||||
void recreateTuplesTable();
|
void recreateTuplesTable();
|
||||||
void recreateVectorsTable();
|
void recreateVectorsTable();
|
||||||
void recreateNullableIntTable();
|
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()
|
void SQLExecutor::doubles()
|
||||||
{
|
{
|
||||||
std::string funct = "floats()";
|
std::string funct = "floats()";
|
||||||
@ -1611,7 +1634,7 @@ void SQLExecutor::blobStmt()
|
|||||||
std::string lastName("lastname");
|
std::string lastName("lastname");
|
||||||
std::string firstName("firstname");
|
std::string firstName("firstname");
|
||||||
std::string address("Address");
|
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);
|
Poco::Data::BLOB blob(BLOBData, 10);
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@ -89,6 +89,7 @@ public:
|
|||||||
void unsignedInts();
|
void unsignedInts();
|
||||||
void floats();
|
void floats();
|
||||||
void doubles();
|
void doubles();
|
||||||
|
void uuids();
|
||||||
void tuples();
|
void tuples();
|
||||||
void tupleVector();
|
void tupleVector();
|
||||||
|
|
||||||
|
@ -106,6 +106,9 @@ public:
|
|||||||
void bind(std::size_t pos, const DateTime& val, Direction dir);
|
void bind(std::size_t pos, const DateTime& val, Direction dir);
|
||||||
/// Binds a DateTime.
|
/// 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);
|
void bind(std::size_t pos, const NullData& val, Direction dir);
|
||||||
/// Binds a null.
|
/// Binds a null.
|
||||||
|
|
||||||
|
@ -116,6 +116,9 @@ public:
|
|||||||
bool extract(std::size_t pos, Poco::DateTime& val);
|
bool extract(std::size_t pos, Poco::DateTime& val);
|
||||||
/// Extracts a DateTime.
|
/// Extracts a DateTime.
|
||||||
|
|
||||||
|
bool extract(std::size_t pos, Poco::UUID& val);
|
||||||
|
/// Extracts a Time.
|
||||||
|
|
||||||
bool extract(std::size_t pos, Poco::Any& val);
|
bool extract(std::size_t pos, Poco::Any& val);
|
||||||
/// Extracts an Any.
|
/// Extracts an Any.
|
||||||
|
|
||||||
@ -264,6 +267,13 @@ private:
|
|||||||
val = dt;
|
val = dt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MetaColumn::FDT_UUID:
|
||||||
|
{
|
||||||
|
UUID uuid;
|
||||||
|
ret = extract(pos, uuid);
|
||||||
|
val = uuid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw Poco::Data::UnknownTypeException("Unknown type during extraction");
|
throw Poco::Data::UnknownTypeException("Unknown type during extraction");
|
||||||
}
|
}
|
||||||
|
@ -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)
|
void Binder::bind(std::size_t pos, const NullData&, Direction)
|
||||||
{
|
{
|
||||||
sqlite3_bind_null(_pStmt, static_cast<int>(pos));
|
sqlite3_bind_null(_pStmt, static_cast<int>(pos));
|
||||||
|
@ -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)
|
bool Extractor::extract(std::size_t pos, Poco::Any& val)
|
||||||
{
|
{
|
||||||
return extractImpl(pos, val);
|
return extractImpl(pos, val);
|
||||||
|
@ -134,6 +134,8 @@ Utility::Utility()
|
|||||||
_types.insert(TypeMap::value_type("TIME", MetaColumn::FDT_TIME));
|
_types.insert(TypeMap::value_type("TIME", MetaColumn::FDT_TIME));
|
||||||
_types.insert(TypeMap::value_type("DATETIME", MetaColumn::FDT_TIMESTAMP));
|
_types.insert(TypeMap::value_type("DATETIME", MetaColumn::FDT_TIMESTAMP));
|
||||||
_types.insert(TypeMap::value_type("TIMESTAMP", 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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "Poco/Data/SQLite/SQLiteException.h"
|
#include "Poco/Data/SQLite/SQLiteException.h"
|
||||||
#include "Poco/Tuple.h"
|
#include "Poco/Tuple.h"
|
||||||
#include "Poco/Any.h"
|
#include "Poco/Any.h"
|
||||||
|
#include "Poco/UUIDGenerator.h"
|
||||||
#include "Poco/SharedPtr.h"
|
#include "Poco/SharedPtr.h"
|
||||||
#include "Poco/DynamicAny.h"
|
#include "Poco/DynamicAny.h"
|
||||||
#include "Poco/DateTime.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()
|
void SQLiteTest::testInternalExtraction()
|
||||||
{
|
{
|
||||||
Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db");
|
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, testTuple1);
|
||||||
CppUnit_addTest(pSuite, SQLiteTest, testTupleVector1);
|
CppUnit_addTest(pSuite, SQLiteTest, testTupleVector1);
|
||||||
CppUnit_addTest(pSuite, SQLiteTest, testDateTime);
|
CppUnit_addTest(pSuite, SQLiteTest, testDateTime);
|
||||||
|
CppUnit_addTest(pSuite, SQLiteTest, testUUID);
|
||||||
CppUnit_addTest(pSuite, SQLiteTest, testInternalExtraction);
|
CppUnit_addTest(pSuite, SQLiteTest, testInternalExtraction);
|
||||||
CppUnit_addTest(pSuite, SQLiteTest, testPrimaryKeyConstraint);
|
CppUnit_addTest(pSuite, SQLiteTest, testPrimaryKeyConstraint);
|
||||||
CppUnit_addTest(pSuite, SQLiteTest, testNullable);
|
CppUnit_addTest(pSuite, SQLiteTest, testNullable);
|
||||||
|
@ -100,6 +100,8 @@ public:
|
|||||||
|
|
||||||
void testDateTime();
|
void testDateTime();
|
||||||
|
|
||||||
|
void testUUID();
|
||||||
|
|
||||||
void testInternalExtraction();
|
void testInternalExtraction();
|
||||||
void testPrimaryKeyConstraint();
|
void testPrimaryKeyConstraint();
|
||||||
void testNullable();
|
void testNullable();
|
||||||
|
@ -1022,6 +1022,7 @@ working with a string:
|
|||||||
|
|
||||||
|
|
||||||
!!!Session Pooling
|
!!!Session Pooling
|
||||||
|
|
||||||
Creating a connection to a database is often a time consuming
|
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.
|
later reuse once it is no longer needed.
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "Poco/Data/LOB.h"
|
#include "Poco/Data/LOB.h"
|
||||||
#include "Poco/DateTime.h"
|
#include "Poco/DateTime.h"
|
||||||
#include "Poco/Nullable.h"
|
#include "Poco/Nullable.h"
|
||||||
|
#include "Poco/UUID.h"
|
||||||
#include "Poco/Any.h"
|
#include "Poco/Any.h"
|
||||||
#include "Poco/Dynamic/Var.h"
|
#include "Poco/Dynamic/Var.h"
|
||||||
#include "Poco/UTFString.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);
|
virtual void bind(std::size_t pos, const std::list<Time>& val, Direction dir = PD_IN);
|
||||||
/// Binds a Time list.
|
/// 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;
|
virtual void bind(std::size_t pos, const NullData& val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a null.
|
/// Binds a null.
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/Constants.h"
|
#include "Poco/Data/Constants.h"
|
||||||
#include "Poco/Data/LOB.h"
|
#include "Poco/Data/LOB.h"
|
||||||
|
#include "Poco/UUID.h"
|
||||||
#include "Poco/UTFString.h"
|
#include "Poco/UTFString.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
@ -304,6 +305,18 @@ public:
|
|||||||
virtual bool extract(std::size_t pos, std::list<Time>& val);
|
virtual bool extract(std::size_t pos, std::list<Time>& val);
|
||||||
/// Extracts a Time list.
|
/// 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;
|
virtual bool extract(std::size_t pos, Any& val) = 0;
|
||||||
/// Extracts an Any. Returns false if null was received.
|
/// Extracts an Any. Returns false if null was received.
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/RefCountedObject.h"
|
#include "Poco/RefCountedObject.h"
|
||||||
#include "Poco/Data/LOB.h"
|
#include "Poco/Data/LOB.h"
|
||||||
|
#include "Poco/UUID.h"
|
||||||
#include "Poco/UTFString.h"
|
#include "Poco/UTFString.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
@ -310,6 +311,18 @@ public:
|
|||||||
virtual void prepare(std::size_t pos, const std::list<Time>& val);
|
virtual void prepare(std::size_t pos, const std::list<Time>& val);
|
||||||
/// Prepares a Time list.
|
/// 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;
|
virtual void prepare(std::size_t pos, const Any&) = 0;
|
||||||
/// Prepares an Any.
|
/// Prepares an Any.
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ public:
|
|||||||
FDT_DATE,
|
FDT_DATE,
|
||||||
FDT_TIME,
|
FDT_TIME,
|
||||||
FDT_TIMESTAMP,
|
FDT_TIMESTAMP,
|
||||||
|
FDT_UUID,
|
||||||
FDT_UNKNOWN
|
FDT_UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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)
|
void AbstractBinder::bind(std::size_t pos, const std::vector<NullData>& val, Direction dir)
|
||||||
{
|
{
|
||||||
throw NotImplementedException("std::vector binder must be implemented.");
|
throw NotImplementedException("std::vector binder must be implemented.");
|
||||||
|
@ -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)
|
bool AbstractExtractor::extract(std::size_t pos, std::vector<Any>& val)
|
||||||
{
|
{
|
||||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||||
|
@ -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)
|
void AbstractPreparator::prepare(std::size_t pos, const std::vector<Any>& val)
|
||||||
{
|
{
|
||||||
throw NotImplementedException("std::vector preparator must be implemented.");
|
throw NotImplementedException("std::vector preparator must be implemented.");
|
||||||
|
@ -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_DATE: return value<Date>(col, row, useFilter);
|
||||||
case MetaColumn::FDT_TIME: return value<Time>(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_TIMESTAMP: return value<DateTime>(col, row);
|
||||||
|
case MetaColumn::FDT_UUID: return value<UUID>(col, row);
|
||||||
default:
|
default:
|
||||||
throw UnknownTypeException("Data type not supported.");
|
throw UnknownTypeException("Data type not supported.");
|
||||||
}
|
}
|
||||||
@ -192,6 +193,7 @@ Poco::Dynamic::Var RecordSet::value(const std::string& name, std::size_t row, bo
|
|||||||
case MetaColumn::FDT_DATE: return value<Date>(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_TIME: return value<Time>(name, row, useFilter);
|
||||||
case MetaColumn::FDT_TIMESTAMP: return value<DateTime>(name, row, useFilter);
|
case MetaColumn::FDT_TIMESTAMP: return value<DateTime>(name, row, useFilter);
|
||||||
|
case MetaColumn::FDT_UUID: return value<UUID>(name, row, useFilter);
|
||||||
default:
|
default:
|
||||||
throw UnknownTypeException("Data type not supported.");
|
throw UnknownTypeException("Data type not supported.");
|
||||||
}
|
}
|
||||||
|
@ -351,6 +351,8 @@ void StatementImpl::makeExtractors(std::size_t count)
|
|||||||
addInternalExtract<Time>(mc); break;
|
addInternalExtract<Time>(mc); break;
|
||||||
case MetaColumn::FDT_TIMESTAMP:
|
case MetaColumn::FDT_TIMESTAMP:
|
||||||
addInternalExtract<DateTime>(mc); break;
|
addInternalExtract<DateTime>(mc); break;
|
||||||
|
case MetaColumn::FDT_UUID:
|
||||||
|
addInternalExtract<UUID>(mc); break;
|
||||||
default:
|
default:
|
||||||
throw Poco::InvalidArgumentException("Data type not supported.");
|
throw Poco::InvalidArgumentException("Data type not supported.");
|
||||||
}
|
}
|
||||||
|
@ -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)
|
void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -100,8 +100,11 @@ public:
|
|||||||
void bind(std::size_t pos, const DateTime& val, Direction dir);
|
void bind(std::size_t pos, const DateTime& val, Direction dir);
|
||||||
/// Binds a DateTime.
|
/// 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);
|
void bind(std::size_t pos, const NullData& val, Direction dir);
|
||||||
/// Binds a DateTime.
|
/// Binds a NullData.
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
};
|
};
|
||||||
|
@ -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)
|
bool Extractor::extract(std::size_t pos, Poco::DateTime& val)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Extractor::extract(std::size_t pos, Poco::UUID& val)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Extractor::extract(std::size_t pos, Poco::Any& val)
|
bool Extractor::extract(std::size_t pos, Poco::Any& val)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -100,9 +100,12 @@ public:
|
|||||||
bool extract(std::size_t pos, Time& val);
|
bool extract(std::size_t pos, Time& val);
|
||||||
/// Extracts a Time.
|
/// Extracts a Time.
|
||||||
|
|
||||||
bool extract(std::size_t pos, Poco::DateTime& val);
|
bool extract(std::size_t pos, DateTime& val);
|
||||||
/// Extracts a DateTime.
|
/// 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);
|
bool isNull(std::size_t col, std::size_t row = -1);
|
||||||
/// Returns true if the current row value at pos column is null.
|
/// 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&)
|
void Preparator::prepare(std::size_t pos, const Poco::Any&)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,9 @@ public:
|
|||||||
void prepare(std::size_t pos, const Poco::DateTime&);
|
void prepare(std::size_t pos, const Poco::DateTime&);
|
||||||
/// Prepares a 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&);
|
void prepare(std::size_t pos, const Poco::Any&);
|
||||||
/// Prepares an Any.
|
/// Prepares an Any.
|
||||||
|
|
||||||
|
@ -523,6 +523,9 @@ public:
|
|||||||
bool isDateTime() const;
|
bool isDateTime() const;
|
||||||
/// Returns true if stored value represents a date/time.
|
/// Returns true if stored value represents a date/time.
|
||||||
|
|
||||||
|
bool isUUID() const;
|
||||||
|
/// Returns true if stored value is a Poco::UUID.
|
||||||
|
|
||||||
std::size_t size() const;
|
std::size_t size() const;
|
||||||
/// Returns the size of this Var.
|
/// Returns the size of this Var.
|
||||||
/// This function returns 0 when Var is empty, 1 for POD or the size (i.e. length)
|
/// This function returns 0 when Var is empty, 1 for POD or the size (i.e. length)
|
||||||
@ -896,6 +899,13 @@ inline bool Var::isDateTime() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Var::isUUID() const
|
||||||
|
{
|
||||||
|
VarHolder* pHolder = content();
|
||||||
|
return pHolder ? pHolder->isUUID() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline std::size_t Var::size() const
|
inline std::size_t Var::size() const
|
||||||
{
|
{
|
||||||
VarHolder* pHolder = content();
|
VarHolder* pHolder = content();
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "Poco/UnicodeConverter.h"
|
#include "Poco/UnicodeConverter.h"
|
||||||
#include "Poco/UTFString.h"
|
#include "Poco/UTFString.h"
|
||||||
#include "Poco/UTF8String.h"
|
#include "Poco/UTF8String.h"
|
||||||
|
#include "Poco/UUID.h"
|
||||||
#include "Poco/Any.h"
|
#include "Poco/Any.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -178,6 +179,10 @@ public:
|
|||||||
/// Throws BadCastException. Must be overridden in a type
|
/// Throws BadCastException. Must be overridden in a type
|
||||||
/// specialization in order to support the conversion.
|
/// specialization in order to support the conversion.
|
||||||
|
|
||||||
|
virtual void convert(UUID& val) const;
|
||||||
|
/// Throws BadCastException. Must be overridden in a type
|
||||||
|
/// specialization in order to support the conversion.
|
||||||
|
|
||||||
#ifndef POCO_INT64_IS_LONG
|
#ifndef POCO_INT64_IS_LONG
|
||||||
|
|
||||||
void convert(long& val) const;
|
void convert(long& val) const;
|
||||||
@ -277,6 +282,10 @@ public:
|
|||||||
/// Returns false. Must be properly overridden in a type
|
/// Returns false. Must be properly overridden in a type
|
||||||
/// specialization in order to support the diagnostic.
|
/// specialization in order to support the diagnostic.
|
||||||
|
|
||||||
|
virtual bool isUUID() const;
|
||||||
|
/// Returns false. Must be properly overridden in a type
|
||||||
|
/// specialization in order to support the diagnostic.
|
||||||
|
|
||||||
virtual std::size_t size() const;
|
virtual std::size_t size() const;
|
||||||
/// Returns 1 iff Var is not empty or this function overridden.
|
/// Returns 1 iff Var is not empty or this function overridden.
|
||||||
|
|
||||||
@ -519,8 +528,16 @@ inline void VarHolder::convert(Timestamp& /*val*/) const
|
|||||||
throw BadCastException("Can not convert to Timestamp");
|
throw BadCastException("Can not convert to Timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void VarHolder::convert(UUID& /*val*/) const
|
||||||
|
{
|
||||||
|
throw BadCastException("Can not convert to UUID");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef POCO_INT64_IS_LONG
|
#ifndef POCO_INT64_IS_LONG
|
||||||
|
|
||||||
|
|
||||||
inline void VarHolder::convert(long& val) const
|
inline void VarHolder::convert(long& val) const
|
||||||
{
|
{
|
||||||
Int32 tmp;
|
Int32 tmp;
|
||||||
@ -536,8 +553,10 @@ inline void VarHolder::convert(unsigned long& val) const
|
|||||||
val = tmp;
|
val = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
||||||
inline void VarHolder::convert(long long& /*val*/) const
|
inline void VarHolder::convert(long long& /*val*/) const
|
||||||
{
|
{
|
||||||
throw BadCastException("Can not convert to long long");
|
throw BadCastException("Can not convert to long long");
|
||||||
@ -549,8 +568,10 @@ inline void VarHolder::convert(unsigned long long& /*val*/) const
|
|||||||
throw BadCastException("Can not convert to unsigned long long");
|
throw BadCastException("Can not convert to unsigned long long");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
inline void VarHolder::convert(bool& /*val*/) const
|
inline void VarHolder::convert(bool& /*val*/) const
|
||||||
{
|
{
|
||||||
throw BadCastException("Can not convert to bool");
|
throw BadCastException("Can not convert to bool");
|
||||||
@ -671,6 +692,12 @@ inline bool VarHolder::isDateTime() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool VarHolder::isUUID() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline std::size_t VarHolder::size() const
|
inline std::size_t VarHolder::size() const
|
||||||
{
|
{
|
||||||
return 1u;
|
return 1u;
|
||||||
@ -1026,7 +1053,6 @@ public:
|
|||||||
return std::numeric_limits<Int16>::is_specialized;
|
return std::numeric_limits<Int16>::is_specialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool isString() const
|
bool isString() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -2750,6 +2776,11 @@ public:
|
|||||||
ts = tmp.timestamp();
|
ts = tmp.timestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void convert(UUID& uuid) const
|
||||||
|
{
|
||||||
|
uuid.parse(_val);
|
||||||
|
}
|
||||||
|
|
||||||
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return cloneHolder(pVarHolder, _val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
@ -3917,6 +3948,11 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isUUID() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VarHolderImpl();
|
VarHolderImpl();
|
||||||
VarHolderImpl(const VarHolderImpl&);
|
VarHolderImpl(const VarHolderImpl&);
|
||||||
@ -4047,6 +4083,11 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isUUID() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VarHolderImpl();
|
VarHolderImpl();
|
||||||
VarHolderImpl(const VarHolderImpl&);
|
VarHolderImpl(const VarHolderImpl&);
|
||||||
@ -4177,6 +4218,11 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isUUID() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VarHolderImpl();
|
VarHolderImpl();
|
||||||
VarHolderImpl(const VarHolderImpl&);
|
VarHolderImpl(const VarHolderImpl&);
|
||||||
@ -4186,6 +4232,102 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class VarHolderImpl<UUID>: public VarHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VarHolderImpl(const UUID& val): _val(val)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~VarHolderImpl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::type_info& type() const
|
||||||
|
{
|
||||||
|
return typeid(UUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void convert(std::string& val) const
|
||||||
|
{
|
||||||
|
val = _val.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
|
{
|
||||||
|
return cloneHolder(pVarHolder, _val);
|
||||||
|
}
|
||||||
|
|
||||||
|
const UUID& value() const
|
||||||
|
{
|
||||||
|
return _val;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isArray() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isStruct() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isInteger() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSigned() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNumeric() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isBoolean() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isString() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDate() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isTime() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDateTime() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isUUID() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
VarHolderImpl();
|
||||||
|
VarHolderImpl(const VarHolderImpl&);
|
||||||
|
VarHolderImpl& operator = (const VarHolderImpl&);
|
||||||
|
|
||||||
|
Poco::UUID _val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef std::vector<Var> Vector;
|
typedef std::vector<Var> Vector;
|
||||||
typedef std::deque<Var> Deque;
|
typedef std::deque<Var> Deque;
|
||||||
typedef std::list<Var> List;
|
typedef std::list<Var> List;
|
||||||
|
@ -47,7 +47,8 @@ bool isJSONString(const Var& any)
|
|||||||
any.type() == typeid(char*) ||
|
any.type() == typeid(char*) ||
|
||||||
any.type() == typeid(Poco::DateTime) ||
|
any.type() == typeid(Poco::DateTime) ||
|
||||||
any.type() == typeid(Poco::LocalDateTime) ||
|
any.type() == typeid(Poco::LocalDateTime) ||
|
||||||
any.type() == typeid(Poco::Timestamp);
|
any.type() == typeid(Poco::Timestamp) ||
|
||||||
|
any.type() == typeid(Poco::UUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2859,6 +2859,32 @@ void VarTest::testDate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VarTest::testUUID()
|
||||||
|
{
|
||||||
|
Poco::UUID uuid("f1881be4-c3b7-4a47-9619-5169db5108a7");
|
||||||
|
|
||||||
|
Var vuuid(uuid);
|
||||||
|
assertTrue (vuuid.isUUID());
|
||||||
|
|
||||||
|
assert (vuuid.convert<std::string>() == "f1881be4-c3b7-4a47-9619-5169db5108a7");
|
||||||
|
|
||||||
|
assert (vuuid.extract<Poco::UUID>() == uuid);
|
||||||
|
|
||||||
|
Var vstr(std::string("f1881be4-c3b7-4a47-9619-5169db5108a7"));
|
||||||
|
assert (vstr.convert<Poco::UUID>() == uuid);
|
||||||
|
|
||||||
|
Var vstr2(std::string("notAnUUID"));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Poco::UUID uuid2 = vstr2.convert<Poco::UUID>();
|
||||||
|
fail("not a valid UUID, must fail");
|
||||||
|
}
|
||||||
|
catch (Poco::SyntaxException&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void VarTest::testGetIdxNoThrow(Var& a1, std::vector<Var>::size_type n)
|
void VarTest::testGetIdxNoThrow(Var& a1, std::vector<Var>::size_type n)
|
||||||
{
|
{
|
||||||
Var val1 = a1[n];
|
Var val1 = a1[n];
|
||||||
@ -3104,6 +3130,7 @@ CppUnit::Test* VarTest::suite()
|
|||||||
CppUnit_addTest(pSuite, VarTest, testJSONDeserializeComplex);
|
CppUnit_addTest(pSuite, VarTest, testJSONDeserializeComplex);
|
||||||
CppUnit_addTest(pSuite, VarTest, testJSONRoundtripStruct);
|
CppUnit_addTest(pSuite, VarTest, testJSONRoundtripStruct);
|
||||||
CppUnit_addTest(pSuite, VarTest, testDate);
|
CppUnit_addTest(pSuite, VarTest, testDate);
|
||||||
|
CppUnit_addTest(pSuite, VarTest, testUUID);
|
||||||
CppUnit_addTest(pSuite, VarTest, testEmpty);
|
CppUnit_addTest(pSuite, VarTest, testEmpty);
|
||||||
CppUnit_addTest(pSuite, VarTest, testIterator);
|
CppUnit_addTest(pSuite, VarTest, testIterator);
|
||||||
|
|
||||||
|
@ -74,10 +74,10 @@ public:
|
|||||||
void testJSONRoundtripStruct();
|
void testJSONRoundtripStruct();
|
||||||
void testJSONDeserializeComplex();
|
void testJSONDeserializeComplex();
|
||||||
void testDate();
|
void testDate();
|
||||||
|
void testUUID();
|
||||||
void testEmpty();
|
void testEmpty();
|
||||||
void testIterator();
|
void testIterator();
|
||||||
|
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
static CppUnit::Test* suite();
|
static CppUnit::Test* suite();
|
||||||
|
Loading…
Reference in New Issue
Block a user