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/AbstractExtractor.h"
|
||||
#include "Poco/Data/LOB.h"
|
||||
#include "Poco/Data/Date.h"
|
||||
#include "Poco/Data/Time.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@@ -324,6 +326,17 @@ private:
|
||||
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);
|
||||
|
||||
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"
|
||||
Extractor& operator=(const Extractor&);
|
||||
|
||||
@@ -333,6 +346,97 @@ private:
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "Poco/Data/Date.h"
|
||||
#include "Poco/Data/Time.h"
|
||||
#include "Poco/Dynamic/Var.h"
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
@@ -240,13 +241,13 @@ bool Extractor::extract(std::size_t pos, Time& 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)
|
||||
{
|
||||
return false;
|
||||
return extractToDynamic<Dynamic::Var>(pos, val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -531,6 +531,22 @@ void MySQLTest::testDouble()
|
||||
_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()
|
||||
{
|
||||
@@ -875,6 +891,17 @@ void MySQLTest::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()
|
||||
{
|
||||
@@ -977,6 +1004,8 @@ CppUnit::Test* MySQLTest::suite()
|
||||
CppUnit_addTest(pSuite, MySQLTest, testUnsignedInts);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testFloat);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testDouble);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testAny);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testDynamicAny);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testTuple);
|
||||
CppUnit_addTest(pSuite, MySQLTest, testTupleVector);
|
||||
#if __cplusplus >= 201103L
|
||||
|
||||
@@ -87,6 +87,9 @@ public:
|
||||
void testFloat();
|
||||
void testDouble();
|
||||
|
||||
void testAny();
|
||||
void testDynamicAny();
|
||||
|
||||
void testTuple();
|
||||
void testTupleVector();
|
||||
|
||||
@@ -134,6 +137,7 @@ private:
|
||||
void recreateVectorsTable();
|
||||
void recreateNullableIntTable();
|
||||
void recreateNullableStringTable();
|
||||
void recreateAnyTable();
|
||||
|
||||
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 */
|
||||
#endif
|
||||
|
||||
#include <my_global.h>
|
||||
#include <mysql.h>
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
using namespace Poco::Data;
|
||||
using namespace Poco::Data::Keywords;
|
||||
using Poco::Data::MySQL::ConnectionException;
|
||||
@@ -62,6 +57,7 @@ using Poco::DateTime;
|
||||
using Poco::NumberParser;
|
||||
using Poco::Any;
|
||||
using Poco::AnyCast;
|
||||
using Poco::DynamicAny;
|
||||
using Poco::NotFoundException;
|
||||
using Poco::InvalidAccessException;
|
||||
using Poco::BadCastException;
|
||||
@@ -562,6 +558,128 @@ void SQLExecutor::doubles()
|
||||
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()
|
||||
{
|
||||
|
||||
@@ -89,6 +89,8 @@ public:
|
||||
void unsignedInts();
|
||||
void floats();
|
||||
void doubles();
|
||||
void any();
|
||||
void dynamicAny();
|
||||
void tuples();
|
||||
void tupleVector();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user