mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-16 18:56:52 +02:00
added bulk, removed step
This commit is contained in:
@@ -249,6 +249,18 @@
|
||||
RelativePath=".\include\Poco\Data\BLOBStream.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\Data\Bulk.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\Data\BulkBinding.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\Data\BulkExtraction.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\Data\Column.h"
|
||||
>
|
||||
@@ -281,6 +293,10 @@
|
||||
RelativePath=".\include\Poco\Data\MetaColumn.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\Data\Position.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\Data\Prepare.h"
|
||||
>
|
||||
@@ -329,10 +345,6 @@
|
||||
RelativePath=".\include\Poco\Data\StatementImpl.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\Data\Step.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\Data\Time.h"
|
||||
>
|
||||
@@ -377,6 +389,10 @@
|
||||
RelativePath=".\src\BLOBStream.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\Bulk.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\Connector.cpp"
|
||||
>
|
||||
@@ -397,6 +413,10 @@
|
||||
RelativePath=".\src\MetaColumn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\Position.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\Range.cpp"
|
||||
>
|
||||
@@ -441,10 +461,6 @@
|
||||
RelativePath=".\src\StatementImpl.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\Step.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\Time.cpp"
|
||||
>
|
||||
|
@@ -9,13 +9,12 @@
|
||||
include $(POCO_BASE)/build/rules/global
|
||||
|
||||
objects = AbstractBinder AbstractBinding AbstractExtraction \
|
||||
AbstractExtractor AbstractPreparation AbstractPrepare \
|
||||
AbstractExtractor AbstractPreparation AbstractPrepare Bulk \
|
||||
Connector BLOB BLOBStream DataException Date Limit MetaColumn \
|
||||
PooledSessionHolder PooledSessionImpl \
|
||||
PooledSessionHolder PooledSessionImpl Position \
|
||||
Range RecordSet Row RowFormatter RowIterator \
|
||||
Session SessionFactory SessionImpl \
|
||||
SessionPool Statement StatementCreator StatementImpl \
|
||||
Step Time
|
||||
SessionPool Statement StatementCreator StatementImpl Time
|
||||
|
||||
target = PocoData
|
||||
target_version = $(LIBVERSION)
|
||||
|
@@ -17,8 +17,8 @@ $(error No ODBC library found. Please install unixODBC or iODBC and try again)
|
||||
endif
|
||||
|
||||
objects = Binder ConnectionHandle Connector EnvironmentHandle \
|
||||
Extractor ODBCColumn ODBCException ODBCStatementImpl Parameter Preparation \
|
||||
SessionImpl TypeInfo Unicode Utility
|
||||
Extractor ODBCColumn ODBCException ODBCStatementImpl \
|
||||
Parameter Preparation SessionImpl TypeInfo Unicode Utility
|
||||
|
||||
target = PocoODBC
|
||||
target_version = $(LIBVERSION)
|
||||
|
@@ -81,6 +81,7 @@ public:
|
||||
};
|
||||
|
||||
Binder(const StatementHandle& rStmt,
|
||||
std::size_t maxFieldSize,
|
||||
ParameterBinding dataBinding = PB_IMMEDIATE,
|
||||
TypeInfo* pDataTypes = 0);
|
||||
/// Creates the Binder.
|
||||
@@ -91,62 +92,119 @@ public:
|
||||
void bind(std::size_t pos, const Poco::Int8& val, Direction dir);
|
||||
/// Binds an Int8.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir);
|
||||
/// Binds an Int8 vector.
|
||||
|
||||
void bind(std::size_t pos, const Poco::UInt8& val, Direction dir);
|
||||
/// Binds an UInt8.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir);
|
||||
/// Binds an UInt8 vector.
|
||||
|
||||
void bind(std::size_t pos, const Poco::Int16& val, Direction dir);
|
||||
/// Binds an Int16.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir);
|
||||
/// Binds an Int16 vector.
|
||||
|
||||
void bind(std::size_t pos, const Poco::UInt16& val, Direction dir);
|
||||
/// Binds an UInt16.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir);
|
||||
/// Binds an UInt16 vector.
|
||||
|
||||
void bind(std::size_t pos, const Poco::Int32& val, Direction dir);
|
||||
/// Binds an Int32.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir);
|
||||
/// Binds an Int32 vector.
|
||||
|
||||
void bind(std::size_t pos, const Poco::UInt32& val, Direction dir);
|
||||
/// Binds an UInt32.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir);
|
||||
/// Binds an UInt32 vector.
|
||||
|
||||
void bind(std::size_t pos, const Poco::Int64& val, Direction dir);
|
||||
/// Binds an Int64.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir);
|
||||
/// Binds an Int64 vector.
|
||||
|
||||
void bind(std::size_t pos, const Poco::UInt64& val, Direction dir);
|
||||
/// Binds an UInt64.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir);
|
||||
/// Binds an UInt64 vector.
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
void bind(std::size_t pos, const long& val, Direction dir);
|
||||
/// Binds a long.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<long>& val, Direction dir);
|
||||
/// Binds a long vector.
|
||||
#endif
|
||||
|
||||
void bind(std::size_t pos, const bool& val, Direction dir);
|
||||
/// Binds a boolean.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<bool>& val, Direction dir);
|
||||
/// Binds a boolean vector.
|
||||
|
||||
void bind(std::size_t pos, const float& val, Direction dir);
|
||||
/// Binds a float.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<float>& val, Direction dir);
|
||||
/// Binds a float vector.
|
||||
|
||||
void bind(std::size_t pos, const double& val, Direction dir);
|
||||
/// Binds a double.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<double>& val, Direction dir);
|
||||
/// Binds a double vector.
|
||||
|
||||
void bind(std::size_t pos, const char& val, Direction dir);
|
||||
/// Binds a single character.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<char>& val, Direction dir);
|
||||
/// Binds a character vector.
|
||||
|
||||
void bind(std::size_t pos, const std::string& val, Direction dir);
|
||||
/// Binds a string.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<std::string>& val, Direction dir);
|
||||
/// Binds a string vector.
|
||||
|
||||
void bind(std::size_t pos, const BLOB& val, Direction dir);
|
||||
/// Binds a BLOB. In-bound only.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<BLOB>& val, Direction dir);
|
||||
/// Binds a BLOB vector. In-bound only.
|
||||
|
||||
void bind(std::size_t pos, const Date& val, Direction dir);
|
||||
/// Binds a Date.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<Date>& val, Direction dir);
|
||||
/// Binds a Date vector.
|
||||
|
||||
void bind(std::size_t pos, const Time& val, Direction dir);
|
||||
/// Binds a Time.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<Time>& val, Direction dir);
|
||||
/// Binds a Time vector.
|
||||
|
||||
void bind(std::size_t pos, const DateTime& val, Direction dir);
|
||||
/// Binds a DateTime.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<DateTime>& val, Direction dir);
|
||||
/// Binds a DateTime vector.
|
||||
|
||||
void bind(std::size_t pos, const NullData& val, Direction dir);
|
||||
/// Binds a null. In-bound only.
|
||||
|
||||
void bind(std::size_t pos, const std::vector<NullData>& val, Direction dir);
|
||||
/// Binds a null vector. In-bound only.
|
||||
|
||||
void setDataBinding(ParameterBinding binding);
|
||||
/// Set data binding type.
|
||||
|
||||
@@ -165,6 +223,12 @@ public:
|
||||
|
||||
private:
|
||||
typedef std::vector<SQLLEN*> LengthVec;
|
||||
typedef std::vector<std::vector<SQLLEN> > LengthVecVec;
|
||||
typedef std::vector<char*> CharPtrVec;
|
||||
typedef std::vector<bool*> BoolPtrVec;
|
||||
typedef std::vector<std::vector<SQL_DATE_STRUCT> > DateVec;
|
||||
typedef std::vector<std::vector<SQL_TIME_STRUCT> > TimeVec;
|
||||
typedef std::vector<std::vector<SQL_TIMESTAMP_STRUCT> > DateTimeVec;
|
||||
typedef std::map<char*, std::string*> StringMap;
|
||||
typedef std::map<SQL_DATE_STRUCT*, Date*> DateMap;
|
||||
typedef std::map<SQL_TIME_STRUCT*, Time*> TimeMap;
|
||||
@@ -185,12 +249,12 @@ private:
|
||||
template <typename T>
|
||||
void bindImpl(std::size_t pos, T& val, SQLSMALLINT cDataType, Direction dir)
|
||||
{
|
||||
_lengthIndicator.push_back(0);
|
||||
|
||||
SQLINTEGER colSize = 0;
|
||||
SQLSMALLINT decDigits = 0;
|
||||
getColSizeAndPrecision(pos, cDataType, colSize, decDigits);
|
||||
|
||||
_lengthIndicator.push_back(0);
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
@@ -198,14 +262,50 @@ private:
|
||||
Utility::sqlDataType(cDataType),
|
||||
colSize,
|
||||
decDigits,
|
||||
(SQLPOINTER) &val,
|
||||
0,
|
||||
0)))
|
||||
(SQLPOINTER) &val, 0, 0)))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter()");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void bindImplVec(std::size_t pos, const std::vector<T>& val, SQLSMALLINT cDataType, Direction dir)
|
||||
{
|
||||
if (PB_IMMEDIATE != _paramBinding)
|
||||
throw InvalidAccessException("std::vector can only be bound immediately.");
|
||||
|
||||
std::size_t length = val.size();
|
||||
SQLINTEGER colSize = 0;
|
||||
SQLSMALLINT decDigits = 0;
|
||||
getColSizeAndPrecision(pos, cDataType, colSize, decDigits);
|
||||
setParamSetSize(pos, length);
|
||||
|
||||
if (_vecLengthIndicator.size() <= pos)
|
||||
{
|
||||
_vecLengthIndicator.resize(pos + 1);
|
||||
_vecLengthIndicator[pos].resize(length, sizeof(T));
|
||||
}
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
cDataType,
|
||||
Utility::sqlDataType(cDataType),
|
||||
colSize,
|
||||
decDigits,
|
||||
(SQLPOINTER) &val[0],
|
||||
0,
|
||||
&_vecLengthIndicator[pos][0])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter()");
|
||||
}
|
||||
}
|
||||
|
||||
void bindImplVecBool(std::size_t pos,
|
||||
const std::vector<bool>& val,
|
||||
SQLSMALLINT cDataType,
|
||||
Direction dir);
|
||||
|
||||
void getColSizeAndPrecision(std::size_t pos,
|
||||
SQLSMALLINT cDataType,
|
||||
SQLINTEGER& colSize,
|
||||
@@ -218,20 +318,40 @@ private:
|
||||
/// to discover the required values are unsuccesfully exhausted, the values
|
||||
/// are both set to zero and no exception is thrown.
|
||||
|
||||
void bindNull(std::size_t pos, SQLSMALLINT cDataType);
|
||||
/// Utility function for binding null values.
|
||||
/// For in-bound purposes only.
|
||||
void setParamSetSize(std::size_t pos, std::size_t length);
|
||||
/// Sets the parameter set size. Used for column-wise binding.
|
||||
|
||||
void getColumnOrParameterSize(std::size_t pos, SQLINTEGER& size);
|
||||
/// Fills the column or parameter size into the 'size' argument.
|
||||
/// Does nothing if neither can be obtained from the driver, so
|
||||
/// size should be set to some default value prior to calling this
|
||||
/// function in order to avoid undefined size value.
|
||||
|
||||
void freeMemory();
|
||||
/// Frees all dynamically allocated memory resources.
|
||||
|
||||
const StatementHandle& _rStmt;
|
||||
|
||||
LengthVec _lengthIndicator;
|
||||
LengthVecVec _vecLengthIndicator;
|
||||
|
||||
ParamMap _inParams;
|
||||
ParamMap _outParams;
|
||||
ParameterBinding _paramBinding;
|
||||
|
||||
DateMap _dates;
|
||||
TimeMap _times;
|
||||
TimestampMap _timestamps;
|
||||
StringMap _strings;
|
||||
|
||||
DateVec _dateVec;
|
||||
TimeVec _timeVec;
|
||||
DateTimeVec _dateTimeVec;
|
||||
CharPtrVec _charPtrs;
|
||||
BoolPtrVec _boolPtrs;
|
||||
const TypeInfo* _pTypeInfo;
|
||||
SQLINTEGER _paramSetSize;
|
||||
std::size_t _maxFieldSize;
|
||||
};
|
||||
|
||||
|
||||
@@ -244,53 +364,107 @@ inline void Binder::bind(std::size_t pos, const Poco::Int8& val, Direction dir)
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir)
|
||||
{
|
||||
bindImplVec(pos, val, SQL_C_STINYINT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const Poco::UInt8& val, Direction dir)
|
||||
{
|
||||
bindImpl(pos, val, SQL_C_UTINYINT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir)
|
||||
{
|
||||
bindImplVec(pos, val, SQL_C_UTINYINT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const Poco::Int16& val, Direction dir)
|
||||
{
|
||||
bindImpl(pos, val, SQL_C_SSHORT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir)
|
||||
{
|
||||
bindImplVec(pos, val, SQL_C_SSHORT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const Poco::UInt16& val, Direction dir)
|
||||
{
|
||||
bindImpl(pos, val, SQL_C_USHORT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir)
|
||||
{
|
||||
bindImplVec(pos, val, SQL_C_USHORT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const Poco::Int32& val, Direction dir)
|
||||
{
|
||||
bindImpl(pos, val, SQL_C_SLONG, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir)
|
||||
{
|
||||
bindImplVec(pos, val, SQL_C_SLONG, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const Poco::UInt32& val, Direction dir)
|
||||
{
|
||||
bindImpl(pos, val, SQL_C_ULONG, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir)
|
||||
{
|
||||
bindImplVec(pos, val, SQL_C_ULONG, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const Poco::Int64& val, Direction dir)
|
||||
{
|
||||
bindImpl(pos, val, SQL_C_SBIGINT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir)
|
||||
{
|
||||
bindImplVec(pos, val, SQL_C_SBIGINT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const Poco::UInt64& val, Direction dir)
|
||||
{
|
||||
bindImpl(pos, val, SQL_C_UBIGINT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir)
|
||||
{
|
||||
bindImplVec(pos, val, SQL_C_UBIGINT, dir);
|
||||
}
|
||||
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
inline void Binder::bind(std::size_t pos, const long& val, Direction dir)
|
||||
{
|
||||
bindImpl(pos, val, SQL_C_SLONG, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const std::vector<long>& val, Direction dir)
|
||||
{
|
||||
bindImplVec(pos, val, SQL_C_SLONG, dir);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -300,24 +474,48 @@ inline void Binder::bind(std::size_t pos, const float& val, Direction dir)
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const std::vector<float>& val, Direction dir)
|
||||
{
|
||||
bindImplVec(pos, val, SQL_C_FLOAT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const double& val, Direction dir)
|
||||
{
|
||||
bindImpl(pos, val, SQL_C_DOUBLE, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const std::vector<double>& val, Direction dir)
|
||||
{
|
||||
bindImplVec(pos, val, SQL_C_DOUBLE, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const bool& val, Direction dir)
|
||||
{
|
||||
bindImpl(pos, val, SQL_C_BIT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const std::vector<bool>& val, Direction dir)
|
||||
{
|
||||
bindImplVecBool(pos, val, SQL_C_BIT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const char& val, Direction dir)
|
||||
{
|
||||
bindImpl(pos, val, SQL_C_STINYINT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::bind(std::size_t pos, const std::vector<char>& val, Direction dir)
|
||||
{
|
||||
bindImplVec(pos, val, SQL_C_STINYINT, dir);
|
||||
}
|
||||
|
||||
|
||||
inline void Binder::setDataBinding(Binder::ParameterBinding binding)
|
||||
{
|
||||
_paramBinding = binding;
|
||||
|
@@ -77,73 +77,133 @@ public:
|
||||
bool extract(std::size_t pos, Poco::Int8& val);
|
||||
/// Extracts an Int8.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::Int8>& val);
|
||||
/// Extracts an Int8 vector.
|
||||
|
||||
bool extract(std::size_t pos, Poco::UInt8& val);
|
||||
/// Extracts an UInt8.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::UInt8>& val);
|
||||
/// Extracts an UInt8 vector.
|
||||
|
||||
bool extract(std::size_t pos, Poco::Int16& val);
|
||||
/// Extracts an Int16.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::Int16>& val);
|
||||
/// Extracts an Int16 vector.
|
||||
|
||||
bool extract(std::size_t pos, Poco::UInt16& val);
|
||||
/// Extracts an UInt16.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::UInt16>& val);
|
||||
/// Extracts an UInt16 vector.
|
||||
|
||||
bool extract(std::size_t pos, Poco::Int32& val);
|
||||
/// Extracts an Int32.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::Int32>& val);
|
||||
/// Extracts an Int32 vector.
|
||||
|
||||
bool extract(std::size_t pos, Poco::UInt32& val);
|
||||
/// Extracts an UInt32.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::UInt32>& val);
|
||||
/// Extracts an UInt32 vector.
|
||||
|
||||
bool extract(std::size_t pos, Poco::Int64& val);
|
||||
/// Extracts an Int64.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::Int64>& val);
|
||||
/// Extracts an Int64 vector.
|
||||
|
||||
bool extract(std::size_t pos, Poco::UInt64& val);
|
||||
/// Extracts an UInt64.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::UInt64>& val);
|
||||
/// Extracts an UInt64 vector.
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
bool extract(std::size_t pos, long& val);
|
||||
/// Extracts a long.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<long>& val);
|
||||
/// Extracts a long vector.
|
||||
#endif
|
||||
|
||||
bool extract(std::size_t pos, bool& val);
|
||||
/// Extracts a boolean.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<bool>& val);
|
||||
/// Extracts a boolean vector.
|
||||
|
||||
bool extract(std::size_t pos, float& val);
|
||||
/// Extracts a float.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<float>& val);
|
||||
/// Extracts a float vector.
|
||||
|
||||
bool extract(std::size_t pos, double& val);
|
||||
/// Extracts a double.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<double>& val);
|
||||
/// Extracts a double vector.
|
||||
|
||||
bool extract(std::size_t pos, char& val);
|
||||
/// Extracts a single character.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<char>& val);
|
||||
/// Extracts a single character vector.
|
||||
|
||||
bool extract(std::size_t pos, std::string& val);
|
||||
/// Extracts a string.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<std::string>& val);
|
||||
/// Extracts a string vector.
|
||||
|
||||
bool extract(std::size_t pos, Poco::Data::BLOB& val);
|
||||
/// Extracts a BLOB.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::Data::BLOB>& val);
|
||||
/// Extracts a BLOB vector.
|
||||
|
||||
bool extract(std::size_t pos, Poco::Data::Date& val);
|
||||
/// Extracts a Date.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::Data::Date>& val);
|
||||
/// Extracts a Date vector.
|
||||
|
||||
bool extract(std::size_t pos, Poco::Data::Time& val);
|
||||
/// Extracts a Time.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::Data::Time>& val);
|
||||
/// Extracts a Time vector.
|
||||
|
||||
bool extract(std::size_t pos, Poco::DateTime& val);
|
||||
/// Extracts a DateTime.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::DateTime>& val);
|
||||
/// Extracts a DateTime vector.
|
||||
|
||||
bool extract(std::size_t pos, Poco::Any& val);
|
||||
/// Extracts an Any.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::Any>& val);
|
||||
/// Extracts an Any vector.
|
||||
|
||||
bool extract(std::size_t pos, Poco::DynamicAny& val);
|
||||
/// Extracts a DynamicAny.
|
||||
|
||||
bool extract(std::size_t pos, std::vector<Poco::DynamicAny>& val);
|
||||
/// Extracts a DynamicAny vector.
|
||||
|
||||
void setDataExtraction(Preparation::DataExtraction ext);
|
||||
/// Set data extraction mode.
|
||||
|
||||
Preparation::DataExtraction getDataExtraction() const;
|
||||
/// Returns data extraction mode.
|
||||
|
||||
bool isNull(std::size_t pos);
|
||||
/// Returns true if the current row value at pos column is null.
|
||||
bool isNull(std::size_t col, std::size_t row = Preparation::INVALID_ROW);
|
||||
/// Returns true if the value at [col,row] is null.
|
||||
|
||||
void reset();
|
||||
/// Resets the internally cached length indicators.
|
||||
@@ -171,13 +231,20 @@ private:
|
||||
bool extractBoundImpl(std::size_t pos, T& val)
|
||||
{
|
||||
if (isNull(pos)) return false;
|
||||
|
||||
poco_assert (typeid(T) == _rPreparation[pos].type());
|
||||
|
||||
poco_assert_dbg (typeid(T) == _rPreparation[pos].type());
|
||||
val = *AnyCast<T>(&_rPreparation[pos]);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool extractBoundImplVec(std::size_t pos, std::vector<T>& val)
|
||||
{
|
||||
poco_assert_dbg (typeid(std::vector<T>) == _rPreparation[pos].type());
|
||||
std::vector<T>& v = RefAnyCast<std::vector<T> >(_rPreparation[pos]);
|
||||
val.assign(v.begin(), v.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool extractManualImpl(std::size_t pos, T& val, SQLSMALLINT cType)
|
||||
{
|
||||
@@ -271,6 +338,8 @@ private:
|
||||
/// SQLLEN macro (a.k.a. SQLINTEGER) yields 64-bit value,
|
||||
/// while SQL_NULL_DATA (#define'd as -1 literal) remains 32-bit.
|
||||
|
||||
SQLINTEGER columnSize(std::size_t pos) const;
|
||||
|
||||
const StatementHandle& _rStmt;
|
||||
Preparation& _rPreparation;
|
||||
Preparation::DataExtraction _dataExtraction;
|
||||
@@ -281,8 +350,6 @@ private:
|
||||
///
|
||||
/// inlines
|
||||
///
|
||||
|
||||
|
||||
inline void Extractor::setDataExtraction(Preparation::DataExtraction ext)
|
||||
{
|
||||
_rPreparation.setDataExtraction(_dataExtraction = ext);
|
||||
@@ -314,6 +381,12 @@ inline bool Extractor::isNullLengthIndicator(SQLLEN val) const
|
||||
}
|
||||
|
||||
|
||||
inline SQLINTEGER Extractor::columnSize(std::size_t pos) const
|
||||
{
|
||||
return (SQLINTEGER) ODBCColumn(_rStmt, pos).length();
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::ODBC
|
||||
|
||||
|
||||
|
@@ -206,17 +206,6 @@ inline bool ODBCStatementImpl::nextRowReady() const
|
||||
}
|
||||
|
||||
|
||||
inline const MetaColumn& ODBCStatementImpl::metaColumn(Poco::UInt32 pos) const
|
||||
{
|
||||
std::size_t sz = _columnPtrs.size();
|
||||
|
||||
if (0 == sz || pos > sz - 1)
|
||||
throw InvalidAccessException(format("Invalid column number: %u", pos));
|
||||
|
||||
return *_columnPtrs[pos];
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::ODBC
|
||||
|
||||
|
||||
|
@@ -82,8 +82,6 @@ public:
|
||||
private:
|
||||
Parameter();
|
||||
|
||||
static const int BUFFER_LENGTH = 2048;
|
||||
|
||||
void init();
|
||||
|
||||
SQLSMALLINT _dataType;
|
||||
|
@@ -76,8 +76,9 @@ class ODBC_API Preparation : public AbstractPreparation
|
||||
/// with respective memory output locations before extracting data.
|
||||
/// Extraction works in two-phases: first prepare is called once, then extract n-times.
|
||||
/// In ODBC, SQLBindCol/SQLFetch is the preferred method of data retrieval (SQLGetData is available,
|
||||
/// however with numerous driver implementation dependent limitations). In order to fit this functionality
|
||||
/// into Poco DataConnectors framework, every ODBC SQL statement instantiates its own Preparation object.
|
||||
/// however with numerous driver implementation dependent limitations and inferior performance).
|
||||
/// In order to fit this functionality into Poco DataConnectors framework, every ODBC SQL statement
|
||||
/// instantiates its own Preparation object.
|
||||
/// This is done once per statement execution (from StatementImpl::bindImpl()).
|
||||
///
|
||||
/// Preparation object is used to :
|
||||
@@ -94,12 +95,26 @@ class ODBC_API Preparation : public AbstractPreparation
|
||||
///
|
||||
{
|
||||
public:
|
||||
typedef std::vector<char*> CharArray;
|
||||
|
||||
enum DataExtraction
|
||||
{
|
||||
DE_MANUAL,
|
||||
DE_BOUND
|
||||
};
|
||||
|
||||
static const std::size_t INVALID_ROW;
|
||||
|
||||
enum DataType
|
||||
{
|
||||
DT_BOOL,
|
||||
DT_CHAR,
|
||||
DT_CHAR_ARRAY,
|
||||
DT_DATE,
|
||||
DT_TIME,
|
||||
DT_DATETIME
|
||||
};
|
||||
|
||||
Preparation(const StatementHandle& rStmt,
|
||||
const std::string& statement,
|
||||
std::size_t maxFieldSize,
|
||||
@@ -112,68 +127,128 @@ public:
|
||||
~Preparation();
|
||||
/// Destroys the Preparation.
|
||||
|
||||
void prepare(std::size_t pos, Poco::Int8);
|
||||
void prepare(std::size_t pos, Poco::Int8& val);
|
||||
/// Prepares an Int8.
|
||||
|
||||
void prepare(std::size_t pos, Poco::UInt8);
|
||||
void prepare(std::size_t pos, std::vector<Poco::Int8>& val);
|
||||
/// Prepares an Int8 vector.
|
||||
|
||||
void prepare(std::size_t pos, Poco::UInt8& val);
|
||||
/// Prepares an UInt8.
|
||||
|
||||
void prepare(std::size_t pos, Poco::Int16);
|
||||
void prepare(std::size_t pos, std::vector<Poco::UInt8>& val);
|
||||
/// Prepares an UInt8 vector.
|
||||
|
||||
void prepare(std::size_t pos, Poco::Int16& val);
|
||||
/// Prepares an Int16.
|
||||
|
||||
void prepare(std::size_t pos, Poco::UInt16);
|
||||
void prepare(std::size_t pos, std::vector<Poco::Int16>& val);
|
||||
/// Prepares an Int16 vector.
|
||||
|
||||
void prepare(std::size_t pos, Poco::UInt16& val);
|
||||
/// Prepares an UInt16.
|
||||
|
||||
void prepare(std::size_t pos, Poco::Int32);
|
||||
void prepare(std::size_t pos, std::vector<Poco::UInt16>& val);
|
||||
/// Prepares an UInt16 vector.
|
||||
|
||||
void prepare(std::size_t pos, Poco::Int32& val);
|
||||
/// Prepares an Int32.
|
||||
|
||||
void prepare(std::size_t pos, Poco::UInt32);
|
||||
void prepare(std::size_t pos, std::vector<Poco::Int32>& val);
|
||||
/// Prepares an Int32 vector.
|
||||
|
||||
void prepare(std::size_t pos, Poco::UInt32& val);
|
||||
/// Prepares an UInt32.
|
||||
|
||||
void prepare(std::size_t pos, Poco::Int64);
|
||||
void prepare(std::size_t pos, std::vector<Poco::UInt32>& val);
|
||||
/// Prepares an UInt32 vector.
|
||||
|
||||
void prepare(std::size_t pos, Poco::Int64& val);
|
||||
/// Prepares an Int64.
|
||||
|
||||
void prepare(std::size_t pos, Poco::UInt64);
|
||||
void prepare(std::size_t pos, std::vector<Poco::Int64>& val);
|
||||
/// Prepares an Int64 vector.
|
||||
|
||||
void prepare(std::size_t pos, Poco::UInt64& val);
|
||||
/// Prepares an UInt64.
|
||||
|
||||
void prepare(std::size_t pos, std::vector<Poco::UInt64>& val);
|
||||
/// Prepares an UInt64 vector.
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
void prepare(std::size_t pos, long);
|
||||
void prepare(std::size_t pos, long& val);
|
||||
/// Prepares a long.
|
||||
|
||||
void prepare(std::size_t pos, std::vector<long>& val);
|
||||
/// Prepares a long vector.
|
||||
#endif
|
||||
|
||||
void prepare(std::size_t pos, bool);
|
||||
void prepare(std::size_t pos, bool& val);
|
||||
/// Prepares a boolean.
|
||||
|
||||
void prepare(std::size_t pos, float);
|
||||
void prepare(std::size_t pos, std::vector<bool>& val);
|
||||
/// Prepares a boolean vector.
|
||||
|
||||
void prepare(std::size_t pos, float& val);
|
||||
/// Prepares a float.
|
||||
|
||||
void prepare(std::size_t pos, double);
|
||||
void prepare(std::size_t pos, std::vector<float>& val);
|
||||
/// Prepares a float vector.
|
||||
|
||||
void prepare(std::size_t pos, double& val);
|
||||
/// Prepares a double.
|
||||
|
||||
void prepare(std::size_t pos, char);
|
||||
void prepare(std::size_t pos, std::vector<double>& val);
|
||||
/// Prepares a double vector.
|
||||
|
||||
void prepare(std::size_t pos, char& val);
|
||||
/// Prepares a single character.
|
||||
|
||||
void prepare(std::size_t pos, const std::string&);
|
||||
void prepare(std::size_t pos, std::vector<char>& val);
|
||||
/// Prepares a single character vector.
|
||||
|
||||
void prepare(std::size_t pos, const std::string& val);
|
||||
/// Prepares a string.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::Data::BLOB&);
|
||||
void prepare(std::size_t pos, const std::vector<std::string>& val);
|
||||
/// Prepares a string vector.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::Data::BLOB& val);
|
||||
/// Prepares a BLOB.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::Data::Date&);
|
||||
void prepare(std::size_t pos, const std::vector<Poco::Data::BLOB>& val);
|
||||
/// Prepares a BLOB vector.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::Data::Date& val);
|
||||
/// Prepares a Date.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::Data::Time&);
|
||||
void prepare(std::size_t pos, const std::vector<Poco::Data::Date>& val);
|
||||
/// Prepares a Date vector.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::Data::Time& val);
|
||||
/// Prepares a Time.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::DateTime&);
|
||||
void prepare(std::size_t pos, const std::vector<Poco::Data::Time>& val);
|
||||
/// Prepares a Time vector.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::DateTime& val);
|
||||
/// Prepares a DateTime.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::Any&);
|
||||
void prepare(std::size_t pos, const std::vector<Poco::DateTime>& val);
|
||||
/// Prepares a DateTime vector.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::Any& val);
|
||||
/// Prepares an Any.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::DynamicAny&);
|
||||
void prepare(std::size_t pos, const std::vector<Poco::Any>& val);
|
||||
/// Prepares an Any vector.
|
||||
|
||||
void prepare(std::size_t pos, const Poco::DynamicAny& val);
|
||||
/// Prepares a DynamicAny.
|
||||
|
||||
void prepare(std::size_t pos, const std::vector<Poco::DynamicAny>& val);
|
||||
/// Prepares a DynamicAny vector.
|
||||
|
||||
std::size_t columns() const;
|
||||
/// Returns the number of columns.
|
||||
/// Resizes the internal storage iff the size is zero.
|
||||
@@ -192,12 +267,16 @@ public:
|
||||
/// Returned length for variable length fields is the one
|
||||
/// supported by this implementation, not the underlying DB.
|
||||
|
||||
int actualDataSize(std::size_t pos) const;
|
||||
/// Returns the returned length. This is usually
|
||||
/// equal to the column size, except for variable length fields
|
||||
/// (BLOB and variable length strings).
|
||||
std::size_t actualDataSize(std::size_t col, std::size_t row = INVALID_ROW) const;
|
||||
/// Returns the returned length for the column and row specified.
|
||||
/// This is usually equal to the column size, except for
|
||||
/// variable length fields (BLOB and variable length strings).
|
||||
/// For null values, the return value is -1 (SQL_NO_DATA)
|
||||
|
||||
std::size_t bulkSize(std::size_t col = 0) const;
|
||||
/// Returns bulk size. Column argument is optional
|
||||
/// since all columns must be the same size.
|
||||
|
||||
void setDataExtraction(DataExtraction ext);
|
||||
/// Set data extraction mode.
|
||||
|
||||
@@ -205,71 +284,222 @@ public:
|
||||
/// Returns data extraction mode.
|
||||
|
||||
private:
|
||||
typedef std::vector<Poco::Any> ValueVec;
|
||||
typedef std::vector<SQLLEN> LengthVec;
|
||||
typedef std::vector<LengthVec> LengthLengthVec;
|
||||
typedef std::map<std::size_t, DataType> IndexMap;
|
||||
|
||||
Preparation();
|
||||
Preparation& operator = (const Preparation&);
|
||||
|
||||
void prepareImpl(std::size_t pos);
|
||||
/// Utility function to prepare Any and DynamicAny
|
||||
template <typename T>
|
||||
void prepareImpl(std::size_t pos, const std::vector<T>* pVal = 0)
|
||||
/// Utility function to prepare Any and DynamicAny.
|
||||
{
|
||||
ODBCColumn col(_rStmt, pos);
|
||||
|
||||
switch (col.type())
|
||||
{
|
||||
case MetaColumn::FDT_INT8:
|
||||
if (pVal)
|
||||
return prepareFixedSize<Poco::Int8>(pos, SQL_C_STINYINT, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<Poco::Int8>(pos, SQL_C_STINYINT);
|
||||
|
||||
case MetaColumn::FDT_UINT8:
|
||||
if (pVal)
|
||||
return prepareFixedSize<Poco::UInt8>(pos, SQL_C_UTINYINT, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<Poco::UInt8>(pos, SQL_C_UTINYINT);
|
||||
|
||||
case MetaColumn::FDT_INT16:
|
||||
if (pVal)
|
||||
return prepareFixedSize<Poco::Int16>(pos, SQL_C_SSHORT, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<Poco::Int16>(pos, SQL_C_SSHORT);
|
||||
|
||||
case MetaColumn::FDT_UINT16:
|
||||
if (pVal)
|
||||
return prepareFixedSize<Poco::UInt16>(pos, SQL_C_USHORT, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<Poco::UInt16>(pos, SQL_C_USHORT);
|
||||
|
||||
case MetaColumn::FDT_INT32:
|
||||
if (pVal)
|
||||
return prepareFixedSize<Poco::Int32>(pos, SQL_C_SLONG, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<Poco::Int32>(pos, SQL_C_SLONG);
|
||||
|
||||
case MetaColumn::FDT_UINT32:
|
||||
if (pVal)
|
||||
return prepareFixedSize<Poco::UInt32>(pos, SQL_C_ULONG, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<Poco::UInt32>(pos, SQL_C_ULONG);
|
||||
|
||||
case MetaColumn::FDT_INT64:
|
||||
if (pVal)
|
||||
return prepareFixedSize<Poco::Int64>(pos, SQL_C_SBIGINT, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<Poco::Int64>(pos, SQL_C_SBIGINT);
|
||||
|
||||
case MetaColumn::FDT_UINT64:
|
||||
if (pVal)
|
||||
return prepareFixedSize<Poco::UInt64>(pos, SQL_C_UBIGINT, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<Poco::UInt64>(pos, SQL_C_UBIGINT);
|
||||
|
||||
case MetaColumn::FDT_BOOL:
|
||||
if (pVal)
|
||||
return prepareVariableLen<bool>(pos, SQL_C_BIT, pVal->size(), DT_BOOL);
|
||||
else
|
||||
return prepareFixedSize<bool>(pos, SQL_C_BIT);
|
||||
|
||||
case MetaColumn::FDT_FLOAT:
|
||||
if (pVal)
|
||||
return prepareFixedSize<float>(pos, SQL_C_FLOAT, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<float>(pos, SQL_C_FLOAT);
|
||||
|
||||
case MetaColumn::FDT_DOUBLE:
|
||||
if (pVal)
|
||||
return prepareFixedSize<double>(pos, SQL_C_DOUBLE, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<double>(pos, SQL_C_DOUBLE);
|
||||
|
||||
case MetaColumn::FDT_STRING:
|
||||
if (pVal)
|
||||
return prepareVariableLenArray(pos, SQL_C_CHAR, maxDataSize(pos), pVal->size(), DT_CHAR_ARRAY);
|
||||
else
|
||||
return prepareVariableLen<char>(pos, SQL_C_CHAR, maxDataSize(pos), DT_CHAR);
|
||||
|
||||
case MetaColumn::FDT_BLOB:
|
||||
if (pVal)
|
||||
return prepareVariableLenArray(pos, SQL_C_BINARY, maxDataSize(pos), pVal->size(), DT_CHAR_ARRAY);
|
||||
else
|
||||
return prepareVariableLen<char>(pos, SQL_C_BINARY, maxDataSize(pos), DT_CHAR);
|
||||
|
||||
case MetaColumn::FDT_DATE:
|
||||
if (pVal)
|
||||
return prepareFixedSize<Date>(pos, SQL_C_TYPE_DATE, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<Date>(pos, SQL_C_TYPE_DATE);
|
||||
|
||||
case MetaColumn::FDT_TIME:
|
||||
if (pVal)
|
||||
return prepareFixedSize<Time>(pos, SQL_C_TYPE_TIME, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<Time>(pos, SQL_C_TYPE_TIME);
|
||||
|
||||
case MetaColumn::FDT_TIMESTAMP:
|
||||
if (pVal)
|
||||
return prepareFixedSize<DateTime>(pos, SQL_C_TYPE_TIMESTAMP, pVal->size());
|
||||
else
|
||||
return prepareFixedSize<DateTime>(pos, SQL_C_TYPE_TIMESTAMP);
|
||||
|
||||
default:
|
||||
throw DataFormatException("Unsupported data type.");
|
||||
}
|
||||
}
|
||||
|
||||
void resize() const;
|
||||
/// Resize the values and lengths vectors.
|
||||
|
||||
template <typename T>
|
||||
void preparePOD(std::size_t pos, SQLSMALLINT valueType)
|
||||
void prepareFixedSize(std::size_t pos, SQLSMALLINT valueType)
|
||||
/// Utility function for preparation of fixed length columns.
|
||||
{
|
||||
poco_assert (DE_BOUND == _dataExtraction);
|
||||
poco_assert (pos >= 0 && pos < _pValues.size());
|
||||
|
||||
std::size_t dataSize = sizeof(T);
|
||||
|
||||
_pValues[pos] = new Poco::Any(T());
|
||||
_pLengths[pos] = new SQLLEN;
|
||||
*_pLengths[pos] = 0;
|
||||
|
||||
T* pVal = AnyCast<T>(_pValues[pos]);
|
||||
|
||||
poco_assert_dbg (pVal);
|
||||
poco_assert (pos < _values.size());
|
||||
_values[pos] = Poco::Any(T());
|
||||
|
||||
T* pVal = AnyCast<T>(&_values[pos]);
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) pVal,
|
||||
(SQLINTEGER) dataSize,
|
||||
_pLengths[pos])))
|
||||
&_lengths[pos])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindCol()");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void prepareRaw(std::size_t pos, SQLSMALLINT valueType, std::size_t size)
|
||||
void prepareFixedSize(std::size_t pos, SQLSMALLINT valueType, std::size_t length)
|
||||
/// Utility function for preparation of fixed length columns that are
|
||||
/// bound to a std::vector.
|
||||
{
|
||||
poco_assert (DE_BOUND == _dataExtraction);
|
||||
poco_assert (pos >= 0 && pos < _pValues.size());
|
||||
std::size_t dataSize = sizeof(T);
|
||||
|
||||
T* pChr = new T[size];
|
||||
poco_assert_dbg (pChr);
|
||||
memset(pChr, 0, size);
|
||||
poco_assert (pos < _values.size());
|
||||
poco_assert (length);
|
||||
_values[pos] = Poco::Any(std::vector<T>(length));
|
||||
_lengths[pos] = 0;
|
||||
poco_assert (0 == _lenLengths[pos].size());
|
||||
_lenLengths[pos].resize(length);
|
||||
|
||||
SharedPtr<T> sp = pChr;
|
||||
_pValues[pos] = new Any(sp);
|
||||
_pLengths[pos] = new SQLLEN;
|
||||
*_pLengths[pos] = (SQLLEN) size;
|
||||
std::vector<T>& cache = RefAnyCast<std::vector<T> >(_values[pos]);
|
||||
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) pChr,
|
||||
(SQLINTEGER) size,
|
||||
_pLengths[pos])))
|
||||
(SQLPOINTER) &cache[0],
|
||||
(SQLINTEGER) dataSize,
|
||||
&_lenLengths[pos][0])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindCol()");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void prepareVariableLen(std::size_t pos, SQLSMALLINT valueType, std::size_t size, DataType dt)
|
||||
/// Utility function for preparation of variable length columns and bool vectors.
|
||||
{
|
||||
poco_assert (DE_BOUND == _dataExtraction);
|
||||
poco_assert (pos < _values.size());
|
||||
|
||||
T* pCache = new T[size];
|
||||
poco_assert_dbg (pCache);
|
||||
std::memset(pCache, 0, size);
|
||||
|
||||
_values[pos] = Any(pCache);
|
||||
_lengths[pos] = (SQLLEN) size;
|
||||
_varLengthArrays.insert(IndexMap::value_type(pos, dt));
|
||||
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) pCache,
|
||||
(SQLINTEGER) size,
|
||||
&_lengths[pos])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindCol()");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void prepareVariableLenArray(std::size_t pos, SQLSMALLINT valueType, std::size_t size, std::size_t length, DataType dt);
|
||||
/// Utility function for preparation of variable length character and BLOB columns.
|
||||
|
||||
|
||||
void freeMemory() const;
|
||||
/// Utility function. Releases memory allocated for variable length columns.
|
||||
|
||||
template <typename T>
|
||||
void deleteCachedArray(std::size_t pos) const
|
||||
{
|
||||
T* p = Poco::AnyCast<T>(&_values[pos]);
|
||||
delete [] p;
|
||||
}
|
||||
|
||||
const StatementHandle& _rStmt;
|
||||
mutable std::vector<Poco::Any*> _pValues;
|
||||
mutable std::vector<SQLLEN*> _pLengths;
|
||||
mutable ValueVec _values;
|
||||
mutable LengthVec _lengths;
|
||||
mutable LengthLengthVec _lenLengths;
|
||||
mutable IndexMap _varLengthArrays;
|
||||
std::size_t _maxFieldSize;
|
||||
DataExtraction _dataExtraction;
|
||||
};
|
||||
@@ -278,128 +508,262 @@ private:
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::Int8)
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::Int8&)
|
||||
{
|
||||
preparePOD<Poco::Int8>(pos, SQL_C_STINYINT);
|
||||
prepareFixedSize<Poco::Int8>(pos, SQL_C_STINYINT);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::UInt8)
|
||||
inline void Preparation::prepare(std::size_t pos, std::vector<Poco::Int8>& val)
|
||||
{
|
||||
preparePOD<Poco::UInt8>(pos, SQL_C_UTINYINT);
|
||||
prepareFixedSize<Poco::Int8>(pos, SQL_C_STINYINT, val.size());
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::Int16)
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::UInt8&)
|
||||
{
|
||||
preparePOD<Poco::Int16>(pos, SQL_C_SSHORT);
|
||||
prepareFixedSize<Poco::UInt8>(pos, SQL_C_UTINYINT);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::UInt16)
|
||||
inline void Preparation::prepare(std::size_t pos, std::vector<Poco::UInt8>& val)
|
||||
{
|
||||
preparePOD<Poco::UInt16>(pos, SQL_C_USHORT);
|
||||
prepareFixedSize<Poco::UInt8>(pos, SQL_C_UTINYINT, val.size());
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::Int32)
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::Int16&)
|
||||
{
|
||||
preparePOD<Poco::Int32>(pos, SQL_C_SLONG);
|
||||
prepareFixedSize<Poco::Int16>(pos, SQL_C_SSHORT);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::UInt32)
|
||||
inline void Preparation::prepare(std::size_t pos, std::vector<Poco::Int16>& val)
|
||||
{
|
||||
preparePOD<Poco::UInt32>(pos, SQL_C_ULONG);
|
||||
prepareFixedSize<Poco::Int16>(pos, SQL_C_SSHORT, val.size());
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::Int64)
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::UInt16&)
|
||||
{
|
||||
preparePOD<Poco::Int64>(pos, SQL_C_SBIGINT);
|
||||
prepareFixedSize<Poco::UInt16>(pos, SQL_C_USHORT);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::UInt64)
|
||||
inline void Preparation::prepare(std::size_t pos, std::vector<Poco::UInt16>& val)
|
||||
{
|
||||
preparePOD<Poco::UInt64>(pos, SQL_C_UBIGINT);
|
||||
prepareFixedSize<Poco::UInt16>(pos, SQL_C_USHORT, val.size());
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::Int32&)
|
||||
{
|
||||
prepareFixedSize<Poco::Int32>(pos, SQL_C_SLONG);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, std::vector<Poco::Int32>& val)
|
||||
{
|
||||
prepareFixedSize<Poco::Int32>(pos, SQL_C_SLONG, val.size());
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::UInt32&)
|
||||
{
|
||||
prepareFixedSize<Poco::UInt32>(pos, SQL_C_ULONG);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, std::vector<Poco::UInt32>& val)
|
||||
{
|
||||
prepareFixedSize<Poco::UInt32>(pos, SQL_C_ULONG, val.size());
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::Int64&)
|
||||
{
|
||||
prepareFixedSize<Poco::Int64>(pos, SQL_C_SBIGINT);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, std::vector<Poco::Int64>& val)
|
||||
{
|
||||
prepareFixedSize<Poco::Int64>(pos, SQL_C_SBIGINT, val.size());
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, Poco::UInt64&)
|
||||
{
|
||||
prepareFixedSize<Poco::UInt64>(pos, SQL_C_UBIGINT);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, std::vector<Poco::UInt64>& val)
|
||||
{
|
||||
prepareFixedSize<Poco::UInt64>(pos, SQL_C_UBIGINT, val.size());
|
||||
}
|
||||
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
inline void Preparation::prepare(std::size_t pos, long)
|
||||
inline void Preparation::prepare(std::size_t pos, long&)
|
||||
{
|
||||
preparePOD<long>(pos, SQL_C_SLONG);
|
||||
prepareFixedSize<long>(pos, SQL_C_SLONG);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, std::vector<long>& val)
|
||||
{
|
||||
prepareFixedSize<long>(pos, SQL_C_SLONG, val.size());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, bool)
|
||||
inline void Preparation::prepare(std::size_t pos, bool&)
|
||||
{
|
||||
preparePOD<bool>(pos, SQL_C_BIT);
|
||||
prepareFixedSize<bool>(pos, SQL_C_BIT);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, float)
|
||||
inline void Preparation::prepare(std::size_t pos, std::vector<bool>& val)
|
||||
{
|
||||
preparePOD<float>(pos, SQL_C_FLOAT);
|
||||
prepareVariableLen<bool>(pos, SQL_C_BIT, val.size(), DT_BOOL);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, double)
|
||||
inline void Preparation::prepare(std::size_t pos, float&)
|
||||
{
|
||||
preparePOD<double>(pos, SQL_C_DOUBLE);
|
||||
prepareFixedSize<float>(pos, SQL_C_FLOAT);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, char)
|
||||
inline void Preparation::prepare(std::size_t pos, std::vector<float>& val)
|
||||
{
|
||||
preparePOD<char>(pos, SQL_C_STINYINT);
|
||||
prepareFixedSize<float>(pos, SQL_C_FLOAT, val.size());
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, double&)
|
||||
{
|
||||
prepareFixedSize<double>(pos, SQL_C_DOUBLE);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, std::vector<double>& val)
|
||||
{
|
||||
prepareFixedSize<double>(pos, SQL_C_DOUBLE, val.size());
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, char&)
|
||||
{
|
||||
prepareFixedSize<char>(pos, SQL_C_STINYINT);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, std::vector<char>& val)
|
||||
{
|
||||
prepareFixedSize<char>(pos, SQL_C_STINYINT, val.size());
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, const std::string&)
|
||||
{
|
||||
prepareRaw<char>(pos, SQL_C_CHAR, maxDataSize(pos));
|
||||
prepareVariableLen<char>(pos, SQL_C_CHAR, maxDataSize(pos), DT_CHAR);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, const std::vector<std::string>& val)
|
||||
{
|
||||
prepareVariableLenArray(pos, SQL_C_CHAR, maxDataSize(pos), val.size(), DT_CHAR_ARRAY);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, const Poco::Data::BLOB&)
|
||||
{
|
||||
prepareRaw<char>(pos, SQL_C_BINARY, maxDataSize(pos));
|
||||
prepareVariableLen<char>(pos, SQL_C_BINARY, maxDataSize(pos), DT_CHAR);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, const std::vector<Poco::Data::BLOB>& val)
|
||||
{
|
||||
prepareVariableLenArray(pos, SQL_C_BINARY, maxDataSize(pos), val.size(), DT_CHAR_ARRAY);
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
prepareFixedSize<SQL_DATE_STRUCT>(pos, SQL_C_TYPE_DATE);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, const std::vector<Poco::Data::Date>& val)
|
||||
{
|
||||
prepareFixedSize<SQL_DATE_STRUCT>(pos, SQL_C_TYPE_DATE, val.size());
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
prepareFixedSize<SQL_TIME_STRUCT>(pos, SQL_C_TYPE_TIME);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, const std::vector<Poco::Data::Time>& val)
|
||||
{
|
||||
prepareFixedSize<SQL_TIME_STRUCT>(pos, SQL_C_TYPE_TIME, val.size());
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, const Poco::DateTime&)
|
||||
{
|
||||
prepareRaw<SQL_TIMESTAMP_STRUCT>(pos,
|
||||
SQL_C_TYPE_TIMESTAMP,
|
||||
sizeof(SQL_TIMESTAMP_STRUCT));
|
||||
prepareFixedSize<SQL_TIMESTAMP_STRUCT>(pos, SQL_C_TYPE_TIMESTAMP);
|
||||
}
|
||||
|
||||
|
||||
inline int Preparation::actualDataSize(std::size_t pos) const
|
||||
inline void Preparation::prepare(std::size_t pos, const std::vector<Poco::DateTime>& val)
|
||||
{
|
||||
poco_assert (pos >= 0 && pos < _pValues.size());
|
||||
poco_assert (_pLengths[pos]);
|
||||
prepareFixedSize<SQL_TIMESTAMP_STRUCT>(pos, SQL_C_TYPE_TIMESTAMP, val.size());
|
||||
}
|
||||
|
||||
return *_pLengths[pos];
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, const Poco::Any& val)
|
||||
{
|
||||
prepareImpl<Poco::Any>(pos);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, const std::vector<Poco::Any>& val)
|
||||
{
|
||||
prepareImpl<Poco::Any>(pos, &val);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, const Poco::DynamicAny& val)
|
||||
{
|
||||
prepareImpl<Poco::DynamicAny>(pos);
|
||||
}
|
||||
|
||||
|
||||
inline void Preparation::prepare(std::size_t pos, const std::vector<Poco::DynamicAny>& val)
|
||||
{
|
||||
prepareImpl<Poco::DynamicAny>(pos, &val);
|
||||
}
|
||||
|
||||
|
||||
inline std::size_t Preparation::actualDataSize(std::size_t col, std::size_t row) const
|
||||
{
|
||||
poco_assert (col < _values.size());
|
||||
|
||||
if (INVALID_ROW == row) return _lengths[col];
|
||||
else return _lenLengths[col].at(row);
|
||||
}
|
||||
|
||||
|
||||
inline std::size_t Preparation::bulkSize(std::size_t col) const
|
||||
{
|
||||
poco_assert (col < _lenLengths.size());
|
||||
|
||||
return _lenLengths[col].size();
|
||||
}
|
||||
|
||||
|
||||
@@ -427,6 +791,14 @@ inline Preparation::DataExtraction Preparation::getDataExtraction() const
|
||||
}
|
||||
|
||||
|
||||
inline Poco::Any& Preparation::operator [] (std::size_t pos)
|
||||
{
|
||||
poco_assert (pos < _values.size());
|
||||
|
||||
return _values[pos];
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::ODBC
|
||||
|
||||
|
||||
|
@@ -97,21 +97,39 @@ public:
|
||||
static void dateSync(Date& dt, const SQL_DATE_STRUCT& ts);
|
||||
/// Transfers data from ODBC SQL_DATE_STRUCT to Poco::DateTime.
|
||||
|
||||
static void dateSync(std::vector<Date>& d, const std::vector<SQL_DATE_STRUCT>& ds);
|
||||
/// Transfers data from ODBC SQL_DATE_STRUCT vector to Poco::DateTime vector.
|
||||
|
||||
static void timeSync(Time& dt, const SQL_TIME_STRUCT& ts);
|
||||
/// Transfers data from ODBC SQL_TIME_STRUCT to Poco::DateTime.
|
||||
|
||||
static void timeSync(std::vector<Time>& t, const std::vector<SQL_TIME_STRUCT>& ts);
|
||||
/// Transfers data from ODBC SQL_TIME_STRUCT vector to Poco::DateTime vector.
|
||||
|
||||
static void dateTimeSync(Poco::DateTime& dt, const SQL_TIMESTAMP_STRUCT& ts);
|
||||
/// Transfers data from ODBC SQL_TIMESTAMP_STRUCT to Poco::DateTime.
|
||||
|
||||
static void dateTimeSync(std::vector<Poco::DateTime>& dt, const std::vector<SQL_TIMESTAMP_STRUCT>& ts);
|
||||
/// Transfers data from ODBC SQL_TIMESTAMP_STRUCT vector to Poco::DateTime vector.
|
||||
|
||||
static void dateSync(SQL_DATE_STRUCT& ts, const Date& dt);
|
||||
/// Transfers data from Poco::Data::Date to ODBC SQL_DATE_STRUCT.
|
||||
|
||||
static void dateSync(std::vector<SQL_DATE_STRUCT>& ds, const std::vector<Date>& d);
|
||||
/// Transfers data from Poco::Data::Date vector to ODBC SQL_DATE_STRUCT vector.
|
||||
|
||||
static void timeSync(SQL_TIME_STRUCT& ts, const Time& dt);
|
||||
/// Transfers data from Poco::Data::Time to ODBC SQL_TIME_STRUCT.
|
||||
|
||||
static void timeSync(std::vector<SQL_TIME_STRUCT>& ts, const std::vector<Time>& t);
|
||||
/// Transfers data from Poco::Data::Time vector to ODBC SQL_TIME_STRUCT vector.
|
||||
|
||||
static void dateTimeSync(SQL_TIMESTAMP_STRUCT& ts, const Poco::DateTime& dt);
|
||||
/// Transfers data from Poco::DateTime to ODBC SQL_TIMESTAMP_STRUCT.
|
||||
|
||||
static void dateTimeSync(std::vector<SQL_TIMESTAMP_STRUCT>& ts, const std::vector<Poco::DateTime>& dt);
|
||||
/// Transfers data from Poco::DateTime to ODBC SQL_TIMESTAMP_STRUCT.
|
||||
|
||||
private:
|
||||
static const TypeInfo _dataTypes;
|
||||
/// C <==> SQL data type mapping
|
||||
@@ -139,15 +157,15 @@ inline int Utility::sqlDataType(int cDataType)
|
||||
}
|
||||
|
||||
|
||||
inline void Utility::dateSync(Date& dt, const SQL_DATE_STRUCT& ts)
|
||||
inline void Utility::dateSync(Date& d, const SQL_DATE_STRUCT& ts)
|
||||
{
|
||||
dt.assign(ts.year, ts.month, ts.day);
|
||||
d.assign(ts.year, ts.month, ts.day);
|
||||
}
|
||||
|
||||
|
||||
inline void Utility::timeSync(Time& dt, const SQL_TIME_STRUCT& ts)
|
||||
inline void Utility::timeSync(Time& t, const SQL_TIME_STRUCT& ts)
|
||||
{
|
||||
dt.assign(ts.hour, ts.minute, ts.second);
|
||||
t.assign(ts.hour, ts.minute, ts.second);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -49,11 +49,14 @@ namespace ODBC {
|
||||
|
||||
|
||||
Binder::Binder(const StatementHandle& rStmt,
|
||||
std::size_t maxFieldSize,
|
||||
Binder::ParameterBinding dataBinding,
|
||||
TypeInfo* pDataTypes):
|
||||
_rStmt(rStmt),
|
||||
_paramBinding(dataBinding),
|
||||
_pTypeInfo(pDataTypes)
|
||||
_pTypeInfo(pDataTypes),
|
||||
_paramSetSize(0),
|
||||
_maxFieldSize(maxFieldSize)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -71,6 +74,42 @@ Binder::~Binder()
|
||||
StringMap::iterator itStr = _strings.begin();
|
||||
StringMap::iterator itStrEnd = _strings.end();
|
||||
for(; itStr != itStrEnd; ++itStr) std::free(itStr->first);
|
||||
|
||||
CharPtrVec::iterator itChr = _charPtrs.begin();
|
||||
CharPtrVec::iterator endChr = _charPtrs.end();
|
||||
for (; itChr != endChr; ++itChr) delete [] *itChr;
|
||||
}
|
||||
|
||||
|
||||
void Binder::freeMemory()
|
||||
{
|
||||
LengthVec::iterator itLen = _lengthIndicator.begin();
|
||||
LengthVec::iterator itLenEnd = _lengthIndicator.end();
|
||||
for(; itLen != itLenEnd; ++itLen) delete *itLen;
|
||||
|
||||
TimeMap::iterator itT = _times.begin();
|
||||
TimeMap::iterator itTEnd = _times.end();
|
||||
for(; itT != itTEnd; ++itT) delete itT->first;
|
||||
|
||||
DateMap::iterator itD = _dates.begin();
|
||||
DateMap::iterator itDEnd = _dates.end();
|
||||
for(; itD != itDEnd; ++itD) delete itD->first;
|
||||
|
||||
TimestampMap::iterator itTS = _timestamps.begin();
|
||||
TimestampMap::iterator itTSEnd = _timestamps.end();
|
||||
for(; itTS != itTSEnd; ++itTS) delete itTS->first;
|
||||
|
||||
StringMap::iterator itStr = _strings.begin();
|
||||
StringMap::iterator itStrEnd = _strings.end();
|
||||
for(; itStr != itStrEnd; ++itStr) std::free(itStr->first);
|
||||
|
||||
CharPtrVec::iterator itChr = _charPtrs.begin();
|
||||
CharPtrVec::iterator endChr = _charPtrs.end();
|
||||
for (; itChr != endChr; ++itChr) std::free(*itChr);
|
||||
|
||||
BoolPtrVec::iterator itBool = _boolPtrs.begin();
|
||||
BoolPtrVec::iterator endBool = _boolPtrs.end();
|
||||
for (; itBool != endBool; ++itBool) delete [] *itBool;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,29 +120,7 @@ void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
|
||||
|
||||
if (isOutBound(dir))
|
||||
{
|
||||
try
|
||||
{
|
||||
Parameter p(_rStmt, pos);
|
||||
size = (SQLUINTEGER) p.columnSize();
|
||||
}
|
||||
catch (StatementException&)
|
||||
{
|
||||
size = DEFAULT_PARAM_SIZE;
|
||||
//On Linux, PostgreSQL driver segfaults on SQLGetDescField, so this is disabled for now
|
||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||
SQLHDESC hIPD = 0;
|
||||
if (!Utility::isError(SQLGetStmtAttr(_rStmt, SQL_ATTR_IMP_PARAM_DESC, &hIPD, SQL_IS_POINTER, 0)))
|
||||
{
|
||||
SQLUINTEGER sz = 0;
|
||||
if (!Utility::isError(SQLGetDescField(hIPD, (SQLSMALLINT) pos + 1, SQL_DESC_LENGTH, &sz, SQL_IS_UINTEGER, 0)) &&
|
||||
sz > 0)
|
||||
{
|
||||
size = sz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
getColumnOrParameterSize(pos, size);
|
||||
char* pChar = (char*) std::calloc(size, sizeof(char));
|
||||
pVal = (SQLPOINTER) pChar;
|
||||
_outParams.insert(ParamMap::value_type(pVal, size));
|
||||
@@ -115,7 +132,7 @@ void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
|
||||
_inParams.insert(ParamMap::value_type(pVal, size));
|
||||
}
|
||||
else
|
||||
throw IllegalStateException("Parameter must be [in] OR [out] bound.");
|
||||
throw InvalidArgumentException("Parameter must be [in] OR [out] bound.");
|
||||
|
||||
SQLLEN* pLenIn = new SQLLEN;
|
||||
*pLenIn = SQL_NTS;
|
||||
@@ -141,7 +158,64 @@ void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir)
|
||||
void Binder::bind(std::size_t pos, const std::vector<std::string>& val, Direction dir)
|
||||
{
|
||||
if (isOutBound(dir) || !isInBound(dir))
|
||||
throw NotImplementedException("String vector parameter type can only be inbound.");
|
||||
|
||||
if (PB_IMMEDIATE != _paramBinding)
|
||||
throw InvalidAccessException("std::vector can only be bound immediately.");
|
||||
|
||||
if (0 == val.size())
|
||||
throw InvalidArgumentException("Empty vector not allowed.");
|
||||
|
||||
setParamSetSize(pos, val.size());
|
||||
|
||||
SQLINTEGER size = 0;
|
||||
getColumnOrParameterSize(pos, size);
|
||||
poco_assert (size > 0);
|
||||
|
||||
if (_vecLengthIndicator.size() <= pos)
|
||||
{
|
||||
_vecLengthIndicator.resize(pos + 1);
|
||||
_vecLengthIndicator[pos].resize(val.size(), SQL_NTS);
|
||||
}
|
||||
|
||||
if (_charPtrs.size() <= pos)
|
||||
_charPtrs.resize(pos + 1, 0);
|
||||
|
||||
_charPtrs[pos] = (char*) std::calloc(val.size() * size, sizeof(char));
|
||||
|
||||
std::size_t strSize;
|
||||
std::size_t offset = 0;
|
||||
std::vector<std::string>::const_iterator it = val.begin();
|
||||
std::vector<std::string>::const_iterator end = val.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
strSize = it->size();
|
||||
if (strSize > size)
|
||||
throw LengthExceededException("SQLBindParameter(std::vector<std::string>)");
|
||||
std::memcpy(_charPtrs[pos] + offset, it->c_str(), strSize);
|
||||
offset += size;
|
||||
}
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
SQL_C_CHAR,
|
||||
SQL_LONGVARCHAR,
|
||||
(SQLUINTEGER) size - 1,
|
||||
0,
|
||||
_charPtrs[pos],
|
||||
(SQLINTEGER) size,
|
||||
&_vecLengthIndicator[pos][0])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter(std::vector<std::string>)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const BLOB& val, Direction dir)
|
||||
{
|
||||
if (isOutBound(dir) || !isInBound(dir))
|
||||
throw NotImplementedException("BLOB parameter type can only be inbound.");
|
||||
@@ -175,6 +249,78 @@ void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir)
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const std::vector<BLOB>& val, Direction dir)
|
||||
{
|
||||
if (isOutBound(dir) || !isInBound(dir))
|
||||
throw NotImplementedException("BLOB vector parameter type can only be inbound.");
|
||||
|
||||
if (PB_IMMEDIATE != _paramBinding)
|
||||
throw InvalidAccessException("std::vector can only be bound immediately.");
|
||||
|
||||
if (0 == val.size())
|
||||
throw InvalidArgumentException("Empty vector not allowed.");
|
||||
|
||||
setParamSetSize(pos, val.size());
|
||||
|
||||
SQLINTEGER size = 0;
|
||||
getColumnOrParameterSize(pos, size);
|
||||
poco_assert (size > 0);
|
||||
|
||||
if (size == _maxFieldSize)
|
||||
{
|
||||
std::size_t maxSize = 0;
|
||||
std::vector<BLOB>::const_iterator it = val.begin();
|
||||
std::vector<BLOB>::const_iterator end = val.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
std::size_t sz = it->size();
|
||||
if (sz < _maxFieldSize && sz > maxSize)
|
||||
maxSize = sz;
|
||||
}
|
||||
if (maxSize) size = maxSize;
|
||||
}
|
||||
|
||||
if (_vecLengthIndicator.size() <= pos)
|
||||
{
|
||||
_vecLengthIndicator.resize(pos + 1);
|
||||
_vecLengthIndicator[pos].resize(val.size(), SQL_NTS);
|
||||
}
|
||||
|
||||
if (_charPtrs.size() <= pos)
|
||||
_charPtrs.resize(pos + 1, 0);
|
||||
|
||||
_charPtrs[pos] = (char*) std::calloc(val.size() * size, sizeof(char));
|
||||
poco_check_ptr (_charPtrs[pos]);
|
||||
|
||||
std::size_t blobSize;
|
||||
std::size_t offset = 0;
|
||||
std::vector<BLOB>::const_iterator it = val.begin();
|
||||
std::vector<BLOB>::const_iterator end = val.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
blobSize = it->size();
|
||||
if (blobSize > size)
|
||||
throw LengthExceededException("SQLBindParameter(std::vector<BLOB>)");
|
||||
std::memcpy(_charPtrs[pos] + offset, it->rawContent(), blobSize);
|
||||
offset += size;
|
||||
}
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
SQL_PARAM_INPUT,
|
||||
SQL_C_BINARY,
|
||||
SQL_LONGVARBINARY,
|
||||
(SQLUINTEGER) size,
|
||||
0,
|
||||
_charPtrs[pos],
|
||||
(SQLINTEGER) size,
|
||||
&_vecLengthIndicator[pos][0])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter(std::vector<BLOB>)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Date& val, Direction dir)
|
||||
{
|
||||
SQLINTEGER size = (SQLINTEGER) sizeof(SQL_DATE_STRUCT);
|
||||
@@ -203,7 +349,51 @@ void Binder::bind(std::size_t pos, const Date& val, Direction dir)
|
||||
0,
|
||||
_lengthIndicator.back())))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter(BLOB)");
|
||||
throw StatementException(_rStmt, "SQLBindParameter(Date)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const std::vector<Date>& val, Direction dir)
|
||||
{
|
||||
if (isOutBound(dir) || !isInBound(dir))
|
||||
throw NotImplementedException("Date vector parameter type can only be inbound.");
|
||||
|
||||
if (PB_IMMEDIATE != _paramBinding)
|
||||
throw InvalidAccessException("std::vector can only be bound immediately.");
|
||||
|
||||
if (0 == val.size())
|
||||
throw InvalidArgumentException("Empty vector not allowed.");
|
||||
|
||||
setParamSetSize(pos, val.size());
|
||||
|
||||
SQLINTEGER size = (SQLINTEGER) sizeof(SQL_DATE_STRUCT);
|
||||
|
||||
if (_vecLengthIndicator.size() <= pos)
|
||||
{
|
||||
_vecLengthIndicator.resize(pos + 1);
|
||||
_vecLengthIndicator[pos].resize(val.size(), size);
|
||||
}
|
||||
|
||||
if (_dateVec.size() <= pos) _dateVec.resize(pos + 1);
|
||||
Utility::dateSync(_dateVec[pos], 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) &_dateVec[pos][0],
|
||||
0,
|
||||
&_vecLengthIndicator[pos][0])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter(Date[])");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +426,51 @@ void Binder::bind(std::size_t pos, const Time& val, Direction dir)
|
||||
0,
|
||||
_lengthIndicator.back())))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter(BLOB)");
|
||||
throw StatementException(_rStmt, "SQLBindParameter(Time)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const std::vector<Time>& val, Direction dir)
|
||||
{
|
||||
if (isOutBound(dir) || !isInBound(dir))
|
||||
throw NotImplementedException("Time vector parameter type can only be inbound.");
|
||||
|
||||
if (PB_IMMEDIATE != _paramBinding)
|
||||
throw InvalidAccessException("std::vector can only be bound immediately.");
|
||||
|
||||
if (0 == val.size())
|
||||
throw InvalidArgumentException("Empty vector not allowed.");
|
||||
|
||||
setParamSetSize(pos, val.size());
|
||||
|
||||
SQLINTEGER size = (SQLINTEGER) sizeof(SQL_TIME_STRUCT);
|
||||
|
||||
if (_vecLengthIndicator.size() <= pos)
|
||||
{
|
||||
_vecLengthIndicator.resize(pos + 1);
|
||||
_vecLengthIndicator[pos].resize(val.size(), size);
|
||||
}
|
||||
|
||||
if (_timeVec.size() <= pos) _timeVec.resize(pos + 1);
|
||||
Utility::timeSync(_timeVec[pos], 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) &_timeVec[pos][0],
|
||||
0,
|
||||
&_vecLengthIndicator[pos][0])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter(Time[])");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,7 +503,51 @@ void Binder::bind(std::size_t pos, const Poco::DateTime& val, Direction dir)
|
||||
0,
|
||||
_lengthIndicator.back())))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter(BLOB)");
|
||||
throw StatementException(_rStmt, "SQLBindParameter(DateTime)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const std::vector<DateTime>& val, Direction dir)
|
||||
{
|
||||
if (isOutBound(dir) || !isInBound(dir))
|
||||
throw NotImplementedException("DateTime vector parameter type can only be inbound.");
|
||||
|
||||
if (PB_IMMEDIATE != _paramBinding)
|
||||
throw InvalidAccessException("std::vector can only be bound immediately.");
|
||||
|
||||
if (0 == val.size())
|
||||
throw InvalidArgumentException("Empty vector not allowed.");
|
||||
|
||||
setParamSetSize(pos, val.size());
|
||||
|
||||
SQLINTEGER size = (SQLINTEGER) sizeof(SQL_TIMESTAMP_STRUCT);
|
||||
|
||||
if (_vecLengthIndicator.size() <= pos)
|
||||
{
|
||||
_vecLengthIndicator.resize(pos + 1);
|
||||
_vecLengthIndicator[pos].resize(val.size(), size);
|
||||
}
|
||||
|
||||
if (_dateTimeVec.size() <= pos) _dateTimeVec.resize(pos + 1);
|
||||
Utility::dateTimeSync(_dateTimeVec[pos], 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_TIMESTAMP,
|
||||
SQL_TIMESTAMP,
|
||||
colSize,
|
||||
decDigits,
|
||||
(SQLPOINTER) &_dateTimeVec[pos][0],
|
||||
0,
|
||||
&_vecLengthIndicator[pos][0])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter(Time[])");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,34 +557,6 @@ void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
|
||||
if (isOutBound(dir) || !isInBound(dir))
|
||||
throw NotImplementedException("NULL parameter type can only be inbound.");
|
||||
|
||||
switch (val)
|
||||
{
|
||||
case NULL_GENERIC:
|
||||
case NULL_INT8: bindNull(pos, SQL_C_STINYINT); break;
|
||||
case NULL_UINT8: bindNull(pos, SQL_C_UTINYINT); break;
|
||||
case NULL_INT16: bindNull(pos, SQL_C_SSHORT); break;
|
||||
case NULL_UINT16: bindNull(pos, SQL_C_USHORT); break;
|
||||
case NULL_INT32: bindNull(pos, SQL_C_SLONG); break;
|
||||
case NULL_UINT32: bindNull(pos, SQL_C_ULONG); break;
|
||||
case NULL_INT64: bindNull(pos, SQL_C_SBIGINT); break;
|
||||
case NULL_UINT64: bindNull(pos, SQL_C_UBIGINT); break;
|
||||
case NULL_BOOL: bindNull(pos, SQL_C_BIT); break;
|
||||
case NULL_FLOAT: bindNull(pos, SQL_C_FLOAT); break;
|
||||
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:
|
||||
throw DataFormatException("Unsupported data type.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Binder::bindNull(std::size_t pos, SQLSMALLINT cDataType)
|
||||
{
|
||||
_inParams.insert(ParamMap::value_type(0, 0));
|
||||
|
||||
SQLLEN* pLenIn = new SQLLEN;
|
||||
@@ -316,13 +566,13 @@ void Binder::bindNull(std::size_t pos, SQLSMALLINT cDataType)
|
||||
|
||||
SQLINTEGER colSize = 0;
|
||||
SQLSMALLINT decDigits = 0;
|
||||
getColSizeAndPrecision(pos, cDataType, colSize, decDigits);
|
||||
getColSizeAndPrecision(pos, SQL_C_STINYINT, colSize, decDigits);
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
SQL_PARAM_INPUT,
|
||||
cDataType,
|
||||
Utility::sqlDataType(cDataType),
|
||||
SQL_C_STINYINT,
|
||||
Utility::sqlDataType(SQL_C_STINYINT),
|
||||
colSize,
|
||||
decDigits,
|
||||
0,
|
||||
@@ -334,6 +584,90 @@ void Binder::bindNull(std::size_t pos, SQLSMALLINT cDataType)
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const std::vector<NullData>& val, Direction dir)
|
||||
{
|
||||
if (isOutBound(dir) || !isInBound(dir))
|
||||
throw NotImplementedException("DateTime vector parameter type can only be inbound.");
|
||||
|
||||
if (PB_IMMEDIATE != _paramBinding)
|
||||
throw InvalidAccessException("std::vector can only be bound immediately.");
|
||||
|
||||
if (0 == val.size())
|
||||
throw InvalidArgumentException("Empty vector not allowed.");
|
||||
|
||||
setParamSetSize(pos, val.size());
|
||||
|
||||
SQLINTEGER size = SQL_NULL_DATA;
|
||||
|
||||
if (_vecLengthIndicator.size() <= pos)
|
||||
{
|
||||
_vecLengthIndicator.resize(pos + 1);
|
||||
_vecLengthIndicator[pos].resize(val.size(), size);
|
||||
}
|
||||
|
||||
SQLINTEGER colSize = 0;
|
||||
SQLSMALLINT decDigits = 0;
|
||||
getColSizeAndPrecision(pos, SQL_TYPE_TIME, colSize, decDigits);
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
SQL_PARAM_INPUT,
|
||||
SQL_C_STINYINT,
|
||||
Utility::sqlDataType(SQL_C_STINYINT),
|
||||
colSize,
|
||||
decDigits,
|
||||
0,
|
||||
0,
|
||||
&_vecLengthIndicator[pos][0])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter()");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Binder::bindImplVecBool(std::size_t pos, const std::vector<bool>& val, SQLSMALLINT cDataType, Direction dir)
|
||||
{
|
||||
if (PB_IMMEDIATE != _paramBinding)
|
||||
throw InvalidAccessException("std::vector can only be bound immediately.");
|
||||
|
||||
std::size_t length = val.size();
|
||||
SQLINTEGER colSize = 0;
|
||||
SQLSMALLINT decDigits = 0;
|
||||
getColSizeAndPrecision(pos, cDataType, colSize, decDigits);
|
||||
|
||||
setParamSetSize(pos, val.size());
|
||||
|
||||
if (_vecLengthIndicator.size() <= pos)
|
||||
{
|
||||
_vecLengthIndicator.resize(pos + 1);
|
||||
_vecLengthIndicator[pos].resize(length, sizeof(bool));
|
||||
}
|
||||
|
||||
if (_boolPtrs.size() <= pos)
|
||||
_boolPtrs.resize(pos + 1);
|
||||
|
||||
_boolPtrs[pos] = new bool[val.size()];
|
||||
|
||||
std::vector<bool>::const_iterator it = val.begin();
|
||||
std::vector<bool>::const_iterator end = val.end();
|
||||
for (int i = 0; it != end; ++it, ++i) _boolPtrs[pos][i] = *it;
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
cDataType,
|
||||
Utility::sqlDataType(cDataType),
|
||||
colSize,
|
||||
decDigits,
|
||||
(SQLPOINTER) &_boolPtrs[pos][0],
|
||||
0,
|
||||
&_vecLengthIndicator[pos][0])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindParameter()");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::size_t Binder::parameterSize(SQLPOINTER pAddr) const
|
||||
{
|
||||
ParamMap::const_iterator it = _inParams.find(pAddr);
|
||||
@@ -370,40 +704,41 @@ 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);
|
||||
DateMap::iterator it = _dates.begin();
|
||||
DateMap::iterator end = _dates.end();
|
||||
for(; it != end; ++it)
|
||||
Utility::dateSync(*it->second, *it->first);
|
||||
}
|
||||
|
||||
if (_times.size())
|
||||
{
|
||||
TimeMap::iterator itTS = _times.begin();
|
||||
TimeMap::iterator itTSEnd = _times.end();
|
||||
for(; itTS != itTSEnd; ++itTS)
|
||||
Utility::timeSync(*itTS->second, *itTS->first);
|
||||
TimeMap::iterator it = _times.begin();
|
||||
TimeMap::iterator end = _times.end();
|
||||
for(; it != end; ++it)
|
||||
Utility::timeSync(*it->second, *it->first);
|
||||
}
|
||||
|
||||
if (_timestamps.size())
|
||||
{
|
||||
TimestampMap::iterator itTS = _timestamps.begin();
|
||||
TimestampMap::iterator itTSEnd = _timestamps.end();
|
||||
for(; itTS != itTSEnd; ++itTS)
|
||||
Utility::dateTimeSync(*itTS->second, *itTS->first);
|
||||
TimestampMap::iterator it = _timestamps.begin();
|
||||
TimestampMap::iterator end = _timestamps.end();
|
||||
for(; it != end; ++it)
|
||||
Utility::dateTimeSync(*it->second, *it->first);
|
||||
}
|
||||
|
||||
if (_strings.size())
|
||||
{
|
||||
StringMap::iterator itStr = _strings.begin();
|
||||
StringMap::iterator itStrEnd = _strings.end();
|
||||
for(; itStr != itStrEnd; ++itStr)
|
||||
itStr->second->assign(itStr->first, strlen(itStr->first));
|
||||
StringMap::iterator it = _strings.begin();
|
||||
StringMap::iterator end = _strings.end();
|
||||
for(; it != end; ++it)
|
||||
it->second->assign(it->first, strlen(it->first));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Binder::reset()
|
||||
{
|
||||
freeMemory();
|
||||
LengthVec().swap(_lengthIndicator);
|
||||
_inParams.clear();
|
||||
_outParams.clear();
|
||||
@@ -411,6 +746,11 @@ void Binder::reset()
|
||||
_times.clear();
|
||||
_timestamps.clear();
|
||||
_strings.clear();
|
||||
_dateVec.clear();
|
||||
_timeVec.clear();
|
||||
_dateTimeVec.clear();
|
||||
_charPtrs.clear();
|
||||
_boolPtrs.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -429,18 +769,16 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
|
||||
decDigits = _pTypeInfo->getInfo(cDataType, "MINIMUM_SCALE");
|
||||
return;
|
||||
}
|
||||
else
|
||||
throw NotFoundException();
|
||||
}catch (NotFoundException&)
|
||||
{
|
||||
} catch (NotFoundException&) { }
|
||||
|
||||
try
|
||||
{
|
||||
Parameter p(_rStmt, pos);
|
||||
colSize = (SQLINTEGER) p.columnSize();
|
||||
decDigits = (SQLSMALLINT) p.decimalDigits();
|
||||
return;
|
||||
}catch (StatementException&)
|
||||
{
|
||||
} catch (StatementException&) { }
|
||||
|
||||
try
|
||||
{
|
||||
ODBCColumn c(_rStmt, pos);
|
||||
@@ -448,8 +786,6 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
|
||||
decDigits = (SQLSMALLINT) c.precision();
|
||||
return;
|
||||
} catch (StatementException&) { }
|
||||
}
|
||||
}
|
||||
|
||||
// no success, set to zero and hope for the best
|
||||
// (most drivers do not require these most of the times anyway)
|
||||
@@ -459,4 +795,67 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
|
||||
}
|
||||
|
||||
|
||||
void Binder::getColumnOrParameterSize(std::size_t pos, SQLINTEGER& size)
|
||||
{
|
||||
std::size_t colSize = 0;
|
||||
std::size_t paramSize = 0;
|
||||
|
||||
try
|
||||
{
|
||||
ODBCColumn col(_rStmt, pos);
|
||||
colSize = col.length();
|
||||
}
|
||||
catch (StatementException&) { }
|
||||
|
||||
try
|
||||
{
|
||||
Parameter p(_rStmt, pos);
|
||||
paramSize = p.columnSize();
|
||||
}
|
||||
catch (StatementException&)
|
||||
{
|
||||
size = DEFAULT_PARAM_SIZE;
|
||||
//On Linux, PostgreSQL driver segfaults on SQLGetDescField, so this is disabled for now
|
||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||
SQLHDESC hIPD = 0;
|
||||
if (!Utility::isError(SQLGetStmtAttr(_rStmt, SQL_ATTR_IMP_PARAM_DESC, &hIPD, SQL_IS_POINTER, 0)))
|
||||
{
|
||||
SQLUINTEGER sz = 0;
|
||||
if (!Utility::isError(SQLGetDescField(hIPD, (SQLSMALLINT) pos + 1, SQL_DESC_LENGTH, &sz, SQL_IS_UINTEGER, 0)) &&
|
||||
sz > 0)
|
||||
{
|
||||
size = sz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (colSize > 0 && paramSize > 0)
|
||||
size = colSize < paramSize ? colSize : paramSize;
|
||||
else if (colSize > 0)
|
||||
size = colSize;
|
||||
else if (paramSize > 0)
|
||||
size = paramSize;
|
||||
|
||||
if (size > _maxFieldSize) size = _maxFieldSize;
|
||||
}
|
||||
|
||||
|
||||
void Binder::setParamSetSize(std::size_t pos, std::size_t length)
|
||||
{
|
||||
if (0 == _paramSetSize)
|
||||
{
|
||||
if (Utility::isError(SQLSetStmtAttr(_rStmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, SQL_IS_UINTEGER)) ||
|
||||
Utility::isError(SQLSetStmtAttr(_rStmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER) length, SQL_IS_UINTEGER)))
|
||||
throw StatementException(_rStmt, "SQLSetStmtAttr()");
|
||||
|
||||
if (Utility::isError(SQLGetStmtAttr(_rStmt, SQL_ATTR_PARAMSET_SIZE, &_paramSetSize, 0, 0)))
|
||||
throw StatementException(_rStmt, "SQLGetStmtAttr()");
|
||||
}
|
||||
|
||||
if (_paramSetSize != length)
|
||||
throw InvalidArgumentException("Invalid parameter array length.");
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::ODBC
|
||||
|
@@ -73,11 +73,29 @@ bool Extractor::extractBoundImpl<std::string>(std::size_t pos, std::string& val)
|
||||
if (isNull(pos)) return false;
|
||||
|
||||
std::size_t dataSize = _rPreparation.actualDataSize(pos);
|
||||
SharedPtr<char>& sp = RefAnyCast<SharedPtr<char> >(_rPreparation[pos]);
|
||||
char* sp = AnyCast<char*>(_rPreparation[pos]);
|
||||
std::size_t len = strlen(sp);
|
||||
if (len < dataSize) dataSize = len;
|
||||
checkDataSize(dataSize);
|
||||
val.assign(sp, dataSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImpl<std::vector<std::string> >(std::size_t pos,
|
||||
std::vector<std::string>& values)
|
||||
{
|
||||
char** pc = AnyCast<char*>(&_rPreparation[pos]);
|
||||
poco_assert_dbg (pc);
|
||||
poco_assert_dbg (_rPreparation.bulkSize() == values.size());
|
||||
std::size_t colWidth = columnSize(pos);
|
||||
std::vector<std::string>::iterator it = values.begin();
|
||||
std::vector<std::string>::iterator end = values.end();
|
||||
for (int row = 0; it != end; ++it, ++row)
|
||||
it->assign(*pc + row * colWidth, _rPreparation.actualDataSize(pos, row));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -89,8 +107,26 @@ bool Extractor::extractBoundImpl<Poco::Data::BLOB>(std::size_t pos, Poco::Data::
|
||||
|
||||
std::size_t dataSize = _rPreparation.actualDataSize(pos);
|
||||
checkDataSize(dataSize);
|
||||
SharedPtr<char>& sp = RefAnyCast<SharedPtr<char> >(_rPreparation[pos]);
|
||||
char* sp = AnyCast<char*>(_rPreparation[pos]);
|
||||
val.assignRaw(sp, dataSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImpl<std::vector<Poco::Data::BLOB> >(std::size_t pos,
|
||||
std::vector<Poco::Data::BLOB>& values)
|
||||
{
|
||||
char** pc = AnyCast<char*>(&_rPreparation[pos]);
|
||||
poco_assert_dbg (pc);
|
||||
poco_assert_dbg (_rPreparation.bulkSize() == values.size());
|
||||
std::size_t colWidth = columnSize(pos);
|
||||
std::vector<Poco::Data::BLOB>::iterator it = values.begin();
|
||||
std::vector<Poco::Data::BLOB>::iterator end = values.end();
|
||||
for (int row = 0; it != end; ++it, ++row)
|
||||
it->assignRaw(*pc + row * colWidth, _rPreparation.actualDataSize(pos, row));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -99,12 +135,18 @@ template<>
|
||||
bool Extractor::extractBoundImpl<Poco::Data::Date>(std::size_t pos, Poco::Data::Date& val)
|
||||
{
|
||||
if (isNull(pos)) return false;
|
||||
SQL_DATE_STRUCT& ds = *AnyCast<SQL_DATE_STRUCT>(&_rPreparation[pos]);
|
||||
Utility::dateSync(val, ds);
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
template<>
|
||||
bool Extractor::extractBoundImpl<std::vector<Poco::Data::Date> >(std::size_t pos,
|
||||
std::vector<Poco::Data::Date>& val)
|
||||
{
|
||||
std::vector<SQL_DATE_STRUCT>& ds = RefAnyCast<std::vector<SQL_DATE_STRUCT> >(_rPreparation[pos]);
|
||||
Utility::dateSync(val, ds);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -116,9 +158,19 @@ bool Extractor::extractBoundImpl<Poco::Data::Time>(std::size_t pos, Poco::Data::
|
||||
|
||||
std::size_t dataSize = _rPreparation.actualDataSize(pos);
|
||||
checkDataSize(dataSize);
|
||||
SharedPtr<SQL_TIME_STRUCT>& sp = RefAnyCast<SharedPtr<SQL_TIME_STRUCT> >(_rPreparation[pos]);
|
||||
SQL_TIME_STRUCT& ts = *AnyCast<SQL_TIME_STRUCT>(&_rPreparation[pos]);
|
||||
Utility::timeSync(val, ts);
|
||||
|
||||
Utility::timeSync(val, *sp);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImpl<std::vector<Poco::Data::Time> >(std::size_t pos,
|
||||
std::vector<Poco::Data::Time>& val)
|
||||
{
|
||||
std::vector<SQL_TIME_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIME_STRUCT> >(_rPreparation[pos]);
|
||||
Utility::timeSync(val, ds);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -130,9 +182,31 @@ bool Extractor::extractBoundImpl<Poco::DateTime>(std::size_t pos, Poco::DateTime
|
||||
|
||||
std::size_t dataSize = _rPreparation.actualDataSize(pos);
|
||||
checkDataSize(dataSize);
|
||||
SharedPtr<SQL_TIMESTAMP_STRUCT>& sp = RefAnyCast<SharedPtr<SQL_TIMESTAMP_STRUCT> >(_rPreparation[pos]);
|
||||
SQL_TIMESTAMP_STRUCT& tss = *AnyCast<SQL_TIMESTAMP_STRUCT>(&_rPreparation[pos]);
|
||||
Utility::dateTimeSync(val, tss);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImpl<std::vector<Poco::DateTime> >(std::size_t pos,
|
||||
std::vector<Poco::DateTime>& val)
|
||||
{
|
||||
std::vector<SQL_TIMESTAMP_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIMESTAMP_STRUCT> >(_rPreparation[pos]);
|
||||
Utility::dateTimeSync(val, ds);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
bool Extractor::extractBoundImpl<std::vector<bool> >(std::size_t pos, std::vector<bool>& val)
|
||||
{
|
||||
std::size_t length = _rPreparation.getLength();
|
||||
bool* p = AnyCast<bool>(&_rPreparation[pos]);
|
||||
for (int i = 0; i < length; ++i)
|
||||
val.push_back(p[i]);
|
||||
|
||||
Utility::dateTimeSync(val, *sp);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -163,8 +237,6 @@ bool Extractor::extractManualImpl<std::string>(std::size_t pos, std::string& val
|
||||
CHUNK_SIZE, //buffer length
|
||||
&len); //length indicator
|
||||
|
||||
_lengths[pos] += len;
|
||||
|
||||
if (SQL_NO_DATA != rc && Utility::isError(rc))
|
||||
throw StatementException(_rStmt, "SQLGetData()");
|
||||
|
||||
@@ -172,18 +244,21 @@ bool Extractor::extractManualImpl<std::string>(std::size_t pos, std::string& val
|
||||
throw UnknownDataLengthException("Could not determine returned data length.");
|
||||
|
||||
if (isNullLengthIndicator(len))
|
||||
{
|
||||
_lengths[pos] = len;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SQL_NO_DATA == rc || !len)
|
||||
break;
|
||||
|
||||
_lengths[pos] += len;
|
||||
fetchedSize = _lengths[pos] > CHUNK_SIZE ? CHUNK_SIZE : _lengths[pos];
|
||||
totalSize += fetchedSize;
|
||||
if (totalSize <= maxSize) val.append(pChar, fetchedSize);
|
||||
else throw DataException(format(FLD_SIZE_EXCEEDED_FMT,
|
||||
fetchedSize,
|
||||
maxSize));
|
||||
|
||||
if (totalSize <= maxSize)
|
||||
val.append(pChar, fetchedSize);
|
||||
else
|
||||
throw DataException(format(FLD_SIZE_EXCEEDED_FMT, fetchedSize, maxSize));
|
||||
}while (true);
|
||||
|
||||
return true;
|
||||
@@ -237,9 +312,7 @@ bool Extractor::extractManualImpl<Poco::Data::BLOB>(std::size_t pos,
|
||||
if (totalSize <= maxSize)
|
||||
val.appendRaw(pChar, fetchedSize);
|
||||
else
|
||||
throw DataException(format(FLD_SIZE_EXCEEDED_FMT,
|
||||
fetchedSize,
|
||||
maxSize));
|
||||
throw DataException(format(FLD_SIZE_EXCEEDED_FMT, fetchedSize, maxSize));
|
||||
|
||||
}while (true);
|
||||
|
||||
@@ -334,6 +407,16 @@ bool Extractor::extract(std::size_t pos, Poco::Int32& val)
|
||||
return extractManualImpl(pos, val, SQL_C_SLONG);
|
||||
else
|
||||
return extractBoundImpl(pos, val);
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::Int32>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplVec(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -347,6 +430,17 @@ bool Extractor::extract(std::size_t pos, Poco::Int64& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::Int64>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplVec(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
bool Extractor::extract(std::size_t pos, long& val)
|
||||
{
|
||||
@@ -355,6 +449,17 @@ bool Extractor::extract(std::size_t pos, long& val)
|
||||
else
|
||||
return extractBoundImpl(pos, val);
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<long>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplVec(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -367,6 +472,17 @@ bool Extractor::extract(std::size_t pos, double& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<double>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplVec(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::string& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -376,6 +492,17 @@ bool Extractor::extract(std::size_t pos, std::string& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<std::string>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImpl(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -385,6 +512,17 @@ bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::Data::BLOB>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImpl(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Data::Date& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -394,6 +532,17 @@ bool Extractor::extract(std::size_t pos, Poco::Data::Date& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::Data::Date>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImpl(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Data::Time& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -403,6 +552,17 @@ bool Extractor::extract(std::size_t pos, Poco::Data::Time& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::Data::Time>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImpl(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::DateTime& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -412,6 +572,17 @@ bool Extractor::extract(std::size_t pos, Poco::DateTime& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::DateTime>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImpl(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Int8& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -421,6 +592,17 @@ bool Extractor::extract(std::size_t pos, Poco::Int8& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::Int8>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplVec(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::UInt8& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -430,6 +612,15 @@ bool Extractor::extract(std::size_t pos, Poco::UInt8& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::UInt8>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplVec(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Int16& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -439,6 +630,17 @@ bool Extractor::extract(std::size_t pos, Poco::Int16& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::Int16>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplVec(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::UInt16& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -448,6 +650,17 @@ bool Extractor::extract(std::size_t pos, Poco::UInt16& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::UInt16>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplVec(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::UInt32& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -457,6 +670,17 @@ bool Extractor::extract(std::size_t pos, Poco::UInt32& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::UInt32>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplVec(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::UInt64& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -466,6 +690,17 @@ bool Extractor::extract(std::size_t pos, Poco::UInt64& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::UInt64>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplVec(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, bool& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -475,6 +710,17 @@ bool Extractor::extract(std::size_t pos, bool& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<bool>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplVec(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, float& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -484,6 +730,17 @@ bool Extractor::extract(std::size_t pos, float& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<float>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplVec(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, char& val)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
@@ -493,32 +750,65 @@ bool Extractor::extract(std::size_t pos, char& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<char>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImplVec(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Any& val)
|
||||
{
|
||||
return extractImpl(pos, val);
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::Any>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImpl(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::DynamicAny& val)
|
||||
{
|
||||
return extractImpl(pos, val);
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::isNull(std::size_t pos)
|
||||
bool Extractor::extract(std::size_t pos, std::vector<Poco::DynamicAny>& val)
|
||||
{
|
||||
if (Preparation::DE_BOUND == _dataExtraction)
|
||||
return extractBoundImpl(pos, val);
|
||||
else
|
||||
throw InvalidAccessException("Direct vector extraction only allowed for bound mode.");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::isNull(std::size_t col, std::size_t row)
|
||||
{
|
||||
if (Preparation::DE_MANUAL == _dataExtraction)
|
||||
{
|
||||
try
|
||||
{
|
||||
return isNullLengthIndicator(_lengths.at(pos));
|
||||
return isNullLengthIndicator(_lengths.at(col));
|
||||
}catch (std::out_of_range& ex)
|
||||
{
|
||||
throw RangeException(ex.what());
|
||||
}
|
||||
}
|
||||
else
|
||||
return SQL_NULL_DATA == _rPreparation.actualDataSize(pos);
|
||||
return SQL_NULL_DATA == _rPreparation.actualDataSize(col, row);
|
||||
}
|
||||
|
||||
|
||||
@@ -526,11 +816,7 @@ void Extractor::checkDataSize(std::size_t size)
|
||||
{
|
||||
std::size_t maxSize = _rPreparation.getMaxFieldSize();
|
||||
if (size > maxSize)
|
||||
{
|
||||
throw DataException(format(FLD_SIZE_EXCEEDED_FMT,
|
||||
size,
|
||||
maxSize));
|
||||
}
|
||||
throw DataException(format(FLD_SIZE_EXCEEDED_FMT, size, maxSize));
|
||||
}
|
||||
|
||||
|
||||
|
@@ -40,11 +40,9 @@
|
||||
#include "Poco/Data/ODBC/ODBCException.h"
|
||||
#include "Poco/Data/AbstractPrepare.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <limits>
|
||||
|
||||
|
||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||
#undef max
|
||||
#pragma warning(disable:4312)// 'type cast' : conversion from 'Poco::UInt32' to 'SQLPOINTER' of greater size
|
||||
#endif
|
||||
|
||||
@@ -68,11 +66,6 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
|
||||
_nextResponse(0),
|
||||
_prepared(false)
|
||||
{
|
||||
if (session().getFeature("autoBind"))
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +97,9 @@ void ODBCStatementImpl::compileImpl()
|
||||
pDT = AnyCast<TypeInfo*>(dti);
|
||||
}catch (NotSupportedException&) { }
|
||||
|
||||
_pBinder = new Binder(_stmt, bind, pDT);
|
||||
std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
|
||||
|
||||
_pBinder = new Binder(_stmt, maxFieldSize, bind, pDT);
|
||||
|
||||
// This is a hack to conform to some ODBC drivers behavior (e.g. MS SQLServer) with
|
||||
// stored procedure calls: driver refuses to report the number of columns, unless all
|
||||
@@ -169,6 +164,16 @@ void ODBCStatementImpl::doPrepare()
|
||||
Extractions& extracts = extractions();
|
||||
Extractions::iterator it = extracts.begin();
|
||||
Extractions::iterator itEnd = extracts.end();
|
||||
|
||||
if (it != itEnd && (*it)->isBulk())
|
||||
{
|
||||
Poco::UInt32 limit = getExtractionLimit();
|
||||
if (limit == Limit::LIMIT_UNLIMITED)
|
||||
throw InvalidArgumentException("Bulk operation not allowed without limit.");
|
||||
checkError(SQLSetStmtAttr(_stmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) limit, 0),
|
||||
"SQLSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE)");
|
||||
}
|
||||
|
||||
for (std::size_t pos = 0; it != itEnd; ++it)
|
||||
{
|
||||
AbstractPrepare* pAP = (*it)->createPrepareObject(_preparations[curDataSet], pos);
|
||||
@@ -199,17 +204,17 @@ void ODBCStatementImpl::doBind(bool clear, bool reset)
|
||||
{
|
||||
Bindings::iterator it = binds.begin();
|
||||
Bindings::iterator itEnd = binds.end();
|
||||
for (std::size_t pos = 0; it != itEnd && (*it)->canBind(); ++it)
|
||||
{
|
||||
(*it)->bind(pos);
|
||||
pos += (*it)->numOfColumnsHandled();
|
||||
}
|
||||
|
||||
if (reset)
|
||||
{
|
||||
it = binds.begin();
|
||||
for (; it != itEnd && (*it)->canBind(); ++it)
|
||||
(*it)->reset();
|
||||
for (; it != itEnd; ++it) (*it)->reset();
|
||||
}
|
||||
|
||||
for (std::size_t pos = 0; it != itEnd && (*it)->canBind(); ++it)
|
||||
{
|
||||
(*it)->bind(pos);
|
||||
pos += (*it)->numOfColumnsHandled();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -292,13 +297,12 @@ bool ODBCStatementImpl::hasNext()
|
||||
if (!nextRowReady())
|
||||
{
|
||||
try { activateNextDataSet(); }
|
||||
catch (InvalidAccessException&)
|
||||
{ return false; }
|
||||
|
||||
try { checkError(SQLMoreResults(_stmt)); }
|
||||
catch (NoDataException&)
|
||||
{ return false; }
|
||||
|
||||
if (SQL_NO_DATA == SQLMoreResults(_stmt))
|
||||
return false;
|
||||
|
||||
addPreparation();
|
||||
doPrepare();
|
||||
fixupExtraction();
|
||||
@@ -324,14 +328,20 @@ void ODBCStatementImpl::makeStep()
|
||||
|
||||
Poco::UInt32 ODBCStatementImpl::next()
|
||||
{
|
||||
std::size_t count = 0;
|
||||
|
||||
if (nextRowReady())
|
||||
{
|
||||
Extractions& extracts = extractions();
|
||||
Extractions::iterator it = extracts.begin();
|
||||
Extractions::iterator itEnd = extracts.end();
|
||||
std::size_t prevCount = 0;
|
||||
for (std::size_t pos = 0; it != itEnd; ++it)
|
||||
{
|
||||
(*it)->extract(pos);
|
||||
count = (*it)->extract(pos);
|
||||
if (prevCount && count != prevCount)
|
||||
throw IllegalStateException("Different extraction counts");
|
||||
prevCount = count;
|
||||
pos += (*it)->numOfColumnsHandled();
|
||||
}
|
||||
_stepCalled = false;
|
||||
@@ -342,7 +352,9 @@ Poco::UInt32 ODBCStatementImpl::next()
|
||||
std::string("Iterator Error: trying to access the next value"));
|
||||
}
|
||||
|
||||
return 1u;
|
||||
return static_cast<Poco::UInt32>(count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -415,4 +427,15 @@ bool ODBCStatementImpl::isStoredProcedure() const
|
||||
}
|
||||
|
||||
|
||||
const MetaColumn& ODBCStatementImpl::metaColumn(Poco::UInt32 pos) const
|
||||
{
|
||||
std::size_t sz = _columnPtrs.size();
|
||||
|
||||
if (0 == sz || pos > sz - 1)
|
||||
throw InvalidAccessException(format("Invalid column number: %u", pos));
|
||||
|
||||
return *_columnPtrs[pos];
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::ODBC
|
||||
|
@@ -43,6 +43,9 @@ namespace Data {
|
||||
namespace ODBC {
|
||||
|
||||
|
||||
const std::size_t Preparation::INVALID_ROW = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
|
||||
Preparation::Preparation(const StatementHandle& rStmt,
|
||||
const std::string& statement,
|
||||
std::size_t maxFieldSize,
|
||||
@@ -68,118 +71,73 @@ Preparation::Preparation(const Preparation& other):
|
||||
|
||||
Preparation::~Preparation()
|
||||
{
|
||||
std::vector<SQLLEN*>::iterator itLen = _pLengths.begin();
|
||||
std::vector<SQLLEN*>::iterator itLenEnd = _pLengths.end();
|
||||
for (; itLen != itLenEnd; ++itLen) delete *itLen;
|
||||
freeMemory();
|
||||
}
|
||||
|
||||
std::vector<Poco::Any*>::iterator itVal = _pValues.begin();
|
||||
std::vector<Poco::Any*>::iterator itValEnd = _pValues.end();
|
||||
for (; itVal != itValEnd; ++itVal) delete *itVal;
|
||||
|
||||
void Preparation::freeMemory() const
|
||||
{
|
||||
IndexMap::iterator it = _varLengthArrays.begin();
|
||||
IndexMap::iterator end = _varLengthArrays.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
switch (it->second)
|
||||
{
|
||||
case DT_BOOL:
|
||||
deleteCachedArray<bool>(it->first);
|
||||
break;
|
||||
|
||||
case DT_CHAR:
|
||||
deleteCachedArray<char>(it->first);
|
||||
break;
|
||||
|
||||
case DT_CHAR_ARRAY:
|
||||
std::free(AnyCast<char>(&_values[it->first]));
|
||||
break;
|
||||
|
||||
case DT_DATE:
|
||||
deleteCachedArray<SQL_DATE_STRUCT>(it->first);
|
||||
break;
|
||||
|
||||
case DT_TIME:
|
||||
deleteCachedArray<SQL_TIME_STRUCT>(it->first);
|
||||
break;
|
||||
|
||||
case DT_DATETIME:
|
||||
deleteCachedArray<SQL_TIMESTAMP_STRUCT>(it->first);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::size_t Preparation::columns() const
|
||||
{
|
||||
if (_pValues.empty()) resize();
|
||||
return _pValues.size();
|
||||
if (_values.empty()) resize();
|
||||
return _values.size();
|
||||
}
|
||||
|
||||
|
||||
void Preparation::resize() const
|
||||
{
|
||||
SQLSMALLINT nCol = 0;
|
||||
if (!Utility::isError(SQLNumResultCols(_rStmt, &nCol)) &&
|
||||
0 != nCol)
|
||||
if (!Utility::isError(SQLNumResultCols(_rStmt, &nCol)) && 0 != nCol)
|
||||
{
|
||||
_pValues.resize(nCol, 0);
|
||||
_pLengths.resize(nCol, 0);
|
||||
_values.resize(nCol, 0);
|
||||
_lengths.resize(nCol, 0);
|
||||
_lenLengths.resize(nCol);
|
||||
if(_varLengthArrays.size())
|
||||
{
|
||||
freeMemory();
|
||||
_varLengthArrays.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Poco::Any& Preparation::operator [] (std::size_t pos)
|
||||
{
|
||||
poco_assert (pos >= 0 && pos < _pValues.size());
|
||||
|
||||
return *_pValues[pos];
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, const Poco::Any&)
|
||||
{
|
||||
prepareImpl(pos);
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, const Poco::DynamicAny&)
|
||||
{
|
||||
prepareImpl(pos);
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepareImpl(std::size_t pos)
|
||||
{
|
||||
ODBCColumn col(_rStmt, pos);
|
||||
|
||||
switch (col.type())
|
||||
{
|
||||
case MetaColumn::FDT_INT8:
|
||||
return preparePOD<Poco::Int8>(pos, SQL_C_STINYINT);
|
||||
|
||||
case MetaColumn::FDT_UINT8:
|
||||
return preparePOD<Poco::UInt8>(pos, SQL_C_UTINYINT);
|
||||
|
||||
case MetaColumn::FDT_INT16:
|
||||
return preparePOD<Poco::Int16>(pos, SQL_C_SSHORT);
|
||||
|
||||
case MetaColumn::FDT_UINT16:
|
||||
return preparePOD<Poco::UInt16>(pos, SQL_C_USHORT);
|
||||
|
||||
case MetaColumn::FDT_INT32:
|
||||
return preparePOD<Poco::Int32>(pos, SQL_C_SLONG);
|
||||
|
||||
case MetaColumn::FDT_UINT32:
|
||||
return preparePOD<Poco::UInt32>(pos, SQL_C_ULONG);
|
||||
|
||||
case MetaColumn::FDT_INT64:
|
||||
return preparePOD<Poco::Int64>(pos, SQL_C_SBIGINT);
|
||||
|
||||
case MetaColumn::FDT_UINT64:
|
||||
return preparePOD<Poco::UInt64>(pos, SQL_C_UBIGINT);
|
||||
|
||||
case MetaColumn::FDT_BOOL:
|
||||
return preparePOD<bool>(pos, SQL_C_BIT);
|
||||
|
||||
case MetaColumn::FDT_FLOAT:
|
||||
return preparePOD<float>(pos, SQL_C_FLOAT);
|
||||
|
||||
case MetaColumn::FDT_DOUBLE:
|
||||
return preparePOD<double>(pos, SQL_C_DOUBLE);
|
||||
|
||||
case MetaColumn::FDT_STRING:
|
||||
return prepareRaw<char>(pos, SQL_C_CHAR, maxDataSize(pos));
|
||||
|
||||
case MetaColumn::FDT_BLOB:
|
||||
return prepareRaw<char>(pos, SQL_C_BINARY, maxDataSize(pos));
|
||||
|
||||
case MetaColumn::FDT_DATE:
|
||||
return prepareRaw<Date>(pos, SQL_C_TYPE_DATE, sizeof(SQL_DATE_STRUCT));
|
||||
|
||||
case MetaColumn::FDT_TIME:
|
||||
return prepareRaw<Time>(pos, SQL_C_TYPE_TIME, sizeof(SQL_TIME_STRUCT));
|
||||
|
||||
case MetaColumn::FDT_TIMESTAMP:
|
||||
return prepareRaw<Time>(pos, SQL_C_TYPE_TIMESTAMP, sizeof(SQL_TIMESTAMP_STRUCT));
|
||||
|
||||
default:
|
||||
throw DataFormatException("Unsupported data type.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::size_t Preparation::maxDataSize(std::size_t pos) const
|
||||
{
|
||||
poco_assert (pos >= 0 && pos < _pValues.size());
|
||||
poco_assert_dbg (pos < _values.size());
|
||||
|
||||
std::size_t sz = 0;
|
||||
std::size_t maxsz = getMaxFieldSize();
|
||||
@@ -195,4 +153,30 @@ std::size_t Preparation::maxDataSize(std::size_t pos) const
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepareVariableLenArray(std::size_t pos, SQLSMALLINT valueType, std::size_t size, std::size_t length, DataType dt)
|
||||
{
|
||||
poco_assert_dbg (DE_BOUND == _dataExtraction);
|
||||
poco_assert_dbg (pos < _values.size());
|
||||
poco_assert_dbg (pos < _lengths.size());
|
||||
poco_assert_dbg (pos < _lenLengths.size());
|
||||
|
||||
char* pArray = (char*) std::calloc(length * size, sizeof(char));
|
||||
|
||||
_values[pos] = Any(pArray);
|
||||
_lengths[pos] = 0;
|
||||
_lenLengths[pos].resize(length);
|
||||
_varLengthArrays.insert(IndexMap::value_type(pos, dt));
|
||||
|
||||
if (Utility::isError(SQLBindCol(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
valueType,
|
||||
(SQLPOINTER) pArray,
|
||||
(SQLINTEGER) size,
|
||||
&_lenLengths[pos][0])))
|
||||
{
|
||||
throw StatementException(_rStmt, "SQLBindCol()");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::ODBC
|
||||
|
@@ -138,6 +138,17 @@ void Utility::dateTimeSync(Poco::DateTime& dt, const SQL_TIMESTAMP_STRUCT& ts)
|
||||
}
|
||||
|
||||
|
||||
void Utility::dateTimeSync(std::vector<Poco::DateTime>& dt, const std::vector<SQL_TIMESTAMP_STRUCT>& ts)
|
||||
{
|
||||
std::size_t size = ts.size();
|
||||
if (dt.size() != size) dt.resize(size);
|
||||
std::vector<Poco::DateTime>::iterator dIt = dt.begin();
|
||||
std::vector<SQL_TIMESTAMP_STRUCT>::const_iterator it = ts.begin();
|
||||
std::vector<SQL_TIMESTAMP_STRUCT>::const_iterator end = ts.end();
|
||||
for (; it != end; ++it, ++dIt) dateTimeSync(*dIt, *it);
|
||||
}
|
||||
|
||||
|
||||
void Utility::dateSync(SQL_DATE_STRUCT& ds, const Date& d)
|
||||
{
|
||||
ds.year = d.year();
|
||||
@@ -146,6 +157,17 @@ void Utility::dateSync(SQL_DATE_STRUCT& ds, const Date& d)
|
||||
}
|
||||
|
||||
|
||||
void Utility::dateSync(std::vector<SQL_DATE_STRUCT>& ds, const std::vector<Date>& d)
|
||||
{
|
||||
std::size_t size = d.size();
|
||||
if (ds.size() != size) ds.resize(size);
|
||||
std::vector<SQL_DATE_STRUCT>::iterator dIt = ds.begin();
|
||||
std::vector<Date>::const_iterator it = d.begin();
|
||||
std::vector<Date>::const_iterator end = d.end();
|
||||
for (; it != end; ++it, ++dIt) dateSync(*dIt, *it);
|
||||
}
|
||||
|
||||
|
||||
void Utility::timeSync(SQL_TIME_STRUCT& ts, const Time& t)
|
||||
{
|
||||
ts.hour = t.hour();
|
||||
@@ -154,6 +176,17 @@ void Utility::timeSync(SQL_TIME_STRUCT& ts, const Time& t)
|
||||
}
|
||||
|
||||
|
||||
void Utility::timeSync(std::vector<SQL_TIME_STRUCT>& ts, const std::vector<Time>& t)
|
||||
{
|
||||
std::size_t size = t.size();
|
||||
if (ts.size() != size) ts.resize(size);
|
||||
std::vector<SQL_TIME_STRUCT>::iterator tIt = ts.begin();
|
||||
std::vector<Time>::const_iterator it = t.begin();
|
||||
std::vector<Time>::const_iterator end = t.end();
|
||||
for (; it != end; ++it, ++tIt) timeSync(*tIt, *it);
|
||||
}
|
||||
|
||||
|
||||
void Utility::dateTimeSync(SQL_TIMESTAMP_STRUCT& ts, const Poco::DateTime& dt)
|
||||
{
|
||||
ts.year = dt.year();
|
||||
@@ -162,7 +195,42 @@ void Utility::dateTimeSync(SQL_TIMESTAMP_STRUCT& ts, const Poco::DateTime& dt)
|
||||
ts.hour = dt.hour();
|
||||
ts.minute = dt.minute();
|
||||
ts.second = dt.second();
|
||||
ts.fraction = (dt.millisecond() * 1000000) + (dt.microsecond() * 1000);
|
||||
// Fraction support is limited to milliseconds due to MS SQL Server limitation
|
||||
// see http://support.microsoft.com/kb/263872
|
||||
ts.fraction = (dt.millisecond() * 1000000);// + (dt.microsecond() * 1000);
|
||||
}
|
||||
|
||||
|
||||
void Utility::dateTimeSync(std::vector<SQL_TIMESTAMP_STRUCT>& ts, const std::vector<Poco::DateTime>& dt)
|
||||
{
|
||||
std::size_t size = dt.size();
|
||||
if (ts.size() != size) ts.resize(size);
|
||||
std::vector<SQL_TIMESTAMP_STRUCT>::iterator tIt = ts.begin();
|
||||
std::vector<Poco::DateTime>::const_iterator it = dt.begin();
|
||||
std::vector<Poco::DateTime>::const_iterator end = dt.end();
|
||||
for (; it != end; ++it, ++tIt) dateTimeSync(*tIt, *it);
|
||||
}
|
||||
|
||||
|
||||
void Utility::dateSync(std::vector<Date>& d, const std::vector<SQL_DATE_STRUCT>& ds)
|
||||
{
|
||||
std::size_t size = ds.size();
|
||||
if (d.size() != size) d.resize(size);
|
||||
std::vector<Date>::iterator dIt = d.begin();
|
||||
std::vector<SQL_DATE_STRUCT>::const_iterator it = ds.begin();
|
||||
std::vector<SQL_DATE_STRUCT>::const_iterator end = ds.end();
|
||||
for (; it != end; ++it, ++dIt) dateSync(*dIt, *it);
|
||||
}
|
||||
|
||||
|
||||
void Utility::timeSync(std::vector<Time>& t, const std::vector<SQL_TIME_STRUCT>& ts)
|
||||
{
|
||||
std::size_t size = ts.size();
|
||||
if (t.size() != size) t.resize(size);
|
||||
std::vector<Time>::iterator dIt = t.begin();
|
||||
std::vector<SQL_TIME_STRUCT>::const_iterator it = ts.begin();
|
||||
std::vector<SQL_TIME_STRUCT>::const_iterator end = ts.end();
|
||||
for (; it != end; ++it, ++dIt) timeSync(*dIt, *it);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -571,7 +571,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, testBulk);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testSetSimple);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testSetComplex);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testSetComplexUnique);
|
||||
|
@@ -391,7 +391,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, testBulk);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testSetSimple);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testSetComplex);
|
||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testSetComplexUnique);
|
||||
|
@@ -146,7 +146,7 @@ void ODBCOracleTest::testBarebone()
|
||||
"(First VARCHAR(30),"
|
||||
"Second INTEGER,"
|
||||
"Third NUMBER)";
|
||||
/*
|
||||
|
||||
*_pSession << "CREATE OR REPLACE "
|
||||
"PROCEDURE multiResultsProcedure(ret1 OUT SYS_REFCURSOR, "
|
||||
"ret2 OUT SYS_REFCURSOR,"
|
||||
@@ -185,7 +185,7 @@ void ODBCOracleTest::testBarebone()
|
||||
SQLExecutor::DE_BOUND,
|
||||
MULTI_INSERT,
|
||||
MULTI_SELECT);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -224,6 +224,19 @@ void ODBCOracleTest::testBLOB()
|
||||
}
|
||||
|
||||
|
||||
void ODBCOracleTest::testBulk()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
_pSession->setFeature("autoBind", true);
|
||||
_pSession->setFeature("autoExtract", true);
|
||||
recreateMiscTable();
|
||||
_pExecutor->doBulkNoBool(100);
|
||||
recreateMiscTable();
|
||||
_pExecutor->doBulkPerformance(1000);
|
||||
}
|
||||
|
||||
|
||||
void ODBCOracleTest::testNull()
|
||||
{
|
||||
// test for NOT NULL violation exception
|
||||
@@ -739,6 +752,22 @@ void ODBCOracleTest::recreateNullsTable(const std::string& notNull)
|
||||
}
|
||||
|
||||
|
||||
void ODBCOracleTest::recreateMiscTable()
|
||||
{
|
||||
dropObject("TABLE", "MiscTest");
|
||||
try
|
||||
{
|
||||
session() << "CREATE TABLE MiscTest "
|
||||
"(First VARCHAR(30),"
|
||||
"Second BLOB,"
|
||||
"Third INTEGER,"
|
||||
"Fourth NUMBER,"
|
||||
"Fifth TIMESTAMP)", now;
|
||||
} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateMiscTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateMiscTable()"); }
|
||||
}
|
||||
|
||||
|
||||
CppUnit::Test* ODBCOracleTest::suite()
|
||||
{
|
||||
if (_pSession = init(_driver, _dsn, _uid, _pwd, _connectString))
|
||||
@@ -771,7 +800,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, testBulk);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testSetSimple);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testSetComplex);
|
||||
CppUnit_addTest(pSuite, ODBCOracleTest, testSetComplexUnique);
|
||||
|
@@ -56,6 +56,7 @@ public:
|
||||
void testBareboneODBC();
|
||||
|
||||
void testBLOB();
|
||||
void testBulk();
|
||||
|
||||
void testMultipleResults();
|
||||
|
||||
@@ -84,6 +85,7 @@ private:
|
||||
void recreateVectorsTable();
|
||||
void recreateAnysTable();
|
||||
void recreateNullsTable(const std::string& notNull = "");
|
||||
void recreateMiscTable();
|
||||
|
||||
static ODBCTest::SessionPtr _pSession;
|
||||
static ODBCTest::ExecPtr _pExecutor;
|
||||
|
@@ -346,6 +346,19 @@ void ODBCPostgreSQLTest::testStoredFunctionDynamicAny()
|
||||
}
|
||||
|
||||
|
||||
void ODBCPostgreSQLTest::testBulk()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
_pSession->setFeature("autoBind", true);
|
||||
_pSession->setFeature("autoExtract", true);
|
||||
recreateMiscTable();
|
||||
_pExecutor->doBulkStringIntFloat(100);
|
||||
recreateMiscTable();
|
||||
_pExecutor->doBulkPerformance(1000);
|
||||
}
|
||||
|
||||
|
||||
void ODBCPostgreSQLTest::configurePLPgSQL()
|
||||
{
|
||||
try
|
||||
@@ -518,6 +531,24 @@ void ODBCPostgreSQLTest::recreateBoolTable()
|
||||
}
|
||||
|
||||
|
||||
void ODBCPostgreSQLTest::recreateMiscTable()
|
||||
{
|
||||
dropObject("TABLE", "MiscTest");
|
||||
try
|
||||
{
|
||||
// pgSQL fails with BLOB bulk operations
|
||||
// Mammoth does not bind columns properly
|
||||
session() << "CREATE TABLE MiscTest "
|
||||
"(First VARCHAR(30),"
|
||||
//"Second BYTEA,"
|
||||
"Third INTEGER,"
|
||||
"Fourth FLOAT,"
|
||||
"Fifth TIMESTAMP)", now;
|
||||
} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateMiscTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateMiscTable()"); }
|
||||
}
|
||||
|
||||
|
||||
CppUnit::Test* ODBCPostgreSQLTest::suite()
|
||||
{
|
||||
if (_pSession = init(_driver, _dsn, _uid, _pwd, _connectString))
|
||||
@@ -550,7 +581,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, testBulk);
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSetSimple);
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSetComplex);
|
||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSetComplexUnique);
|
||||
|
@@ -64,6 +64,7 @@ public:
|
||||
void testBareboneODBC();
|
||||
|
||||
void testBLOB();
|
||||
void testBulk();
|
||||
|
||||
void testStoredFunction();
|
||||
void testStoredFunctionAny();
|
||||
@@ -86,6 +87,7 @@ private:
|
||||
void recreateAnysTable();
|
||||
void recreateNullsTable(const std::string& notNull="");
|
||||
void recreateBoolTable();
|
||||
void recreateMiscTable();
|
||||
|
||||
void configurePLPgSQL();
|
||||
/// Configures PL/pgSQL in the database. A reasonable defaults
|
||||
|
@@ -112,9 +112,8 @@ void ODBCSQLServerTest::testBareboneODBC()
|
||||
"Fifth FLOAT,"
|
||||
"Sixth DATETIME)";
|
||||
|
||||
//TODO: auto binding fails at SQLExecute() ("String data, right truncated")
|
||||
//executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_MANUAL);
|
||||
//executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
|
||||
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_MANUAL);
|
||||
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
|
||||
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
|
||||
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
|
||||
|
||||
@@ -611,6 +610,23 @@ void ODBCSQLServerTest::recreateBoolTable()
|
||||
}
|
||||
|
||||
|
||||
void ODBCSQLServerTest::recreateMiscTable()
|
||||
{
|
||||
dropObject("TABLE", "MiscTest");
|
||||
try
|
||||
{
|
||||
session() << "CREATE TABLE MiscTest "
|
||||
"(First VARCHAR(30),"
|
||||
"Second VARBINARY(30),"
|
||||
"Third INTEGER,"
|
||||
"Fourth FLOAT,"
|
||||
"Fifth DATETIME,"
|
||||
"Sixth BIT)", now;
|
||||
} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateMiscTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateMiscTable()"); }
|
||||
}
|
||||
|
||||
|
||||
CppUnit::Test* ODBCSQLServerTest::suite()
|
||||
{
|
||||
if (_pSession = init(_driver, _dsn, _uid, _pwd, _connectString, _db))
|
||||
@@ -643,7 +659,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, testBulk);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSetSimple);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSetComplex);
|
||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSetComplexUnique);
|
||||
|
@@ -89,6 +89,7 @@ private:
|
||||
void recreateAnysTable();
|
||||
void recreateNullsTable(const std::string& notNull = "");
|
||||
void recreateBoolTable();
|
||||
void recreateMiscTable();
|
||||
|
||||
static SessionPtr _pSession;
|
||||
static ExecPtr _pExecutor;
|
||||
|
@@ -141,6 +141,19 @@ void ODBCSQLiteTest::testNull()
|
||||
}
|
||||
|
||||
|
||||
void ODBCSQLiteTest::testBulk()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
_pSession->setFeature("autoBind", true);
|
||||
_pSession->setFeature("autoExtract", true);
|
||||
recreateMiscTable();
|
||||
_pExecutor->doBulkStringIntFloat(100);
|
||||
recreateMiscTable();
|
||||
_pExecutor->doBulkPerformance(1000);
|
||||
}
|
||||
|
||||
|
||||
void ODBCSQLiteTest::dropObject(const std::string& type, const std::string& name)
|
||||
{
|
||||
try
|
||||
@@ -262,6 +275,23 @@ void ODBCSQLiteTest::recreateNullsTable(const std::string& notNull)
|
||||
}
|
||||
|
||||
|
||||
void ODBCSQLiteTest::recreateMiscTable()
|
||||
{
|
||||
dropObject("TABLE", "MiscTest");
|
||||
try
|
||||
{
|
||||
// SQLite fails with BLOB bulk operations
|
||||
session() << "CREATE TABLE MiscTest "
|
||||
"(First VARCHAR(30),"
|
||||
//"Second BLOB,"
|
||||
"Third INTEGER,"
|
||||
"Fourth REAL,"
|
||||
"Fifth DATETIME)", now;
|
||||
} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateMiscTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateMiscTable()"); }
|
||||
}
|
||||
|
||||
|
||||
CppUnit::Test* ODBCSQLiteTest::suite()
|
||||
{
|
||||
if (_pSession = init(_driver, _dsn, _uid, _pwd, _connectString))
|
||||
@@ -294,7 +324,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, testBulk);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testSetSimple);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testSetComplex);
|
||||
CppUnit_addTest(pSuite, ODBCSQLiteTest, testSetComplexUnique);
|
||||
|
@@ -54,6 +54,7 @@ public:
|
||||
|
||||
void testBareboneODBC();
|
||||
void testNull();
|
||||
void testBulk();
|
||||
|
||||
static CppUnit::Test* suite();
|
||||
|
||||
@@ -69,6 +70,7 @@ private:
|
||||
void recreateVectorsTable();
|
||||
void recreateAnysTable();
|
||||
void recreateNullsTable(const std::string& notNull = "");
|
||||
void recreateMiscTable();
|
||||
|
||||
static ODBCTest::SessionPtr _pSession;
|
||||
static ODBCTest::ExecPtr _pExecutor;
|
||||
|
@@ -407,27 +407,16 @@ void ODBCTest::testPrepare()
|
||||
}
|
||||
|
||||
|
||||
void ODBCTest::testStep()
|
||||
void ODBCTest::testBulk()
|
||||
{
|
||||
if (!_pSession) fail ("Test not available.");
|
||||
|
||||
for (int i = 0; i < 8;)
|
||||
{
|
||||
recreateIntsTable();
|
||||
_pSession->setFeature("autoBind", bindValue(i));
|
||||
_pSession->setFeature("autoExtract", bindValue(i+1));
|
||||
std::string mode = bindValue(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;
|
||||
}
|
||||
_pSession->setFeature("autoBind", true);
|
||||
_pSession->setFeature("autoExtract", true);
|
||||
recreateMiscTable();
|
||||
_pExecutor->doBulk(100);
|
||||
recreateMiscTable();
|
||||
_pExecutor->doBulkPerformance(1000);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -91,7 +91,7 @@ public:
|
||||
virtual void testLimitPrepare();
|
||||
virtual void testLimitZero();
|
||||
virtual void testPrepare();
|
||||
virtual void testStep();
|
||||
virtual void testBulk();
|
||||
|
||||
virtual void testSetSimple();
|
||||
virtual void testSetComplex();
|
||||
@@ -165,6 +165,7 @@ protected:
|
||||
virtual void recreateAnysTable() { /* no-op */ };
|
||||
virtual void recreateNullsTable(const std::string& notNull="") { /* no-op */ };
|
||||
virtual void recreateBoolTable() { /* no-op */ };
|
||||
virtual void recreateMiscTable() { /* no-op */ };
|
||||
|
||||
static SessionPtr init(const std::string& driver,
|
||||
std::string& dsn,
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -140,7 +140,10 @@ public:
|
||||
void limitPrepare();
|
||||
void limitZero();
|
||||
void prepare();
|
||||
void doStep(Poco::UInt32 dataSize, Poco::UInt32 stepSize);
|
||||
void doBulk(Poco::UInt32 size);
|
||||
void doBulkPerformance(Poco::UInt32 size);
|
||||
void doBulkNoBool(Poco::UInt32 size);
|
||||
void doBulkStringIntFloat(Poco::UInt32 size);
|
||||
|
||||
void setSimple();
|
||||
void setComplex();
|
||||
@@ -194,8 +197,17 @@ private:
|
||||
static const std::string MULTI_INSERT;
|
||||
static const std::string MULTI_SELECT;
|
||||
|
||||
Poco::Data::Session& session();
|
||||
|
||||
Poco::Data::Session* _pSession;
|
||||
};
|
||||
|
||||
|
||||
inline Poco::Data::Session& SQLExecutor::session()
|
||||
{
|
||||
poco_check_ptr (_pSession);
|
||||
return *_pSession;
|
||||
}
|
||||
|
||||
|
||||
#endif // SQLExecutor_INCLUDED
|
||||
|
@@ -135,7 +135,7 @@ public:
|
||||
bool extract(std::size_t pos, Poco::DynamicAny& val);
|
||||
/// Extracts a DynamicAny.
|
||||
|
||||
bool isNull(std::size_t pos);
|
||||
bool isNull(std::size_t pos, std::size_t row = -1);
|
||||
/// Returns true if the current row value at pos column is null.
|
||||
/// Because of the loss of information about null-ness of the
|
||||
/// underlying database values due to the nature of SQLite engine,
|
||||
@@ -148,6 +148,8 @@ public:
|
||||
/// bool value in the pair is true if the null indicator has
|
||||
/// been set and the second bool value in the pair is true if
|
||||
/// the column is actually null.
|
||||
/// The row argument, needed for connectors with bulk capabilities,
|
||||
/// is ignored in this implementation.
|
||||
|
||||
void reset();
|
||||
/// Clears the cached nulls indicator vector.
|
||||
|
@@ -251,7 +251,7 @@ bool Extractor::extract(std::size_t pos, Poco::DynamicAny& val)
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::isNull(std::size_t pos)
|
||||
bool Extractor::isNull(std::size_t pos, std::size_t)
|
||||
{
|
||||
if (pos >= _nulls.size())
|
||||
_nulls.resize(pos + 1);
|
||||
|
@@ -33,12 +33,12 @@
|
||||
#include "SQLiteTest.h"
|
||||
#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"
|
||||
#include "Poco/Data/SessionFactory.h"
|
||||
#include "Poco/Data/SQLite/Connector.h"
|
||||
#include "Poco/Data/SQLite/SQLiteException.h"
|
||||
#include "Poco/Data/TypeHandler.h"
|
||||
@@ -117,7 +117,7 @@ public:
|
||||
pBinder->bind(pos++, obj.age, dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, const Person& obj, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, Person& obj, AbstractPreparation* pPrepare)
|
||||
{
|
||||
// the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))
|
||||
poco_assert_dbg (pPrepare != 0);
|
||||
|
@@ -41,40 +41,29 @@
|
||||
|
||||
|
||||
#include "Poco/Data/Data.h"
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
class DateTime;
|
||||
class Any;
|
||||
class DynamicAny;
|
||||
|
||||
|
||||
namespace Data {
|
||||
|
||||
|
||||
class Date;
|
||||
class Time;
|
||||
class BLOB;
|
||||
|
||||
|
||||
enum NullData
|
||||
{
|
||||
NULL_GENERIC = 0,
|
||||
NULL_INT8,
|
||||
NULL_UINT8,
|
||||
NULL_INT16,
|
||||
NULL_UINT16,
|
||||
NULL_INT32,
|
||||
NULL_UINT32,
|
||||
NULL_INT64,
|
||||
NULL_UINT64,
|
||||
NULL_BOOL,
|
||||
NULL_FLOAT,
|
||||
NULL_DOUBLE,
|
||||
NULL_STRING,
|
||||
NULL_BLOB,
|
||||
NULL_DATE,
|
||||
NULL_TIME,
|
||||
NULL_TIMESTAMP
|
||||
NULL_GENERIC = 0
|
||||
};
|
||||
|
||||
|
||||
@@ -82,8 +71,7 @@ static const NullData null = NULL_GENERIC;
|
||||
|
||||
|
||||
class Data_API AbstractBinder
|
||||
/// Interface for Binding data types to placeholders. The default placeholder format
|
||||
/// in the SQL query is ":name".
|
||||
/// Interface for Binding data types to placeholders.
|
||||
{
|
||||
public:
|
||||
enum Direction
|
||||
@@ -103,65 +91,122 @@ public:
|
||||
virtual void bind(std::size_t pos, const Poco::Int8& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds an Int8.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir = PD_IN);
|
||||
/// Binds an Int8 vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const Poco::UInt8& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds an UInt8.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir = PD_IN);
|
||||
/// Binds an UInt8 vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const Poco::Int16& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds an Int16.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir = PD_IN);
|
||||
/// Binds an Int16 vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const Poco::UInt16& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds an UInt16.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir = PD_IN);
|
||||
/// Binds an UInt16 vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const Poco::Int32& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds an Int32.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir = PD_IN);
|
||||
/// Binds an Int32 vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const Poco::UInt32& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds an UInt32.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir = PD_IN);
|
||||
/// Binds an UInt32 vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const Poco::Int64& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds an Int64.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir = PD_IN);
|
||||
/// Binds an Int64 vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const Poco::UInt64& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds an UInt64.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir = PD_IN);
|
||||
/// Binds an UInt64 vector.
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
virtual void bind(std::size_t pos, const long& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds a long.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<long>& val, Direction dir = PD_IN);
|
||||
/// Binds a long vector.
|
||||
#endif
|
||||
|
||||
virtual void bind(std::size_t pos, const bool& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds a boolean.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<bool>& val, Direction dir = PD_IN);
|
||||
/// Binds a boolean vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const float& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds a float.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<float>& val, Direction dir = PD_IN);
|
||||
/// Binds a float vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const double& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds a double.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<double>& val, Direction dir = PD_IN);
|
||||
/// Binds a double vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const char& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds a single character.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<char>& val, Direction dir = PD_IN);
|
||||
/// Binds a character vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const char* const& pVal, Direction dir = PD_IN) = 0;
|
||||
/// Binds a const char ptr.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::string& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds a string.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<std::string>& val, Direction dir = PD_IN);
|
||||
/// Binds a string vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const BLOB& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds a BLOB.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<BLOB>& val, Direction dir = PD_IN);
|
||||
/// Binds a BLOB vector.
|
||||
|
||||
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 std::vector<DateTime>& val, Direction dir = PD_IN);
|
||||
/// Binds a DateTime vector.
|
||||
|
||||
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 std::vector<Date>& val, Direction dir = PD_IN);
|
||||
/// Binds a Date vector.
|
||||
|
||||
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 std::vector<Time>& val, Direction dir = PD_IN);
|
||||
/// Binds a Time vector.
|
||||
|
||||
virtual void bind(std::size_t pos, const NullData& val, Direction dir = PD_IN) = 0;
|
||||
/// Binds a null.
|
||||
|
||||
virtual void bind(std::size_t pos, const std::vector<NullData>& val, Direction dir = PD_IN);
|
||||
/// Binds a null vector.
|
||||
|
||||
void bind(std::size_t pos, const Any& val, Direction dir = PD_IN);
|
||||
/// Binds an Any.
|
||||
|
||||
|
@@ -64,7 +64,7 @@ public:
|
||||
PD_IN_OUT = AbstractBinder::PD_IN_OUT
|
||||
};
|
||||
|
||||
AbstractBinding(const std::string& name = "", Direction direction = PD_IN);
|
||||
AbstractBinding(const std::string& name = "", Direction direction = PD_IN, Poco::UInt32 bulkSize = 0);
|
||||
/// Creates the AbstractBinding.
|
||||
|
||||
virtual ~AbstractBinding();
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
/// Returns the number of rows that the binding handles.
|
||||
///
|
||||
/// The trivial case will be one single row but
|
||||
/// for collection data types (ie vector) it can be larger.
|
||||
/// for collection data types it can be larger.
|
||||
|
||||
virtual bool canBind() const = 0;
|
||||
/// Returns true if we have enough data to bind
|
||||
@@ -103,10 +103,17 @@ public:
|
||||
const std::string& name() const;
|
||||
/// Returns the name for this binding.
|
||||
|
||||
bool isBulk() const;
|
||||
/// Returns true if extraction is bulk.
|
||||
|
||||
Poco::UInt32 bulkSize() const;
|
||||
/// Returns the size of the bulk binding.
|
||||
|
||||
private:
|
||||
AbstractBinder* _pBinder;
|
||||
std::string _name;
|
||||
Direction _direction;
|
||||
Poco::UInt32 _bulkSize;
|
||||
};
|
||||
|
||||
|
||||
@@ -135,6 +142,18 @@ inline AbstractBinder::Direction AbstractBinding::getDirection() const
|
||||
}
|
||||
|
||||
|
||||
inline bool AbstractBinding::isBulk() const
|
||||
{
|
||||
return _bulkSize > 0;
|
||||
}
|
||||
|
||||
|
||||
inline Poco::UInt32 AbstractBinding::bulkSize() const
|
||||
{
|
||||
return _bulkSize;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
|
@@ -63,7 +63,7 @@ class Data_API AbstractExtraction: public Poco::RefCountedObject
|
||||
{
|
||||
public:
|
||||
AbstractExtraction(Poco::UInt32 limit = Limit::LIMIT_UNLIMITED,
|
||||
Poco::UInt32 position = 0);
|
||||
Poco::UInt32 position = 0, bool bulk = false);
|
||||
/// Creates the AbstractExtraction. A limit value equal to EXTRACT_UNLIMITED (0xffffffffu)
|
||||
/// means that we extract as much data as possible during one execute.
|
||||
/// Otherwise the limit value is used to partition data extracting to a limited amount of rows.
|
||||
@@ -95,13 +95,14 @@ public:
|
||||
virtual std::size_t numOfRowsAllowed() const = 0;
|
||||
/// Returns the upper limit on number of rows that the extraction will handle.
|
||||
|
||||
virtual void extract(std::size_t pos) = 0;
|
||||
virtual std::size_t extract(std::size_t pos) = 0;
|
||||
/// Extracts a value from the param, starting at the given column position.
|
||||
/// Returns the number of rows extracted.
|
||||
|
||||
virtual void reset() = 0;
|
||||
/// Resets the extractor so that it can be re-used.
|
||||
|
||||
virtual AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const = 0;
|
||||
virtual AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) = 0;
|
||||
/// Creates a Prepare object for the extracting object
|
||||
|
||||
void setLimit(Poco::UInt32 limit);
|
||||
@@ -118,10 +119,14 @@ public:
|
||||
/// null values and be able to later provide information about them.
|
||||
/// Here, this function throws NotImplementedException.
|
||||
|
||||
bool isBulk() const;
|
||||
/// Returns true if this is bulk extraction.
|
||||
|
||||
private:
|
||||
AbstractExtractor* _pExtractor;
|
||||
Poco::UInt32 _limit;
|
||||
Poco::UInt32 _position;
|
||||
bool _bulk;
|
||||
};
|
||||
|
||||
|
||||
@@ -169,6 +174,12 @@ inline Poco::UInt32 AbstractExtraction::position() const
|
||||
}
|
||||
|
||||
|
||||
inline bool AbstractExtraction::isBulk() const
|
||||
{
|
||||
return _bulk;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
|
@@ -41,6 +41,7 @@
|
||||
|
||||
|
||||
#include "Poco/Data/Data.h"
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
@@ -74,67 +75,127 @@ public:
|
||||
virtual bool extract(std::size_t pos, Poco::Int8& val) = 0;
|
||||
/// Extracts an Int8. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<Poco::Int8>& val);
|
||||
/// Extracts an Int8 vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, Poco::UInt8& val) = 0;
|
||||
/// Extracts an UInt8. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<Poco::UInt8>& val);
|
||||
/// Extracts an UInt8vector .
|
||||
|
||||
virtual bool extract(std::size_t pos, Poco::Int16& val) = 0;
|
||||
/// Extracts an Int16. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<Poco::Int16>& val);
|
||||
/// Extracts an Int16 vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, Poco::UInt16& val) = 0;
|
||||
/// Extracts an UInt16. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<Poco::UInt16>& val);
|
||||
/// Extracts an UInt16 vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, Poco::Int32& val) = 0;
|
||||
/// Extracts an Int32. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<Poco::Int32>& val);
|
||||
/// Extracts an Int32 vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, Poco::UInt32& val) = 0;
|
||||
/// Extracts an UInt32. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<Poco::UInt32>& val);
|
||||
/// Extracts an UInt32 vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, Poco::Int64& val) = 0;
|
||||
/// Extracts an Int64. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<Poco::Int64>& val);
|
||||
/// Extracts an Int64 vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, Poco::UInt64& val) = 0;
|
||||
/// Extracts an UInt64. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<Poco::UInt64>& val);
|
||||
/// Extracts an UInt64 vector.
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
virtual bool extract(std::size_t pos, long& val) = 0;
|
||||
/// Extracts a long. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<long>& val);
|
||||
/// Extracts a long vector.
|
||||
#endif
|
||||
|
||||
virtual bool extract(std::size_t pos, bool& val) = 0;
|
||||
/// Extracts a boolean. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<bool>& val);
|
||||
/// Extracts a boolean vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, float& val) = 0;
|
||||
/// Extracts a float. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<float>& val);
|
||||
/// Extracts a float vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, double& val) = 0;
|
||||
/// Extracts a double. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<double>& val);
|
||||
/// Extracts a double vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, char& val) = 0;
|
||||
/// Extracts a single character. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<char>& val);
|
||||
/// Extracts a character vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::string& val) = 0;
|
||||
/// Extracts a string. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<std::string>& val);
|
||||
/// Extracts a string vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, BLOB& val) = 0;
|
||||
/// Extracts a BLOB. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<BLOB>& val);
|
||||
/// Extracts a BLOB vector.
|
||||
|
||||
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, std::vector<DateTime>& val);
|
||||
/// Extracts a DateTime vector.
|
||||
|
||||
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, std::vector<Date>& val);
|
||||
/// Extracts a Date vector.
|
||||
|
||||
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, std::vector<Time>& val);
|
||||
/// Extracts a Time vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, Any& val) = 0;
|
||||
/// Extracts an Any. Returns false if null was received.
|
||||
|
||||
virtual bool extract(std::size_t pos, std::vector<Any>& val);
|
||||
/// Extracts an Any vector.
|
||||
|
||||
virtual bool extract(std::size_t pos, DynamicAny& val) = 0;
|
||||
/// Extracts a DynamicAny. Returns false if null was received.
|
||||
|
||||
virtual bool isNull(std::size_t pos) = 0;
|
||||
/// Returns true if the current row value at pos column is null.
|
||||
virtual bool extract(std::size_t pos, std::vector<DynamicAny>& val);
|
||||
/// Extracts a DynamicAny vector.
|
||||
|
||||
virtual bool isNull(std::size_t col, std::size_t row = -1) = 0;
|
||||
/// Returns true if the value at [col,row] position is null.
|
||||
|
||||
virtual void reset();
|
||||
/// Resets any information internally cached by the extractor.
|
||||
|
@@ -42,6 +42,7 @@
|
||||
|
||||
#include "Poco/Data/Data.h"
|
||||
#include "Poco/RefCountedObject.h"
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
@@ -64,80 +65,171 @@ class BLOB;
|
||||
class Data_API AbstractPreparation: public Poco::RefCountedObject
|
||||
/// Interface used for database preparation where we first have to register all data types (and memory output locations)
|
||||
/// before extracting data, i.e. extract works as two-pase extract: first we call prepare once, then extract n-times.
|
||||
/// Only some database connectors will need to implement this interface.
|
||||
/// Note that the values in the interface serve only the purpose of type distinction.
|
||||
/// There are cases (bulk operations using std::vector storage) when extract is called only once.
|
||||
/// The value passed to a prepare() call is not be used by the prepare, serving only as an indication of the data type
|
||||
/// being prepared.
|
||||
/// Implementing this interface is not mandatory for a connector. Connectors that only extract data after SQL execution
|
||||
/// (e.g. SQLite) do not need this functionality at all.
|
||||
{
|
||||
public:
|
||||
AbstractPreparation();
|
||||
AbstractPreparation(Poco::UInt32 length = 1u);
|
||||
/// Creates the AbstractPreparation.
|
||||
|
||||
virtual ~AbstractPreparation();
|
||||
/// Destroys the AbstractPreparation.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::Int8) = 0;
|
||||
virtual void prepare(std::size_t pos, Poco::Int8&) = 0;
|
||||
/// Prepares an Int8.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::UInt8) = 0;
|
||||
virtual void prepare(std::size_t pos, std::vector<Poco::Int8>& val);
|
||||
/// Prepares an Int8 vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::UInt8&) = 0;
|
||||
/// Prepares an UInt8.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::Int16) = 0;
|
||||
virtual void prepare(std::size_t pos, std::vector<Poco::UInt8>& val);
|
||||
/// Prepares an UInt8 vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::Int16&) = 0;
|
||||
/// Prepares an Int16.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::UInt16) = 0;
|
||||
virtual void prepare(std::size_t pos, std::vector<Poco::Int16>& val);
|
||||
/// Prepares an Int16 vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::UInt16&) = 0;
|
||||
/// Prepares an UInt16.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::Int32) = 0;
|
||||
virtual void prepare(std::size_t pos, std::vector<Poco::UInt16>& val);
|
||||
/// Prepares an UInt16 vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::Int32&) = 0;
|
||||
/// Prepares an Int32.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::UInt32) = 0;
|
||||
virtual void prepare(std::size_t pos, std::vector<Poco::Int32>& val);
|
||||
/// Prepares an Int32 vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::UInt32&) = 0;
|
||||
/// Prepares an UInt32.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::Int64) = 0;
|
||||
virtual void prepare(std::size_t pos, std::vector<Poco::UInt32>& val);
|
||||
/// Prepares an UInt32 vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::Int64&) = 0;
|
||||
/// Prepares an Int64.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::UInt64) = 0;
|
||||
virtual void prepare(std::size_t pos, std::vector<Poco::Int64>& val);
|
||||
/// Prepares an Int64 vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, Poco::UInt64&) = 0;
|
||||
/// Prepares an UInt64.
|
||||
|
||||
virtual void prepare(std::size_t pos, std::vector<Poco::UInt64>& val);
|
||||
/// Prepares an UInt64 vector.
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
virtual void prepare(std::size_t pos, long) = 0;
|
||||
virtual void prepare(std::size_t pos, long&) = 0;
|
||||
/// Prepares a long.
|
||||
|
||||
virtual void prepare(std::size_t pos, std::vector<long>& val);
|
||||
/// Prepares a long vector.
|
||||
#endif
|
||||
|
||||
virtual void prepare(std::size_t pos, bool) = 0;
|
||||
virtual void prepare(std::size_t pos, bool&) = 0;
|
||||
/// Prepares a boolean.
|
||||
|
||||
virtual void prepare(std::size_t pos, float) = 0;
|
||||
virtual void prepare(std::size_t pos, std::vector<bool>& val);
|
||||
/// Prepares a boolean vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, float&) = 0;
|
||||
/// Prepares a float.
|
||||
|
||||
virtual void prepare(std::size_t pos, double) = 0;
|
||||
virtual void prepare(std::size_t pos, std::vector<float>& val);
|
||||
/// Prepares a float vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, double&) = 0;
|
||||
/// Prepares a double.
|
||||
|
||||
virtual void prepare(std::size_t pos, char) = 0;
|
||||
virtual void prepare(std::size_t pos, std::vector<double>& val);
|
||||
/// Prepares a double vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, char&) = 0;
|
||||
/// Prepares a single character.
|
||||
|
||||
virtual void prepare(std::size_t pos, std::vector<char>& val);
|
||||
/// Prepares a character vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, const std::string&) = 0;
|
||||
/// Prepares a string.
|
||||
|
||||
virtual void prepare(std::size_t pos, const std::vector<std::string>& val);
|
||||
/// Prepares a string vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, const BLOB&) = 0;
|
||||
/// Prepares a BLOB.
|
||||
|
||||
virtual void prepare(std::size_t pos, const std::vector<BLOB>& val);
|
||||
/// Prepares a BLOB vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, const DateTime&) = 0;
|
||||
/// Prepares a DateTime.
|
||||
|
||||
virtual void prepare(std::size_t pos, const std::vector<DateTime>& val);
|
||||
/// Prepares a DateTime vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, const Date&) = 0;
|
||||
/// Prepares a Date.
|
||||
|
||||
virtual void prepare(std::size_t pos, const std::vector<Date>& val);
|
||||
/// Prepares a Date vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, const Time&) = 0;
|
||||
/// Prepares a Time.
|
||||
|
||||
virtual void prepare(std::size_t pos, const std::vector<Time>& val);
|
||||
/// Prepares a Time vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, const Any&) = 0;
|
||||
/// Prepares an Any.
|
||||
|
||||
virtual void prepare(std::size_t pos, const std::vector<Any>& val);
|
||||
/// Prepares an Any vector.
|
||||
|
||||
virtual void prepare(std::size_t pos, const DynamicAny&) = 0;
|
||||
/// Prepares a DynamicAny.
|
||||
|
||||
virtual void prepare(std::size_t pos, const std::vector<DynamicAny>& val);
|
||||
/// Prepares a DynamicAny vector.
|
||||
|
||||
void setLength(Poco::UInt32 length);
|
||||
/// Sets the length of prepared data.
|
||||
/// Needed only for data lengths greater than 1 (i.e. for
|
||||
/// bulk operations).
|
||||
|
||||
Poco::UInt32 getLength() const;
|
||||
/// Returns the length of prepared data. Defaults to 1.
|
||||
/// The length is greater than one for bulk operations.
|
||||
|
||||
private:
|
||||
Poco::UInt32 _length;
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// inlines
|
||||
///
|
||||
inline void AbstractPreparation::setLength(Poco::UInt32 length)
|
||||
{
|
||||
_length = length;
|
||||
}
|
||||
|
||||
|
||||
inline Poco::UInt32 AbstractPreparation::getLength() const
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
|
@@ -113,7 +113,9 @@ class Binding<std::vector<T> >: public AbstractBinding
|
||||
/// Specialization for std::vector.
|
||||
{
|
||||
public:
|
||||
explicit Binding(const std::vector<T>& val, const std::string& name = "", Direction direction = PD_IN):
|
||||
explicit Binding(const std::vector<T>& val,
|
||||
const std::string& name = "",
|
||||
Direction direction = PD_IN):
|
||||
AbstractBinding(name, direction),
|
||||
_val(val),
|
||||
_begin(val.begin()),
|
||||
@@ -148,6 +150,7 @@ public:
|
||||
{
|
||||
poco_assert_dbg(getBinder() != 0);
|
||||
poco_assert_dbg(canBind());
|
||||
|
||||
TypeHandler<T>::bind(pos, *_begin, getBinder(), getDirection());
|
||||
++_begin;
|
||||
}
|
||||
@@ -181,7 +184,9 @@ class Binding<std::vector<bool> >: public AbstractBinding
|
||||
/// Only IN binding is supported.
|
||||
{
|
||||
public:
|
||||
explicit Binding(const std::vector<bool>& val, const std::string& name = "", Direction direction = PD_IN):
|
||||
explicit Binding(const std::vector<bool>& val,
|
||||
const std::string& name = "",
|
||||
Direction direction = PD_IN):
|
||||
AbstractBinding(name, direction),
|
||||
_val(val),
|
||||
_deq(_val.begin(), _val.end()),
|
||||
@@ -203,7 +208,7 @@ public:
|
||||
|
||||
std::size_t numOfColumnsHandled() const
|
||||
{
|
||||
return TypeHandler<bool>::size();
|
||||
return 1u;
|
||||
}
|
||||
|
||||
std::size_t numOfRowsHandled() const
|
||||
@@ -222,6 +227,7 @@ public:
|
||||
poco_assert_dbg(canBind());
|
||||
TypeHandler<bool>::bind(pos, *_begin, getBinder(), getDirection());
|
||||
++_begin;
|
||||
|
||||
}
|
||||
|
||||
void reset()
|
||||
@@ -584,9 +590,7 @@ template <typename T>
|
||||
Binding<T>* use(const T& t, const std::string& name = "")
|
||||
/// Convenience function for a more compact Binding creation.
|
||||
{
|
||||
Binding<T>* pB = new Binding<T>(t, name, AbstractBinding::PD_IN);
|
||||
poco_check_ptr (pB);
|
||||
return pB;
|
||||
return new Binding<T>(t, name, AbstractBinding::PD_IN);
|
||||
}
|
||||
|
||||
|
||||
@@ -594,9 +598,7 @@ template <typename T>
|
||||
Binding<T>* in(const T& t, const std::string& name = "")
|
||||
/// Convenience function for a more compact Binding creation.
|
||||
{
|
||||
Binding<T>* pB = new Binding<T>(t, name, AbstractBinding::PD_IN);
|
||||
poco_check_ptr (pB);
|
||||
return pB;
|
||||
return new Binding<T>(t, name, AbstractBinding::PD_IN);
|
||||
}
|
||||
|
||||
|
||||
@@ -604,9 +606,7 @@ template <typename T>
|
||||
Binding<T>* out(T& t, const std::string& name = "")
|
||||
/// Convenience function for a more compact Binding creation.
|
||||
{
|
||||
Binding<T>* pB = new Binding<T>(t, name, AbstractBinding::PD_OUT);
|
||||
poco_check_ptr (pB);
|
||||
return pB;
|
||||
return new Binding<T>(t, name, AbstractBinding::PD_OUT);
|
||||
}
|
||||
|
||||
|
||||
@@ -614,9 +614,7 @@ template <typename T>
|
||||
Binding<T>* io(T& t, const std::string& name = "")
|
||||
/// Convenience function for a more compact Binding creation.
|
||||
{
|
||||
Binding<T>* pB = new Binding<T>(t, name, AbstractBinding::PD_IN_OUT);
|
||||
poco_check_ptr (pB);
|
||||
return pB;
|
||||
return new Binding<T>(t, name, AbstractBinding::PD_IN_OUT);
|
||||
}
|
||||
|
||||
|
||||
|
109
Data/include/Poco/Data/Bulk.h
Normal file
109
Data/include/Poco/Data/Bulk.h
Normal file
@@ -0,0 +1,109 @@
|
||||
//
|
||||
// BulkExtraction.h
|
||||
//
|
||||
// $Id: //poco/Main/Data/include/Poco/Data/Bulk.h#9 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: DataCore
|
||||
// Module: Bulk
|
||||
//
|
||||
// Definition of the BulkExtraction 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_Bulk_INCLUDED
|
||||
#define Data_Bulk_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Data/Limit.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
class Data_API Bulk
|
||||
{
|
||||
public:
|
||||
Bulk(const Limit& limit);
|
||||
/// Creates the Bulk.
|
||||
|
||||
Bulk(Poco::UInt32 value);
|
||||
/// Creates the Bulk.
|
||||
|
||||
~Bulk();
|
||||
/// Destroys the bulk.
|
||||
|
||||
const Limit& limit() const;
|
||||
/// Returns the limit asociated with this bulk object.
|
||||
|
||||
Poco::UInt32 size() const;
|
||||
/// Returns the value of the limit asociated with
|
||||
/// this bulk object.
|
||||
|
||||
private:
|
||||
Bulk();
|
||||
|
||||
Limit _limit;
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// inlines
|
||||
///
|
||||
inline const Limit& Bulk::limit() const
|
||||
{
|
||||
return _limit;
|
||||
}
|
||||
|
||||
|
||||
inline Poco::UInt32 Bulk::size() const
|
||||
{
|
||||
return _limit.value();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline Bulk bulk(const T& limit)
|
||||
/// Convenience function for creation of bulk.
|
||||
{
|
||||
return Bulk(limit);
|
||||
}
|
||||
|
||||
|
||||
inline void bulk()
|
||||
/// Dummy bulk function. Used for bulk binding creation
|
||||
/// (see BulkBinding.h).
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
#endif // Data_Bulk_INCLUDED
|
131
Data/include/Poco/Data/BulkBinding.h
Normal file
131
Data/include/Poco/Data/BulkBinding.h
Normal file
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// BulkBinding.h
|
||||
//
|
||||
// $Id: //poco/Main/Data/include/Poco/Data/BulkBinding.h#6 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: DataCore
|
||||
// Module: BulkBinding
|
||||
//
|
||||
// Definition of the BulkBinding 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_BulkBinding_INCLUDED
|
||||
#define Data_BulkBinding_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Data/Data.h"
|
||||
#include "Poco/Data/AbstractBinding.h"
|
||||
#include "Poco/Data/DataException.h"
|
||||
#include "Poco/Data/TypeHandler.h"
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
template <class T>
|
||||
class BulkBinding: public AbstractBinding
|
||||
/// A BulkBinding maps a value to a column.
|
||||
/// Bulk binding support is provided only for std::vector.
|
||||
{
|
||||
public:
|
||||
explicit BulkBinding(const T& val, Poco::UInt32 bulkSize, const std::string& name = "", Direction direction = PD_IN):
|
||||
AbstractBinding(name, direction, bulkSize),
|
||||
_val(val),
|
||||
_bound(false)
|
||||
/// Creates the BulkBinding.
|
||||
{
|
||||
if (0 == _val.size())
|
||||
throw InvalidArgumentException("Zero size containers not allowed.");
|
||||
}
|
||||
|
||||
~BulkBinding()
|
||||
/// Destroys the BulkBinding.
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t numOfColumnsHandled() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::size_t numOfRowsHandled() const
|
||||
{
|
||||
return _val.size();
|
||||
}
|
||||
|
||||
bool canBind() const
|
||||
{
|
||||
return !_bound;
|
||||
}
|
||||
|
||||
void bind(std::size_t pos)
|
||||
{
|
||||
poco_assert_dbg(getBinder() != 0);
|
||||
TypeHandler<T>::bind(pos, _val, getBinder(), getDirection());
|
||||
_bound = true;
|
||||
}
|
||||
|
||||
void reset ()
|
||||
{
|
||||
_bound = false;
|
||||
getBinder()->reset();
|
||||
}
|
||||
|
||||
private:
|
||||
const T& _val;
|
||||
bool _bound;
|
||||
};
|
||||
|
||||
|
||||
typedef void (*BulkFnType)();
|
||||
|
||||
template <typename T>
|
||||
BulkBinding<std::vector<T> >* use(const std::vector<T>& t, BulkFnType, const std::string& name = "")
|
||||
/// Convenience function for a more compact BulkBinding creation.
|
||||
{
|
||||
return new BulkBinding<std::vector<T> >(t, static_cast<Poco::UInt32>(t.size()), name);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
BulkBinding<std::vector<T> >* in(const std::vector<T>& t, BulkFnType, const std::string& name = "")
|
||||
/// Convenience function for a more compact BulkBinding creation.
|
||||
{
|
||||
return new BulkBinding<std::vector<T> >(t, static_cast<Poco::UInt32>(t.size()), name);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
#endif // Data_BulkBinding_INCLUDED
|
168
Data/include/Poco/Data/BulkExtraction.h
Normal file
168
Data/include/Poco/Data/BulkExtraction.h
Normal file
@@ -0,0 +1,168 @@
|
||||
//
|
||||
// BulkExtraction.h
|
||||
//
|
||||
// $Id: //poco/Main/Data/include/Poco/Data/BulkExtraction.h#9 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: DataCore
|
||||
// Module: BulkExtraction
|
||||
//
|
||||
// Definition of the BulkExtraction 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_BulkExtraction_INCLUDED
|
||||
#define Data_BulkExtraction_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Data/Data.h"
|
||||
#include "Poco/Data/AbstractExtraction.h"
|
||||
#include "Poco/Data/Bulk.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
template <class T>
|
||||
class BulkExtraction: public AbstractExtraction
|
||||
/// Specialization for bulk extraction of values from a query result set.
|
||||
/// Bulk extraction support is provided only for following STL containers:
|
||||
/// - std::vector
|
||||
/// - std::deque
|
||||
/// - std::list
|
||||
{
|
||||
public:
|
||||
BulkExtraction(T& result, Poco::UInt32 limit, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(limit, position, true),
|
||||
_rResult(result),
|
||||
_default()
|
||||
{
|
||||
if (static_cast<Poco::UInt32>(result.size()) != limit)
|
||||
result.resize(limit);
|
||||
}
|
||||
|
||||
virtual ~BulkExtraction()
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t numOfColumnsHandled() const
|
||||
{
|
||||
return TypeHandler<T>::size();
|
||||
}
|
||||
|
||||
std::size_t numOfRowsHandled() const
|
||||
{
|
||||
return _rResult.size();
|
||||
}
|
||||
|
||||
std::size_t numOfRowsAllowed() const
|
||||
{
|
||||
return getLimit();
|
||||
}
|
||||
|
||||
bool isNull(std::size_t row) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return _nulls.at(row);
|
||||
}catch (std::out_of_range& ex)
|
||||
{
|
||||
throw RangeException(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t extract(std::size_t col)
|
||||
{
|
||||
AbstractExtractor* pExt = getExtractor();
|
||||
TypeHandler<T>::extract(col, _rResult, _default, pExt);
|
||||
typename T::iterator it = _rResult.begin();
|
||||
typename T::iterator end = _rResult.end();
|
||||
for (int row = 0; it !=end; ++it, ++row)
|
||||
_nulls.push_back(pExt->isNull(col, row));
|
||||
|
||||
return _rResult.size();
|
||||
}
|
||||
|
||||
virtual void reset()
|
||||
{
|
||||
}
|
||||
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t col)
|
||||
{
|
||||
Poco::UInt32 limit = getLimit();
|
||||
if (limit != _rResult.size()) _rResult.resize(limit);
|
||||
pPrep->setLength(limit);
|
||||
return new Prepare<T>(pPrep, col, _rResult);
|
||||
}
|
||||
|
||||
protected:
|
||||
const T& result() const
|
||||
{
|
||||
return _rResult;
|
||||
}
|
||||
|
||||
private:
|
||||
T& _rResult;
|
||||
T _default; // copy the default
|
||||
std::deque<bool> _nulls;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
BulkExtraction<std::vector<T> >* into(std::vector<T>& t, const Bulk& bulk)
|
||||
/// Convenience function to allow for a more compact creation of an extraction object
|
||||
/// with std::vector bulk extraction support.
|
||||
{
|
||||
return new BulkExtraction<std::vector<T> >(t, bulk.size());
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
BulkExtraction<std::deque<T> >* into(std::deque<T>& t, const Bulk& bulk)
|
||||
/// Convenience function to allow for a more compact creation of an extraction object
|
||||
/// with std::deque bulk extraction support.
|
||||
{
|
||||
return new BulkExtraction<std::deque<T> >(t, bulk.size());
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
BulkExtraction<std::list<T> >* into(std::list<T>& t, const Bulk& bulk)
|
||||
/// Convenience function to allow for a more compact creation of an extraction object
|
||||
/// with std::list bulk extraction support.
|
||||
{
|
||||
return new BulkExtraction<std::list<T> >(t, bulk.size());
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
#endif // Data_BulkExtraction_INCLUDED
|
@@ -57,10 +57,10 @@ POCO_DECLARE_EXCEPTION(Data_API, BindingException, DataException)
|
||||
POCO_DECLARE_EXCEPTION(Data_API, ExtractException, DataException)
|
||||
POCO_DECLARE_EXCEPTION(Data_API, LimitException, DataException)
|
||||
POCO_DECLARE_EXCEPTION(Data_API, NotSupportedException, DataException)
|
||||
POCO_DECLARE_EXCEPTION(Data_API, NotImplementedException, DataException)
|
||||
POCO_DECLARE_EXCEPTION(Data_API, SessionUnavailableException, DataException)
|
||||
POCO_DECLARE_EXCEPTION(Data_API, SessionPoolExhaustedException, DataException)
|
||||
POCO_DECLARE_EXCEPTION(Data_API, NoDataException, DataException)
|
||||
POCO_DECLARE_EXCEPTION(Data_API, LengthExceededException, DataException)
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
@@ -45,6 +45,7 @@
|
||||
#include "Poco/Data/Prepare.h"
|
||||
#include "Poco/Data/TypeHandler.h"
|
||||
#include "Poco/Data/Column.h"
|
||||
#include "Poco/Data/Position.h"
|
||||
#include "Poco/Data/DataException.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
@@ -63,8 +64,8 @@ class Extraction: public AbstractExtraction
|
||||
/// Concrete Data Type specific extraction of values from a query result set.
|
||||
{
|
||||
public:
|
||||
Extraction(T& result, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(T& result, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default(),
|
||||
_extracted(false)
|
||||
@@ -73,8 +74,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
Extraction(T& result, const T& def, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(T& result, const T& def, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default(def),
|
||||
_extracted(false)
|
||||
@@ -108,13 +109,14 @@ public:
|
||||
return _null;
|
||||
}
|
||||
|
||||
void extract(std::size_t pos)
|
||||
std::size_t extract(std::size_t pos)
|
||||
{
|
||||
if (_extracted) throw ExtractException("value already extracted");
|
||||
_extracted = true;
|
||||
AbstractExtractor* pExt = getExtractor();
|
||||
TypeHandler<T>::extract(pos, _rResult, _default, pExt);
|
||||
_null = pExt->isNull(pos);
|
||||
return 1u;
|
||||
}
|
||||
|
||||
void reset()
|
||||
@@ -122,14 +124,14 @@ public:
|
||||
_extracted = false;
|
||||
}
|
||||
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos)
|
||||
{
|
||||
return new Prepare<T>(pPrep, pos, _default);
|
||||
return new Prepare<T>(pPrep, pos, _rResult);
|
||||
}
|
||||
|
||||
private:
|
||||
T& _rResult;
|
||||
T _default; // copy the default
|
||||
T _default;
|
||||
bool _extracted;
|
||||
bool _null;
|
||||
};
|
||||
@@ -140,18 +142,21 @@ class Extraction<std::vector<T> >: public AbstractExtraction
|
||||
/// Vector Data Type specialization for extraction of values from a query result set.
|
||||
{
|
||||
public:
|
||||
Extraction(std::vector<T>& result, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(std::vector<T>& result, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default()
|
||||
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
Extraction(std::vector<T>& result, const T& def, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(std::vector<T>& result, const T& def, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default(def)
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
virtual ~Extraction()
|
||||
@@ -184,24 +189,20 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void extract(std::size_t pos)
|
||||
std::size_t extract(std::size_t pos)
|
||||
{
|
||||
AbstractExtractor* pExt = getExtractor();
|
||||
|
||||
// for vector specialization, a temporary must be used to
|
||||
// allow for extraction of bool values
|
||||
T tmp = _default;
|
||||
TypeHandler<T>::extract(pos, tmp, _default, pExt);
|
||||
_rResult.push_back(tmp);
|
||||
|
||||
_rResult.push_back(_default);
|
||||
TypeHandler<T>::extract(pos, _rResult.back(), _default, pExt);
|
||||
_nulls.push_back(pExt->isNull(pos));
|
||||
return 1u;
|
||||
}
|
||||
|
||||
virtual void reset()
|
||||
{
|
||||
}
|
||||
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos)
|
||||
{
|
||||
return new Prepare<T>(pPrep, pos, _default);
|
||||
}
|
||||
@@ -215,7 +216,92 @@ protected:
|
||||
|
||||
private:
|
||||
std::vector<T>& _rResult;
|
||||
T _default; // copy the default
|
||||
T _default;
|
||||
std::deque<bool> _nulls;
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
class Extraction<std::vector<bool> >: public AbstractExtraction
|
||||
/// Vector bool specialization for extraction of values from a query result set.
|
||||
{
|
||||
public:
|
||||
Extraction(std::vector<bool>& result, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default()
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
Extraction(std::vector<bool>& result, const bool& def, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default(def)
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
virtual ~Extraction()
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t numOfColumnsHandled() const
|
||||
{
|
||||
return TypeHandler<bool>::size();
|
||||
}
|
||||
|
||||
std::size_t numOfRowsHandled() const
|
||||
{
|
||||
return _rResult.size();
|
||||
}
|
||||
|
||||
std::size_t numOfRowsAllowed() const
|
||||
{
|
||||
return getLimit();
|
||||
}
|
||||
|
||||
bool isNull(std::size_t row) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return _nulls.at(row);
|
||||
}catch (std::out_of_range& ex)
|
||||
{
|
||||
throw RangeException(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t extract(std::size_t pos)
|
||||
{
|
||||
AbstractExtractor* pExt = getExtractor();
|
||||
|
||||
bool tmp = _default;
|
||||
TypeHandler<bool>::extract(pos, tmp, _default, pExt);
|
||||
_rResult.push_back(tmp);
|
||||
_nulls.push_back(pExt->isNull(pos));
|
||||
return 1u;
|
||||
}
|
||||
|
||||
virtual void reset()
|
||||
{
|
||||
}
|
||||
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos)
|
||||
{
|
||||
return new Prepare<bool>(pPrep, pos, _default);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
const std::vector<bool>& result() const
|
||||
{
|
||||
return _rResult;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<bool>& _rResult;
|
||||
bool _default;
|
||||
std::deque<bool> _nulls;
|
||||
};
|
||||
|
||||
@@ -225,18 +311,20 @@ class Extraction<std::list<T> >: public AbstractExtraction
|
||||
/// List Data Type specialization for extraction of values from a query result set.
|
||||
{
|
||||
public:
|
||||
Extraction(std::list<T>& result, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(std::list<T>& result, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default()
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
Extraction(std::list<T>& result, const T& def, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(std::list<T>& result, const T& def, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default(def)
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
virtual ~Extraction()
|
||||
@@ -269,19 +357,20 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void extract(std::size_t pos)
|
||||
std::size_t extract(std::size_t pos)
|
||||
{
|
||||
AbstractExtractor* pExt = getExtractor();
|
||||
_rResult.push_back(_default);
|
||||
TypeHandler<T>::extract(pos, _rResult.back(), _default, pExt);
|
||||
_nulls.push_back(pExt->isNull(pos));
|
||||
return 1u;
|
||||
}
|
||||
|
||||
virtual void reset()
|
||||
{
|
||||
}
|
||||
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos)
|
||||
{
|
||||
return new Prepare<T>(pPrep, pos, _default);
|
||||
}
|
||||
@@ -295,7 +384,7 @@ protected:
|
||||
|
||||
private:
|
||||
std::list<T>& _rResult;
|
||||
T _default; // copy the default
|
||||
T _default;
|
||||
std::deque<bool> _nulls;
|
||||
};
|
||||
|
||||
@@ -305,18 +394,20 @@ class Extraction<std::deque<T> >: public AbstractExtraction
|
||||
/// Deque Data Type specialization for extraction of values from a query result set.
|
||||
{
|
||||
public:
|
||||
Extraction(std::deque<T>& result, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(std::deque<T>& result, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default()
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
Extraction(std::deque<T>& result, const T& def, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(std::deque<T>& result, const T& def, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default(def)
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
virtual ~Extraction()
|
||||
@@ -349,19 +440,20 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void extract(std::size_t pos)
|
||||
std::size_t extract(std::size_t pos)
|
||||
{
|
||||
AbstractExtractor* pExt = getExtractor();
|
||||
_rResult.push_back(_default);
|
||||
TypeHandler<T>::extract(pos, _rResult.back(), _default, pExt);
|
||||
_nulls.push_back(pExt->isNull(pos));
|
||||
return 1u;
|
||||
}
|
||||
|
||||
virtual void reset()
|
||||
{
|
||||
}
|
||||
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos)
|
||||
{
|
||||
return new Prepare<T>(pPrep, pos, _default);
|
||||
}
|
||||
@@ -375,7 +467,7 @@ protected:
|
||||
|
||||
private:
|
||||
std::deque<T>& _rResult;
|
||||
T _default; // copy the default
|
||||
T _default;
|
||||
std::deque<bool> _nulls;
|
||||
};
|
||||
|
||||
@@ -393,8 +485,8 @@ class InternalExtraction: public Extraction<C>
|
||||
/// InternalExtraction objects can not be copied or assigned.
|
||||
{
|
||||
public:
|
||||
explicit InternalExtraction(C& result, Column<T,C>* pColumn, Poco::UInt32 position = 0):
|
||||
Extraction<C>(result, T(), position),
|
||||
explicit InternalExtraction(C& result, Column<T,C>* pColumn, const Position& pos = Position(0)):
|
||||
Extraction<C>(result, T(), pos),
|
||||
_pColumn(pColumn)
|
||||
/// Creates InternalExtraction.
|
||||
{
|
||||
@@ -447,18 +539,22 @@ class Extraction<std::set<T> >: public AbstractExtraction
|
||||
/// Set Data Type specialization for extraction of values from a query result set.
|
||||
{
|
||||
public:
|
||||
Extraction(std::set<T>& result, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
typedef typename std::set<T>::iterator Iterator;
|
||||
|
||||
Extraction(std::set<T>& result, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default()
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
Extraction(std::set<T>& result, const T& def, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(std::set<T>& result, const T& def, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default(def)
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
~Extraction()
|
||||
@@ -480,25 +576,26 @@ public:
|
||||
return getLimit();
|
||||
}
|
||||
|
||||
void extract(std::size_t pos)
|
||||
std::size_t extract(std::size_t pos)
|
||||
{
|
||||
T tmp;
|
||||
TypeHandler<T>::extract(pos, tmp, _default, getExtractor());
|
||||
_rResult.insert(tmp);
|
||||
return 1u;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
}
|
||||
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos)
|
||||
{
|
||||
return new Prepare<T>(pPrep, pos, _default);
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<T>& _rResult;
|
||||
T _default; // copy the default
|
||||
T _default;
|
||||
};
|
||||
|
||||
|
||||
@@ -507,18 +604,20 @@ class Extraction<std::multiset<T> >: public AbstractExtraction
|
||||
/// Multiset Data Type specialization for extraction of values from a query result set.
|
||||
{
|
||||
public:
|
||||
Extraction(std::multiset<T>& result, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(std::multiset<T>& result, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default()
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
Extraction(std::multiset<T>& result, const T& def, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(std::multiset<T>& result, const T& def, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default(def)
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
~Extraction()
|
||||
@@ -540,25 +639,26 @@ public:
|
||||
return getLimit();
|
||||
}
|
||||
|
||||
void extract(std::size_t pos)
|
||||
std::size_t extract(std::size_t pos)
|
||||
{
|
||||
T tmp;
|
||||
TypeHandler<T>::extract(pos, tmp, _default, getExtractor());
|
||||
_rResult.insert(tmp);
|
||||
return 1u;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
}
|
||||
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos)
|
||||
{
|
||||
return new Prepare<T>(pPrep, pos, _default);
|
||||
}
|
||||
|
||||
private:
|
||||
std::multiset<T>& _rResult;
|
||||
T _default; // copy the default
|
||||
T _default;
|
||||
};
|
||||
|
||||
|
||||
@@ -567,18 +667,20 @@ class Extraction<std::map<K, V> >: public AbstractExtraction
|
||||
/// Map Data Type specialization for extraction of values from a query result set.
|
||||
{
|
||||
public:
|
||||
Extraction(std::map<K, V>& result, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(std::map<K, V>& result, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default()
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
Extraction(std::map<K, V>& result, const V& def, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(std::map<K, V>& result, const V& def, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default(def)
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
~Extraction()
|
||||
@@ -600,18 +702,19 @@ public:
|
||||
return getLimit();
|
||||
}
|
||||
|
||||
void extract(std::size_t pos)
|
||||
std::size_t extract(std::size_t pos)
|
||||
{
|
||||
V tmp;
|
||||
TypeHandler<V>::extract(pos, tmp, _default, getExtractor());
|
||||
_rResult.insert(std::make_pair(tmp(), tmp));
|
||||
return 1u;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
}
|
||||
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos)
|
||||
{
|
||||
return new Prepare<V>(pPrep, pos, _default);
|
||||
}
|
||||
@@ -619,7 +722,7 @@ public:
|
||||
|
||||
private:
|
||||
std::map<K, V>& _rResult;
|
||||
V _default; // copy the default
|
||||
V _default;
|
||||
};
|
||||
|
||||
|
||||
@@ -628,18 +731,20 @@ class Extraction<std::multimap<K, V> >: public AbstractExtraction
|
||||
/// Multimap Data Type specialization for extraction of values from a query result set.
|
||||
{
|
||||
public:
|
||||
Extraction(std::multimap<K, V>& result, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(std::multimap<K, V>& result, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default()
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
Extraction(std::multimap<K, V>& result, const V& def, Poco::UInt32 position = 0):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, position),
|
||||
Extraction(std::multimap<K, V>& result, const V& def, const Position& pos = Position(0)):
|
||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
||||
_rResult(result),
|
||||
_default(def)
|
||||
{
|
||||
_rResult.clear();
|
||||
}
|
||||
|
||||
~Extraction()
|
||||
@@ -661,38 +766,40 @@ public:
|
||||
return getLimit();
|
||||
}
|
||||
|
||||
void extract(std::size_t pos)
|
||||
std::size_t extract(std::size_t pos)
|
||||
{
|
||||
V tmp;
|
||||
TypeHandler<V>::extract(pos, tmp, _default, getExtractor());
|
||||
_rResult.insert(std::make_pair(tmp(), tmp));
|
||||
return 1u;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
}
|
||||
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos) const
|
||||
AbstractPrepare* createPrepareObject(AbstractPreparation* pPrep, std::size_t pos)
|
||||
{
|
||||
return new Prepare<V>(pPrep, pos, _default);
|
||||
}
|
||||
|
||||
private:
|
||||
std::multimap<K, V>& _rResult;
|
||||
V _default; // copy the default
|
||||
V _default;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
Extraction<T>* into(T& t, Poco::UInt32 pos = 0)
|
||||
Extraction<T>* into(T& t, const Position& pos = 0)
|
||||
/// Convenience function to allow for a more compact creation of an extraction object
|
||||
/// with multiple recordset support.
|
||||
{
|
||||
return new Extraction<T>(t, pos);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
Extraction<T>* into(T& t, Poco::UInt32 pos, const T& def)
|
||||
Extraction<T>* into(T& t, const Position& pos, const T& def)
|
||||
/// Convenience function to allow for a more compact creation of an extraction object with the given default
|
||||
{
|
||||
return new Extraction<T>(t, def, pos);
|
||||
|
@@ -77,6 +77,12 @@ public:
|
||||
bool isLowerLimit() const;
|
||||
/// Returns true if the limit is a lower limit, otherwise it is an upperLimit
|
||||
|
||||
bool operator == (const Limit& other) const;
|
||||
/// Equality operator.
|
||||
|
||||
bool operator != (const Limit& other) const;
|
||||
/// Inequality operator.
|
||||
|
||||
private:
|
||||
Poco::UInt32 _value;
|
||||
bool _hardLimit;
|
||||
@@ -105,6 +111,22 @@ inline bool Limit::isLowerLimit() const
|
||||
}
|
||||
|
||||
|
||||
inline bool Limit::operator == (const Limit& other) const
|
||||
{
|
||||
return other._value == _value &&
|
||||
other._hardLimit == _hardLimit &&
|
||||
other._isLowerLimit == _isLowerLimit;
|
||||
}
|
||||
|
||||
|
||||
inline bool Limit::operator != (const Limit& other) const
|
||||
{
|
||||
return other._value != _value ||
|
||||
other._hardLimit != _hardLimit ||
|
||||
other._isLowerLimit != _isLowerLimit;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
|
@@ -1,13 +1,13 @@
|
||||
//
|
||||
// Step.h
|
||||
// PositionExtraction.h
|
||||
//
|
||||
// $Id: //poco/Main/Data/include/Poco/Data/Step.h#7 $
|
||||
// $Id: //poco/Main/Data/include/Poco/Data/Position.h#9 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: DataCore
|
||||
// Module: Step
|
||||
// Module: Position
|
||||
//
|
||||
// Definition of the Step class.
|
||||
// Definition of the PositionExtraction class.
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
@@ -36,59 +36,56 @@
|
||||
//
|
||||
|
||||
|
||||
#ifndef Data_Step_INCLUDED
|
||||
#define Data_Step_INCLUDED
|
||||
#ifndef Data_Position_INCLUDED
|
||||
#define Data_Position_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Data/Data.h"
|
||||
#include "Poco/Data/Limit.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
class Data_API Step
|
||||
/// Step stores information how many rows should be returned at evry advance through the recordset.
|
||||
class Data_API Position
|
||||
/// Utility class wrapping unsigned integer. Used to
|
||||
/// indicate the recordset position in batch SQL statements.
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
DEFAULT_STEP = 1u
|
||||
};
|
||||
Position(Poco::UInt32 value);
|
||||
/// Creates the Position.
|
||||
|
||||
Step(Poco::UInt32 value = 1u);
|
||||
/// Creates the Step.
|
||||
///
|
||||
/// Value contains the step and defaults to DEFAULT_STEP.
|
||||
|
||||
~Step();
|
||||
/// Destroys the Step.
|
||||
~Position();
|
||||
/// Destroys the Position.
|
||||
|
||||
Poco::UInt32 value() const;
|
||||
/// Returns the value of the limit
|
||||
/// Returns the position value.
|
||||
|
||||
private:
|
||||
Position();
|
||||
|
||||
Poco::UInt32 _value;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
inline Poco::UInt32 Step::value() const
|
||||
///
|
||||
/// inlines
|
||||
///
|
||||
inline Poco::UInt32 Position::value() const
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
Step step(T step)
|
||||
inline Position from(const T& value)
|
||||
/// Convenience function for creation of position.
|
||||
{
|
||||
return Step(static_cast<Poco::UInt32>(step));
|
||||
return Position(value);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
#endif // Data_Step_INCLUDED
|
||||
#endif // Data_Position_INCLUDED
|
@@ -44,11 +44,7 @@
|
||||
#include "Poco/Data/AbstractPrepare.h"
|
||||
#include "Poco/Data/TypeHandler.h"
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@@ -60,7 +56,10 @@ class Prepare: public AbstractPrepare
|
||||
/// Class for calling the appropriate AbstractPreparation method.
|
||||
{
|
||||
public:
|
||||
Prepare(AbstractPreparation* pPrepare, std::size_t pos, const T& val): AbstractPrepare(pPrepare), _pos(pos), _val(val)
|
||||
Prepare(AbstractPreparation* pPrepare, std::size_t pos, T& val):
|
||||
AbstractPrepare(pPrepare),
|
||||
_pos(pos),
|
||||
_val(val)
|
||||
/// Creates the Prepare.
|
||||
{
|
||||
}
|
||||
@@ -78,16 +77,21 @@ public:
|
||||
|
||||
private:
|
||||
std::size_t _pos;
|
||||
const T& _val;
|
||||
T& _val;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class Prepare<std::vector<T> >: public AbstractPrepare
|
||||
/// Class for calling the appropriate AbstractPreparation method.
|
||||
/// Prepare specialization for std::vector.
|
||||
/// This specialization is needed for bulk operations to enforce
|
||||
/// the whole vector preparation, rather than only individual contained values.
|
||||
{
|
||||
public:
|
||||
Prepare(AbstractPreparation* pPrepare, std::size_t pos, const T& val): AbstractPrepare(pPrepare), _pos(pos), _val(val)
|
||||
Prepare(AbstractPreparation* pPrepare, std::size_t pos, std::vector<T>& val = std::vector<T>()):
|
||||
AbstractPrepare(pPrepare),
|
||||
_pos(pos),
|
||||
_val(val)
|
||||
/// Creates the Prepare.
|
||||
{
|
||||
}
|
||||
@@ -100,174 +104,12 @@ public:
|
||||
void prepare()
|
||||
/// Prepares data.
|
||||
{
|
||||
TypeHandler<T>::prepare(_pos, _val, preparation());
|
||||
TypeHandler<std::vector<T> >::prepare(_pos, _val, preparation());
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t _pos;
|
||||
const T& _val;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class Prepare<std::list<T> >: public AbstractPrepare
|
||||
/// Class for calling the appropriate AbstractPreparation method.
|
||||
{
|
||||
public:
|
||||
Prepare(AbstractPreparation* pPrepare, std::size_t pos, const T& val): AbstractPrepare(pPrepare), _pos(pos), _val(val)
|
||||
/// Creates the Prepare.
|
||||
{
|
||||
}
|
||||
|
||||
~Prepare()
|
||||
/// Destroys the Prepare.
|
||||
{
|
||||
}
|
||||
|
||||
void prepare()
|
||||
/// Prepares data.
|
||||
{
|
||||
TypeHandler<T>::prepare(_pos, _val, preparation());
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t _pos;
|
||||
const T& _val;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class Prepare<std::deque<T> >: public AbstractPrepare
|
||||
/// Class for calling the appropriate AbstractPreparation method.
|
||||
{
|
||||
public:
|
||||
Prepare(AbstractPreparation* pPrepare, std::size_t pos, const T& val): AbstractPrepare(pPrepare), _pos(pos), _val(val)
|
||||
/// Creates the Prepare.
|
||||
{
|
||||
}
|
||||
|
||||
~Prepare()
|
||||
/// Destroys the Prepare.
|
||||
{
|
||||
}
|
||||
|
||||
void prepare()
|
||||
/// Prepares data.
|
||||
{
|
||||
TypeHandler<T>::prepare(_pos, _val, preparation());
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t _pos;
|
||||
const T& _val;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class Prepare<std::set<T> >: public AbstractPrepare
|
||||
/// Class for calling the appropriate AbstractPreparation method.
|
||||
{
|
||||
public:
|
||||
Prepare(AbstractPreparation* pPrepare, std::size_t pos, const T& val): AbstractPrepare(pPrepare), _pos(pos), _val(val)
|
||||
/// Creates the Prepare.
|
||||
{
|
||||
}
|
||||
|
||||
~Prepare()
|
||||
/// Destroys the Prepare.
|
||||
{
|
||||
}
|
||||
|
||||
void prepare()
|
||||
/// Prepares data.
|
||||
{
|
||||
TypeHandler<T>::prepare(_pos, _val, preparation());
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t _pos;
|
||||
const T& _val;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class Prepare<std::multiset<T> >: public AbstractPrepare
|
||||
/// Class for calling the appropriate AbstractPreparation method.
|
||||
{
|
||||
public:
|
||||
Prepare(AbstractPreparation* pPrepare, std::size_t pos, const T& val): AbstractPrepare(pPrepare), _pos(pos), _val(val)
|
||||
/// Creates the Prepare.
|
||||
{
|
||||
}
|
||||
|
||||
~Prepare()
|
||||
/// Destroys the Prepare.
|
||||
{
|
||||
}
|
||||
|
||||
void prepare()
|
||||
/// Prepares data.
|
||||
{
|
||||
TypeHandler<T>::prepare(_pos, _val, preparation());
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t _pos;
|
||||
const T& _val;
|
||||
};
|
||||
|
||||
|
||||
template<typename K, typename V>
|
||||
class Prepare<std::map<K, V> >: public AbstractPrepare
|
||||
/// Class for calling the appropriate AbstractPreparation method.
|
||||
{
|
||||
public:
|
||||
Prepare(AbstractPreparation* pPrepare, std::size_t pos, const V& val): AbstractPrepare(pPrepare), _pos(pos), _val(val)
|
||||
/// Creates the Prepare.
|
||||
{
|
||||
}
|
||||
|
||||
~Prepare()
|
||||
/// Destroys the Prepare.
|
||||
{
|
||||
}
|
||||
|
||||
void prepare()
|
||||
/// Prepares data.
|
||||
{
|
||||
TypeHandler<V>::prepare(_pos, _val, preparation());
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t _pos;
|
||||
const V& _val;
|
||||
};
|
||||
|
||||
|
||||
template<typename K, typename V>
|
||||
class Prepare<std::multimap<K, V> >: public AbstractPrepare
|
||||
/// Class for calling the appropriate AbstractPreparation method.
|
||||
{
|
||||
public:
|
||||
Prepare(AbstractPreparation* pPrepare, std::size_t pos, const V& val): AbstractPrepare(pPrepare), _pos(pos), _val(val)
|
||||
/// Creates the Prepare.
|
||||
{
|
||||
}
|
||||
|
||||
~Prepare()
|
||||
/// Destroys the Prepare.
|
||||
{
|
||||
}
|
||||
|
||||
void prepare()
|
||||
/// Prepares data.
|
||||
{
|
||||
TypeHandler<V>::prepare(_pos, _val, preparation());
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t _pos;
|
||||
const V& _val;
|
||||
std::vector<T>& _val;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -43,7 +43,7 @@
|
||||
#include "Poco/Data/Data.h"
|
||||
#include "Poco/Data/StatementImpl.h"
|
||||
#include "Poco/Data/Range.h"
|
||||
#include "Poco/Data/Step.h"
|
||||
#include "Poco/Data/Bulk.h"
|
||||
#include "Poco/SharedPtr.h"
|
||||
#include "Poco/Mutex.h"
|
||||
#include "Poco/ActiveMethod.h"
|
||||
@@ -171,15 +171,24 @@ public:
|
||||
}
|
||||
|
||||
Statement& operator , (Manipulator manip);
|
||||
/// Handles manipulators, such as now.
|
||||
/// Handles manipulators, such as now, async, etc.
|
||||
|
||||
Statement& operator , (AbstractBinding* info);
|
||||
/// Registers the Binding at the Statement
|
||||
/// Registers the Binding at the Statement.
|
||||
|
||||
Statement& operator , (AbstractExtraction* extract);
|
||||
/// Registers objects used for extracting data at the Statement.
|
||||
/// the position argument is used by connectors that support multilple
|
||||
/// recordsets to specify which recordset this extraction belongs to.
|
||||
|
||||
Statement& operator , (const Bulk& bulk);
|
||||
/// Sets the bulk execution mode (both binding and extraction) for this
|
||||
/// statement.Statement must not have any extracors or binders set at the
|
||||
/// time when this operator is applied.
|
||||
/// Failure to adhere to the above constraint shall result in
|
||||
/// InvalidAccessException.
|
||||
/// Additionally, any binding buffers passed to the statement later
|
||||
/// through use() or in() must be of the same size (determined by size
|
||||
/// of the bulk passed to this function). Since they are resized automatically
|
||||
/// by the framework, the extraction buffers do not have to adhere to this.
|
||||
|
||||
Statement& operator , (const Limit& extrLimit);
|
||||
/// Sets a limit on the maximum number of rows a select is allowed to return.
|
||||
@@ -191,14 +200,8 @@ public:
|
||||
///
|
||||
/// 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
|
||||
/// Creates a string from the accumulated SQL statement.
|
||||
|
||||
ResultType execute();
|
||||
/// Executes the statement synchronously or asynchronously.
|
||||
@@ -296,85 +299,77 @@ private:
|
||||
// Manipulators
|
||||
//
|
||||
|
||||
void Data_API now(Statement& statement);
|
||||
inline void Data_API now(Statement& statement)
|
||||
/// Enforces immediate execution of the statement.
|
||||
/// If _isAsync flag has been set, execution is invoked asynchronously.
|
||||
{
|
||||
statement.execute();
|
||||
}
|
||||
|
||||
|
||||
void Data_API sync(Statement& statement);
|
||||
inline void Data_API sync(Statement& statement)
|
||||
/// Sets the _isAsync flag to false, signalling synchronous execution.
|
||||
/// Synchronous execution is default, so specifying this manipulator
|
||||
/// only makes sense if async() was called for the statement before.
|
||||
{
|
||||
statement.setAsync(false);
|
||||
}
|
||||
|
||||
|
||||
void Data_API async(Statement& statement);
|
||||
/// Sets the _isAsync flag to true, signalling asynchronous execution.
|
||||
inline void Data_API async(Statement& statement)
|
||||
/// Sets the _async flag to true, signalling asynchronous execution.
|
||||
{
|
||||
statement.setAsync(true);
|
||||
}
|
||||
|
||||
|
||||
void Data_API deque(Statement& statement);
|
||||
inline void Data_API deque(Statement& statement)
|
||||
/// Sets the internal storage to std::deque.
|
||||
/// std::deque is default storage, so specifying this manipulator
|
||||
/// only makes sense if list() or deque() were called for the statement before.
|
||||
{
|
||||
if (!statement.canModifyStorage())
|
||||
throw InvalidAccessException("Storage not modifiable.");
|
||||
|
||||
statement.setStorage("deque");
|
||||
}
|
||||
|
||||
|
||||
void Data_API vector(Statement& statement);
|
||||
inline void Data_API vector(Statement& statement)
|
||||
/// Sets the internal storage to std::vector.
|
||||
{
|
||||
if (!statement.canModifyStorage())
|
||||
throw InvalidAccessException("Storage not modifiable.");
|
||||
|
||||
statement.setStorage("vector");
|
||||
}
|
||||
|
||||
|
||||
void Data_API list(Statement& statement);
|
||||
inline void Data_API list(Statement& statement)
|
||||
/// Sets the internal storage to std::list.
|
||||
{
|
||||
if (!statement.canModifyStorage())
|
||||
throw InvalidAccessException("Storage not modifiable.");
|
||||
|
||||
statement.setStorage("list");
|
||||
}
|
||||
|
||||
|
||||
void Data_API reset(Statement& statement);
|
||||
inline void Data_API reset(Statement& statement)
|
||||
/// Sets all internal settings to their respective default values.
|
||||
{
|
||||
if (!statement.canModifyStorage())
|
||||
throw InvalidAccessException("Storage not modifiable.");
|
||||
|
||||
statement.setStorage("deque");
|
||||
statement.setAsync(false);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
|
||||
inline Statement& Statement::operator , (Manipulator manip)
|
||||
{
|
||||
manip(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline Statement& Statement::operator , (AbstractBinding* info)
|
||||
{
|
||||
_pImpl->addBinding(info);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline Statement& Statement::operator , (AbstractExtraction* extract)
|
||||
{
|
||||
_pImpl->addExtract(extract);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline Statement& Statement::operator , (const Limit& extrLimit)
|
||||
{
|
||||
_pImpl->setExtractionLimit(extrLimit);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline Statement& Statement::operator , (const Range& extrRange)
|
||||
{
|
||||
_pImpl->setExtractionLimit(extrRange.lower());
|
||||
_pImpl->setExtractionLimit(extrRange.upper());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline Statement& Statement::operator , (const Step& extrStep)
|
||||
{
|
||||
_pImpl->setStep(extrStep.value());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline std::string Statement::toString() const
|
||||
{
|
||||
@@ -460,6 +455,7 @@ inline void swap(Statement& s1, Statement& s2)
|
||||
}
|
||||
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
|
@@ -44,6 +44,7 @@
|
||||
#include "Poco/Data/AbstractBinding.h"
|
||||
#include "Poco/Data/AbstractExtraction.h"
|
||||
#include "Poco/Data/Range.h"
|
||||
#include "Poco/Data/Bulk.h"
|
||||
#include "Poco/Data/Column.h"
|
||||
#include "Poco/Data/Extraction.h"
|
||||
#include "Poco/Data/SessionImpl.h"
|
||||
@@ -86,6 +87,14 @@ public:
|
||||
STORAGE_UNKNOWN_IMPL
|
||||
};
|
||||
|
||||
enum BulkType
|
||||
{
|
||||
BULK_UNDEFINED,
|
||||
BULK_BINDING,
|
||||
BULK_EXTRACTION,
|
||||
BULK_FORBIDDEN
|
||||
};
|
||||
|
||||
static const std::string DEQUE;
|
||||
static const std::string VECTOR;
|
||||
static const std::string LIST;
|
||||
@@ -133,12 +142,6 @@ 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.
|
||||
@@ -168,7 +171,7 @@ protected:
|
||||
/// returns the number of rows retreved.
|
||||
///
|
||||
/// Will throw, if the resultset is empty.
|
||||
/// Expects the statement to be compiled and bound
|
||||
/// Expects the statement to be compiled and bound.
|
||||
|
||||
virtual bool canBind() const = 0;
|
||||
/// Returns if another bind is possible.
|
||||
@@ -254,6 +257,12 @@ protected:
|
||||
Poco::UInt32 activateNextDataSet();
|
||||
/// Returns the next data set, or -1 if the last data set was reached.
|
||||
|
||||
Poco::UInt32 getExtractionLimit();
|
||||
/// Returns the extraction limit value.
|
||||
|
||||
const Limit& extractionLimit() const;
|
||||
/// Returns the extraction limit.
|
||||
|
||||
private:
|
||||
void compile();
|
||||
/// Compiles the statement, if not yet compiled. doesn't bind yet
|
||||
@@ -319,6 +328,31 @@ private:
|
||||
bool isNull(std::size_t col, std::size_t row) const;
|
||||
/// Returns true if the value in [col, row] is null.
|
||||
|
||||
void forbidBulk();
|
||||
/// Forbids bulk operations.
|
||||
|
||||
void setBulkBinding();
|
||||
/// Sets the bulk binding flag.
|
||||
|
||||
void setBulkExtraction(const Bulk& l);
|
||||
/// Sets the bulk extraction flag and extraction limit.
|
||||
|
||||
bool bulkBindingAllowed() const;
|
||||
/// Returns true if statement can be set to bind data in bulk.
|
||||
/// Once bulk binding is set for a statement, it can be
|
||||
/// neither altered nor mixed with non-bulk mode binding.
|
||||
|
||||
bool bulkExtractionAllowed() const;
|
||||
/// Returns true if statement can be set to extract data in bulk.
|
||||
/// Once bulk extraction is set for a statement, it can be
|
||||
/// neither altered nor mixed with non-bulk mode extraction.
|
||||
|
||||
bool isBulkBinding() const;
|
||||
/// Returns true if statement is set to bind data in bulk.
|
||||
|
||||
bool isBulkExtraction() const;
|
||||
/// Returns true if statement is set to extract data in bulk.
|
||||
|
||||
StatementImpl(const StatementImpl& stmt);
|
||||
StatementImpl& operator = (const StatementImpl& stmt);
|
||||
|
||||
@@ -332,7 +366,8 @@ private:
|
||||
AbstractBindingVec _bindings;
|
||||
AbstractExtractionVecVec _extractors;
|
||||
Poco::UInt32 _curDataSet;
|
||||
Poco::UInt32 _step;
|
||||
BulkType _bulkBinding;
|
||||
BulkType _bulkExtraction;
|
||||
|
||||
friend class Statement;
|
||||
};
|
||||
@@ -411,18 +446,6 @@ 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();
|
||||
@@ -459,6 +482,57 @@ inline Poco::UInt32 StatementImpl::currentDataSet() const
|
||||
}
|
||||
|
||||
|
||||
inline Poco::UInt32 StatementImpl::getExtractionLimit()
|
||||
{
|
||||
return _extrLimit.value();
|
||||
}
|
||||
|
||||
|
||||
inline const Limit& StatementImpl::extractionLimit() const
|
||||
{
|
||||
return _extrLimit;
|
||||
}
|
||||
|
||||
|
||||
inline void StatementImpl::forbidBulk()
|
||||
{
|
||||
_bulkBinding = BULK_FORBIDDEN;
|
||||
_bulkExtraction = BULK_FORBIDDEN;
|
||||
}
|
||||
|
||||
|
||||
inline void StatementImpl::setBulkBinding()
|
||||
{
|
||||
_bulkBinding = BULK_BINDING;
|
||||
}
|
||||
|
||||
|
||||
inline bool StatementImpl::bulkBindingAllowed() const
|
||||
{
|
||||
return BULK_UNDEFINED == _bulkBinding ||
|
||||
BULK_BINDING == _bulkBinding;
|
||||
}
|
||||
|
||||
|
||||
inline bool StatementImpl::bulkExtractionAllowed() const
|
||||
{
|
||||
return BULK_UNDEFINED == _bulkExtraction ||
|
||||
BULK_EXTRACTION == _bulkExtraction;
|
||||
}
|
||||
|
||||
|
||||
inline bool StatementImpl::isBulkBinding() const
|
||||
{
|
||||
return BULK_BINDING == _bulkBinding;
|
||||
}
|
||||
|
||||
|
||||
inline bool StatementImpl::isBulkExtraction() const
|
||||
{
|
||||
return BULK_EXTRACTION == _bulkExtraction;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
|
@@ -52,8 +52,21 @@ namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
class AbstractTypeHandler
|
||||
/// Parent class for type handlers.
|
||||
/// The reason for this class is to prevent instantiations of type handlers.
|
||||
/// For documentation on type handlers, see TypeHandler class.
|
||||
{
|
||||
protected:
|
||||
AbstractTypeHandler();
|
||||
~AbstractTypeHandler();
|
||||
AbstractTypeHandler(const AbstractTypeHandler&);
|
||||
AbstractTypeHandler& operator = (const AbstractTypeHandler&);
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
class TypeHandler
|
||||
class TypeHandler: public AbstractTypeHandler
|
||||
/// Converts Rows to a Type and the other way around. Provide template specializations to support your own complex types.
|
||||
///
|
||||
/// Take as example the following (simplified) class:
|
||||
@@ -66,7 +79,7 @@ class TypeHandler
|
||||
/// [....] // public set/get methods, a default constructor, optional < operator (for set, multiset) or function operator (for map, multimap)
|
||||
/// };
|
||||
///
|
||||
/// The TypeHandler must provide a costum bind, size, prepare and extract method:
|
||||
/// The TypeHandler must provide a custom bind, size, prepare and extract method:
|
||||
///
|
||||
/// template <>
|
||||
/// class TypeHandler<struct Person>
|
||||
@@ -132,19 +145,16 @@ public:
|
||||
static void extract(std::size_t pos, T& obj, const T& defVal, AbstractExtractor* pExt)
|
||||
{
|
||||
poco_assert_dbg (pExt != 0);
|
||||
if (!pExt->extract(pos, obj))
|
||||
obj = defVal;
|
||||
if (!pExt->extract(pos, obj)) obj = defVal;
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, const T& obj, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, T& obj, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert_dbg (pPrepare != 0);
|
||||
pPrepare->prepare(pos, obj);
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator = (const TypeHandler&);
|
||||
};
|
||||
@@ -204,7 +214,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<19>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -280,8 +290,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -336,7 +344,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<18>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -409,8 +417,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -463,7 +469,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<17>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -533,8 +539,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -585,7 +589,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<16>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -652,8 +656,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -702,7 +704,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<15>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -766,8 +768,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -814,7 +814,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<14>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -875,8 +875,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -921,7 +919,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<13>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -979,8 +977,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -1023,7 +1019,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<12>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -1078,8 +1074,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -1120,7 +1114,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<11>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -1172,8 +1166,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -1212,7 +1204,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<10>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -1261,8 +1253,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -1290,7 +1280,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<9>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -1336,8 +1326,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -1364,7 +1352,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<8>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -1407,8 +1395,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -1434,7 +1420,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<7>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -1474,8 +1460,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -1500,7 +1484,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<6>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -1537,8 +1521,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -1562,7 +1544,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<5>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -1596,8 +1578,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -1620,7 +1600,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<4>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -1651,8 +1631,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -1674,7 +1652,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<3>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -1702,8 +1680,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -1724,7 +1700,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<2>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -1749,8 +1725,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -1770,7 +1744,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<1>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -1792,8 +1766,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
@@ -1812,7 +1784,7 @@ public:
|
||||
pBinder->bind(pos++, tuple.template get<0>(), dir);
|
||||
}
|
||||
|
||||
static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparation* pPrepare)
|
||||
static void prepare(std::size_t pos, TupleRef tuple, AbstractPreparation* pPrepare)
|
||||
{
|
||||
poco_assert (pPrepare != 0);
|
||||
pPrepare->prepare(pos++, tuple.template get<0>());
|
||||
@@ -1832,8 +1804,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
TypeHandler();
|
||||
~TypeHandler();
|
||||
TypeHandler(const TypeHandler&);
|
||||
TypeHandler& operator=(const TypeHandler&);
|
||||
};
|
||||
|
@@ -35,10 +35,13 @@
|
||||
|
||||
|
||||
#include "Poco/Data/AbstractBinder.h"
|
||||
#include "Poco/Data/Date.h"
|
||||
#include "Poco/Data/Time.h"
|
||||
#include "Poco/Data/BLOB.h"
|
||||
#include "Poco/Data/DataException.h"
|
||||
#include "Poco/DateTime.h"
|
||||
#include "Poco/Any.h"
|
||||
#include "Poco/DynamicAny.h"
|
||||
#include "Poco/Data/BLOB.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@@ -55,40 +58,162 @@ AbstractBinder::~AbstractBinder()
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<long>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<bool>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<float>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<double>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<char>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<std::string>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<BLOB>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<DateTime>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<Date>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<Time>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const std::vector<NullData>& val, Direction dir)
|
||||
{
|
||||
throw NotImplementedException("std::vector binder must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const Any& val, Direction dir)
|
||||
{
|
||||
if(val.type() == typeid(Int32))
|
||||
const std::type_info& type = val.type();
|
||||
|
||||
if(type == typeid(Int32))
|
||||
bind(pos, RefAnyCast<Int32>(val), dir);
|
||||
else if(val.type() == typeid(std::string))
|
||||
else if(type == typeid(std::string))
|
||||
bind(pos, RefAnyCast<std::string>(val), dir);
|
||||
else if (val.type() == typeid(bool))
|
||||
else if (type == typeid(bool))
|
||||
bind(pos, RefAnyCast<bool>(val), dir);
|
||||
else if(val.type() == typeid(char))
|
||||
else if(type == typeid(char))
|
||||
bind(pos, RefAnyCast<char>(val), dir);
|
||||
else if(val.type() == typeid(Int8))
|
||||
else if(type == typeid(Int8))
|
||||
bind(pos, RefAnyCast<Int8>(val), dir);
|
||||
else if(val.type() == typeid(UInt8))
|
||||
else if(type == typeid(UInt8))
|
||||
bind(pos, RefAnyCast<UInt8>(val), dir);
|
||||
else if(val.type() == typeid(Int16))
|
||||
else if(type == typeid(Int16))
|
||||
bind(pos, RefAnyCast<Int16>(val), dir);
|
||||
else if(val.type() == typeid(UInt16))
|
||||
else if(type == typeid(UInt16))
|
||||
bind(pos, RefAnyCast<UInt16>(val), dir);
|
||||
else if(val.type() == typeid(UInt32))
|
||||
else if(type == typeid(UInt32))
|
||||
bind(pos, RefAnyCast<UInt32>(val), dir);
|
||||
else if(val.type() == typeid(Int64))
|
||||
else if(type == typeid(Int64))
|
||||
bind(pos, RefAnyCast<Int64>(val), dir);
|
||||
else if(val.type() == typeid(UInt64))
|
||||
else if(type == typeid(UInt64))
|
||||
bind(pos, RefAnyCast<UInt64>(val), dir);
|
||||
else if(val.type() == typeid(float))
|
||||
else if(type == typeid(float))
|
||||
bind(pos, RefAnyCast<float>(val), dir);
|
||||
else if(val.type() == typeid(double))
|
||||
else if(type == typeid(double))
|
||||
bind(pos, RefAnyCast<double>(val), dir);
|
||||
else if(val.type() == typeid(DateTime))
|
||||
else if(type == typeid(DateTime))
|
||||
bind(pos, RefAnyCast<DateTime>(val), dir);
|
||||
else if(val.type() == typeid(BLOB))
|
||||
else if(type == typeid(Date))
|
||||
bind(pos, RefAnyCast<Date>(val), dir);
|
||||
else if(type == typeid(Time))
|
||||
bind(pos, RefAnyCast<Time>(val), dir);
|
||||
else if(type == typeid(BLOB))
|
||||
bind(pos, RefAnyCast<BLOB>(val), dir);
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
else if(val.type() == typeid(long))
|
||||
else if(type == typeid(long))
|
||||
bind(pos, RefAnyCast<long>(val), dir);
|
||||
#endif
|
||||
else
|
||||
@@ -98,38 +223,44 @@ void AbstractBinder::bind(std::size_t pos, const Any& val, Direction dir)
|
||||
|
||||
void AbstractBinder::bind(std::size_t pos, const DynamicAny& val, Direction dir)
|
||||
{
|
||||
if(val.type() == typeid(Int32))
|
||||
const std::type_info& type = val.type();
|
||||
|
||||
if(type == typeid(Int32))
|
||||
bind(pos, val.extract<Int32>(), dir);
|
||||
else if(val.type() == typeid(std::string))
|
||||
else if(type == typeid(std::string))
|
||||
bind(pos, val.extract<std::string>(), dir);
|
||||
else if (val.type() == typeid(bool))
|
||||
else if (type == typeid(bool))
|
||||
bind(pos, val.extract<bool>(), dir);
|
||||
else if(val.type() == typeid(char))
|
||||
else if(type == typeid(char))
|
||||
bind(pos, val.extract<char>(), dir);
|
||||
else if(val.type() == typeid(Int8))
|
||||
else if(type == typeid(Int8))
|
||||
bind(pos, val.extract<Int8>(), dir);
|
||||
else if(val.type() == typeid(UInt8))
|
||||
else if(type == typeid(UInt8))
|
||||
bind(pos, val.extract<UInt8>(), dir);
|
||||
else if(val.type() == typeid(Int16))
|
||||
else if(type == typeid(Int16))
|
||||
bind(pos, val.extract<Int16>(), dir);
|
||||
else if(val.type() == typeid(UInt16))
|
||||
else if(type == typeid(UInt16))
|
||||
bind(pos, val.extract<UInt16>(), dir);
|
||||
else if(val.type() == typeid(UInt32))
|
||||
else if(type == typeid(UInt32))
|
||||
bind(pos, val.extract<UInt32>(), dir);
|
||||
else if(val.type() == typeid(Int64))
|
||||
else if(type == typeid(Int64))
|
||||
bind(pos, val.extract<Int64>(), dir);
|
||||
else if(val.type() == typeid(UInt64))
|
||||
else if(type == typeid(UInt64))
|
||||
bind(pos, val.extract<UInt64>(), dir);
|
||||
else if(val.type() == typeid(float))
|
||||
else if(type == typeid(float))
|
||||
bind(pos, val.extract<float>(), dir);
|
||||
else if(val.type() == typeid(double))
|
||||
else if(type == typeid(double))
|
||||
bind(pos, val.extract<double>(), dir);
|
||||
else if(val.type() == typeid(DateTime))
|
||||
else if(type == typeid(DateTime))
|
||||
bind(pos, val.extract<DateTime>(), dir);
|
||||
else if(val.type() == typeid(BLOB))
|
||||
else if(type == typeid(Date))
|
||||
bind(pos, val.extract<Date>(), dir);
|
||||
else if(type == typeid(Time))
|
||||
bind(pos, val.extract<Time>(), dir);
|
||||
else if(type == typeid(BLOB))
|
||||
bind(pos, val.extract<BLOB>(), dir);
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
else if(val.type() == typeid(long))
|
||||
else if(type == typeid(long))
|
||||
bind(pos, val.extract<long>(), dir);
|
||||
#endif
|
||||
else
|
||||
|
@@ -41,10 +41,13 @@ namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
AbstractBinding::AbstractBinding(const std::string& name, Direction direction):
|
||||
AbstractBinding::AbstractBinding(const std::string& name,
|
||||
Direction direction,
|
||||
Poco::UInt32 bulkSize):
|
||||
_pBinder(0),
|
||||
_name(name),
|
||||
_direction(direction)
|
||||
_direction(direction),
|
||||
_bulkSize(bulkSize)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -42,10 +42,12 @@ namespace Data {
|
||||
|
||||
|
||||
AbstractExtraction::AbstractExtraction(Poco::UInt32 limit,
|
||||
Poco::UInt32 position):
|
||||
Poco::UInt32 position,
|
||||
bool bulk):
|
||||
_pExtractor(0),
|
||||
_limit(limit),
|
||||
_position(position)
|
||||
_position(position),
|
||||
_bulk(bulk)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -35,6 +35,7 @@
|
||||
|
||||
|
||||
#include "Poco/Data/AbstractExtractor.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@@ -51,4 +52,126 @@ AbstractExtractor::~AbstractExtractor()
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<Poco::Int8>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<Poco::UInt8>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<Poco::Int16>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<Poco::UInt16>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<Poco::Int32>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<Poco::UInt32>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<Poco::Int64>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<Poco::UInt64>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<long>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<bool>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<float>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<double>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<char>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<std::string>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<BLOB>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<DateTime>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<Date>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<Time>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<Any>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool AbstractExtractor::extract(std::size_t pos, std::vector<DynamicAny>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
@@ -41,7 +41,8 @@ namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
AbstractPreparation::AbstractPreparation()
|
||||
AbstractPreparation::AbstractPreparation(Poco::UInt32 length):
|
||||
_length(length)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -51,4 +52,126 @@ AbstractPreparation::~AbstractPreparation()
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, std::vector<Poco::Int8>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, std::vector<Poco::UInt8>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, std::vector<Poco::Int16>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, std::vector<Poco::UInt16>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, std::vector<Poco::Int32>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, std::vector<Poco::UInt32>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, std::vector<Poco::Int64>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, std::vector<Poco::UInt64>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
void AbstractPreparation::prepare(std::size_t pos, std::vector<long>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, std::vector<bool>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, std::vector<float>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, std::vector<double>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, std::vector<char>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, const std::vector<std::string>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, const std::vector<BLOB>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, const std::vector<DateTime>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, const std::vector<Date>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, const std::vector<Time>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, const std::vector<Any>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
void AbstractPreparation::prepare(std::size_t pos, const std::vector<DynamicAny>& val)
|
||||
{
|
||||
throw NotImplementedException("std::vector preparation must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
59
Data/src/Bulk.cpp
Normal file
59
Data/src/Bulk.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// Bulk.cpp
|
||||
//
|
||||
// $Id: //poco/Main/Data/src/Bulk.cpp#7 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: DataCore
|
||||
// Module: Bulk
|
||||
//
|
||||
// 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/Bulk.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
Bulk::Bulk(const Limit& limit): _limit(limit.value(), false, false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Bulk::Bulk(Poco::UInt32 value): _limit(value, false, false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Bulk::~Bulk()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
@@ -51,10 +51,10 @@ POCO_IMPLEMENT_EXCEPTION(BindingException, DataException, "Binding error")
|
||||
POCO_IMPLEMENT_EXCEPTION(ExtractException, DataException, "Extraction error")
|
||||
POCO_IMPLEMENT_EXCEPTION(LimitException, DataException, "Limit error")
|
||||
POCO_IMPLEMENT_EXCEPTION(NotSupportedException, DataException, "Feature or property not supported")
|
||||
POCO_IMPLEMENT_EXCEPTION(NotImplementedException, DataException, "Feature or property not implemented")
|
||||
POCO_IMPLEMENT_EXCEPTION(SessionUnavailableException, DataException, "Session is unavailable")
|
||||
POCO_IMPLEMENT_EXCEPTION(SessionPoolExhaustedException, DataException, "No more sessions available from the session pool")
|
||||
POCO_IMPLEMENT_EXCEPTION(NoDataException, DataException, "No data found")
|
||||
POCO_IMPLEMENT_EXCEPTION(LengthExceededException, DataException, "Data too long")
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
@@ -1,11 +1,11 @@
|
||||
//
|
||||
// Step.cpp
|
||||
// Position.cpp
|
||||
//
|
||||
// $Id: //poco/Main/Data/src/Step.cpp#5 $
|
||||
// $Id: //poco/Main/Data/src/Position.cpp#7 $
|
||||
//
|
||||
// Library: Data
|
||||
// Package: DataCore
|
||||
// Module: Step
|
||||
// Module: Position
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
@@ -34,20 +34,19 @@
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/Step.h"
|
||||
#include "Poco/Data/Position.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
Step::Step(Poco::UInt32 value):
|
||||
_value(value)
|
||||
Position::Position(Poco::UInt32 value): _value(value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Step::~Step()
|
||||
Position::~Position()
|
||||
{
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include "Poco/Data/DataException.h"
|
||||
#include "Poco/Data/Extraction.h"
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/Data/Bulk.h"
|
||||
#include "Poco/Any.h"
|
||||
#include "Poco/Tuple.h"
|
||||
#include "Poco/ActiveMethod.h"
|
||||
@@ -189,58 +190,84 @@ const std::string& Statement::getStorage() const
|
||||
}
|
||||
|
||||
|
||||
void now(Statement& statement)
|
||||
Statement& Statement::operator , (Manipulator manip)
|
||||
{
|
||||
statement.execute();
|
||||
manip(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void sync(Statement& statement)
|
||||
Statement& Statement::operator , (AbstractBinding* pBind)
|
||||
{
|
||||
statement.setAsync(false);
|
||||
if (pBind->isBulk())
|
||||
{
|
||||
if(_pImpl->bulkBindingAllowed())
|
||||
_pImpl->setBulkBinding();
|
||||
else
|
||||
throw InvalidAccessException("Bulk and non-bulk binding modes can not be mixed.");
|
||||
}
|
||||
else _pImpl->forbidBulk();
|
||||
|
||||
_pImpl->addBinding(pBind);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void async(Statement& statement)
|
||||
Statement& Statement::operator , (AbstractExtraction* pExtract)
|
||||
{
|
||||
statement.setAsync(true);
|
||||
if (pExtract->isBulk())
|
||||
{
|
||||
if(_pImpl->bulkExtractionAllowed())
|
||||
{
|
||||
Bulk b(pExtract->getLimit());
|
||||
_pImpl->setBulkExtraction(b);
|
||||
}
|
||||
else
|
||||
throw InvalidAccessException("Bulk and non-bulk extraction modes can not be mixed.");
|
||||
}
|
||||
else _pImpl->forbidBulk();
|
||||
|
||||
_pImpl->addExtract(pExtract);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void vector(Statement& statement)
|
||||
Statement& Statement::operator , (const Limit& extrLimit)
|
||||
{
|
||||
if (!statement.canModifyStorage())
|
||||
throw InvalidAccessException("Storage not modifiable.");
|
||||
if (_pImpl->isBulkExtraction() && _pImpl->extractionLimit() != extrLimit)
|
||||
throw InvalidArgumentException("Limit for bulk extraction already set.");
|
||||
|
||||
statement.setStorage("vector");
|
||||
_pImpl->setExtractionLimit(extrLimit);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void list(Statement& statement)
|
||||
Statement& Statement::operator , (const Range& extrRange)
|
||||
{
|
||||
if (!statement.canModifyStorage())
|
||||
throw InvalidAccessException("Storage not modifiable.");
|
||||
if (_pImpl->isBulkExtraction())
|
||||
throw InvalidAccessException("Can not set range for bulk extraction.");
|
||||
|
||||
statement.setStorage("list");
|
||||
_pImpl->setExtractionLimit(extrRange.lower());
|
||||
_pImpl->setExtractionLimit(extrRange.upper());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void deque(Statement& statement)
|
||||
Statement& Statement::operator , (const Bulk& bulk)
|
||||
{
|
||||
if (!statement.canModifyStorage())
|
||||
throw InvalidAccessException("Storage not modifiable.");
|
||||
|
||||
statement.setStorage("deque");
|
||||
if (0 == _pImpl->extractions().size() &&
|
||||
0 == _pImpl->bindings().size() &&
|
||||
_pImpl->bulkExtractionAllowed() &&
|
||||
_pImpl->bulkBindingAllowed())
|
||||
{
|
||||
Limit l(_pImpl->getExtractionLimit(), false, false);
|
||||
_pImpl->setBulkExtraction(bulk);
|
||||
_pImpl->setBulkBinding();
|
||||
}
|
||||
else
|
||||
throw InvalidAccessException("Can not set bulk operations.");
|
||||
|
||||
|
||||
void reset(Statement& statement)
|
||||
{
|
||||
if (!statement.canModifyStorage())
|
||||
throw InvalidAccessException("Storage not modifiable.");
|
||||
|
||||
statement.setStorage("deque");
|
||||
statement.setAsync(false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -59,7 +59,6 @@ const std::string StatementImpl::LIST = "list";
|
||||
const std::string StatementImpl::DEQUE = "deque";
|
||||
const std::string StatementImpl::UNKNOWN = "unknown";
|
||||
|
||||
|
||||
StatementImpl::StatementImpl(SessionImpl& rSession):
|
||||
_state(ST_INITIALIZED),
|
||||
_extrLimit(upperLimit((Poco::UInt32) Limit::LIMIT_UNLIMITED, false)),
|
||||
@@ -70,7 +69,8 @@ StatementImpl::StatementImpl(SessionImpl& rSession):
|
||||
_ostr(),
|
||||
_bindings(),
|
||||
_curDataSet(0),
|
||||
_step(1u)
|
||||
_bulkBinding(BULK_UNDEFINED),
|
||||
_bulkExtraction(BULK_UNDEFINED)
|
||||
{
|
||||
_extractors.resize(1);
|
||||
}
|
||||
@@ -94,9 +94,8 @@ Poco::UInt32 StatementImpl::execute()
|
||||
lim = executeWithLimit();
|
||||
|
||||
if (lim < _lowerLimit)
|
||||
{
|
||||
throw LimitException("Did not receive enough data.");
|
||||
}
|
||||
|
||||
return lim;
|
||||
}
|
||||
|
||||
@@ -106,16 +105,17 @@ Poco::UInt32 StatementImpl::executeWithLimit()
|
||||
poco_assert (_state != ST_DONE);
|
||||
compile();
|
||||
Poco::UInt32 count = 0;
|
||||
Poco::UInt32 limit = _extrLimit.value();
|
||||
do
|
||||
{
|
||||
bind();
|
||||
while (hasNext() && count < _extrLimit.value())
|
||||
while (count < limit && hasNext())
|
||||
count += next();
|
||||
} while (canBind());
|
||||
} while (count < limit && canBind());
|
||||
|
||||
if (!canBind() && (!hasNext() || _extrLimit.value() == 0))
|
||||
if (!canBind() && (!hasNext() || limit == 0))
|
||||
_state = ST_DONE;
|
||||
else if (hasNext() && _extrLimit.value() == count && _extrLimit.isHardLimit())
|
||||
else if (hasNext() && limit == count && _extrLimit.isHardLimit())
|
||||
throw LimitException("HardLimit reached. We got more data than we asked for");
|
||||
else
|
||||
_state = ST_PAUSED;
|
||||
@@ -176,12 +176,8 @@ void StatementImpl::bind()
|
||||
{
|
||||
if (!hasNext())
|
||||
{
|
||||
if (canBind())
|
||||
{
|
||||
bindImpl();
|
||||
}
|
||||
else
|
||||
_state = ST_DONE;
|
||||
if (canBind()) bindImpl();
|
||||
else _state = ST_DONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,6 +199,17 @@ void StatementImpl::setExtractionLimit(const Limit& extrLimit)
|
||||
}
|
||||
|
||||
|
||||
void StatementImpl::setBulkExtraction(const Bulk& b)
|
||||
{
|
||||
Poco::UInt32 limit = getExtractionLimit();
|
||||
if (Limit::LIMIT_UNLIMITED != limit && b.size() != limit)
|
||||
throw InvalidArgumentException("Can not set limit for statement.");
|
||||
|
||||
setExtractionLimit(b.limit());
|
||||
_bulkExtraction = BULK_EXTRACTION;
|
||||
}
|
||||
|
||||
|
||||
void StatementImpl::fixupExtraction()
|
||||
{
|
||||
Poco::Data::AbstractExtractionVec::iterator it = extractions().begin();
|
||||
@@ -339,7 +346,7 @@ Poco::UInt32 StatementImpl::activateNextDataSet()
|
||||
if (_curDataSet + 1 < dataSetCount())
|
||||
return ++_curDataSet;
|
||||
else
|
||||
throw InvalidAccessException("End of data sets reached.");
|
||||
throw NoDataException("End of data sets reached.");
|
||||
}
|
||||
|
||||
|
||||
|
@@ -65,6 +65,7 @@ using Poco::InvalidAccessException;
|
||||
using Poco::RangeException;
|
||||
using Poco::NotFoundException;
|
||||
using Poco::InvalidArgumentException;
|
||||
using Poco::NotImplementedException;
|
||||
|
||||
|
||||
DataTest::DataTest(const std::string& name): CppUnit::TestCase(name)
|
||||
@@ -1026,16 +1027,34 @@ void DataTest::testDateAndTime()
|
||||
Date d1(2007, 6, 15);
|
||||
d1.assign(d.year() - 1, d.month(), d.day());
|
||||
assert (d1 < d); assert (d1 != d);
|
||||
if (d.month() > 1)
|
||||
d1.assign(d.year(), d.month() - 1, d.day());
|
||||
else
|
||||
d1.assign(d.year() - 1, 12, d.day());
|
||||
|
||||
assert (d1 < d); assert (d1 != d);
|
||||
|
||||
if (d.day() > 1)
|
||||
{
|
||||
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);
|
||||
|
||||
if (d.month() < 12)
|
||||
d1.assign(d.year(), d.month() + 1, d.day());
|
||||
else
|
||||
d1.assign(d.year() + 1, 1, d.day());
|
||||
assert (d1 > d); assert (d1 != d);
|
||||
|
||||
if (d.day() < dt.daysOfMonth(dt.year(), dt.month()))
|
||||
{
|
||||
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);
|
||||
|
||||
|
@@ -116,7 +116,7 @@ public:
|
||||
bool extract(std::size_t pos, Poco::DateTime& val);
|
||||
/// Extracts a DateTime.
|
||||
|
||||
bool isNull(std::size_t pos);
|
||||
bool isNull(std::size_t col, std::size_t row = -1);
|
||||
/// Returns true if the current row value at pos column is null.
|
||||
|
||||
void reset();
|
||||
@@ -128,7 +128,7 @@ inline void Extractor::reset()
|
||||
}
|
||||
|
||||
|
||||
inline bool Extractor::isNull(std::size_t pos)
|
||||
inline bool Extractor::isNull(std::size_t col, std::size_t row)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@@ -50,69 +50,69 @@ Preparation::~Preparation()
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, Poco::Int8)
|
||||
void Preparation::prepare(std::size_t pos, Poco::Int8&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, Poco::UInt8)
|
||||
void Preparation::prepare(std::size_t pos, Poco::UInt8&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, Poco::Int16)
|
||||
void Preparation::prepare(std::size_t pos, Poco::Int16&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, Poco::UInt16)
|
||||
void Preparation::prepare(std::size_t pos, Poco::UInt16&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, Poco::Int32)
|
||||
void Preparation::prepare(std::size_t pos, Poco::Int32&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, Poco::UInt32)
|
||||
void Preparation::prepare(std::size_t pos, Poco::UInt32&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, Poco::Int64)
|
||||
void Preparation::prepare(std::size_t pos, Poco::Int64&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, Poco::UInt64)
|
||||
void Preparation::prepare(std::size_t pos, Poco::UInt64&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
void Preparation::prepare(std::size_t pos, long)
|
||||
void Preparation::prepare(std::size_t pos, long&)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, bool)
|
||||
void Preparation::prepare(std::size_t pos, bool&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, float)
|
||||
void Preparation::prepare(std::size_t pos, float&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, double)
|
||||
void Preparation::prepare(std::size_t pos, double&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Preparation::prepare(std::size_t pos, char)
|
||||
void Preparation::prepare(std::size_t pos, char&)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -55,45 +55,45 @@ public:
|
||||
~Preparation();
|
||||
/// Destroys the Preparation.
|
||||
|
||||
void prepare(std::size_t pos, Poco::Int8);
|
||||
void prepare(std::size_t pos, Poco::Int8&);
|
||||
/// Prepares an Int8.
|
||||
|
||||
void prepare(std::size_t pos, Poco::UInt8);
|
||||
void prepare(std::size_t pos, Poco::UInt8&);
|
||||
/// Prepares an UInt8.
|
||||
|
||||
void prepare(std::size_t pos, Poco::Int16);
|
||||
void prepare(std::size_t pos, Poco::Int16&);
|
||||
/// Prepares an Int16.
|
||||
|
||||
void prepare(std::size_t pos, Poco::UInt16);
|
||||
void prepare(std::size_t pos, Poco::UInt16&);
|
||||
/// Prepares an UInt16.
|
||||
|
||||
void prepare(std::size_t pos, Poco::Int32);
|
||||
void prepare(std::size_t pos, Poco::Int32&);
|
||||
/// Prepares an Int32.
|
||||
|
||||
void prepare(std::size_t pos, Poco::UInt32);
|
||||
void prepare(std::size_t pos, Poco::UInt32&);
|
||||
/// Prepares an UInt32.
|
||||
|
||||
void prepare(std::size_t pos, Poco::Int64);
|
||||
void prepare(std::size_t pos, Poco::Int64&);
|
||||
/// Prepares an Int64.
|
||||
|
||||
void prepare(std::size_t pos, Poco::UInt64);
|
||||
void prepare(std::size_t pos, Poco::UInt64&);
|
||||
/// Prepares an UInt64.
|
||||
|
||||
#ifndef POCO_LONG_IS_64_BIT
|
||||
void prepare(std::size_t pos, long);
|
||||
void prepare(std::size_t pos, long&);
|
||||
/// Prepares a long.
|
||||
#endif
|
||||
|
||||
void prepare(std::size_t pos, bool);
|
||||
void prepare(std::size_t pos, bool&);
|
||||
/// Prepares a boolean.
|
||||
|
||||
void prepare(std::size_t pos, float);
|
||||
void prepare(std::size_t pos, float&);
|
||||
/// Prepares a float.
|
||||
|
||||
void prepare(std::size_t pos, double);
|
||||
void prepare(std::size_t pos, double&);
|
||||
/// Prepares a double.
|
||||
|
||||
void prepare(std::size_t pos, char);
|
||||
void prepare(std::size_t pos, char&);
|
||||
/// Prepares a single character.
|
||||
|
||||
void prepare(std::size_t pos, const std::string&);
|
||||
|
Reference in New Issue
Block a user