Skip to content

Commit e7ac6e3

Browse files
committed
Any and DynamicAny binding/extraction
1 parent 76221cc commit e7ac6e3

28 files changed

Lines changed: 773 additions & 159 deletions

‎Data/ODBC/include/Poco/Data/ODBC/Binder.h‎

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ class ODBC_API Binder: public Poco::Data::AbstractBinder
110110
void bind(std::size_t pos, const Poco::UInt64& val, Direction dir = PD_IN);
111111
/// Binds an UInt64.
112112

113+
#ifndef POCO_LONG_IS_64_BIT
114+
void bind(std::size_t pos, const long& val, Direction dir = PD_IN);
115+
/// Binds a long.
116+
#endif
117+
113118
void bind(std::size_t pos, const bool& val, Direction dir = PD_IN);
114119
/// Binds a boolean.
115120

@@ -205,13 +210,13 @@ class ODBC_API Binder: public Poco::Data::AbstractBinder
205210
/// For in-bound purposes only.
206211

207212
const StatementHandle& _rStmt;
208-
LengthVec _lengthIndicator;
209-
ParamMap _inParams;
210-
ParamMap _outParams;
211-
ParameterBinding _paramBinding;
212-
TimestampMap _timestamps;
213-
StringMap _strings;
214-
const TypeInfo* _pTypeInfo;
213+
LengthVec _lengthIndicator;
214+
ParamMap _inParams;
215+
ParamMap _outParams;
216+
ParameterBinding _paramBinding;
217+
TimestampMap _timestamps;
218+
StringMap _strings;
219+
const TypeInfo* _pTypeInfo;
215220
};
216221

217222

@@ -266,6 +271,14 @@ inline void Binder::bind(std::size_t pos, const Poco::UInt64& val, Direction dir
266271
}
267272

268273

274+
#ifndef POCO_LONG_IS_64_BIT
275+
inline void Binder::bind(std::size_t pos, const long& val, Direction dir)
276+
{
277+
bindImpl(pos, val, SQL_C_SLONG, dir);
278+
}
279+
#endif
280+
281+
269282
inline void Binder::bind(std::size_t pos, const float& val, Direction dir)
270283
{
271284
bindImpl(pos, val, SQL_C_FLOAT, dir);

‎Data/ODBC/include/Poco/Data/ODBC/Extractor.h‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "Poco/Data/ODBC/Utility.h"
4949
#include "Poco/DateTime.h"
5050
#include "Poco/Any.h"
51+
#include "Poco/DynamicAny.h"
5152
#include "Poco/Exception.h"
5253
#include <map>
5354
#ifdef POCO_OS_FAMILY_WINDOWS
@@ -97,6 +98,11 @@ class ODBC_API Extractor: public Poco::Data::AbstractExtractor
9798
bool extract(std::size_t pos, Poco::UInt64& val);
9899
/// Extracts an UInt64.
99100

101+
#ifndef POCO_LONG_IS_64_BIT
102+
bool extract(std::size_t pos, long& val);
103+
/// Extracts a long.
104+
#endif
105+
100106
bool extract(std::size_t pos, bool& val);
101107
/// Extracts a boolean.
102108

@@ -121,6 +127,9 @@ class ODBC_API Extractor: public Poco::Data::AbstractExtractor
121127
bool extract(std::size_t pos, Poco::Any& val);
122128
/// Extracts an Any.
123129

130+
bool extract(std::size_t pos, Poco::DynamicAny& val);
131+
/// Extracts a DynamicAny.
132+
124133
void setDataExtraction(Preparation::DataExtraction ext);
125134
/// Set data extraction mode.
126135

@@ -158,6 +167,7 @@ class ODBC_API Extractor: public Poco::Data::AbstractExtractor
158167
if (isNull(pos)) return false;
159168

160169
poco_assert (typeid(T) == _rPreparation[pos].type());
170+
161171
val = *AnyCast<T>(&_rPreparation[pos]);
162172
return true;
163173
}
@@ -193,6 +203,63 @@ class ODBC_API Extractor: public Poco::Data::AbstractExtractor
193203
return true;
194204
}
195205

206+
template <typename T>
207+
bool extractImpl(std::size_t pos, T& val)
208+
/// Utility function for extraction of Any and DynamicAny.
209+
{
210+
ODBCColumn column(_rStmt, pos);
211+
212+
switch (column.type())
213+
{
214+
case MetaColumn::FDT_INT8:
215+
{ Poco::Int8 i = 0; extract(pos, i); val = i; return true; }
216+
217+
case MetaColumn::FDT_UINT8:
218+
{ Poco::UInt8 i = 0; extract(pos, i); val = i; return true; }
219+
220+
case MetaColumn::FDT_INT16:
221+
{ Poco::Int16 i = 0; extract(pos, i); val = i; return true; }
222+
223+
case MetaColumn::FDT_UINT16:
224+
{ Poco::UInt16 i = 0; extract(pos, i); val = i; return true; }
225+
226+
case MetaColumn::FDT_INT32:
227+
{ Poco::Int32 i = 0; extract(pos, i); val = i; return true; }
228+
229+
case MetaColumn::FDT_UINT32:
230+
{ Poco::UInt32 i = 0; extract(pos, i); val = i; return true; }
231+
232+
case MetaColumn::FDT_INT64:
233+
{ Poco::Int64 i = 0; extract(pos, i); val = i; return true; }
234+
235+
case MetaColumn::FDT_UINT64:
236+
{ Poco::UInt64 i = 0; extract(pos, i); val = i; return true; }
237+
238+
case MetaColumn::FDT_BOOL:
239+
{ bool b; extract(pos, b); val = b; return true; }
240+
241+
case MetaColumn::FDT_FLOAT:
242+
{ float f; extract(pos, f); val = f; return true; }
243+
244+
case MetaColumn::FDT_DOUBLE:
245+
{ double d; extract(pos, d); val = d; return true; }
246+
247+
case MetaColumn::FDT_STRING:
248+
{ std::string s; extract(pos, s); val = s; return true; }
249+
250+
case MetaColumn::FDT_BLOB:
251+
{ Poco::Data::BLOB b; extract(pos, b); val = b; return true; }
252+
253+
case MetaColumn::FDT_TIMESTAMP:
254+
{ Poco::DateTime b; extract(pos, b); val = b; return true; }
255+
256+
default:
257+
throw DataFormatException("Unsupported data type.");
258+
}
259+
260+
return false;
261+
}
262+
196263
bool isNullLengthIndicator(SQLLEN val) const;
197264
/// The reason for this utility wrapper are platforms where
198265
/// SQLLEN macro (a.k.a. SQLINTEGER) yields 64-bit value,

‎Data/ODBC/include/Poco/Data/ODBC/Preparation.h‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "Poco/Data/AbstractPreparation.h"
4848
#include "Poco/Data/BLOB.h"
4949
#include "Poco/Any.h"
50+
#include "Poco/DynamicAny.h"
5051
#include "Poco/DateTime.h"
5152
#include "Poco/SharedPtr.h"
5253
#include <vector>
@@ -126,6 +127,11 @@ class ODBC_API Preparation : public AbstractPreparation
126127
void prepare(std::size_t pos, Poco::UInt64);
127128
/// Prepares an UInt64.
128129

130+
#ifndef POCO_LONG_IS_64_BIT
131+
void prepare(std::size_t pos, long);
132+
/// Prepares a long.
133+
#endif
134+
129135
void prepare(std::size_t pos, bool);
130136
/// Prepares a boolean.
131137

@@ -150,6 +156,9 @@ class ODBC_API Preparation : public AbstractPreparation
150156
void prepare(std::size_t pos, const Poco::Any&);
151157
/// Prepares an Any.
152158

159+
void prepare(std::size_t pos, const Poco::DynamicAny&);
160+
/// Prepares a DynamicAny.
161+
153162
std::size_t columns() const;
154163
/// Returns the number of columns.
155164
/// Resizes the internal storage iff the size is zero.
@@ -181,6 +190,9 @@ class ODBC_API Preparation : public AbstractPreparation
181190
/// Returns data extraction mode.
182191

183192
private:
193+
void prepareImpl(std::size_t pos);
194+
/// Utility function to prepare Any and DynamicAny
195+
184196
template <typename T>
185197
void preparePOD(std::size_t pos, SQLSMALLINT valueType)
186198
{
@@ -293,6 +305,14 @@ inline void Preparation::prepare(std::size_t pos, Poco::UInt64)
293305
}
294306

295307

308+
#ifndef POCO_LONG_IS_64_BIT
309+
inline void Preparation::prepare(std::size_t pos, long)
310+
{
311+
preparePOD<long>(pos, SQL_C_SLONG);
312+
}
313+
#endif
314+
315+
296316
inline void Preparation::prepare(std::size_t pos, bool)
297317
{
298318
preparePOD<bool>(pos, SQL_C_BIT);

‎Data/ODBC/src/Extractor.cpp‎

Lines changed: 16 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,17 @@ bool Extractor::extract(std::size_t pos, Poco::Int64& val)
265265
}
266266

267267

268+
#ifndef POCO_LONG_IS_64_BIT
269+
bool Extractor::extract(std::size_t pos, long& val)
270+
{
271+
if (Preparation::DE_MANUAL == _dataExtraction)
272+
return extractManualImpl(pos, val, SQL_C_SLONG);
273+
else
274+
return extractBoundImpl(pos, val);
275+
}
276+
#endif
277+
278+
268279
bool Extractor::extract(std::size_t pos, double& val)
269280
{
270281
if (Preparation::DE_MANUAL == _dataExtraction)
@@ -384,57 +395,13 @@ bool Extractor::extract(std::size_t pos, char& val)
384395

385396
bool Extractor::extract(std::size_t pos, Poco::Any& val)
386397
{
387-
ODBCColumn column(_rStmt, pos);
388-
389-
switch (column.type())
390-
{
391-
case MetaColumn::FDT_INT8:
392-
{ Poco::Int8 i = 0; extract(pos, i); val = i; return true; }
393-
394-
case MetaColumn::FDT_UINT8:
395-
{ Poco::UInt8 i = 0; extract(pos, i); val = i; return true; }
396-
397-
case MetaColumn::FDT_INT16:
398-
{ Poco::Int16 i = 0; extract(pos, i); val = i; return true; }
399-
400-
case MetaColumn::FDT_UINT16:
401-
{ Poco::UInt16 i = 0; extract(pos, i); val = i; return true; }
402-
403-
case MetaColumn::FDT_INT32:
404-
{ Poco::Int32 i = 0; extract(pos, i); val = i; return true; }
405-
406-
case MetaColumn::FDT_UINT32:
407-
{ Poco::UInt32 i = 0; extract(pos, i); val = i; return true; }
408-
409-
case MetaColumn::FDT_INT64:
410-
{ Poco::Int64 i = 0; extract(pos, i); val = i; return true; }
411-
412-
case MetaColumn::FDT_UINT64:
413-
{ Poco::UInt64 i = 0; extract(pos, i); val = i; return true; }
414-
415-
case MetaColumn::FDT_BOOL:
416-
{ bool b; extract(pos, b); val = b; return true; }
417-
418-
case MetaColumn::FDT_FLOAT:
419-
{ float f; extract(pos, f); val = f; return true; }
420-
421-
case MetaColumn::FDT_DOUBLE:
422-
{ double d; extract(pos, d); val = d; return true; }
423-
424-
case MetaColumn::FDT_STRING:
425-
{ std::string s; extract(pos, s); val = s; return true; }
426-
427-
case MetaColumn::FDT_BLOB:
428-
{ Poco::Data::BLOB b; extract(pos, b); val = b; return true; }
429-
430-
case MetaColumn::FDT_TIMESTAMP:
431-
{ Poco::DateTime b; extract(pos, b); val = b; return true; }
398+
return extractImpl(pos, val);
399+
}
432400

433-
default:
434-
throw DataFormatException("Unsupported data type.");
435-
}
436401

437-
return false;
402+
bool Extractor::extract(std::size_t pos, Poco::DynamicAny& val)
403+
{
404+
return extractImpl(pos, val);
438405
}
439406

440407

‎Data/ODBC/src/Preparation.cpp‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@ Poco::Any& Preparation::operator [] (std::size_t pos)
9595

9696

9797
void Preparation::prepare(std::size_t pos, const Poco::Any&)
98+
{
99+
prepareImpl(pos);
100+
}
101+
102+
103+
void Preparation::prepare(std::size_t pos, const Poco::DynamicAny&)
104+
{
105+
prepareImpl(pos);
106+
}
107+
108+
109+
void Preparation::prepareImpl(std::size_t pos)
98110
{
99111
ODBCColumn col(_rStmt, pos);
100112

@@ -131,7 +143,7 @@ void Preparation::prepare(std::size_t pos, const Poco::Any&)
131143
return preparePOD<float>(pos, SQL_C_FLOAT);
132144

133145
case MetaColumn::FDT_DOUBLE:
134-
return preparePOD<float>(pos, SQL_C_DOUBLE);
146+
return preparePOD<double>(pos, SQL_C_DOUBLE);
135147

136148
case MetaColumn::FDT_STRING:
137149
return prepareRaw<char>(pos, SQL_C_CHAR, maxDataSize(pos));

‎Data/ODBC/testsuite/src/ODBCDB2Test.cpp‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,38 @@ void ODBCDB2Test::testAsync()
10821082
}
10831083

10841084

1085+
void ODBCDB2Test::testAny()
1086+
{
1087+
if (!_pSession) fail ("Test not available.");
1088+
1089+
for (int i = 0; i < 8;)
1090+
{
1091+
recreateAnysTable();
1092+
_pSession->setFeature("autoBind", bindValues[i]);
1093+
_pSession->setFeature("autoExtract", bindValues[i+1]);
1094+
_pExecutor->any();
1095+
1096+
i += 2;
1097+
}
1098+
}
1099+
1100+
1101+
void ODBCDB2Test::testDynamicAny()
1102+
{
1103+
if (!_pSession) fail ("Test not available.");
1104+
1105+
for (int i = 0; i < 8;)
1106+
{
1107+
recreateAnysTable();
1108+
_pSession->setFeature("autoBind", bindValues[i]);
1109+
_pSession->setFeature("autoExtract", bindValues[i+1]);
1110+
_pExecutor->dynamicAny();
1111+
1112+
i += 2;
1113+
}
1114+
}
1115+
1116+
10851117
void ODBCDB2Test::dropObject(const std::string& type, const std::string& name)
10861118
{
10871119
try
@@ -1182,6 +1214,15 @@ void ODBCDB2Test::recreateVectorsTable()
11821214
}
11831215

11841216

1217+
void ODBCDB2Test::recreateAnysTable()
1218+
{
1219+
dropObject("TABLE", "Anys");
1220+
try { *_pSession << "CREATE TABLE Anys (i0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
1221+
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateAnysTable()"); }
1222+
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateAnysTable()"); }
1223+
}
1224+
1225+
11851226
void ODBCDB2Test::recreateNullsTable(const std::string& notNull)
11861227
{
11871228
dropObject("TABLE", "NullTest");
@@ -1338,6 +1379,8 @@ CppUnit::Test* ODBCDB2Test::suite()
13381379
CppUnit_addTest(pSuite, ODBCDB2Test, testNull);
13391380
CppUnit_addTest(pSuite, ODBCDB2Test, testRowIterator);
13401381
CppUnit_addTest(pSuite, ODBCDB2Test, testAsync);
1382+
CppUnit_addTest(pSuite, ODBCDB2Test, testAny);
1383+
CppUnit_addTest(pSuite, ODBCDB2Test, testDynamicAny);
13411384

13421385
return pSuite;
13431386
}

‎Data/ODBC/testsuite/src/ODBCDB2Test.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ class ODBCDB2Test: public CppUnit::TestCase
127127

128128
void testAsync();
129129

130+
void testAny();
131+
void testDynamicAny();
132+
130133
void setUp();
131134
void tearDown();
132135

@@ -146,6 +149,7 @@ class ODBCDB2Test: public CppUnit::TestCase
146149
void recreateFloatsTable();
147150
void recreateTuplesTable();
148151
void recreateVectorsTable();
152+
void recreateAnysTable();
149153
void recreateNullsTable(const std::string& notNull = "");
150154

151155
static bool init(const std::string& driver, const std::string& dsn);

0 commit comments

Comments
 (0)