Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Add UUID support in Poco::Data and Poco::Data::ODBC #2699

Closed
klion-ru opened this issue May 21, 2019 · 1 comment
Closed
Assignees

Comments

@klion-ru
Copy link

Expected behavior

I would like to use Poco::UUID with Poco::Data::ODBC

in SQL requests.

Actual behavior

Now, it is impossible in all version of Poco.

Steps to reproduce the problem

Some my changes are attached below.

POCO version

1.9.1

Compiler and version

Visual Studio 2015

Operating system and version

Windows 7

Other relevant information

Patch:
poco-1.9.1_uuid_in_odbc.patch.txt

diff --git a/Data/include/Poco/Data/AbstractBinder.h b/Data/include/Poco/Data/AbstractBinder.h
index d88efba..be082f2 100644
--- a/Data/include/Poco/Data/AbstractBinder.h
+++ b/Data/include/Poco/Data/AbstractBinder.h
@@ -27,6 +27,7 @@
 #include "Poco/Any.h"
 #include "Poco/Dynamic/Var.h"
 #include "Poco/UTFString.h"
+#include "Poco/UUID.h"
 #include <vector>
 #include <deque>
 #include <list>
@@ -37,14 +38,22 @@ namespace Poco {
 namespace Data {
 
 
-typedef NullType NullData;
-
+enum NullData
+{
+	NULL_GENERIC = Poco::NULL_GENERIC,
+	DATA_NULL_INTEGER = 1,
+	DATA_NULL_STRING = 2,
+	DATA_NULL_DATE = 3,
+	DATA_NULL_TIME = 4,
+	DATA_NULL_DATETIME = 5,
+	DATA_NULL_BLOB = 6,
+	DATA_NULL_FLOAT = 7,
+	DATA_NULL_UUID = 8
+};
 
 namespace Keywords {
 
-
-static const NullData null = NULL_GENERIC;
-
+	static const NullData null = NULL_GENERIC;
 
 } // namespace Keywords
 
@@ -329,6 +338,18 @@ public:
 	virtual void bind(std::size_t pos, const std::list<NullData>& val, Direction dir = PD_IN);
 		/// Binds a null list.
 
+	virtual void bind(std::size_t pos, const Poco::UUID& val, Direction dir = PD_IN) = 0;
+	/// Binds a UUID. In-bound only.
+
+	virtual void bind(std::size_t pos, const std::vector<Poco::UUID>& val, Direction dir = PD_IN);
+	/// Binds a UUID vector.
+
+	virtual void bind(std::size_t pos, const std::deque<Poco::UUID>& val, Direction dir = PD_IN);
+	/// Binds a UUID deque.
+
+	virtual void bind(std::size_t pos, const std::list<Poco::UUID>& val, Direction dir = PD_IN);
+	/// Binds a UUID list.
+
 	void bind(std::size_t pos, const Any& val, Direction dir = PD_IN);
 		/// Binds an Any.
 	
diff --git a/Data/include/Poco/Data/AbstractExtractor.h b/Data/include/Poco/Data/AbstractExtractor.h
index aa973bc..80ad78f 100644
--- a/Data/include/Poco/Data/AbstractExtractor.h
+++ b/Data/include/Poco/Data/AbstractExtractor.h
@@ -22,6 +22,7 @@
 #include "Poco/Data/Constants.h"
 #include "Poco/Data/LOB.h"
 #include "Poco/UTFString.h"
+#include "Poco/UUID.h"
 #include <vector>
 #include <deque>
 #include <list>
@@ -328,6 +329,18 @@ public:
 	virtual bool extract(std::size_t pos, std::list<Poco::Dynamic::Var>& val);
 		/// Extracts a Var list.
 
+	virtual bool extract(std::size_t pos, Poco::UUID& val) = 0;
+		/// Extracts an UUID.
+
+	virtual bool extract(std::size_t pos, std::vector<Poco::UUID>& val);
+		/// Extracts an UUID vector.
+
+	virtual bool extract(std::size_t pos, std::deque<Poco::UUID>& val);
+		/// Extracts an UUID deque.
+
+	virtual bool extract(std::size_t pos, std::list<Poco::UUID>& val);
+		/// Extracts an UUID list.
+
 	virtual bool isNull(std::size_t col, std::size_t row = POCO_DATA_INVALID_ROW) = 0;
 		/// Returns true if the value at [col,row] position is null.
 
diff --git a/Data/include/Poco/Data/AbstractPreparator.h b/Data/include/Poco/Data/AbstractPreparator.h
index da086b0..5082afe 100644
--- a/Data/include/Poco/Data/AbstractPreparator.h
+++ b/Data/include/Poco/Data/AbstractPreparator.h
@@ -22,6 +22,7 @@
 #include "Poco/RefCountedObject.h"
 #include "Poco/Data/LOB.h"
 #include "Poco/UTFString.h"
+#include "Poco/UUID.h"
 #include <vector>
 #include <deque>
 #include <list>
@@ -334,6 +335,18 @@ public:
 	virtual void prepare(std::size_t pos, const std::list<Poco::Dynamic::Var>& val);
 		/// Prepares a Var list.
 
+	virtual void prepare(std::size_t pos, const Poco::UUID& val) = 0;
+		/// Prepares an UUID.
+
+	virtual void prepare(std::size_t pos, const std::vector<Poco::UUID>& val);
+		/// Prepares an UUID vector.
+
+	virtual void prepare(std::size_t pos, const std::deque<Poco::UUID>& val);
+		/// Prepares an UUID deque.
+
+	virtual void prepare(std::size_t pos, const std::list<Poco::UUID>& val);
+		/// Prepares an UUID list.
+
 	void setLength(Poco::UInt32 length);
 		/// Sets the length of prepared data.
 		/// Needed only for data lengths greater than 1 (i.e. for
diff --git a/Data/include/Poco/Data/TypeHandler.h b/Data/include/Poco/Data/TypeHandler.h
index 4a2424c..764ee9c 100644
--- a/Data/include/Poco/Data/TypeHandler.h
+++ b/Data/include/Poco/Data/TypeHandler.h
@@ -26,6 +26,7 @@
 #include "Poco/Tuple.h"
 #include "Poco/AutoPtr.h"
 #include "Poco/SharedPtr.h"
+#include "Poco/UUID.h"
 #include <cstddef>
 
 
@@ -308,6 +309,66 @@ private:
 	TypeHandler& operator=(const TypeHandler&);
 };
 
+void 
+TypeHandler<Nullable<Poco::UUID> >::
+bind(std::size_t pos, const Nullable<Poco::UUID>& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
+{
+	poco_assert_dbg(!pBinder.isNull());
+	if (obj.isNull())
+	{
+		pBinder->bind(pos++, Poco::Data::DATA_NULL_UUID, dir);
+	}
+	else
+	{
+		pBinder->bind(pos++, obj.value(), dir);
+	}
+}
+
+void
+TypeHandler<Nullable<Poco::UUID> >::
+prepare(std::size_t pos, const Nullable<Poco::UUID>& obj, AbstractPreparator::Ptr pPreparator)
+{
+	poco_assert_dbg(!pPreparator.isNull());
+	if (obj.isNull())
+	{
+		pPreparator->prepare(pos++, Poco::Data::DATA_NULL_UUID);
+	}
+	else
+	{
+		pPreparator->prepare(pos++, obj.value());
+	}
+}
+
+void
+TypeHandler<Nullable<Poco::DateTime> >::
+bind(std::size_t pos, const Nullable<DateTime>& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
+{
+	poco_assert_dbg(!pBinder.isNull());
+	if (obj.isNull())
+	{
+		pBinder->bind(pos++, Poco::Data::DATA_NULL_DATETIME, dir);
+	}
+	else
+	{
+		pBinder->bind(pos++, obj.value(), dir);
+	}
+}
+
+void
+TypeHandler<Nullable<Poco::DateTime> >::
+prepare(std::size_t pos, const Nullable<Poco::DateTime>& obj, AbstractPreparator::Ptr pPreparator)
+{
+	poco_assert_dbg(!pPreparator.isNull());
+	if (obj.isNull())
+	{
+		pPreparator->prepare(pos++, Poco::Data::DATA_NULL_DATETIME);
+	}
+	else
+	{
+		pPreparator->prepare(pos++, obj.value());
+	}
+}
+
 
 /// Poco::Tuple TypeHandler specializations
 
diff --git a/Data/ODBC/include/Poco/Data/ODBC/Binder.h b/Data/ODBC/include/Poco/Data/ODBC/Binder.h
index 0d3c38e..3698a5c 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/Binder.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/Binder.h
@@ -27,6 +27,7 @@
 #include "Poco/Data/ODBC/Utility.h"
 #include "Poco/Data/ODBC/TypeInfo.h"
 #include "Poco/Exception.h"
+#include "Poco/UUID.h"
 #include <vector>
 #include <deque>
 #include <list>
@@ -334,6 +335,18 @@ public:
 	void bind(std::size_t pos, const std::list<NullData>& val, Direction dir);
 		/// Binds a null list.
 
+	void bind(std::size_t pos, const Poco::UUID& val, Direction dir);
+	/// Binds a UUID. In-bound only.
+
+	void bind(std::size_t pos, const std::vector<Poco::UUID>& val, Direction dir);
+	/// Binds a UUID vector.
+
+	void bind(std::size_t pos, const std::deque<Poco::UUID>& val, Direction dir);
+	/// Binds a UUID deque.
+
+	void bind(std::size_t pos, const std::list<Poco::UUID>& val, Direction dir);
+	/// Binds a UUID list.
+
 	void setDataBinding(ParameterBinding binding);
 		/// Set data binding type.
 
@@ -1497,6 +1510,24 @@ inline void Binder::bind(std::size_t pos, const std::list<NullData>& val, Direct
 	bindImplNullContainer(pos, val, dir);
 }
 
+inline void Binder::bind(std::size_t pos, const std::vector<Poco::UUID>& val, Direction dir)
+{
+	bindImplVec(pos, val, SQL_C_BINARY, dir);
+}
+
+
+inline void Binder::bind(std::size_t pos, const std::deque<Poco::UUID>& val, Direction dir)
+{
+	bindImplContainer(pos, val, SQL_C_BINARY, dir);
+}
+
+
+inline void Binder::bind(std::size_t pos, const std::list<Poco::UUID>& val, Direction dir)
+{
+	bindImplContainer(pos, val, SQL_C_BINARY, dir);
+}
+
+
 
 inline void Binder::setDataBinding(Binder::ParameterBinding binding)
 {
diff --git a/Data/ODBC/include/Poco/Data/ODBC/Extractor.h b/Data/ODBC/include/Poco/Data/ODBC/Extractor.h
index f3ce016..5a93803 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/Extractor.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/Extractor.h
@@ -30,6 +30,7 @@
 #include "Poco/DateTime.h"
 #include "Poco/Any.h"
 #include "Poco/Dynamic/Var.h"
+#include "Poco/UUID.h"
 #include "Poco/Nullable.h"
 #include "Poco/UTFString.h"
 #include "Poco/Exception.h"
@@ -329,6 +330,18 @@ public:
 	bool extract(std::size_t pos, std::list<Poco::DynamicAny>& val);
 		/// Extracts a DynamicAny list.
 
+	bool extract(std::size_t pos, Poco::UUID& val);
+	/// Extracts an UUID.
+
+	bool extract(std::size_t pos, std::vector<Poco::UUID>& val);
+	/// Extracts an UUID vector.
+
+	bool extract(std::size_t pos, std::deque<Poco::UUID>& val);
+	/// Extracts an UUID deque.
+
+	bool extract(std::size_t pos, std::list<Poco::UUID>& val);
+	/// Extracts an UUID list.
+
 	void setDataExtraction(Preparator::DataExtraction ext);
 		/// Set data extraction mode.
 
diff --git a/Data/ODBC/include/Poco/Data/ODBC/Preparator.h b/Data/ODBC/include/Poco/Data/ODBC/Preparator.h
index aa38ea2..60b3c79 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/Preparator.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/Preparator.h
@@ -27,6 +27,7 @@
 #include "Poco/Data/LOB.h"
 #include "Poco/Any.h"
 #include "Poco/DynamicAny.h"
+#include "Poco/UUID.h"
 #include "Poco/DateTime.h"
 #include "Poco/SharedPtr.h"
 #include "Poco/UTFString.h"
@@ -377,6 +378,19 @@ public:
 	void prepare(std::size_t pos, const std::list<Poco::DynamicAny>& val);
 		/// Prepares a DynamicAny list.
 
+	void prepare(std::size_t pos, const Poco::UUID& val);
+	/// Prepares an UUID.
+
+	void prepare(std::size_t pos, const std::vector<Poco::UUID>& val);
+	/// Prepares an UUID vector.
+
+	void prepare(std::size_t pos, const std::deque<Poco::UUID>& val);
+	/// Prepares an UUID deque.
+
+	void prepare(std::size_t pos, const std::list<Poco::UUID>& val);
+	/// Prepares an UUID list.
+
+
 	std::size_t columns() const;
 		/// Returns the number of columns.
 		/// Resizes the internal storage iff the size is zero.
@@ -886,7 +900,7 @@ inline void Preparator::prepare(std::size_t pos, const long&)
 
 inline void Preparator::prepare(std::size_t pos, const unsigned long&)
 {
-	prepareFixedSize<long>(pos, SQL_C_SLONG);
+	prepareFixedSize<unsigned long>(pos, SQL_C_ULONG); //klion 20.01.2017
 }
 
 
@@ -1220,6 +1234,28 @@ inline void Preparator::prepare(std::size_t pos, const std::list<Poco::DynamicAn
 	prepareImpl<std::list<Poco::DynamicAny> >(pos, &val);
 }
 
+inline void Preparator::prepare(std::size_t pos, const Poco::UUID&)
+{
+	prepareFixedSize<Poco::UUID>(pos, SQL_C_BINARY); // SQL_C_GUID
+}
+
+
+inline void Preparator::prepare(std::size_t pos, const std::vector<Poco::UUID>& val)
+{
+	prepareFixedSize<Poco::UUID>(pos, SQL_C_BINARY, val.size()); // SQL_C_GUID
+}
+
+
+inline void Preparator::prepare(std::size_t pos, const std::deque<Poco::UUID>& val)
+{
+	prepareFixedSize<Poco::UUID>(pos, SQL_C_BINARY, val.size()); // SQL_C_GUID
+}
+
+
+inline void Preparator::prepare(std::size_t pos, const std::list<Poco::UUID>& val)
+{
+	prepareFixedSize<Poco::UUID>(pos, SQL_C_BINARY, val.size()); // SQL_C_GUID
+}
 
 inline std::size_t Preparator::bulkSize(std::size_t col) const
 {
diff --git a/Data/ODBC/src/Binder.cpp b/Data/ODBC/src/Binder.cpp
index 1031b77..1e992cc 100644
--- a/Data/ODBC/src/Binder.cpp
+++ b/Data/ODBC/src/Binder.cpp
@@ -128,6 +128,9 @@ void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
 
 	_lengthIndicator.push_back(pLenIn);
 
+	if (colSize == 8000 && colSize < size) //klion 20.01.2017
+		colSize = size;
+
 	if (Utility::isError(SQLBindParameter(_rStmt, 
 		(SQLUSMALLINT) pos + 1, 
 		toODBCDirection(dir), 
@@ -179,6 +182,9 @@ void Binder::bind(std::size_t pos, const UTF16String& val, Direction dir)
 
 	_lengthIndicator.push_back(pLenIn);
 
+	if (colSize == 4000 && colSize < size) //klion 20.01.2017
+		colSize = size;
+
 	if (Utility::isError(SQLBindParameter(_rStmt,
 		(SQLUSMALLINT)pos + 1,
 		toODBCDirection(dir),
@@ -301,6 +307,13 @@ void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
 
 	_inParams.insert(ParamMap::value_type(SQLPOINTER(0), SQLINTEGER(0)));
 
+	int cDataType = SQL_C_TINYINT; // klion
+	switch (val)
+	{
+		case DATA_NULL_UUID: cDataType = SQL_C_GUID; break; // klion
+		case DATA_NULL_DATETIME: cDataType = SQL_C_TYPE_TIMESTAMP; break; // klion
+	}
+
 	SQLLEN* pLenIn = new SQLLEN;
 	*pLenIn  = SQL_NULL_DATA;
 
@@ -308,13 +321,13 @@ void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
 
 	SQLINTEGER colSize = 0;
 	SQLSMALLINT decDigits = 0;
-	getColSizeAndPrecision(pos, SQL_C_STINYINT, colSize, decDigits);
+	getColSizeAndPrecision(pos, cDataType, colSize, decDigits);
 
 	if (Utility::isError(SQLBindParameter(_rStmt, 
 		(SQLUSMALLINT) pos + 1, 
 		SQL_PARAM_INPUT, 
-		SQL_C_STINYINT, 
-		Utility::sqlDataType(SQL_C_STINYINT), 
+		cDataType,
+		Utility::sqlDataType(cDataType),
 		colSize,
 		decDigits,
 		0, 
@@ -325,6 +338,28 @@ void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
 	}
 }
 
+void Binder::bind(std::size_t pos, const Poco::UUID& val, Direction dir)
+{
+	SQLINTEGER colSize = 16; // sizeof(Poco::UUID);
+	SQLSMALLINT decDigits = 0;
+
+	SQLLEN* pLenIn = new SQLLEN;
+	*pLenIn = colSize;
+
+	_lengthIndicator.push_back(pLenIn);
+
+	if (Utility::isError(SQLBindParameter(_rStmt,
+		(SQLUSMALLINT)pos + 1,
+		toODBCDirection(dir),
+		SQL_C_GUID, 
+		SQL_GUID,
+		colSize,
+		decDigits,
+		(SQLPOINTER)&val, 0, _lengthIndicator.back())))
+	{
+		throw StatementException(_rStmt, "SQLBindParameter()");
+	}
+}
 
 std::size_t Binder::parameterSize(SQLPOINTER pAddr) const
 {
@@ -437,6 +472,15 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
 		if (found)
 		{
 			decDigits = tmp;
+			if (cDataType == SQL_TYPE_TIMESTAMP) //klion 20.01.2017
+			{
+				found = _pTypeInfo->tryGetInfo(cDataType, "MAXIMUM_SCALE", tmp);
+				if (found)
+				{
+					if (decDigits < tmp)
+						decDigits = tmp;
+				}
+			}
 			return;
 		}
 	}
@@ -448,8 +492,11 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
 		decDigits = (SQLSMALLINT) p.decimalDigits();
 		return;
 	} 
-	catch (StatementException&)
+	catch (StatementException& e)
 	{ 
+#ifdef _DEBUG
+		e.toString();
+#endif
 	}
 
 	try
@@ -459,8 +506,11 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
 		decDigits = (SQLSMALLINT) c.precision();
 		return;
 	} 
-	catch (StatementException&) 
+	catch (StatementException& e) 
 	{ 
+#ifdef _DEBUG
+		e.toString();
+#endif
 	}
 
 	// last check, just in case
diff --git a/Data/ODBC/src/Extractor.cpp b/Data/ODBC/src/Extractor.cpp
index 046e3e3..38804c4 100644
--- a/Data/ODBC/src/Extractor.cpp
+++ b/Data/ODBC/src/Extractor.cpp
@@ -1299,6 +1299,42 @@ bool Extractor::extract(std::size_t pos, std::list<Poco::DynamicAny>& val)
 		throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
 }
 
+bool Extractor::extract(std::size_t pos, Poco::UUID& val)
+{
+	if (Preparator::DE_MANUAL == _dataExtraction)
+		return extractManualImpl(pos, val, SQL_C_BINARY); // SQL_C_GUID
+	else
+		return extractBoundImpl(pos, val);
+}
+
+
+bool Extractor::extract(std::size_t pos, std::vector<Poco::UUID>& val)
+{
+	if (Preparator::DE_BOUND == _dataExtraction)
+		return extractBoundImplContainer(pos, val);
+	else
+		throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
+}
+
+
+bool Extractor::extract(std::size_t pos, std::deque<Poco::UUID>& val)
+{
+	if (Preparator::DE_BOUND == _dataExtraction)
+		return extractBoundImplContainer(pos, val);
+	else
+		throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
+}
+
+
+bool Extractor::extract(std::size_t pos, std::list<Poco::UUID>& val)
+{
+	if (Preparator::DE_BOUND == _dataExtraction)
+		return extractBoundImplContainer(pos, val);
+	else
+		throw InvalidAccessException("Direct container extraction only allowed for bound mode.");
+}
+
+
 
 bool Extractor::isNull(std::size_t col, std::size_t row)
 {
diff --git a/Data/ODBC/src/Preparator.cpp b/Data/ODBC/src/Preparator.cpp
index 1b00eca..16754b8 100644
--- a/Data/ODBC/src/Preparator.cpp
+++ b/Data/ODBC/src/Preparator.cpp
@@ -158,7 +158,8 @@ std::size_t Preparator::maxDataSize(std::size_t pos) const
 
 		// accomodate for terminating zero (non-bulk only!)
 		MetaColumn::ColumnDataType type = mc.type();
-		if (!isBulk() && ((ODBCMetaColumn::FDT_WSTRING == type) || (ODBCMetaColumn::FDT_STRING == type))) ++sz;
+                //klion 20.01.2017
+		if (sz > 0 && !isBulk() && ((ODBCMetaColumn::FDT_WSTRING == type) || (ODBCMetaColumn::FDT_STRING == type))) ++sz;
 	}
 	catch (StatementException&) { }
 
diff --git a/Data/ODBC/src/TypeInfo.cpp b/Data/ODBC/src/TypeInfo.cpp
index ca5aa0e..6444500 100644
--- a/Data/ODBC/src/TypeInfo.cpp
+++ b/Data/ODBC/src/TypeInfo.cpp
@@ -57,6 +57,7 @@ void TypeInfo::fillCTypes()
 	_cDataTypes.insert(ValueType(SQL_TYPE_DATE, SQL_C_TYPE_DATE));
 	_cDataTypes.insert(ValueType(SQL_TYPE_TIME, SQL_C_TYPE_TIME));
 	_cDataTypes.insert(ValueType(SQL_TYPE_TIMESTAMP, SQL_C_TYPE_TIMESTAMP));
+	_cDataTypes.insert(ValueType(SQL_GUID, SQL_C_GUID));
 }
 
 
@@ -81,6 +82,7 @@ void TypeInfo::fillSQLTypes()
 	_sqlDataTypes.insert(ValueType(SQL_C_TYPE_DATE, SQL_TYPE_DATE));
 	_sqlDataTypes.insert(ValueType(SQL_C_TYPE_TIME, SQL_TYPE_TIME));
 	_sqlDataTypes.insert(ValueType(SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP));
+	_sqlDataTypes.insert(ValueType(SQL_C_GUID, SQL_GUID));
 }
 
 
diff --git a/Data/ODBC/src/Unicode_WIN32.cpp b/Data/ODBC/src/Unicode_WIN32.cpp
index fe637e4..d78f430 100644
--- a/Data/ODBC/src/Unicode_WIN32.cpp
+++ b/Data/ODBC/src/Unicode_WIN32.cpp
@@ -331,7 +331,7 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType,
 		pcbErrorMsg);
 
 	makeUTF8(bufState, stateLen * sizeof(wchar_t), szSqlState, stateLen);
-	makeUTF8(bufErr, *pcbErrorMsg * sizeof(wchar_t), szErrorMsg, cbErrorMsgMax);
+	makeUTF8(bufErr, *pcbErrorMsg * sizeof(wchar_t), szErrorMsg, cbErrorMsgMax-1);  //klion 20.01.2017
 
 	return rc;
 }
diff --git a/Data/ODBC/testsuite/src/SQLExecutor.cpp b/Data/ODBC/testsuite/src/SQLExecutor.cpp
index 483af8f..7d1ae85 100644
--- a/Data/ODBC/testsuite/src/SQLExecutor.cpp
+++ b/Data/ODBC/testsuite/src/SQLExecutor.cpp
@@ -3003,7 +3003,7 @@ void SQLExecutor::notNulls(const std::string& sqlState)
 {
 	try
 	{
-		session() << "INSERT INTO NullTest (i,r,v) VALUES (?,?,?)", use(null), use(null), use(null), now;
+		session() << "INSERT INTO NullTest (i,r,v) VALUES (?,?,?)", use(Poco::Data::Keywords::null), use(Poco::Data::Keywords::null), use(Poco::Data::Keywords::null), now;
 		fail ("must fail");
 	}catch (StatementException& se) 
 	{ 
diff --git a/Data/src/AbstractBinder.cpp b/Data/src/AbstractBinder.cpp
index 4854467..3ff153d 100644
--- a/Data/src/AbstractBinder.cpp
+++ b/Data/src/AbstractBinder.cpp
@@ -421,6 +421,23 @@ void AbstractBinder::bind(std::size_t pos, const std::list<NullData>& val, Direc
 	throw NotImplementedException("std::list binder must be implemented.");
 }
 
+void AbstractBinder::bind(std::size_t pos, const std::vector<Poco::UUID>& val, Direction dir)
+{
+	throw NotImplementedException("std::vector binder must be implemented.");
+}
+
+
+void AbstractBinder::bind(std::size_t pos, const std::deque<Poco::UUID>& val, Direction dir)
+{
+	throw NotImplementedException("std::deque binder must be implemented.");
+}
+
+
+void AbstractBinder::bind(std::size_t pos, const std::list<Poco::UUID>& val, Direction dir)
+{
+	throw NotImplementedException("std::list binder must be implemented.");
+}
+
 
 void AbstractBinder::bind(std::size_t pos, const Any& val, Direction dir)
 {
@@ -463,7 +480,7 @@ void AbstractBinder::bind(std::size_t pos, const Any& val, Direction dir)
 	else if(type == typeid(BLOB))
 		bind(pos, RefAnyCast<BLOB>(val), dir);
 	else if(type == typeid(void))
-		bind(pos, Keywords::null, dir);
+		bind(pos, NULL_GENERIC, dir);
 #ifndef POCO_LONG_IS_64_BIT
 	else if(type == typeid(long))
 		bind(pos, RefAnyCast<long>(val), dir);
@@ -514,7 +531,7 @@ void AbstractBinder::bind(std::size_t pos, const Poco::Dynamic::Var& val, Direct
 	else if(type == typeid(BLOB))
 		bind(pos, val.extract<BLOB>(), dir);
 	else if(type == typeid(void))
-		bind(pos, Keywords::null, dir);
+		bind(pos, NULL_GENERIC, dir);
 #ifndef POCO_LONG_IS_64_BIT
 	else if(type == typeid(long))
 		bind(pos, val.extract<long>(), dir);
diff --git a/Data/src/AbstractExtractor.cpp b/Data/src/AbstractExtractor.cpp
index 566c721..11b9187 100644
--- a/Data/src/AbstractExtractor.cpp
+++ b/Data/src/AbstractExtractor.cpp
@@ -433,5 +433,22 @@ bool AbstractExtractor::extract(std::size_t pos, std::list<Poco::Dynamic::Var>&
 	throw NotImplementedException("std::list extractor must be implemented.");
 }
 
+bool AbstractExtractor::extract(std::size_t pos, std::vector<Poco::UUID>& val)
+{
+	throw NotImplementedException("std::vector extractor must be implemented.");
+}
+
+
+bool AbstractExtractor::extract(std::size_t pos, std::deque<Poco::UUID>& val)
+{
+	throw NotImplementedException("std::deque extractor must be implemented.");
+}
+
+
+bool AbstractExtractor::extract(std::size_t pos, std::list<Poco::UUID>& val)
+{
+	throw NotImplementedException("std::list extractor must be implemented.");
+}
+
 
 } } // namespace Poco::Data
diff --git a/Data/src/AbstractPreparator.cpp b/Data/src/AbstractPreparator.cpp
index 58eb4fb..e8309a3 100644
--- a/Data/src/AbstractPreparator.cpp
+++ b/Data/src/AbstractPreparator.cpp
@@ -434,5 +434,20 @@ void AbstractPreparator::prepare(std::size_t pos, const std::list<Poco::Dynamic:
 	throw NotImplementedException("std::list preparator must be implemented.");
 }
 
+void AbstractPreparator::prepare(std::size_t pos, const std::vector<Poco::UUID>& val)
+{
+	throw NotImplementedException("std::vector preparator must be implemented.");
+}
+
+void AbstractPreparator::prepare(std::size_t pos, const std::deque<Poco::UUID>& val)
+{
+	throw NotImplementedException("std::deque preparator must be implemented.");
+}
+
+void AbstractPreparator::prepare(std::size_t pos, const std::list<Poco::UUID>& val)
+{
+	throw NotImplementedException("std::list preparator must be implemented.");
+}
+
 
 } } // namespace Poco::Data
diff --git a/Data/testsuite/src/Binder.cpp b/Data/testsuite/src/Binder.cpp
index c85c26f..1040328 100644
--- a/Data/testsuite/src/Binder.cpp
+++ b/Data/testsuite/src/Binder.cpp
@@ -144,6 +144,10 @@ void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
 {
 }
 
+void Binder::bind(std::size_t pos, const Poco::UUID& val, Direction dir)
+{
+}
+
 
 void Binder::reset()
 {
diff --git a/Data/testsuite/src/Binder.h b/Data/testsuite/src/Binder.h
index 8aa0038..53011f0 100644
--- a/Data/testsuite/src/Binder.h
+++ b/Data/testsuite/src/Binder.h
@@ -101,7 +101,10 @@ public:
 		/// Binds a DateTime.
 
 	void bind(std::size_t pos, const NullData& val, Direction dir);
-		/// Binds a DateTime.
+		/// Binds a NullData.
+	
+	void bind(std::size_t pos, const Poco::UUID& val, Direction dir);
+		/// Binds a UUID.
 
 	void reset();
 };
diff --git a/Data/testsuite/src/Extractor.cpp b/Data/testsuite/src/Extractor.cpp
index 5808ffe..34cfe39 100644
--- a/Data/testsuite/src/Extractor.cpp
+++ b/Data/testsuite/src/Extractor.cpp
@@ -184,5 +184,9 @@ bool Extractor::extract(std::size_t pos, Poco::Dynamic::Var& val)
 	return true;
 }
 
+bool Extractor::extract(std::size_t pos, Poco::UUID& val)
+{
+	return true;
+}
 
 } } } // namespace Poco::Data::Test
diff --git a/Data/testsuite/src/Extractor.h b/Data/testsuite/src/Extractor.h
index b3da759..57607b1 100644
--- a/Data/testsuite/src/Extractor.h
+++ b/Data/testsuite/src/Extractor.h
@@ -62,6 +62,9 @@ public:
 	bool extract(std::size_t pos, Poco::Dynamic::Var& val);
 		/// Extracts a Var.
 
+	bool extract(std::size_t pos, Poco::UUID& val);
+		/// Extracts an UUID.
+
 #ifndef POCO_LONG_IS_64_BIT
 	bool extract(std::size_t pos, long& val);
 		/// Extracts a long.
diff --git a/Data/testsuite/src/Preparator.cpp b/Data/testsuite/src/Preparator.cpp
index 7c65f69..36e0877 100644
--- a/Data/testsuite/src/Preparator.cpp
+++ b/Data/testsuite/src/Preparator.cpp
@@ -144,5 +144,9 @@ void Preparator::prepare(std::size_t pos, const Poco::Dynamic::Var&)
 {
 }
 
+void Preparator::prepare(std::size_t pos, const Poco::UUID&)
+{
+}
+
 
 } } } // namespace Poco::Data::Test
diff --git a/Data/testsuite/src/Preparator.h b/Data/testsuite/src/Preparator.h
index 79460d4..6d7e675 100644
--- a/Data/testsuite/src/Preparator.h
+++ b/Data/testsuite/src/Preparator.h
@@ -103,6 +103,9 @@ public:
 
 	void prepare(std::size_t pos, const Poco::Dynamic::Var&);
 		/// Prepares a Var.
+	
+	void prepare(std::size_t pos, const Poco::UUID& val);
+		/// Prepares an UUID.
 };
@obiltschnig
Copy link
Member

See #3318

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants