mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-27 11:06:50 +01:00
* Implement extraction of Dynamic::Var and Any in MySQL extractor (#1863) * Remove probably unnecessary include <my_global.h> from SQLExecutor
This commit is contained in:
committed by
Aleksandar Fabijanic
parent
e59fba4ddd
commit
fe7230a6d5
@@ -25,6 +25,8 @@
|
|||||||
#include "Poco/Data/MySQL/ResultMetadata.h"
|
#include "Poco/Data/MySQL/ResultMetadata.h"
|
||||||
#include "Poco/Data/AbstractExtractor.h"
|
#include "Poco/Data/AbstractExtractor.h"
|
||||||
#include "Poco/Data/LOB.h"
|
#include "Poco/Data/LOB.h"
|
||||||
|
#include "Poco/Data/Date.h"
|
||||||
|
#include "Poco/Data/Time.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
@@ -324,6 +326,17 @@ private:
|
|||||||
bool realExtractFixed(std::size_t pos, enum_field_types type, void* buffer, bool isUnsigned = false);
|
bool realExtractFixed(std::size_t pos, enum_field_types type, void* buffer, bool isUnsigned = false);
|
||||||
bool realExtractFixedBlob(std::size_t pos, enum_field_types type, void* buffer, size_t len);
|
bool realExtractFixedBlob(std::size_t pos, enum_field_types type, void* buffer, size_t len);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T extractAny(std::size_t pos, bool& success)
|
||||||
|
{
|
||||||
|
T value;
|
||||||
|
success = extract(pos, value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool extractToDynamic(std::size_t pos, T& val);
|
||||||
|
|
||||||
// Prevent VC8 warning "operator= could not be generated"
|
// Prevent VC8 warning "operator= could not be generated"
|
||||||
Extractor& operator=(const Extractor&);
|
Extractor& operator=(const Extractor&);
|
||||||
|
|
||||||
@@ -333,6 +346,97 @@ private:
|
|||||||
ResultMetadata& _metadata;
|
ResultMetadata& _metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool Extractor::extractToDynamic(std::size_t pos, T &val)
|
||||||
|
{
|
||||||
|
MetaColumn::ColumnDataType columnType = _metadata.metaColumn(static_cast<Poco::UInt32>(pos)).type();
|
||||||
|
|
||||||
|
T resultValue;
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
switch (columnType)
|
||||||
|
{
|
||||||
|
case MetaColumn::FDT_BOOL:
|
||||||
|
resultValue = extractAny<bool>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_INT8:
|
||||||
|
resultValue = extractAny<Int8>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_UINT8:
|
||||||
|
resultValue = extractAny<UInt8>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_INT16:
|
||||||
|
resultValue = extractAny<Int16>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_UINT16:
|
||||||
|
resultValue = extractAny<UInt16>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_INT32:
|
||||||
|
resultValue = extractAny<Int32>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_UINT32:
|
||||||
|
resultValue = extractAny<UInt32>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_INT64:
|
||||||
|
resultValue = extractAny<Int64>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_UINT64:
|
||||||
|
resultValue = extractAny<UInt64>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_FLOAT:
|
||||||
|
resultValue = extractAny<float>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_DOUBLE:
|
||||||
|
resultValue = extractAny<double>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_STRING:
|
||||||
|
resultValue = extractAny<std::string>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_WSTRING:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_BLOB:
|
||||||
|
resultValue = extractAny<std::string>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_CLOB:
|
||||||
|
resultValue = extractAny<CLOB>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_DATE:
|
||||||
|
resultValue = extractAny<Date>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_TIME:
|
||||||
|
resultValue = extractAny<Time>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_TIMESTAMP:
|
||||||
|
resultValue = extractAny<DateTime>(pos, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaColumn::FDT_UNKNOWN:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(success)
|
||||||
|
val.swap(resultValue);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
} } } // namespace Poco::Data::MySQL
|
} } } // namespace Poco::Data::MySQL
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "Poco/Data/Date.h"
|
#include "Poco/Data/Date.h"
|
||||||
#include "Poco/Data/Time.h"
|
#include "Poco/Data/Time.h"
|
||||||
|
#include "Poco/Dynamic/Var.h"
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
namespace Data {
|
namespace Data {
|
||||||
@@ -240,13 +241,13 @@ bool Extractor::extract(std::size_t pos, Time& val)
|
|||||||
|
|
||||||
bool Extractor::extract(std::size_t pos, Any& val)
|
bool Extractor::extract(std::size_t pos, Any& val)
|
||||||
{
|
{
|
||||||
return false;
|
return extractToDynamic<Any>(pos, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Extractor::extract(std::size_t pos, Dynamic::Var& val)
|
bool Extractor::extract(std::size_t pos, Dynamic::Var& val)
|
||||||
{
|
{
|
||||||
return false;
|
return extractToDynamic<Dynamic::Var>(pos, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -531,6 +531,22 @@ void MySQLTest::testDouble()
|
|||||||
_pExecutor->doubles();
|
_pExecutor->doubles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MySQLTest::testAny()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
recreateAnyTable();
|
||||||
|
_pExecutor->any();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MySQLTest::testDynamicAny()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
recreateAnyTable();
|
||||||
|
_pExecutor->dynamicAny();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MySQLTest::testTuple()
|
void MySQLTest::testTuple()
|
||||||
{
|
{
|
||||||
@@ -875,6 +891,17 @@ void MySQLTest::recreateNullableStringTable()
|
|||||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateNullableStringTable()"); }
|
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateNullableStringTable()"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MySQLTest::recreateAnyTable()
|
||||||
|
{
|
||||||
|
dropTable("Anys");
|
||||||
|
try {
|
||||||
|
*_pSession << "CREATE TABLE Anys (int_8 TINYINT, int_16 SMALLINT, int_32 MEDIUMINT, int_64 BIGINT, flt FLOAT, dbl DOUBLE, "
|
||||||
|
"str0 VARCHAR(255), str1 TEXT, date0 DATE, time0 TIME, date_time0 DATETIME, empty INTEGER)", now;
|
||||||
|
}
|
||||||
|
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateAnyTable()"); }
|
||||||
|
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateAnyTable()"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MySQLTest::recreateVectorsTable()
|
void MySQLTest::recreateVectorsTable()
|
||||||
{
|
{
|
||||||
@@ -977,6 +1004,8 @@ 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, testAny);
|
||||||
|
CppUnit_addTest(pSuite, MySQLTest, testDynamicAny);
|
||||||
CppUnit_addTest(pSuite, MySQLTest, testTuple);
|
CppUnit_addTest(pSuite, MySQLTest, testTuple);
|
||||||
CppUnit_addTest(pSuite, MySQLTest, testTupleVector);
|
CppUnit_addTest(pSuite, MySQLTest, testTupleVector);
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
|
|||||||
@@ -87,6 +87,9 @@ public:
|
|||||||
void testFloat();
|
void testFloat();
|
||||||
void testDouble();
|
void testDouble();
|
||||||
|
|
||||||
|
void testAny();
|
||||||
|
void testDynamicAny();
|
||||||
|
|
||||||
void testTuple();
|
void testTuple();
|
||||||
void testTupleVector();
|
void testTupleVector();
|
||||||
|
|
||||||
@@ -134,6 +137,7 @@ private:
|
|||||||
void recreateVectorsTable();
|
void recreateVectorsTable();
|
||||||
void recreateNullableIntTable();
|
void recreateNullableIntTable();
|
||||||
void recreateNullableStringTable();
|
void recreateNullableStringTable();
|
||||||
|
void recreateAnyTable();
|
||||||
|
|
||||||
static void dbInfo(Poco::Data::Session& session);
|
static void dbInfo(Poco::Data::Session& session);
|
||||||
|
|
||||||
|
|||||||
@@ -45,13 +45,8 @@ typedef unsigned int uint; /* System V compatibility */
|
|||||||
typedef unsigned long ulong; /* System V compatibility */
|
typedef unsigned long ulong; /* System V compatibility */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <my_global.h>
|
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
|
|
||||||
#ifdef max
|
|
||||||
#undef max
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace Poco::Data;
|
using namespace Poco::Data;
|
||||||
using namespace Poco::Data::Keywords;
|
using namespace Poco::Data::Keywords;
|
||||||
using Poco::Data::MySQL::ConnectionException;
|
using Poco::Data::MySQL::ConnectionException;
|
||||||
@@ -62,6 +57,7 @@ using Poco::DateTime;
|
|||||||
using Poco::NumberParser;
|
using Poco::NumberParser;
|
||||||
using Poco::Any;
|
using Poco::Any;
|
||||||
using Poco::AnyCast;
|
using Poco::AnyCast;
|
||||||
|
using Poco::DynamicAny;
|
||||||
using Poco::NotFoundException;
|
using Poco::NotFoundException;
|
||||||
using Poco::InvalidAccessException;
|
using Poco::InvalidAccessException;
|
||||||
using Poco::BadCastException;
|
using Poco::BadCastException;
|
||||||
@@ -562,6 +558,128 @@ void SQLExecutor::doubles()
|
|||||||
poco_assert (ret == data);
|
poco_assert (ret == data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SQLExecutor::any()
|
||||||
|
{
|
||||||
|
std::string funct = "any()";
|
||||||
|
Any i8 = Poco::Int8(42);
|
||||||
|
Any i16 = Poco::Int16(420);
|
||||||
|
Any i32 = Poco::UInt32(42058);
|
||||||
|
Any i64 = Poco::Int64(2205861);
|
||||||
|
Any f = float(42.5);
|
||||||
|
Any d = double(4278.5);
|
||||||
|
Any s = std::string("42");
|
||||||
|
Any date = Date(DateTime());
|
||||||
|
Any t = Time(DateTime());
|
||||||
|
Any dateTime = DateTime(2017, 9, 2, 18, 49, 15);
|
||||||
|
Any e;
|
||||||
|
assert (e.empty());
|
||||||
|
|
||||||
|
try { *_pSession << "INSERT INTO Anys VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, null)",
|
||||||
|
use(i8), use(i16), use(i32), use(i64), use(f), use(d), use(s), use(s), use(date),
|
||||||
|
use(t), use(dateTime), 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 Anys", 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); }
|
||||||
|
poco_assert (count == 1);
|
||||||
|
|
||||||
|
i8 = Poco::Int8(0);
|
||||||
|
i16 = Poco::Int16(0);
|
||||||
|
i32 = Poco::Int32(0);
|
||||||
|
i64 = Poco::Int64(0);
|
||||||
|
f = 0.0f;
|
||||||
|
d = 0.0;
|
||||||
|
s = std::string("");
|
||||||
|
Any s2 = std::string("");
|
||||||
|
Any dateR = Date();
|
||||||
|
Any tR = Time();
|
||||||
|
Any dateTimeR = DateTime(2010, 5, 25);
|
||||||
|
e = 1;
|
||||||
|
assert (!e.empty());
|
||||||
|
|
||||||
|
try { *_pSession << "SELECT * FROM Anys", into(i8), into(i16), into(i32), into(i64),
|
||||||
|
into(f), into(d), into(s), into(s2), into(dateR), into(tR), into(dateTimeR), into(e), now; }
|
||||||
|
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
|
||||||
|
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
|
||||||
|
|
||||||
|
assert (42 == AnyCast<Poco::Int8>(i8));
|
||||||
|
assert (420 == AnyCast<Poco::Int16>(i16));
|
||||||
|
assert (42058 == AnyCast<Poco::Int32>(i32));
|
||||||
|
assert (2205861 == AnyCast<Poco::Int64>(i64));
|
||||||
|
assert (42.5f == AnyCast<float>(f));
|
||||||
|
assert (4278.5 == AnyCast<double>(d));
|
||||||
|
assert ("42" == AnyCast<std::string>(s));
|
||||||
|
assert ("42" == AnyCast<std::string>(s2));
|
||||||
|
assert (AnyCast<Date>(date) == AnyCast<Date>(dateR));
|
||||||
|
assert (AnyCast<Time>(t) == AnyCast<Time>(tR));
|
||||||
|
assert (AnyCast<DateTime>(dateTimeR) == AnyCast<DateTime>(dateTime));
|
||||||
|
assert (e.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SQLExecutor::dynamicAny()
|
||||||
|
{
|
||||||
|
std::string funct = "dynamicAny()";
|
||||||
|
DynamicAny i8 = Poco::Int8(42);
|
||||||
|
DynamicAny i16 = Poco::Int16(420);
|
||||||
|
DynamicAny i32 = Poco::UInt32(42058);
|
||||||
|
DynamicAny i64 = Poco::Int64(2205861);
|
||||||
|
DynamicAny f = float(42.5);
|
||||||
|
DynamicAny d = double(4278.5);
|
||||||
|
DynamicAny s = std::string("42");
|
||||||
|
DynamicAny date = Date(DateTime());
|
||||||
|
DynamicAny t = Time(DateTime());
|
||||||
|
DynamicAny dateTime = DateTime();
|
||||||
|
DynamicAny e;
|
||||||
|
assert (e.isEmpty());
|
||||||
|
|
||||||
|
try { *_pSession << "INSERT INTO Anys VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, null)",
|
||||||
|
use(i8), use(i16), use(i32), use(i64), use(f), use(d), use(s), use(s), use(date),
|
||||||
|
use(t), use(dateTime), 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 Anys", 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); }
|
||||||
|
poco_assert (count == 1);
|
||||||
|
|
||||||
|
i8 = Poco::Int8(0);
|
||||||
|
i16 = Poco::Int16(0);
|
||||||
|
i32 = Poco::Int32(0);
|
||||||
|
i64 = Poco::Int64(0);
|
||||||
|
f = 0.0f;
|
||||||
|
d = 0.0;
|
||||||
|
s = std::string("");
|
||||||
|
DynamicAny s2 = std::string("");
|
||||||
|
DynamicAny dateR = Date();
|
||||||
|
DynamicAny tR = Time();
|
||||||
|
DynamicAny dateTimeR = DateTime(2017, 9, 2);
|
||||||
|
e = 1;
|
||||||
|
assert (!e.isEmpty());
|
||||||
|
|
||||||
|
try { *_pSession << "SELECT * FROM Anys", into(i8), into(i16), into(i32), into(i64),
|
||||||
|
into(f), into(d), into(s), into(s2), into(dateR), into(tR), into(dateTimeR), into(e), now; }
|
||||||
|
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
|
||||||
|
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
|
||||||
|
|
||||||
|
assert (42 == i8);
|
||||||
|
assert (420 == i16);
|
||||||
|
assert (42058 == i32);
|
||||||
|
assert (2205861 == i64);
|
||||||
|
assert (42.5f == f);
|
||||||
|
assert (4278.5 == d);
|
||||||
|
assert ("42" == s);
|
||||||
|
assert ("42" == s2);
|
||||||
|
assert (date == dateR);
|
||||||
|
assert (t == tR);
|
||||||
|
assert (dateTimeR == dateTime);
|
||||||
|
assert (e.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SQLExecutor::insertSingleBulkVec()
|
void SQLExecutor::insertSingleBulkVec()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ public:
|
|||||||
void unsignedInts();
|
void unsignedInts();
|
||||||
void floats();
|
void floats();
|
||||||
void doubles();
|
void doubles();
|
||||||
|
void any();
|
||||||
|
void dynamicAny();
|
||||||
void tuples();
|
void tuples();
|
||||||
void tupleVector();
|
void tupleVector();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user