mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-18 08:22:37 +01:00
step, date, time
This commit is contained in:
parent
95c5230389
commit
fca08a18df
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -84,6 +84,7 @@ public:
|
||||
void testLimitPrepare();
|
||||
void testLimitZero();
|
||||
void testPrepare();
|
||||
void testStep();
|
||||
|
||||
void testSetSimple();
|
||||
void testSetComplex();
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -107,6 +107,8 @@ public:
|
||||
void testTuple10();
|
||||
void testTupleVector10();
|
||||
|
||||
void testDateTime();
|
||||
|
||||
void testInternalExtraction();
|
||||
void testPrimaryKeyConstraint();
|
||||
void testNull();
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
316
Data/include/Poco/Data/Date.h
Normal file
316
Data/include/Poco/Data/Date.h
Normal 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
|
@ -67,6 +67,8 @@ public:
|
||||
FDT_DOUBLE,
|
||||
FDT_STRING,
|
||||
FDT_BLOB,
|
||||
FDT_DATE,
|
||||
FDT_TIME,
|
||||
FDT_TIMESTAMP,
|
||||
FDT_UNKNOWN
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
94
Data/include/Poco/Data/Step.h
Normal file
94
Data/include/Poco/Data/Step.h
Normal 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
|
320
Data/include/Poco/Data/Time.h
Normal file
320
Data/include/Poco/Data/Time.h
Normal 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
112
Data/src/Date.cpp
Normal 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
|
@ -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.");
|
||||
|
@ -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
55
Data/src/Step.cpp
Normal 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
109
Data/src/Time.cpp
Normal 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
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
void testRow();
|
||||
void testRowSort();
|
||||
void testRowFormat();
|
||||
void testDateAndTime();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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&)
|
||||
{
|
||||
}
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user