step, date, time

This commit is contained in:
Aleksandar Fabijanic 2007-11-10 23:21:28 +00:00
parent 95c5230389
commit fca08a18df
63 changed files with 2161 additions and 96 deletions

View File

@ -269,6 +269,10 @@
RelativePath=".\include\Poco\Data\DataException.h"
>
</File>
<File
RelativePath=".\include\Poco\Data\Date.h"
>
</File>
<File
RelativePath=".\include\Poco\Data\Extraction.h"
>
@ -329,6 +333,14 @@
RelativePath=".\include\Poco\Data\StatementImpl.h"
>
</File>
<File
RelativePath=".\include\Poco\Data\Step.h"
>
</File>
<File
RelativePath=".\include\Poco\Data\Time.h"
>
</File>
<File
RelativePath=".\include\Poco\Data\TypeHandler.h"
>
@ -377,6 +389,10 @@
RelativePath=".\src\DataException.cpp"
>
</File>
<File
RelativePath=".\src\Date.cpp"
>
</File>
<File
RelativePath=".\src\Limit.cpp"
>
@ -429,6 +445,14 @@
RelativePath=".\src\StatementImpl.cpp"
>
</File>
<File
RelativePath=".\src\Step.cpp"
>
</File>
<File
RelativePath=".\src\Time.cpp"
>
</File>
</Filter>
</Filter>
<Filter

View File

@ -10,11 +10,12 @@ include $(POCO_BASE)/build/rules/global
objects = AbstractBinder AbstractBinding AbstractExtraction \
AbstractExtractor AbstractPreparation AbstractPrepare \
BLOB BLOBStream DataException Limit MetaColumn \
Connector BLOB BLOBStream DataException Date Limit MetaColumn \
PooledSessionHolder PooledSessionImpl \
Range RecordSet Row RowFormatter RowIterator \
Session SessionFactory SessionImpl \
Connector SessionPool Statement StatementCreator StatementImpl
SessionPool Statement StatementCreator StatementImpl \
Step Time
target = PocoData
target_version = $(LIBVERSION)

View File

@ -42,6 +42,8 @@
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/AbstractBinder.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/Data/BLOB.h"
#include "Poco/Data/ODBC/Handle.h"
#include "Poco/Data/ODBC/Parameter.h"
@ -133,6 +135,12 @@ public:
void bind(std::size_t pos, const BLOB& val, Direction dir);
/// Binds a BLOB. In-bound only.
void bind(std::size_t pos, const Date& val, Direction dir);
/// Binds a Date.
void bind(std::size_t pos, const Time& val, Direction dir);
/// Binds a Time.
void bind(std::size_t pos, const DateTime& val, Direction dir);
/// Binds a DateTime.
@ -153,9 +161,11 @@ public:
/// holders back into the externally supplied buffers.
private:
typedef std::vector<SQLLEN*> LengthVec;
typedef std::vector<SQLLEN*> LengthVec;
typedef std::map<char*, std::string*> StringMap;
typedef std::map<SQL_DATE_STRUCT*, Date*> DateMap;
typedef std::map<SQL_TIME_STRUCT*, Time*> TimeMap;
typedef std::map<SQL_TIMESTAMP_STRUCT*, DateTime*> TimestampMap;
typedef std::map<char*, std::string*> StringMap;
void describeParameter(std::size_t pos);
/// Sets the description field for the parameter, if needed.
@ -214,6 +224,8 @@ private:
ParamMap _inParams;
ParamMap _outParams;
ParameterBinding _paramBinding;
DateMap _dates;
TimeMap _times;
TimestampMap _timestamps;
StringMap _strings;
const TypeInfo* _pTypeInfo;

View File

@ -121,6 +121,12 @@ public:
bool extract(std::size_t pos, Poco::Data::BLOB& val);
/// Extracts a BLOB.
bool extract(std::size_t pos, Poco::Data::Date& val);
/// Extracts a Date.
bool extract(std::size_t pos, Poco::Data::Time& val);
/// Extracts a Time.
bool extract(std::size_t pos, Poco::DateTime& val);
/// Extracts a DateTime.
@ -265,10 +271,10 @@ private:
/// SQLLEN macro (a.k.a. SQLINTEGER) yields 64-bit value,
/// while SQL_NULL_DATA (#define'd as -1 literal) remains 32-bit.
const StatementHandle& _rStmt;
Preparation& _rPreparation;
const StatementHandle& _rStmt;
Preparation& _rPreparation;
Preparation::DataExtraction _dataExtraction;
std::vector<SQLLEN> _lengths;
std::vector<SQLLEN> _lengths;
};

View File

@ -84,8 +84,9 @@ protected:
bool hasNext();
/// Returns true if a call to next() will return data.
void next();
/// Retrieves the next row from the resultset.
Poco::UInt32 next();
/// Retrieves the next row or set of rows from the resultset.
/// Returns the number of rows retrieved.
/// Will throw, if the resultset is empty.
bool canBind() const;

View File

@ -46,6 +46,8 @@
#include "Poco/Data/ODBC/Utility.h"
#include "Poco/Data/AbstractPreparation.h"
#include "Poco/Data/BLOB.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/Any.h"
#include "Poco/DynamicAny.h"
#include "Poco/DateTime.h"
@ -62,6 +64,8 @@ namespace Data {
namespace ODBC {
class Date;
class Time;
class BLOB;
@ -153,6 +157,12 @@ public:
void prepare(std::size_t pos, const Poco::Data::BLOB&);
/// Prepares a BLOB.
void prepare(std::size_t pos, const Poco::Data::Date&);
/// Prepares a Date.
void prepare(std::size_t pos, const Poco::Data::Time&);
/// Prepares a Time.
void prepare(std::size_t pos, const Poco::DateTime&);
/// Prepares a DateTime.
@ -358,6 +368,22 @@ inline void Preparation::prepare(std::size_t pos, const Poco::Data::BLOB&)
}
inline void Preparation::prepare(std::size_t pos, const Poco::Data::Date&)
{
prepareRaw<SQL_DATE_STRUCT>(pos,
SQL_C_TYPE_DATE,
sizeof(SQL_DATE_STRUCT));
}
inline void Preparation::prepare(std::size_t pos, const Poco::Data::Time&)
{
prepareRaw<SQL_TIME_STRUCT>(pos,
SQL_C_TYPE_TIME,
sizeof(SQL_TIME_STRUCT));
}
inline void Preparation::prepare(std::size_t pos, const Poco::DateTime&)
{
prepareRaw<SQL_TIMESTAMP_STRUCT>(pos,

View File

@ -126,20 +126,6 @@ private:
};
inline DynamicAny TypeInfo::getInfo(SQLSMALLINT type, const std::string& param) const
{
TypeInfoVec::const_iterator it = _typeInfo.begin();
TypeInfoVec::const_iterator end = _typeInfo.end();
for (; it != end; ++it)
{
if (type == it->get<1>())
return (*it)[param];
}
throw NotFoundException(param);
}
} } } // namespace Poco::Data::ODBC

View File

@ -42,6 +42,8 @@
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/ODBC/TypeInfo.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/DateTime.h"
#include <sstream>
#include <map>
@ -95,9 +97,21 @@ public:
static int sqlDataType(int cDataType);
/// Returns SQL data type corresponding to supplied C data type.
static void dateSync(Date& dt, const SQL_DATE_STRUCT& ts);
/// Transfers data from ODBC SQL_DATE_STRUCT to Poco::DateTime.
static void timeSync(Time& dt, const SQL_TIME_STRUCT& ts);
/// Transfers data from ODBC SQL_TIME_STRUCT to Poco::DateTime.
static void dateTimeSync(Poco::DateTime& dt, const SQL_TIMESTAMP_STRUCT& ts);
/// Transfers data from ODBC SQL_TIMESTAMP_STRUCT to Poco::DateTime.
static void dateSync(SQL_DATE_STRUCT& ts, const Date& dt);
/// Transfers data from Poco::Data::Date to ODBC SQL_DATE_STRUCT.
static void timeSync(SQL_TIME_STRUCT& ts, const Time& dt);
/// Transfers data from Poco::Data::Time to ODBC SQL_TIME_STRUCT.
static void dateTimeSync(SQL_TIMESTAMP_STRUCT& ts, const Poco::DateTime& dt);
/// Transfers data from Poco::DateTime to ODBC SQL_TIMESTAMP_STRUCT.
@ -128,6 +142,18 @@ inline int Utility::sqlDataType(int cDataType)
}
inline void Utility::dateSync(Date& dt, const SQL_DATE_STRUCT& ts)
{
dt.assign(ts.year, ts.month, ts.day);
}
inline void Utility::timeSync(Time& dt, const SQL_TIME_STRUCT& ts)
{
dt.assign(ts.hour, ts.minute, ts.second);
}
} } } // namespace Poco::Data::ODBC

View File

@ -175,6 +175,72 @@ void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir)
}
void Binder::bind(std::size_t pos, const Date& val, Direction dir)
{
SQLINTEGER size = (SQLINTEGER) sizeof(SQL_DATE_STRUCT);
SQLLEN* pLenIn = new SQLLEN;
*pLenIn = size;
_lengthIndicator.push_back(pLenIn);
SQL_DATE_STRUCT* pDS = new SQL_DATE_STRUCT;
Utility::dateSync(*pDS, val);
_dates.insert(DateMap::value_type(pDS, const_cast<Date*>(&val)));
SQLINTEGER colSize = 0;
SQLSMALLINT decDigits = 0;
getColSizeAndPrecision(pos, SQL_TYPE_DATE, colSize, decDigits);
if (Utility::isError(SQLBindParameter(_rStmt,
(SQLUSMALLINT) pos + 1,
toODBCDirection(dir),
SQL_C_DATE,
SQL_DATE,
colSize,
decDigits,
(SQLPOINTER) pDS,
0,
_lengthIndicator.back())))
{
throw StatementException(_rStmt, "SQLBindParameter(BLOB)");
}
}
void Binder::bind(std::size_t pos, const Time& val, Direction dir)
{
SQLINTEGER size = (SQLINTEGER) sizeof(SQL_TIME_STRUCT);
SQLLEN* pLenIn = new SQLLEN;
*pLenIn = size;
_lengthIndicator.push_back(pLenIn);
SQL_TIME_STRUCT* pTS = new SQL_TIME_STRUCT;
Utility::timeSync(*pTS, val);
_times.insert(TimeMap::value_type(pTS, const_cast<Time*>(&val)));
SQLINTEGER colSize = 0;
SQLSMALLINT decDigits = 0;
getColSizeAndPrecision(pos, SQL_TYPE_TIME, colSize, decDigits);
if (Utility::isError(SQLBindParameter(_rStmt,
(SQLUSMALLINT) pos + 1,
toODBCDirection(dir),
SQL_C_TIME,
SQL_TIME,
colSize,
decDigits,
(SQLPOINTER) pTS,
0,
_lengthIndicator.back())))
{
throw StatementException(_rStmt, "SQLBindParameter(BLOB)");
}
}
void Binder::bind(std::size_t pos, const Poco::DateTime& val, Direction dir)
{
SQLINTEGER size = (SQLINTEGER) sizeof(SQL_TIMESTAMP_STRUCT);
@ -229,6 +295,8 @@ void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
case NULL_DOUBLE: bindNull(pos, SQL_C_DOUBLE); break;
case NULL_STRING: bindNull(pos, SQL_C_CHAR); break;
case NULL_BLOB: bindNull(pos, SQL_C_BINARY); break;
case NULL_DATE: bindNull(pos, SQL_C_DATE); break;
case NULL_TIME: bindNull(pos, SQL_C_TIME); break;
case NULL_TIMESTAMP: bindNull(pos, SQL_C_TIMESTAMP); break;
default:
@ -300,6 +368,22 @@ SQLSMALLINT Binder::toODBCDirection(Direction dir) const
void Binder::synchronize()
{
if (_dates.size())
{
DateMap::iterator itTS = _dates.begin();
DateMap::iterator itTSEnd = _dates.end();
for(; itTS != itTSEnd; ++itTS)
Utility::dateSync(*itTS->second, *itTS->first);
}
if (_times.size())
{
TimeMap::iterator itTS = _times.begin();
TimeMap::iterator itTSEnd = _times.end();
for(; itTS != itTSEnd; ++itTS)
Utility::timeSync(*itTS->second, *itTS->first);
}
if (_timestamps.size())
{
TimestampMap::iterator itTS = _timestamps.begin();

View File

@ -95,6 +95,34 @@ bool Extractor::extractBoundImpl<Poco::Data::BLOB>(std::size_t pos, Poco::Data::
}
template<>
bool Extractor::extractBoundImpl<Poco::Data::Date>(std::size_t pos, Poco::Data::Date& val)
{
if (isNull(pos)) return false;
std::size_t dataSize = _rPreparation.actualDataSize(pos);
checkDataSize(dataSize);
SharedPtr<SQL_DATE_STRUCT>& sp = RefAnyCast<SharedPtr<SQL_DATE_STRUCT> >(_rPreparation[pos]);
Utility::dateSync(val, *sp);
return true;
}
template<>
bool Extractor::extractBoundImpl<Poco::Data::Time>(std::size_t pos, Poco::Data::Time& val)
{
if (isNull(pos)) return false;
std::size_t dataSize = _rPreparation.actualDataSize(pos);
checkDataSize(dataSize);
SharedPtr<SQL_TIME_STRUCT>& sp = RefAnyCast<SharedPtr<SQL_TIME_STRUCT> >(_rPreparation[pos]);
Utility::timeSync(val, *sp);
return true;
}
template<>
bool Extractor::extractBoundImpl<Poco::DateTime>(std::size_t pos, Poco::DateTime& val)
{
@ -219,6 +247,60 @@ bool Extractor::extractManualImpl<Poco::Data::BLOB>(std::size_t pos,
}
template<>
bool Extractor::extractManualImpl<Poco::Data::Date>(std::size_t pos,
Poco::Data::Date& val,
SQLSMALLINT cType)
{
SQL_DATE_STRUCT ds;
resizeLengths(pos);
SQLRETURN rc = SQLGetData(_rStmt,
(SQLUSMALLINT) pos + 1,
cType, //C data type
&ds, //returned value
sizeof(ds), //buffer length
&_lengths[pos]); //length indicator
if (Utility::isError(rc))
throw StatementException(_rStmt, "SQLGetData()");
if (isNullLengthIndicator(_lengths[pos]))
return false;
else
Utility::dateSync(val, ds);
return true;
}
template<>
bool Extractor::extractManualImpl<Poco::Data::Time>(std::size_t pos,
Poco::Data::Time& val,
SQLSMALLINT cType)
{
SQL_TIME_STRUCT ts;
resizeLengths(pos);
SQLRETURN rc = SQLGetData(_rStmt,
(SQLUSMALLINT) pos + 1,
cType, //C data type
&ts, //returned value
sizeof(ts), //buffer length
&_lengths[pos]); //length indicator
if (Utility::isError(rc))
throw StatementException(_rStmt, "SQLGetData()");
if (isNullLengthIndicator(_lengths[pos]))
return false;
else
Utility::timeSync(val, ts);
return true;
}
template<>
bool Extractor::extractManualImpl<Poco::DateTime>(std::size_t pos,
Poco::DateTime& val,
@ -303,6 +385,24 @@ bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
}
bool Extractor::extract(std::size_t pos, Poco::Data::Date& val)
{
if (Preparation::DE_MANUAL == _dataExtraction)
return extractManualImpl(pos, val, SQL_C_DATE);
else
return extractBoundImpl(pos, val);
}
bool Extractor::extract(std::size_t pos, Poco::Data::Time& val)
{
if (Preparation::DE_MANUAL == _dataExtraction)
return extractManualImpl(pos, val, SQL_C_TIME);
else
return extractBoundImpl(pos, val);
}
bool Extractor::extract(std::size_t pos, Poco::DateTime& val)
{
if (Preparation::DE_MANUAL == _dataExtraction)

View File

@ -128,6 +128,10 @@ void ODBCColumn::init()
case SQL_LONGVARBINARY:
case -98:// IBM DB2 non-standard type
setType(MetaColumn::FDT_BLOB); break;
case SQL_TYPE_DATE:
setType(MetaColumn::FDT_DATE); break;
case SQL_TYPE_TIME:
setType(MetaColumn::FDT_TIME); break;
case SQL_TYPE_TIMESTAMP:
setType(MetaColumn::FDT_TIMESTAMP); break;
default:

View File

@ -41,8 +41,11 @@
#include "Poco/Data/AbstractPrepare.h"
#include <limits>
#include <sql.h>
#undef max
#ifdef POCO_OS_FAMILY_WINDOWS
#undef max
#pragma warning(disable:4312)// 'type cast' : conversion from 'Poco::UInt32' to 'SQLPOINTER' of greater size
#endif
namespace Poco {
namespace Data {
@ -61,19 +64,10 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
_prepared(false)
{
if (session().getFeature("autoBind"))
{
SQLSetStmtAttr(_stmt,
SQL_ATTR_PARAM_BIND_TYPE,
(SQLPOINTER) SQL_PARAM_BIND_BY_COLUMN,
0);
}
else
{
SQLSetStmtAttr(_stmt,
SQL_ATTR_ROW_ARRAY_SIZE,
(SQLPOINTER) 1,
0);
}
SQLSetStmtAttr(_stmt, SQL_ATTR_PARAM_BIND_TYPE, (SQLPOINTER) SQL_PARAM_BIND_BY_COLUMN, 0);
Poco::UInt32 step = getStep();
SQLSetStmtAttr(_stmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) step, 0);
}
@ -315,7 +309,7 @@ void ODBCStatementImpl::makeStep()
}
void ODBCStatementImpl::next()
Poco::UInt32 ODBCStatementImpl::next()
{
if (nextRowReady())
{
@ -334,6 +328,8 @@ void ODBCStatementImpl::next()
throw StatementException(_stmt,
std::string("Iterator Error: trying to access the next value"));
}
return 1u;
}

View File

@ -187,6 +187,20 @@ void TypeInfo::fillTypeInfo(SQLHDBC pHDBC)
}
DynamicAny TypeInfo::getInfo(SQLSMALLINT type, const std::string& param) const
{
TypeInfoVec::const_iterator it = _typeInfo.begin();
TypeInfoVec::const_iterator end = _typeInfo.end();
for (; it != end; ++it)
{
if (type == it->get<1>())
return (*it)[param];
}
throw NotFoundException(param);
}
int TypeInfo::cDataType(int sqlDataType) const
{
DataTypeMap::const_iterator it = _cDataTypes.find(sqlDataType);

View File

@ -127,17 +127,33 @@ void Utility::dateTimeSync(Poco::DateTime& dt, const SQL_TIMESTAMP_STRUCT& ts)
double msec = ts.fraction/1000000;
double usec = 1000 * (msec - floor(msec));
dt.assign(ts.year,
ts.month,
ts.day,
ts.hour,
ts.minute,
ts.second,
dt.assign(ts.year,
ts.month,
ts.day,
ts.hour,
ts.minute,
ts.second,
(int) floor(msec),
(int) floor(usec));
}
void Utility::dateSync(SQL_DATE_STRUCT& ds, const Date& d)
{
ds.year = d.year();
ds.month = d.month();
ds.day = d.day();
}
void Utility::timeSync(SQL_TIME_STRUCT& ts, const Time& t)
{
ts.hour = t.hour();
ts.minute = t.minute();
ts.second = t.second();
}
void Utility::dateTimeSync(SQL_TIMESTAMP_STRUCT& ts, const Poco::DateTime& dt)
{
ts.year = dt.year();

View File

@ -435,6 +435,31 @@ void ODBCDB2Test::testPrepare()
}
void ODBCDB2Test::testStep()
{
if (!_pSession) fail ("Test not available.");
std::cout << std::endl << "DB2" << std::endl;
for (int i = 0; i < 8;)
{
recreateIntsTable();
_pSession->setFeature("autoBind", bindValues[i]);
_pSession->setFeature("autoExtract", bindValues[i+1]);
std::string mode = bindValues[i+1] ? "auto" : "manual";
std::cout << "Extraction: " << mode << std::endl;
_pExecutor->doStep(1000, 1);
recreateIntsTable();
_pExecutor->doStep(1000, 10);
recreateIntsTable();
_pExecutor->doStep(1000, 100);
recreateIntsTable();
_pExecutor->doStep(1000, 1000);
i += 2;
}
}
void ODBCDB2Test::testSetSimple()
{
if (!_pSession) fail ("Test not available.");
@ -773,6 +798,36 @@ void ODBCDB2Test::testBLOBStmt()
}
void ODBCDB2Test::testDate()
{
if (!_pSession) fail ("Test not available.");
for (int i = 0; i < 8;)
{
recreatePersonDateTable();
_pSession->setFeature("autoBind", bindValues[i]);
_pSession->setFeature("autoExtract", bindValues[i+1]);
_pExecutor->date();
i += 2;
}
}
void ODBCDB2Test::testTime()
{
if (!_pSession) fail ("Test not available.");
for (int i = 0; i < 8;)
{
recreatePersonTimeTable();
_pSession->setFeature("autoBind", bindValues[i]);
_pSession->setFeature("autoExtract", bindValues[i+1]);
_pExecutor->time();
i += 2;
}
}
void ODBCDB2Test::testDateTime()
{
if (!_pSession) fail ("Test not available.");
@ -1260,6 +1315,24 @@ void ODBCDB2Test::recreatePersonBLOBTable()
}
void ODBCDB2Test::recreatePersonDateTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornDate DATE)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTable()"); }
}
void ODBCDB2Test::recreatePersonTimeTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornTime TIME)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
}
void ODBCDB2Test::recreatePersonDateTimeTable()
{
dropObject("TABLE", "Person");
@ -1453,6 +1526,7 @@ CppUnit::Test* ODBCDB2Test::suite()
CppUnit_addTest(pSuite, ODBCDB2Test, testLimitPrepare);
CppUnit_addTest(pSuite, ODBCDB2Test, testLimitZero);
CppUnit_addTest(pSuite, ODBCDB2Test, testPrepare);
CppUnit_addTest(pSuite, ODBCDB2Test, testStep);
CppUnit_addTest(pSuite, ODBCDB2Test, testSetSimple);
CppUnit_addTest(pSuite, ODBCDB2Test, testSetComplex);
CppUnit_addTest(pSuite, ODBCDB2Test, testSetComplexUnique);
@ -1474,6 +1548,8 @@ CppUnit::Test* ODBCDB2Test::suite()
CppUnit_addTest(pSuite, ODBCDB2Test, testEmptyDB);
CppUnit_addTest(pSuite, ODBCDB2Test, testBLOB);
CppUnit_addTest(pSuite, ODBCDB2Test, testBLOBStmt);
CppUnit_addTest(pSuite, ODBCDB2Test, testDate);
CppUnit_addTest(pSuite, ODBCDB2Test, testTime);
CppUnit_addTest(pSuite, ODBCDB2Test, testDateTime);
CppUnit_addTest(pSuite, ODBCDB2Test, testFloat);
CppUnit_addTest(pSuite, ODBCDB2Test, testDouble);

View File

@ -84,6 +84,7 @@ public:
void testLimitPrepare();
void testLimitZero();
void testPrepare();
void testStep();
void testSetSimple();
void testSetComplex();
@ -108,6 +109,8 @@ public:
void testBLOB();
void testBLOBStmt();
void testDate();
void testTime();
void testDateTime();
void testFloat();
@ -147,6 +150,8 @@ private:
void dropObject(const std::string& type, const std::string& tableName);
void recreatePersonTable();
void recreatePersonBLOBTable();
void recreatePersonDateTable();
void recreatePersonTimeTable();
void recreatePersonDateTimeTable();
void recreateStringsTable();
void recreateIntsTable();

View File

@ -95,19 +95,6 @@ void ODBCMySQLTest::testBareboneODBC()
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
tableCreateString = "CREATE TABLE Test "
"(First VARCHAR(30),"
"Second VARCHAR(30),"
"Third VARBINARY(30),"
"Fourth INTEGER,"
"Fifth FLOAT,"
"Sixth DATE)";
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_MANUAL, false);
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND, false);
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL, false);
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND, false);
/*
MySQL supports batch statements as of 3.51.18
http://bugs.mysql.com/bug.php?id=7445
@ -436,6 +423,31 @@ void ODBCMySQLTest::testPrepare()
}
void ODBCMySQLTest::testStep()
{
if (!_pSession) fail ("Test not available.");
std::cout << std::endl << "MySQL" << std::endl;
for (int i = 0; i < 8;)
{
recreateIntsTable();
_pSession->setFeature("autoBind", bindValues[i]);
_pSession->setFeature("autoExtract", bindValues[i+1]);
std::string mode = bindValues[i+1] ? "auto" : "manual";
std::cout << "Extraction: " << mode << std::endl;
_pExecutor->doStep(1000, 1);
recreateIntsTable();
_pExecutor->doStep(1000, 10);
recreateIntsTable();
_pExecutor->doStep(1000, 100);
recreateIntsTable();
_pExecutor->doStep(1000, 1000);
i += 2;
}
}
void ODBCMySQLTest::testSetSimple()
{
if (!_pSession) fail ("Test not available.");
@ -774,6 +786,36 @@ void ODBCMySQLTest::testBLOBStmt()
}
void ODBCMySQLTest::testDate()
{
if (!_pSession) fail ("Test not available.");
for (int i = 0; i < 8;)
{
recreatePersonDateTable();
_pSession->setFeature("autoBind", bindValues[i]);
_pSession->setFeature("autoExtract", bindValues[i+1]);
_pExecutor->date();
i += 2;
}
}
void ODBCMySQLTest::testTime()
{
if (!_pSession) fail ("Test not available.");
for (int i = 0; i < 8;)
{
recreatePersonTimeTable();
_pSession->setFeature("autoBind", bindValues[i]);
_pSession->setFeature("autoExtract", bindValues[i+1]);
_pExecutor->time();
i += 2;
}
}
void ODBCMySQLTest::testDateTime()
{
if (!_pSession) fail ("Test not available.");
@ -1038,6 +1080,24 @@ void ODBCMySQLTest::recreatePersonBLOBTable()
}
void ODBCMySQLTest::recreatePersonDateTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornDate DATE)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTable()"); }
}
void ODBCMySQLTest::recreatePersonTimeTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornTime TIME)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
}
void ODBCMySQLTest::recreatePersonDateTimeTable()
{
dropObject("TABLE", "Person");
@ -1229,6 +1289,7 @@ CppUnit::Test* ODBCMySQLTest::suite()
CppUnit_addTest(pSuite, ODBCMySQLTest, testLimitPrepare);
CppUnit_addTest(pSuite, ODBCMySQLTest, testLimitZero);
CppUnit_addTest(pSuite, ODBCMySQLTest, testPrepare);
CppUnit_addTest(pSuite, ODBCMySQLTest, testStep);
CppUnit_addTest(pSuite, ODBCMySQLTest, testSetSimple);
CppUnit_addTest(pSuite, ODBCMySQLTest, testSetComplex);
CppUnit_addTest(pSuite, ODBCMySQLTest, testSetComplexUnique);
@ -1250,6 +1311,8 @@ CppUnit::Test* ODBCMySQLTest::suite()
CppUnit_addTest(pSuite, ODBCMySQLTest, testEmptyDB);
CppUnit_addTest(pSuite, ODBCMySQLTest, testBLOB);
CppUnit_addTest(pSuite, ODBCMySQLTest, testBLOBStmt);
CppUnit_addTest(pSuite, ODBCMySQLTest, testDate);
CppUnit_addTest(pSuite, ODBCMySQLTest, testTime);
CppUnit_addTest(pSuite, ODBCMySQLTest, testDateTime);
CppUnit_addTest(pSuite, ODBCMySQLTest, testFloat);
CppUnit_addTest(pSuite, ODBCMySQLTest, testDouble);

View File

@ -87,6 +87,7 @@ public:
void testLimitPrepare();
void testLimitZero();
void testPrepare();
void testStep();
void testSetSimple();
void testSetComplex();
@ -111,6 +112,8 @@ public:
void testBLOB();
void testBLOBStmt();
void testDate();
void testTime();
void testDateTime();
void testFloat();
void testDouble();
@ -147,6 +150,8 @@ private:
void dropObject(const std::string& type, const std::string& name);
void recreatePersonTable();
void recreatePersonBLOBTable();
void recreatePersonDateTable();
void recreatePersonTimeTable();
void recreatePersonDateTimeTable();
void recreateStringsTable();
void recreateIntsTable();

View File

@ -112,19 +112,6 @@ void ODBCOracleTest::testBarebone()
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
tableCreateString = "CREATE TABLE Test "
"(First VARCHAR(30),"
"Second VARCHAR(30),"
"Third BLOB,"
"Fourth INTEGER,"
"Fifth NUMBER,"
"Sixth DATE)";
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_MANUAL);
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
_pExecutor->bareboneODBCTest(_dbConnString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
tableCreateString = "CREATE TABLE Test "
"(First VARCHAR(30),"
"Second INTEGER,"
@ -490,6 +477,31 @@ void ODBCOracleTest::testPrepare()
}
void ODBCOracleTest::testStep()
{
if (!_pSession) fail ("Test not available.");
std::cout << std::endl << "Oracle" << std::endl;
for (int i = 0; i < 8;)
{
recreateIntsTable();
_pSession->setFeature("autoBind", bindValues[i]);
_pSession->setFeature("autoExtract", bindValues[i+1]);
std::string mode = bindValues[i+1] ? "auto" : "manual";
std::cout << "Extraction: " << mode << std::endl;
_pExecutor->doStep(1000, 1);
recreateIntsTable();
_pExecutor->doStep(1000, 10);
recreateIntsTable();
_pExecutor->doStep(1000, 100);
recreateIntsTable();
_pExecutor->doStep(1000, 1000);
i += 2;
}
}
void ODBCOracleTest::testSetSimple()
{
if (!_pSession) fail ("Test not available.");
@ -828,6 +840,21 @@ void ODBCOracleTest::testBLOBStmt()
}
void ODBCOracleTest::testDate()
{
if (!_pSession) fail ("Test not available.");
for (int i = 0; i < 8;)
{
recreatePersonDateTable();
_pSession->setFeature("autoBind", bindValues[i]);
_pSession->setFeature("autoExtract", bindValues[i+1]);
_pExecutor->date();
i += 2;
}
}
void ODBCOracleTest::testDateTime()
{
if (!_pSession) fail ("Test not available.");
@ -1447,12 +1474,21 @@ void ODBCOracleTest::recreatePersonBLOBTable()
void ODBCOracleTest::recreatePersonDateTimeTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born DATE)", now; }
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born TIMESTAMP)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
}
void ODBCOracleTest::recreatePersonDateTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornDate DATE)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTable()"); }
}
void ODBCOracleTest::recreateIntsTable()
{
dropObject("TABLE", "Strings");
@ -1669,6 +1705,7 @@ CppUnit::Test* ODBCOracleTest::suite()
CppUnit_addTest(pSuite, ODBCOracleTest, testLimitPrepare);
CppUnit_addTest(pSuite, ODBCOracleTest, testLimitZero);
CppUnit_addTest(pSuite, ODBCOracleTest, testPrepare);
CppUnit_addTest(pSuite, ODBCOracleTest, testStep);
CppUnit_addTest(pSuite, ODBCOracleTest, testSetSimple);
CppUnit_addTest(pSuite, ODBCOracleTest, testSetComplex);
CppUnit_addTest(pSuite, ODBCOracleTest, testSetComplexUnique);
@ -1690,6 +1727,7 @@ CppUnit::Test* ODBCOracleTest::suite()
CppUnit_addTest(pSuite, ODBCOracleTest, testEmptyDB);
CppUnit_addTest(pSuite, ODBCOracleTest, testBLOB);
CppUnit_addTest(pSuite, ODBCOracleTest, testBLOBStmt);
CppUnit_addTest(pSuite, ODBCOracleTest, testDate);
CppUnit_addTest(pSuite, ODBCOracleTest, testDateTime);
CppUnit_addTest(pSuite, ODBCOracleTest, testFloat);
CppUnit_addTest(pSuite, ODBCOracleTest, testDouble);

View File

@ -85,6 +85,7 @@ public:
void testLimitPrepare();
void testLimitZero();
void testPrepare();
void testStep();
void testSetSimple();
void testSetComplex();
@ -109,6 +110,7 @@ public:
void testBLOB();
void testBLOBStmt();
void testDate();
void testDateTime();
void testFloat();
void testDouble();
@ -151,6 +153,7 @@ private:
void dropObject(const std::string& type, const std::string& name);
void recreatePersonTable();
void recreatePersonBLOBTable();
void recreatePersonDateTable();
void recreatePersonDateTimeTable();
void recreateStringsTable();
void recreateIntsTable();

View File

@ -451,6 +451,31 @@ void ODBCPostgreSQLTest::testPrepare()
}
void ODBCPostgreSQLTest::testStep()
{
if (!_pSession) fail ("Test not available.");
std::cout << std::endl << "PostgreSQL" << std::endl;
for (int i = 0; i < 8;)
{
recreateIntsTable();
_pSession->setFeature("autoBind", bindValues[i]);
_pSession->setFeature("autoExtract", bindValues[i+1]);
std::string mode = bindValues[i+1] ? "auto" : "manual";
std::cout << "Extraction: " << mode << std::endl;
_pExecutor->doStep(1000, 1);
recreateIntsTable();
_pExecutor->doStep(1000, 10);
recreateIntsTable();
_pExecutor->doStep(1000, 100);
recreateIntsTable();
_pExecutor->doStep(1000, 1000);
i += 2;
}
}
void ODBCPostgreSQLTest::testSetSimple()
{
if (!_pSession) fail ("Test not available.");
@ -796,6 +821,36 @@ void ODBCPostgreSQLTest::testDateTime()
}
void ODBCPostgreSQLTest::testDate()
{
if (!_pSession) fail ("Test not available.");
for (int i = 0; i < 8;)
{
recreatePersonDateTable();
_pSession->setFeature("autoBind", bindValues[i]);
_pSession->setFeature("autoExtract", bindValues[i+1]);
_pExecutor->date();
i += 2;
}
}
void ODBCPostgreSQLTest::testTime()
{
if (!_pSession) fail ("Test not available.");
for (int i = 0; i < 8;)
{
recreatePersonTimeTable();
_pSession->setFeature("autoBind", bindValues[i]);
_pSession->setFeature("autoExtract", bindValues[i+1]);
_pExecutor->time();
i += 2;
}
}
void ODBCPostgreSQLTest::testFloat()
{
if (!_pSession) fail ("Test not available.");
@ -1210,6 +1265,24 @@ void ODBCPostgreSQLTest::recreatePersonDateTimeTable()
}
void ODBCPostgreSQLTest::recreatePersonDateTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornDate DATE)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTable()"); }
}
void ODBCPostgreSQLTest::recreatePersonTimeTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornTime TIME)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
}
void ODBCPostgreSQLTest::recreateIntsTable()
{
dropObject("TABLE", "Strings");
@ -1432,6 +1505,7 @@ CppUnit::Test* ODBCPostgreSQLTest::suite()
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testLimitPrepare);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testLimitZero);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testPrepare);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStep);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSetSimple);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSetComplex);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSetComplexUnique);
@ -1453,6 +1527,8 @@ CppUnit::Test* ODBCPostgreSQLTest::suite()
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testEmptyDB);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testBLOB);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testBLOBStmt);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testDate);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testTime);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testDateTime);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testFloat);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testDouble);

View File

@ -93,6 +93,7 @@ public:
void testLimitPrepare();
void testLimitZero();
void testPrepare();
void testStep();
void testSetSimple();
void testSetComplex();
@ -118,6 +119,8 @@ public:
void testBLOBStmt();
void testDateTime();
void testDate();
void testTime();
void testFloat();
void testDouble();
@ -157,6 +160,8 @@ private:
void recreatePersonTable();
void recreatePersonBLOBTable();
void recreatePersonDateTimeTable();
void recreatePersonDateTable();
void recreatePersonTimeTable();
void recreateStringsTable();
void recreateIntsTable();
void recreateFloatsTable();

View File

@ -439,6 +439,31 @@ void ODBCSQLServerTest::testPrepare()
}
void ODBCSQLServerTest::testStep()
{
if (!_pSession) fail ("Test not available.");
std::cout << std::endl << "MS SQL Server" << std::endl;
for (int i = 0; i < 8;)
{
recreateIntsTable();
_pSession->setFeature("autoBind", bindValues[i]);
_pSession->setFeature("autoExtract", bindValues[i+1]);
std::string mode = bindValues[i+1] ? "auto" : "manual";
std::cout << "Extraction: " << mode << std::endl;
_pExecutor->doStep(1000, 1);
recreateIntsTable();
_pExecutor->doStep(1000, 10);
recreateIntsTable();
_pExecutor->doStep(1000, 100);
recreateIntsTable();
_pExecutor->doStep(1000, 1000);
i += 2;
}
}
void ODBCSQLServerTest::testSetSimple()
{
if (!_pSession) fail ("Test not available.");
@ -1518,8 +1543,11 @@ bool ODBCSQLServerTest::init(const std::string& driver, const std::string& dsn)
CppUnit::Test* ODBCSQLServerTest::suite()
{
#ifdef POCO_OS_FAMILY_WINDOWS
#ifdef POCO_ODBC_USE_SQL_NATIVE
if (init("SQL Native Client", "PocoDataSQLServerTest"))
#else
if (init("SQL Server", "PocoDataSQLServerTest"))
//if (init("SQL Native Client", "PocoDataSQLServerTest"))
#endif
#else
if (init("FreeTDS", "PocoDataSQLServerTest"))
#endif
@ -1548,6 +1576,7 @@ CppUnit::Test* ODBCSQLServerTest::suite()
CppUnit_addTest(pSuite, ODBCSQLServerTest, testLimitPrepare);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testLimitZero);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testPrepare);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStep);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSetSimple);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSetComplex);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSetComplexUnique);

View File

@ -44,6 +44,10 @@
#include "SQLExecutor.h"
// uncomment to use native SQL Server ODBC driver
// #define POCO_ODBC_USE_SQL_NATIVE
class ODBCSQLServerTest: public CppUnit::TestCase
/// SQLServer ODBC test class
/// Tested:
@ -87,6 +91,7 @@ public:
void testLimitPrepare();
void testLimitZero();
void testPrepare();
void testStep();
void testSetSimple();
void testSetComplex();

View File

@ -444,6 +444,31 @@ void ODBCSQLiteTest::testPrepare()
}
void ODBCSQLiteTest::testStep()
{
if (!_pSession) fail ("Test not available.");
std::cout << std::endl << "SQLite" << std::endl;
for (int i = 0; i < 8;)
{
recreateIntsTable();
_pSession->setFeature("autoBind", bindValues[i]);
_pSession->setFeature("autoExtract", bindValues[i+1]);
std::string mode = bindValues[i+1] ? "auto" : "manual";
std::cout << "Extraction: " << mode << std::endl;
_pExecutor->doStep(1000, 1);
recreateIntsTable();
_pExecutor->doStep(1000, 10);
recreateIntsTable();
_pExecutor->doStep(1000, 100);
recreateIntsTable();
_pExecutor->doStep(1000, 1000);
i += 2;
}
}
void ODBCSQLiteTest::testSetSimple()
{
if (!_pSession) fail ("Test not available.");
@ -1179,6 +1204,7 @@ CppUnit::Test* ODBCSQLiteTest::suite()
CppUnit_addTest(pSuite, ODBCSQLiteTest, testLimitPrepare);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testLimitZero);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testPrepare);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testStep);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testSetSimple);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testSetComplex);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testSetComplexUnique);

View File

@ -84,6 +84,7 @@ public:
void testLimitPrepare();
void testLimitZero();
void testPrepare();
void testStep();
void testSetSimple();
void testSetComplex();

View File

@ -38,8 +38,11 @@
#include "Poco/Any.h"
#include "Poco/DynamicAny.h"
#include "Poco/DateTime.h"
#include "Poco/Stopwatch.h"
#include "Poco/Exception.h"
#include "Poco/Data/Common.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/Data/BLOB.h"
#include "Poco/Data/StatementImpl.h"
#include "Poco/Data/RecordSet.h"
@ -78,6 +81,7 @@ using Poco::Any;
using Poco::AnyCast;
using Poco::DynamicAny;
using Poco::DateTime;
using Poco::Stopwatch;
using Poco::NotFoundException;
using Poco::InvalidAccessException;
using Poco::BadCastException;
@ -1405,7 +1409,6 @@ void SQLExecutor::limitPrepare()
}
void SQLExecutor::prepare()
{
std::string funct = "prepare()";
@ -1427,6 +1430,30 @@ void SQLExecutor::prepare()
}
void SQLExecutor::doStep(Poco::UInt32 dataSize, Poco::UInt32 stepSize)
{
std::string funct = "step()";
std::vector<int> data(dataSize, 1);
Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(data)));
stmt.execute();
data.clear();
assert (0 == data.size());
Stopwatch sw;
sw.start();
try { *_pSession << "SELECT * FROM Strings", into(data), step(stepSize), now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
sw.stop();
std::cout << stepSize << '/' << sw.elapsed() / 1000.0 << " [ms]" << std::endl;
assert (dataSize == data.size());
assert (1 == data[data.size()-1]);
}
void SQLExecutor::setSimple()
{
std::string funct = "setSimple()";
@ -2079,6 +2106,83 @@ void SQLExecutor::dateTime()
}
void SQLExecutor::date()
{
std::string funct = "date()";
std::string lastName("lastname");
std::string firstName("firstname");
std::string address("Address");
Date bornDate(1965, 6, 18);
int count = 0;
try { *_pSession << "INSERT INTO PERSON VALUES (?,?,?,?)",
use(lastName),
use(firstName),
use(address),
use(bornDate),
now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
try { *_pSession << "SELECT COUNT(*) FROM PERSON", into(count), now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
assert (count == 1);
Date d;
Time t;
try { *_pSession << "SELECT BornDate FROM Person", into(d), now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
assert (d == bornDate);
Statement stmt = (*_pSession << "SELECT BornDate FROM Person", now);
RecordSet rset(stmt);
DateTime dt1 = rset["BornDate"].convert<DateTime>();
Date d2(dt1);
assert (d2 == bornDate);
}
void SQLExecutor::time()
{
std::string funct = "time()";
std::string lastName("lastname");
std::string firstName("firstname");
std::string address("Address");
Time bornTime (5, 35, 1);
int count = 0;
try { *_pSession << "INSERT INTO PERSON VALUES (?,?,?,?)",
use(lastName),
use(firstName),
use(address),
use(bornTime),
now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
try { *_pSession << "SELECT COUNT(*) FROM PERSON", into(count), now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
assert (count == 1);
Date d;
Time t;
try { *_pSession << "SELECT BornTime FROM Person", into(t), now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
assert (t == bornTime);
Statement stmt = (*_pSession << "SELECT BornTime FROM Person", now);
RecordSet rset(stmt);
DateTime dt2 = rset["BornTime"].convert<DateTime>();
Time t2(dt2);
assert (t2 == bornTime);
}
void SQLExecutor::tuples()
{
typedef Tuple<int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int> TupleType;

View File

@ -104,6 +104,7 @@ public:
void limitPrepare();
void limitZero();
void prepare();
void doStep(Poco::UInt32 dataSize, Poco::UInt32 stepSize);
void setSimple();
void setComplex();
@ -129,6 +130,8 @@ public:
void blobStmt();
void dateTime();
void date();
void time();
void floats();
void doubles();
void tuples();

View File

@ -114,6 +114,12 @@ public:
void bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir);
/// Binds a BLOB.
void bind(std::size_t pos, const Date& val, Direction dir);
/// Binds a Date.
void bind(std::size_t pos, const Time& val, Direction dir);
/// Binds a Time.
void bind(std::size_t pos, const DateTime& val, Direction dir);
/// Binds a DateTime.

View File

@ -120,6 +120,12 @@ public:
bool extract(std::size_t pos, Poco::Data::BLOB& val);
/// Extracts a BLOB.
bool extract(std::size_t pos, Poco::Data::Date& val);
/// Extracts a Date.
bool extract(std::size_t pos, Poco::Data::Time& val);
/// Extracts a Time.
bool extract(std::size_t pos, Poco::DateTime& val);
/// Extracts a DateTime.
@ -248,6 +254,20 @@ private:
val = b;
break;
}
case MetaColumn::FDT_DATE:
{
Date d;
ret = extract(pos, d);
val = d;
break;
}
case MetaColumn::FDT_TIME:
{
Time t;
ret = extract(pos, t);
val = t;
break;
}
case MetaColumn::FDT_TIMESTAMP:
{
DateTime dt;

View File

@ -77,8 +77,8 @@ protected:
bool hasNext();
/// Returns true if a call to next() will return data.
void next();
/// Retrieves the next row from the resultset.
Poco::UInt32 next();
/// Retrieves the next row from the resultset and returns 1.
/// Will throw, if the resultset is empty.
bool canBind() const;

View File

@ -57,6 +57,9 @@ class SQLite_API Utility
/// Various utility functions for SQLite, mostly return code handling
{
public:
static const std::string SQLITE_DATE_FORMAT;
static const std::string SQLITE_TIME_FORMAT;
static std::string lastError(sqlite3* pDb);
/// Retreives the last error code from sqlite and converts it to a string

View File

@ -36,6 +36,8 @@
#include "Poco/Data/SQLite/Binder.h"
#include "Poco/Data/SQLite/Utility.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/Data/BLOB.h"
#include "Poco/Exception.h"
#include "Poco/DateTimeFormatter.h"
@ -103,6 +105,23 @@ void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir)
}
void Binder::bind(std::size_t pos, const Date& val, Direction dir)
{
DateTime dt(val.year(), val.month(), val.day());
std::string str(DateTimeFormatter::format(dt, Utility::SQLITE_DATE_FORMAT));
bind(pos, str, dir);
}
void Binder::bind(std::size_t pos, const Time& val, Direction dir)
{
DateTime dt;
dt.assign(dt.year(), dt.month(), dt.day(), val.hour(), val.minute(), val.second());
std::string str(DateTimeFormatter::format(dt, Utility::SQLITE_TIME_FORMAT));
bind(pos, str, dir);
}
void Binder::bind(std::size_t pos, const DateTime& val, Direction dir)
{
std::string dt(DateTimeFormatter::format(val, DateTimeFormat::ISO8601_FORMAT));

View File

@ -36,6 +36,8 @@
#include "Poco/Data/SQLite/Extractor.h"
#include "Poco/Data/SQLite/Utility.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/Data/BLOB.h"
#include "Poco/Data/DataException.h"
#include "Poco/DateTimeParser.h"
@ -205,6 +207,28 @@ bool Extractor::extract(std::size_t pos, char& val)
}
bool Extractor::extract(std::size_t pos, Date& val)
{
std::string str;
extract(pos, str);
int tzd;
DateTime dt = DateTimeParser::parse(Utility::SQLITE_DATE_FORMAT, str, tzd);
val = dt;
return true;
}
bool Extractor::extract(std::size_t pos, Time& val)
{
std::string str;
extract(pos, str);
int tzd;
DateTime dt = DateTimeParser::parse(Utility::SQLITE_TIME_FORMAT, str, tzd);
val = dt;
return true;
}
bool Extractor::extract(std::size_t pos, DateTime& val)
{
std::string dt;

View File

@ -196,7 +196,7 @@ bool SQLiteStatementImpl::hasNext()
}
void SQLiteStatementImpl::next()
Poco::UInt32 SQLiteStatementImpl::next()
{
if (SQLITE_ROW == _nextResponse)
{
@ -222,6 +222,8 @@ void SQLiteStatementImpl::next()
int rc = _nextResponse;
Utility::throwException(rc, std::string("Iterator Error: trying to access the next value"));
}
return 1u;
}

View File

@ -49,6 +49,10 @@ namespace Data {
namespace SQLite {
const std::string Utility::SQLITE_DATE_FORMAT = "%Y-%m-%d";
const std::string Utility::SQLITE_TIME_FORMAT = "%H:%M:%S";
std::string Utility::lastError(sqlite3 *pDB)
{
return std::string(sqlite3_errmsg(pDB));
@ -76,6 +80,8 @@ MetaColumn::ColumnDataType Utility::getColumnType(sqlite3_stmt* pStmt, std::size
return MetaColumn::FDT_DOUBLE;
else if (sqliteType.npos != sqliteType.find("BLOB"))
return MetaColumn::FDT_BLOB;
else if (sqliteType.npos != sqliteType.find("DATE"))
return MetaColumn::FDT_TIMESTAMP;
throw Poco::NotFoundException();
}

View File

@ -34,6 +34,8 @@
#include "CppUnit/TestCaller.h"
#include "CppUnit/TestSuite.h"
#include "Poco/Data/Common.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/Data/BLOB.h"
#include "Poco/Data/Statement.h"
#include "Poco/Data/RecordSet.h"
@ -42,6 +44,8 @@
#include "Poco/Data/TypeHandler.h"
#include "Poco/Tuple.h"
#include "Poco/Any.h"
#include "Poco/DynamicAny.h"
#include "Poco/DateTime.h"
#include "Poco/Exception.h"
#include <iostream>
@ -51,6 +55,7 @@ using Poco::Tuple;
using Poco::Any;
using Poco::AnyCast;
using Poco::DynamicAny;
using Poco::DateTime;
using Poco::InvalidAccessException;
using Poco::RangeException;
using Poco::BadCastException;
@ -1499,6 +1504,42 @@ void SQLiteTest::testTupleVector1()
}
void SQLiteTest::testDateTime()
{
Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db"));
tmp << "DROP TABLE IF EXISTS DateTimes", now;
tmp << "CREATE TABLE DateTimes (dt0 DATE)", now;
DateTime dt(1965, 6, 18, 5, 35, 1);
tmp << "INSERT INTO DateTimes VALUES (?)", use(dt), now;
DateTime rdt;
assert (rdt != dt);
tmp << "SELECT * FROM DateTimes", into(rdt), now;
assert (rdt == dt);
tmp << "DELETE FROM DateTimes", now;
Date d(dt);
tmp << "INSERT INTO DateTimes VALUES (?)", use(d), now;
Date rd;
assert (rd != d);
tmp << "SELECT * FROM DateTimes", into(rd), now;
assert (rd == d);
tmp << "DELETE FROM DateTimes", now;
Time t(dt);
tmp << "INSERT INTO DateTimes VALUES (?)", use(t), now;
Time rt;
assert (rt != t);
tmp << "SELECT * FROM DateTimes", into(rt), now;
assert (rt == t);
}
void SQLiteTest::testInternalExtraction()
{
Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db"));
@ -1901,6 +1942,7 @@ CppUnit::Test* SQLiteTest::suite()
CppUnit_addTest(pSuite, SQLiteTest, testTupleVector2);
CppUnit_addTest(pSuite, SQLiteTest, testTuple1);
CppUnit_addTest(pSuite, SQLiteTest, testTupleVector1);
CppUnit_addTest(pSuite, SQLiteTest, testDateTime);
CppUnit_addTest(pSuite, SQLiteTest, testInternalExtraction);
CppUnit_addTest(pSuite, SQLiteTest, testPrimaryKeyConstraint);
CppUnit_addTest(pSuite, SQLiteTest, testNull);

View File

@ -107,6 +107,8 @@ public:
void testTuple10();
void testTupleVector10();
void testDateTime();
void testInternalExtraction();
void testPrimaryKeyConstraint();
void testNull();

View File

@ -52,6 +52,8 @@ class DynamicAny;
namespace Data {
class Date;
class Time;
class BLOB;
enum NullData
@ -70,6 +72,8 @@ enum NullData
NULL_DOUBLE,
NULL_STRING,
NULL_BLOB,
NULL_DATE,
NULL_TIME,
NULL_TIMESTAMP
};
@ -149,6 +153,12 @@ public:
virtual void bind(std::size_t pos, const DateTime& val, Direction dir = PD_IN) = 0;
/// Binds a DateTime.
virtual void bind(std::size_t pos, const Date& val, Direction dir = PD_IN) = 0;
/// Binds a Date.
virtual void bind(std::size_t pos, const Time& val, Direction dir = PD_IN) = 0;
/// Binds a Time.
virtual void bind(std::size_t pos, const NullData& val, Direction dir = PD_IN) = 0;
/// Binds a null.

View File

@ -55,6 +55,8 @@ class DynamicAny;
namespace Data {
class Date;
class Time;
class BLOB;
@ -119,6 +121,12 @@ public:
virtual bool extract(std::size_t pos, DateTime& val) = 0;
/// Extracts a DateTime. Returns false if null was received.
virtual bool extract(std::size_t pos, Date& val) = 0;
/// Extracts a Date. Returns false if null was received.
virtual bool extract(std::size_t pos, Time& val) = 0;
/// Extracts a Time. Returns false if null was received.
virtual bool extract(std::size_t pos, Any& val) = 0;
/// Extracts an Any. Returns false if null was received.

View File

@ -56,6 +56,8 @@ class DynamicAny;
namespace Data {
class Date;
class Time;
class BLOB;
@ -122,6 +124,12 @@ public:
virtual void prepare(std::size_t pos, const DateTime&) = 0;
/// Prepares a DateTime.
virtual void prepare(std::size_t pos, const Date&) = 0;
/// Prepares a Date.
virtual void prepare(std::size_t pos, const Time&) = 0;
/// Prepares a Time.
virtual void prepare(std::size_t pos, const Any&) = 0;
/// Prepares an Any.

View File

@ -0,0 +1,316 @@
//
// Date.h
//
// $Id: //poco/Main/Data/include/Poco/Data/Date.h#7 $
//
// Library: Data
// Package: DataCore
// Module: Date
//
// Definition of the Date class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#ifndef Data_Date_INCLUDED
#define Data_Date_INCLUDED
#include "Poco/Data/Data.h"
#include "Poco/DynamicAnyHolder.h"
#include "Poco/Exception.h"
namespace Poco {
class DateTime;
namespace Data {
class Time;
class Data_API Date
/// Date class wraps a DateTime and exposes date related interface.
/// The purpose of this class is binding/extraction support for date fields.
{
public:
Date();
/// Creates the Date
Date(int year, int month, int day);
/// Creates the Date
Date(const DateTime& dt);
/// Creates the Date from DateTime
~Date();
/// Destroys the Date.
Poco::UInt32 year() const;
/// Returns the year.
Poco::UInt32 month() const;
/// Returns the month.
Poco::UInt32 day() const;
/// Returns the day.
void assign(int year, int month, int day);
/// Assigns date.
Date& operator = (const DateTime& dt);
/// Assignment operator for DateTime.
bool operator == (const Date& date);
/// Equality operator.
bool operator != (const Date& date);
/// Inequality operator.
bool operator < (const Date& date);
/// Less then operator.
bool operator > (const Date& date);
/// Greater then operator.
private:
int _year;
int _month;
int _day;
};
//
// inlines
//
inline Poco::UInt32 Date::year() const
{
return _year;
}
inline Poco::UInt32 Date::month() const
{
return _month;
}
inline Poco::UInt32 Date::day() const
{
return _day;
}
inline Date& Date::operator = (const DateTime& dt)
{
assign(dt.year(), dt.month(), dt.day());
return *this;
}
inline bool Date::operator == (const Date& date)
{
return _year == date.year() &&
_month == date.month() &&
_day == date.day();
}
inline bool Date::operator != (const Date& date)
{
return !(*this == date);
}
inline bool Date::operator > (const Date& date)
{
return !(*this == date) && !(*this < date);
}
} } // namespace Poco::Data
//
// DynamicAnyHolderImpl<BLOB>
//
namespace Poco {
template <>
class DynamicAnyHolderImpl<Data::Date>: public DynamicAnyHolder
{
public:
DynamicAnyHolderImpl(const Data::Date& val): _val(val)
{
}
~DynamicAnyHolderImpl()
{
}
const std::type_info& type() const
{
return typeid(Data::Date);
}
void convert(Int8& val) const
{
throw Poco::BadCastException();
}
void convert(Int16& val) const
{
throw Poco::BadCastException();
}
void convert(Int32& val) const
{
throw Poco::BadCastException();
}
void convert(Int64& val) const
{
throw Poco::BadCastException();
}
void convert(UInt8& val) const
{
throw Poco::BadCastException();
}
void convert(UInt16& val) const
{
throw Poco::BadCastException();
}
void convert(UInt32& val) const
{
throw Poco::BadCastException();
}
void convert(UInt64& val) const
{
throw Poco::BadCastException();
}
void convert(bool& val) const
{
throw Poco::BadCastException();
}
void convert(float& val) const
{
throw Poco::BadCastException();
}
void convert(double& val) const
{
throw Poco::BadCastException();
}
void convert(char& val) const
{
throw Poco::BadCastException();
}
void convert(Poco::Timestamp& val) const
{
DateTime dt;
dt.assign(_val.year(), _val.month(), _val.day());
val = dt.timestamp();
}
void convert(Poco::DateTime& val) const
{
val.assign(_val.year(), _val.month(), _val.day());
}
void convert(Poco::LocalDateTime& val) const
{
val.assign(_val.year(), _val.month(), _val.day());
}
bool isArray() const
{
return false;
}
virtual bool isStruct() const
{
return false;
}
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
void convert(std::string& val) const
{
DateTime dt(_val.year(), _val.month(), _val.day());
val = DateTimeFormatter::format(dt, "%Y/%m/%d");
}
DynamicAnyHolder* clone() const
{
return new DynamicAnyHolderImpl(_val);
}
const Data::Date& value() const
{
return _val;
}
private:
Data::Date _val;
};
} // namespace Poco
#endif // Data_Date_INCLUDED

View File

@ -67,6 +67,8 @@ public:
FDT_DOUBLE,
FDT_STRING,
FDT_BLOB,
FDT_DATE,
FDT_TIME,
FDT_TIMESTAMP,
FDT_UNKNOWN
};

View File

@ -85,26 +85,30 @@ inline const Limit& Range::upper() const
}
template <typename T> Limit limit(T lim, bool hard = false)
template <typename T>
Limit limit(T lim, bool hard = false)
/// Creates an upperLimit
{
return Limit(static_cast<Poco::UInt32>(lim), hard, false);
}
template <typename T> Limit upperLimit(T lim, bool hard = false)
template <typename T>
Limit upperLimit(T lim, bool hard = false)
{
return limit(lim, hard);
}
template <typename T> Limit lowerLimit(T lim)
template <typename T>
Limit lowerLimit(T lim)
{
return Limit(static_cast<Poco::UInt32>(lim), true, true);
}
template <typename T> Range range(T low, T upp, bool hard = false)
template <typename T>
Range range(T low, T upp, bool hard = false)
{
return Range(static_cast<Poco::UInt32>(low), static_cast<Poco::UInt32>(upp), hard);
}

View File

@ -43,6 +43,7 @@
#include "Poco/Data/Data.h"
#include "Poco/Data/StatementImpl.h"
#include "Poco/Data/Range.h"
#include "Poco/Data/Step.h"
#include "Poco/SharedPtr.h"
#include "Poco/Mutex.h"
#include "Poco/ActiveMethod.h"
@ -186,10 +187,16 @@ public:
/// Set per default to zero to Limit::LIMIT_UNLIMITED, which disables the limit.
Statement& operator , (const Range& extrRange);
/// Sets a an etxraction Range on the maximum number of rows a select is allowed to return.
/// Sets a an extraction range for the maximum number of rows a select is allowed to return.
///
/// Set per default to Limit::LIMIT_UNLIMITED which disables the range.
Statement& operator , (const Step& extrStep);
/// Sets a an extraction step (the number of rows a select is allowed to return
/// on every fetch attempt).
///
/// Set per default to Step::DEFAULT_STEP (1 row at a time).
std::string toString() const;
/// Creates a string from the accumulated SQL statement
@ -362,6 +369,13 @@ inline Statement& Statement::operator , (const Range& extrRange)
}
inline Statement& Statement::operator , (const Step& extrStep)
{
_pImpl->setStep(extrStep.value());
return *this;
}
inline std::string Statement::toString() const
{
return _pImpl->toString();

View File

@ -133,6 +133,12 @@ public:
Storage getStorage() const;
/// Returns the storage type for this statement.
void setStep(Poco::UInt32 step);
/// Sets the step for this statement;
Poco::UInt32 getStep() const;
/// Returns the step type for this statement.
std::size_t extractionCount() const;
/// Returns the number of extraction storage buffers associated
/// with the statement.
@ -157,8 +163,9 @@ protected:
/// several consecutive calls to hasNext without data getting lost,
/// ie. hasNext(); hasNext(); next() must be equal to hasNext(); next();
virtual void next() = 0;
/// Retrieves the next row from the resultset.
virtual Poco::UInt32 next() = 0;
/// Retrieves the next row or set of rows from the resultset and
/// returns the number of rows retreved.
///
/// Will throw, if the resultset is empty.
/// Expects the statement to be compiled and bound
@ -325,6 +332,7 @@ private:
AbstractBindingVec _bindings;
AbstractExtractionVecVec _extractors;
Poco::UInt32 _curDataSet;
Poco::UInt32 _step;
friend class Statement;
};
@ -403,6 +411,18 @@ inline StatementImpl::Storage StatementImpl::getStorage() const
}
inline void StatementImpl::setStep(Poco::UInt32 step)
{
_step = step;
}
inline Poco::UInt32 StatementImpl::getStep() const
{
return _step;
}
inline std::size_t StatementImpl::extractionCount() const
{
return extractions().size();

View File

@ -0,0 +1,94 @@
//
// Step.h
//
// $Id: //poco/Main/Data/include/Poco/Data/Step.h#7 $
//
// Library: Data
// Package: DataCore
// Module: Step
//
// Definition of the Step class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#ifndef Data_Step_INCLUDED
#define Data_Step_INCLUDED
#include "Poco/Data/Data.h"
namespace Poco {
namespace Data {
class Data_API Step
/// Step stores information how many rows should be returned at evry advance through the recordset.
{
public:
enum
{
DEFAULT_STEP = 1u
};
Step(Poco::UInt32 value = 1u);
/// Creates the Step.
///
/// Value contains the step and defaults to DEFAULT_STEP.
~Step();
/// Destroys the Step.
Poco::UInt32 value() const;
/// Returns the value of the limit
private:
Poco::UInt32 _value;
};
//
// inlines
//
inline Poco::UInt32 Step::value() const
{
return _value;
}
template <typename T>
Step step(T step)
{
return Step(static_cast<Poco::UInt32>(step));
}
} } // namespace Poco::Data
#endif // Data_Step_INCLUDED

View File

@ -0,0 +1,320 @@
//
// Time.h
//
// $Id: //poco/Main/Data/include/Poco/Data/Time.h#7 $
//
// Library: Data
// Package: DataCore
// Module: Time
//
// Definition of the Time class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#ifndef Data_Time_INCLUDED
#define Data_Time_INCLUDED
#include "Poco/Data/Data.h"
#include "Poco/DynamicAnyHolder.h"
#include "Poco/Exception.h"
namespace Poco {
class DateTime;
namespace Data {
class Date;
class Data_API Time
/// Time class wraps a DateTime and exposes time related interface.
/// The purpose of this class is binding/extraction support for time fields.
{
public:
Time();
/// Creates the Time
Time(int hour, int minute, int second);
/// Creates the Time
Time(const DateTime& dt);
/// Creates the Time from DateTime
~Time();
/// Destroys the Time.
Poco::UInt32 hour() const;
/// Returns the hour.
Poco::UInt32 minute() const;
/// Returns the minute.
Poco::UInt32 second() const;
/// Returns the second.
void assign(int hour, int minute, int second);
/// Assigns time.
Time& operator = (const DateTime& dt);
/// Assignment operator for DateTime.
bool operator == (const Time& time);
/// Equality operator.
bool operator != (const Time& time);
/// Inequality operator.
bool operator < (const Time& time);
/// Less then operator.
bool operator > (const Time& time);
/// Greater then operator.
private:
int _hour;
int _minute;
int _second;
};
//
// inlines
//
inline Poco::UInt32 Time::hour() const
{
return _hour;
}
inline Poco::UInt32 Time::minute() const
{
return _minute;
}
inline Time& Time::operator = (const DateTime& dt)
{
assign(dt.hour(), dt.minute(), dt.second());
return *this;
}
inline Poco::UInt32 Time::second() const
{
return _second;
}
inline bool Time::operator == (const Time& time)
{
return _hour == time.hour() &&
_minute == time.minute() &&
_second == time.second();
}
inline bool Time::operator != (const Time& time)
{
return !(*this == time);
}
inline bool Time::operator > (const Time& time)
{
return !(*this == time) && !(*this < time);
}
} } // namespace Poco::Data
//
// DynamicAnyHolderImpl<BLOB>
//
namespace Poco {
template <>
class DynamicAnyHolderImpl<Data::Time>: public DynamicAnyHolder
{
public:
DynamicAnyHolderImpl(const Data::Time& val): _val(val)
{
}
~DynamicAnyHolderImpl()
{
}
const std::type_info& type() const
{
return typeid(Data::Time);
}
void convert(Int8& val) const
{
throw Poco::BadCastException();
}
void convert(Int16& val) const
{
throw Poco::BadCastException();
}
void convert(Int32& val) const
{
throw Poco::BadCastException();
}
void convert(Int64& val) const
{
throw Poco::BadCastException();
}
void convert(UInt8& val) const
{
throw Poco::BadCastException();
}
void convert(UInt16& val) const
{
throw Poco::BadCastException();
}
void convert(UInt32& val) const
{
throw Poco::BadCastException();
}
void convert(UInt64& val) const
{
throw Poco::BadCastException();
}
void convert(bool& val) const
{
throw Poco::BadCastException();
}
void convert(float& val) const
{
throw Poco::BadCastException();
}
void convert(double& val) const
{
throw Poco::BadCastException();
}
void convert(char& val) const
{
throw Poco::BadCastException();
}
void convert(Poco::Timestamp& val) const
{
Poco::DateTime dt;
dt.assign(dt.year(), dt.month(), dt.day(), _val.hour(), _val.minute(), _val.second());
val = dt.timestamp();
}
void convert(Poco::DateTime& val) const
{
Poco::DateTime dt;
dt.assign(dt.year(), dt.month(), dt.day(), _val.hour(), _val.minute(), _val.second());
val = dt;
}
void convert(Poco::LocalDateTime& val) const
{
Poco::LocalDateTime ldt;
ldt.assign(ldt.year(), ldt.month(), ldt.day(), _val.hour(), _val.minute(), _val.second());
val = ldt;
}
bool isArray() const
{
return false;
}
virtual bool isStruct() const
{
return false;
}
bool isInteger() const
{
return false;
}
bool isSigned() const
{
return false;
}
bool isNumeric() const
{
return false;
}
bool isString() const
{
return false;
}
void convert(std::string& val) const
{
DateTime dt(0, 1, 1, _val.hour(), _val.minute(), _val.second());
val = DateTimeFormatter::format(dt, "%H:%M:%S");
}
DynamicAnyHolder* clone() const
{
return new DynamicAnyHolderImpl(_val);
}
const Data::Time& value() const
{
return _val;
}
private:
Data::Time _val;
};
} // namespace Poco
#endif // Data_Time_INCLUDED

112
Data/src/Date.cpp Normal file
View File

@ -0,0 +1,112 @@
//
// Date.cpp
//
// $Id: //poco/Main/Data/src/Date.cpp#5 $
//
// Library: Data
// Package: DataCore
// Module: Date
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#include "Poco/Data/Date.h"
#include "Poco/DateTime.h"
#include "Poco/NumberFormatter.h"
using Poco::DateTime;
using Poco::NumberFormatter;
namespace Poco {
namespace Data {
Date::Date()
{
DateTime dt;
assign(dt.year(), dt.month(), dt.day());
}
Date::Date(int year, int month, int day)
{
assign(year, month, day);
}
Date::Date(const DateTime& dt)
{
assign(dt.year(), dt.month(), dt.day());
}
Date::~Date()
{
}
void Date::assign(int year, int month, int day)
{
if (year < 0 || year > 9999)
throw InvalidArgumentException("Year must be between 0 and 9999");
if (month < 1 || month > 12)
throw InvalidArgumentException("Month must be between 1 and 12");
if (day < 1 || day > DateTime::daysOfMonth(year, month))
throw InvalidArgumentException("Month must be between 1 and " +
NumberFormatter::format(DateTime::daysOfMonth(year, month)));
_year = year;
_month = month;
_day = day;
}
bool Date::operator < (const Date& date)
{
int year = date.year();
if (_year < year) return true;
else if (_year > year) return false;
else // years equal
{
int month = date.month();
if (_month < month) return true;
else
if (_month > month) return false;
else // months equal
if (_day < date.day()) return true;
}
return false;
}
} } // namespace Poco::Data

View File

@ -36,6 +36,8 @@
#include "Poco/Data/RecordSet.h"
#include "Poco/Data/Session.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/Data/DataException.h"
#include "Poco/DateTime.h"
@ -94,6 +96,8 @@ DynamicAny RecordSet::value(std::size_t col, std::size_t row) const
case MetaColumn::FDT_DOUBLE: return value<double>(col, row);
case MetaColumn::FDT_STRING: return value<std::string>(col, row);
case MetaColumn::FDT_BLOB: return value<BLOB>(col, row);
case MetaColumn::FDT_DATE: return value<Date>(col, row);
case MetaColumn::FDT_TIME: return value<Time>(col, row);
case MetaColumn::FDT_TIMESTAMP: return value<DateTime>(col, row);
default:
throw UnknownTypeException("Data type not supported.");
@ -118,6 +122,8 @@ DynamicAny RecordSet::value(const std::string& name, std::size_t row) const
case MetaColumn::FDT_DOUBLE: return value<double>(name, row);
case MetaColumn::FDT_STRING: return value<std::string>(name, row);
case MetaColumn::FDT_BLOB: return value<BLOB>(name, row);
case MetaColumn::FDT_DATE: return value<Date>(name, row);
case MetaColumn::FDT_TIME: return value<Time>(name, row);
case MetaColumn::FDT_TIMESTAMP: return value<DateTime>(name, row);
default:
throw UnknownTypeException("Data type not supported.");

View File

@ -40,6 +40,8 @@
#include "Poco/Data/AbstractBinder.h"
#include "Poco/Data/Extraction.h"
#include "Poco/Data/BLOB.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/SharedPtr.h"
#include "Poco/DateTime.h"
#include "Poco/Exception.h"
@ -67,7 +69,8 @@ StatementImpl::StatementImpl(SessionImpl& rSession):
_storage(STORAGE_UNKNOWN_IMPL),
_ostr(),
_bindings(),
_curDataSet(0)
_curDataSet(0),
_step(1u)
{
_extractors.resize(1);
}
@ -107,10 +110,7 @@ Poco::UInt32 StatementImpl::executeWithLimit()
{
bind();
while (hasNext() && count < _extrLimit.value())
{
next();
++count;
}
count += next();
} while (canBind());
if (!canBind() && (!hasNext() || _extrLimit.value() == 0))
@ -132,11 +132,7 @@ Poco::UInt32 StatementImpl::executeWithoutLimit()
do
{
bind();
while (hasNext())
{
next();
++count;
}
while (hasNext()) count += next();
} while (canBind());
_state = ST_DONE;
@ -312,6 +308,10 @@ void StatementImpl::makeExtractors(Poco::UInt32 count)
addInternalExtract<std::string>(mc); break;
case MetaColumn::FDT_BLOB:
addInternalExtract<BLOB>(mc); break;
case MetaColumn::FDT_DATE:
addInternalExtract<Date>(mc); break;
case MetaColumn::FDT_TIME:
addInternalExtract<Time>(mc); break;
case MetaColumn::FDT_TIMESTAMP:
addInternalExtract<DateTime>(mc); break;
default:

55
Data/src/Step.cpp Normal file
View File

@ -0,0 +1,55 @@
//
// Step.cpp
//
// $Id: //poco/Main/Data/src/Step.cpp#5 $
//
// Library: Data
// Package: DataCore
// Module: Step
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#include "Poco/Data/Step.h"
namespace Poco {
namespace Data {
Step::Step(Poco::UInt32 value):
_value(value)
{
}
Step::~Step()
{
}
} } // namespace Poco::Data

109
Data/src/Time.cpp Normal file
View File

@ -0,0 +1,109 @@
//
// Time.cpp
//
// $Id: //poco/Main/Data/src/Time.cpp#5 $
//
// Library: Data
// Package: DataCore
// Module: Time
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#include "Poco/Data/Time.h"
#include "Poco/DateTime.h"
using Poco::DateTime;
namespace Poco {
namespace Data {
Time::Time()
{
DateTime dt;
assign(dt.hour(), dt.minute(), dt.second());
}
Time::Time(int hour, int minute, int second)
{
assign(hour, minute, second);
}
Time::Time(const DateTime& dt)
{
assign(dt.hour(), dt.minute(), dt.second());
}
Time::~Time()
{
}
void Time::assign(int hour, int minute, int second)
{
if (hour < 0 || hour > 23)
throw InvalidArgumentException("Hour must be between 0 and 23.");
if (minute < 0 || minute > 59)
throw InvalidArgumentException("Minute must be between 0 and 59.");
if (second < 0 || second > 59)
throw InvalidArgumentException("Second must be between 0 and 59.");
_hour = hour;
_minute = minute;
_second = second;
}
bool Time::operator < (const Time& time)
{
int hour = time.hour();
if (_hour < hour) return true;
else if (_hour > hour) return false;
else // hours equal
{
int minute = time.minute();
if (_minute < minute) return true;
else
if (_minute > minute) return false;
else // minutes equal
if (_second < time.second()) return true;
}
return false;
}
} } // namespace Poco::Data

View File

@ -132,6 +132,16 @@ void Binder::bind(std::size_t pos, const BLOB& val, Direction dir)
}
void Binder::bind(std::size_t pos, const Date& val, Direction dir)
{
}
void Binder::bind(std::size_t pos, const Time& val, Direction dir)
{
}
void Binder::bind(std::size_t pos, const DateTime& val, Direction dir)
{
}

View File

@ -104,6 +104,12 @@ public:
void bind(std::size_t pos, const BLOB& val, Direction dir);
/// Binds a BLOB.
void bind(std::size_t pos, const Date& val, Direction dir);
/// Binds a Date.
void bind(std::size_t pos, const Time& val, Direction dir);
/// Binds a Time.
void bind(std::size_t pos, const DateTime& val, Direction dir);
/// Binds a DateTime.

View File

@ -38,9 +38,12 @@
#include "Poco/Data/BLOBStream.h"
#include "Poco/Data/MetaColumn.h"
#include "Poco/Data/Column.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Connector.h"
#include "Poco/BinaryReader.h"
#include "Poco/BinaryWriter.h"
#include "Poco/DateTime.h"
#include "Poco/Types.h"
#include "Poco/Exception.h"
#include <cstring>
@ -56,9 +59,11 @@ using Poco::BinaryWriter;
using Poco::UInt32;
using Poco::Int64;
using Poco::UInt64;
using Poco::DateTime;
using Poco::InvalidAccessException;
using Poco::RangeException;
using Poco::NotFoundException;
using Poco::InvalidArgumentException;
DataTest::DataTest(const std::string& name): CppUnit::TestCase(name)
@ -1003,6 +1008,74 @@ void DataTest::testRowFormat()
}
void DataTest::testDateAndTime()
{
DateTime dt;
Date d(dt);
Time t(dt);
assert (dt.year() == d.year());
assert (dt.month() == d.month());
assert (dt.day() == d.day());
assert (dt.hour() == t.hour());
assert (dt.minute() == t.minute());
assert (dt.second() == t.second());
Date d1(2007, 6, 15);
d1.assign(d.year() - 1, d.month(), d.day());
assert (d1 < d); assert (d1 != d);
d1.assign(d.year(), d.month() - 1, d.day());
assert (d1 < d); assert (d1 != d);
d1.assign(d.year(), d.month(), d.day() - 1);
assert (d1 < d); assert (d1 != d);
d1.assign(d.year() + 1, d.month(), d.day());
assert (d1 > d); assert (d1 != d);
d1.assign(d.year(), d.month() + 1, d.day());
assert (d1 > d); assert (d1 != d);
d1.assign(d.year(), d.month(), d.day() + 1);
assert (d1 > d); assert (d1 != d);
d1.assign(d.year(), d.month(), d.day());
assert (d1 == d);
try { d1.assign(-1, 1, 1); fail ("must fail"); }
catch (InvalidArgumentException&) { }
try { d1.assign(1, 0, 1); fail ("must fail"); }
catch (InvalidArgumentException&) { }
try { d1.assign(1, 1, 0); fail ("must fail"); }
catch (InvalidArgumentException&) { }
Time t1(12, 30, 15);
t1.assign(t.hour() - 1, t.minute(), t.second());
assert (t1 < t); assert (t1 != t);
t1.assign(t.hour(), t.minute() - 1, t.second());
assert (t1 < t); assert (t1 != t);
t1.assign(t.hour(), t.minute(), t.second() - 1);
assert (t1 < t); assert (t1 != t);
t1.assign(t.hour() + 1, t.minute(), t.second());
assert (t1 > t); assert (t1 != t);
t1.assign(t.hour(), t.minute() + 1, t.second());
assert (t1 > t); assert (t1 != t);
t1.assign(t.hour(), t.minute(), t.second() + 1);
assert (t1 > t); assert (t1 != t);
t1.assign(t.hour(), t.minute(), t.second());
assert (t1 == t);
try { t1.assign(-1, 0, 0); fail ("must fail"); }
catch (InvalidArgumentException&) { }
try { t1.assign(0, -1, 0); fail ("must fail"); }
catch (InvalidArgumentException&) { }
try { t1.assign(0, 0, -1); fail ("must fail"); }
catch (InvalidArgumentException&) { }
d1 = dt;
assert (d1 == dt);
t1 = dt;
assert (t1 == dt);
}
void DataTest::setUp()
{
}
@ -1029,6 +1102,7 @@ CppUnit::Test* DataTest::suite()
CppUnit_addTest(pSuite, DataTest, testRow);
CppUnit_addTest(pSuite, DataTest, testRowSort);
CppUnit_addTest(pSuite, DataTest, testRowFormat);
CppUnit_addTest(pSuite, DataTest, testDateAndTime);
return pSuite;
}

View File

@ -61,6 +61,7 @@ public:
void testRow();
void testRowSort();
void testRowFormat();
void testDateAndTime();
void setUp();
void tearDown();

View File

@ -155,6 +155,19 @@ bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
return true;
}
bool Extractor::extract(std::size_t pos, Poco::Data::Date& val)
{
return true;
}
bool Extractor::extract(std::size_t pos, Poco::Data::Time& val)
{
return true;
}
bool Extractor::extract(std::size_t pos, Poco::DateTime& val)
{
return true;

View File

@ -107,6 +107,12 @@ public:
bool extract(std::size_t pos, Poco::Data::BLOB& val);
/// Extracts a BLOB.
bool extract(std::size_t pos, Date& val);
/// Extracts a Date.
bool extract(std::size_t pos, Time& val);
/// Extracts a Time.
bool extract(std::size_t pos, Poco::DateTime& val);
/// Extracts a DateTime.

View File

@ -127,6 +127,16 @@ void Preparation::prepare(std::size_t pos, const Poco::Data::BLOB&)
}
void Preparation::prepare(std::size_t pos, const Poco::Data::Date&)
{
}
void Preparation::prepare(std::size_t pos, const Poco::Data::Time&)
{
}
void Preparation::prepare(std::size_t pos, const Poco::DateTime&)
{
}

View File

@ -102,6 +102,12 @@ public:
void prepare(std::size_t pos, const Poco::Data::BLOB&);
/// Prepares a BLOB.
void prepare(std::size_t pos, const Poco::Data::Date&);
/// Prepares a Date.
void prepare(std::size_t pos, const Poco::Data::Time&);
/// Prepares a Time.
void prepare(std::size_t pos, const Poco::DateTime&);
/// Prepares a DateTime.

View File

@ -103,7 +103,7 @@ bool TestStatementImpl::hasNext()
}
void TestStatementImpl::next()
Poco::UInt32 TestStatementImpl::next()
{
Poco::Data::AbstractExtractionVec::iterator it = extractions().begin();
Poco::Data::AbstractExtractionVec::iterator itEnd = extractions().end();
@ -113,6 +113,8 @@ void TestStatementImpl::next()
(*it)->extract(pos);
pos += (*it)->numOfColumnsHandled();
}
return 1u;
}

View File

@ -72,8 +72,8 @@ protected:
bool hasNext();
/// Returns true if a call to next() will return data.
void next();
/// Retrieves the next row from the resultset.
Poco::UInt32 next();
/// Retrieves the next row or set of rows from the resultset.
/// Will throw, if the resultset is empty.
bool canBind() const;