mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-28 11:31:53 +01:00
bulk internal extraction fixes and tests; some renaming/refactoring
This commit is contained in:
@@ -17,7 +17,7 @@ $(error No ODBC library found. Please install unixODBC or iODBC and try again)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
objects = Binder ConnectionHandle Connector EnvironmentHandle \
|
objects = Binder ConnectionHandle Connector EnvironmentHandle \
|
||||||
Extractor ODBCColumn ODBCException ODBCStatementImpl \
|
Extractor ODBCMetaColumn ODBCException ODBCStatementImpl \
|
||||||
Parameter Preparation SessionImpl TypeInfo Unicode Utility
|
Parameter Preparation SessionImpl TypeInfo Unicode Utility
|
||||||
|
|
||||||
target = PocoODBC
|
target = PocoODBC
|
||||||
|
|||||||
@@ -176,7 +176,7 @@
|
|||||||
RelativePath=".\include\Poco\Data\Odbc\ODBC.h">
|
RelativePath=".\include\Poco\Data\Odbc\ODBC.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\Poco\Data\ODBC\ODBCColumn.h">
|
RelativePath=".\include\Poco\Data\ODBC\ODBCMetaColumn.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\Poco\Data\Odbc\ODBCException.h">
|
RelativePath=".\include\Poco\Data\Odbc\ODBCException.h">
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
RelativePath=".\src\Extractor.cpp">
|
RelativePath=".\src\Extractor.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\ODBCColumn.cpp">
|
RelativePath=".\src\ODBCMetaColumn.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\ODBCException.cpp">
|
RelativePath=".\src\ODBCException.cpp">
|
||||||
|
|||||||
@@ -246,11 +246,11 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\Poco\Data\ODBC\ODBCColumn.h"
|
RelativePath=".\include\Poco\Data\ODBC\ODBCException.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\Poco\Data\ODBC\ODBCException.h"
|
RelativePath=".\include\Poco\Data\ODBC\ODBCMetaColumn.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
@@ -314,11 +314,11 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\ODBCColumn.cpp"
|
RelativePath=".\src\ODBCException.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\ODBCException.cpp"
|
RelativePath=".\src\ODBCMetaColumn.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
#include "Poco/Data/AbstractBinder.h"
|
#include "Poco/Data/AbstractBinder.h"
|
||||||
#include "Poco/Data/ODBC/Handle.h"
|
#include "Poco/Data/ODBC/Handle.h"
|
||||||
#include "Poco/Data/ODBC/Parameter.h"
|
#include "Poco/Data/ODBC/Parameter.h"
|
||||||
#include "Poco/Data/ODBC/ODBCColumn.h"
|
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
|
||||||
#include "Poco/Data/ODBC/Utility.h"
|
#include "Poco/Data/ODBC/Utility.h"
|
||||||
#include "Poco/Data/ODBC/TypeInfo.h"
|
#include "Poco/Data/ODBC/TypeInfo.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
#include "Poco/Data/ODBC/ODBC.h"
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
#include "Poco/Data/AbstractExtractor.h"
|
#include "Poco/Data/AbstractExtractor.h"
|
||||||
#include "Poco/Data/ODBC/Preparation.h"
|
#include "Poco/Data/ODBC/Preparation.h"
|
||||||
#include "Poco/Data/ODBC/ODBCColumn.h"
|
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
|
||||||
#include "Poco/Data/ODBC/Error.h"
|
#include "Poco/Data/ODBC/Error.h"
|
||||||
#include "Poco/Data/ODBC/Utility.h"
|
#include "Poco/Data/ODBC/Utility.h"
|
||||||
#include "Poco/DateTime.h"
|
#include "Poco/DateTime.h"
|
||||||
@@ -401,7 +401,7 @@ private:
|
|||||||
bool extractImpl(std::size_t pos, T& val)
|
bool extractImpl(std::size_t pos, T& val)
|
||||||
/// Utility function for extraction of Any and DynamicAny.
|
/// Utility function for extraction of Any and DynamicAny.
|
||||||
{
|
{
|
||||||
ODBCColumn column(_rStmt, pos);
|
ODBCMetaColumn column(_rStmt, pos);
|
||||||
|
|
||||||
switch (column.type())
|
switch (column.type())
|
||||||
{
|
{
|
||||||
@@ -504,7 +504,7 @@ inline bool Extractor::isNullLengthIndicator(SQLLEN val) const
|
|||||||
|
|
||||||
inline SQLINTEGER Extractor::columnSize(std::size_t pos) const
|
inline SQLINTEGER Extractor::columnSize(std::size_t pos) const
|
||||||
{
|
{
|
||||||
std::size_t size = ODBCColumn(_rStmt, pos).length();
|
std::size_t size = ODBCMetaColumn(_rStmt, pos).length();
|
||||||
std::size_t maxSize = _rPreparation.maxDataSize(pos);
|
std::size_t maxSize = _rPreparation.maxDataSize(pos);
|
||||||
if (size > maxSize) size = maxSize;
|
if (size > maxSize) size = maxSize;
|
||||||
return (SQLINTEGER) size;
|
return (SQLINTEGER) size;
|
||||||
|
|||||||
@@ -77,8 +77,13 @@ public:
|
|||||||
~Handle()
|
~Handle()
|
||||||
/// Destroys the Handle.
|
/// Destroys the Handle.
|
||||||
{
|
{
|
||||||
SQLRETURN rc = SQLFreeHandle(handleType, _handle);
|
#if defined(_DEBUG)
|
||||||
poco_assert (!Utility::isError(rc));
|
SQLRETURN rc =
|
||||||
|
#endif
|
||||||
|
SQLFreeHandle(handleType, _handle);
|
||||||
|
// N.B. Destructors should not throw, but neither do we want to
|
||||||
|
// leak resources. So, we throw here in debug mode if things go bad.
|
||||||
|
poco_assert_dbg (!Utility::isError(rc));
|
||||||
}
|
}
|
||||||
|
|
||||||
operator const H& () const
|
operator const H& () const
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
//
|
//
|
||||||
// ODBCColumn.h
|
// ODBCMetaColumn.h
|
||||||
//
|
//
|
||||||
// $Id: //poco/Main/Data/ODBC/include/Poco/Data/ODBC/ODBCColumn.h#3 $
|
// $Id: //poco/Main/Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h#3 $
|
||||||
//
|
//
|
||||||
// Library: ODBC
|
// Library: ODBC
|
||||||
// Package: ODBC
|
// Package: ODBC
|
||||||
// Module: ODBCColumn
|
// Module: ODBCMetaColumn
|
||||||
//
|
//
|
||||||
// Definition of ODBCColumn.
|
// Definition of ODBCMetaColumn.
|
||||||
//
|
//
|
||||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||||
// and Contributors.
|
// and Contributors.
|
||||||
@@ -56,14 +56,14 @@ namespace Data {
|
|||||||
namespace ODBC {
|
namespace ODBC {
|
||||||
|
|
||||||
|
|
||||||
class ODBC_API ODBCColumn: public MetaColumn
|
class ODBC_API ODBCMetaColumn: public MetaColumn
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ODBCColumn(const StatementHandle& rStmt, std::size_t position);
|
explicit ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position);
|
||||||
/// Creates the ODBCColumn.
|
/// Creates the ODBCMetaColumn.
|
||||||
|
|
||||||
~ODBCColumn();
|
~ODBCMetaColumn();
|
||||||
/// Destroys the ODBCColumn.
|
/// Destroys the ODBCMetaColumn.
|
||||||
|
|
||||||
std::size_t dataLength() const;
|
std::size_t dataLength() const;
|
||||||
/// A numeric value that is either the maximum or actual character length of a character
|
/// A numeric value that is either the maximum or actual character length of a character
|
||||||
@@ -73,7 +73,7 @@ public:
|
|||||||
/// This information is returned from the SQL_DESC_LENGTH record field of the IRD.
|
/// This information is returned from the SQL_DESC_LENGTH record field of the IRD.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ODBCColumn();
|
ODBCMetaColumn();
|
||||||
|
|
||||||
static const int NAME_BUFFER_LENGTH = 2048;
|
static const int NAME_BUFFER_LENGTH = 2048;
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ private:
|
|||||||
///
|
///
|
||||||
/// inlines
|
/// inlines
|
||||||
///
|
///
|
||||||
inline std::size_t ODBCColumn::dataLength() const
|
inline std::size_t ODBCMetaColumn::dataLength() const
|
||||||
{
|
{
|
||||||
return _dataLength;
|
return _dataLength;
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
#include "Poco/Data/ODBC/Binder.h"
|
#include "Poco/Data/ODBC/Binder.h"
|
||||||
#include "Poco/Data/ODBC/Extractor.h"
|
#include "Poco/Data/ODBC/Extractor.h"
|
||||||
#include "Poco/Data/ODBC/Preparation.h"
|
#include "Poco/Data/ODBC/Preparation.h"
|
||||||
#include "Poco/Data/ODBC/ODBCColumn.h"
|
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
|
||||||
#include "Poco/Data/StatementImpl.h"
|
#include "Poco/Data/StatementImpl.h"
|
||||||
#include "Poco/Data/Column.h"
|
#include "Poco/Data/Column.h"
|
||||||
#include "Poco/SharedPtr.h"
|
#include "Poco/SharedPtr.h"
|
||||||
@@ -66,7 +66,7 @@ class ODBC_API ODBCStatementImpl: public Poco::Data::StatementImpl
|
|||||||
/// Implements statement functionality needed for ODBC
|
/// Implements statement functionality needed for ODBC
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::vector<ODBCColumn*> ColumnPtrVec;
|
typedef std::vector<ODBCMetaColumn*> ColumnPtrVec;
|
||||||
|
|
||||||
ODBCStatementImpl(SessionImpl& rSession);
|
ODBCStatementImpl(SessionImpl& rSession);
|
||||||
/// Creates the ODBCStatementImpl.
|
/// Creates the ODBCStatementImpl.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
#include "Poco/Data/ODBC/ODBC.h"
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
#include "Poco/Data/ODBC/Handle.h"
|
#include "Poco/Data/ODBC/Handle.h"
|
||||||
#include "Poco/Data/ODBC/ODBCColumn.h"
|
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
|
||||||
#include "Poco/Data/ODBC/Utility.h"
|
#include "Poco/Data/ODBC/Utility.h"
|
||||||
#include "Poco/Data/AbstractPreparation.h"
|
#include "Poco/Data/AbstractPreparation.h"
|
||||||
#include "Poco/Data/BLOB.h"
|
#include "Poco/Data/BLOB.h"
|
||||||
@@ -415,7 +415,7 @@ private:
|
|||||||
void prepareImpl(std::size_t pos, const C* pVal = 0)
|
void prepareImpl(std::size_t pos, const C* pVal = 0)
|
||||||
/// Utility function to prepare Any and DynamicAny.
|
/// Utility function to prepare Any and DynamicAny.
|
||||||
{
|
{
|
||||||
ODBCColumn col(_rStmt, pos);
|
ODBCMetaColumn col(_rStmt, pos);
|
||||||
|
|
||||||
switch (col.type())
|
switch (col.type())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -444,7 +444,7 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ODBCColumn c(_rStmt, pos);
|
ODBCMetaColumn c(_rStmt, pos);
|
||||||
colSize = (SQLINTEGER) c.length();
|
colSize = (SQLINTEGER) c.length();
|
||||||
decDigits = (SQLSMALLINT) c.precision();
|
decDigits = (SQLSMALLINT) c.precision();
|
||||||
return;
|
return;
|
||||||
@@ -465,7 +465,7 @@ void Binder::getColumnOrParameterSize(std::size_t pos, SQLINTEGER& size)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ODBCColumn col(_rStmt, pos);
|
ODBCMetaColumn col(_rStmt, pos);
|
||||||
colSize = col.length();
|
colSize = col.length();
|
||||||
}
|
}
|
||||||
catch (StatementException&) { }
|
catch (StatementException&) { }
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/ODBC/Extractor.h"
|
#include "Poco/Data/ODBC/Extractor.h"
|
||||||
#include "Poco/Data/ODBC/ODBCColumn.h"
|
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
|
||||||
#include "Poco/Data/ODBC/Utility.h"
|
#include "Poco/Data/ODBC/Utility.h"
|
||||||
#include "Poco/Data/ODBC/ODBCException.h"
|
#include "Poco/Data/ODBC/ODBCException.h"
|
||||||
#include "Poco/Data/BLOB.h"
|
#include "Poco/Data/BLOB.h"
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
//
|
//
|
||||||
// ODBCColumn.cpp
|
// ODBCMetaColumn.cpp
|
||||||
//
|
//
|
||||||
// $Id: //poco/Main/Data/ODBC/src/ODBCColumn.cpp#5 $
|
// $Id: //poco/Main/Data/ODBC/src/ODBCMetaColumn.cpp#5 $
|
||||||
//
|
//
|
||||||
// Library: ODBC
|
// Library: ODBC
|
||||||
// Package: ODBC
|
// Package: ODBC
|
||||||
// Module: ODBCColumn
|
// Module: ODBCMetaColumn
|
||||||
//
|
//
|
||||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||||
// and Contributors.
|
// and Contributors.
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/ODBC/ODBCColumn.h"
|
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
|
||||||
#include "Poco/Data/ODBC/Utility.h"
|
#include "Poco/Data/ODBC/Utility.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ namespace Data {
|
|||||||
namespace ODBC {
|
namespace ODBC {
|
||||||
|
|
||||||
|
|
||||||
ODBCColumn::ODBCColumn(const StatementHandle& rStmt, std::size_t position) :
|
ODBCMetaColumn::ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position) :
|
||||||
MetaColumn(position),
|
MetaColumn(position),
|
||||||
_rStmt(rStmt)
|
_rStmt(rStmt)
|
||||||
{
|
{
|
||||||
@@ -51,12 +51,12 @@ ODBCColumn::ODBCColumn(const StatementHandle& rStmt, std::size_t position) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ODBCColumn::~ODBCColumn()
|
ODBCMetaColumn::~ODBCMetaColumn()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCColumn::getDescription()
|
void ODBCMetaColumn::getDescription()
|
||||||
{
|
{
|
||||||
memset(_columnDesc.name, 0, NAME_BUFFER_LENGTH);
|
memset(_columnDesc.name, 0, NAME_BUFFER_LENGTH);
|
||||||
_columnDesc.nameBufferLength = 0;
|
_columnDesc.nameBufferLength = 0;
|
||||||
@@ -80,7 +80,7 @@ void ODBCColumn::getDescription()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCColumn::init()
|
void ODBCMetaColumn::init()
|
||||||
{
|
{
|
||||||
getDescription();
|
getDescription();
|
||||||
|
|
||||||
@@ -414,7 +414,7 @@ void ODBCStatementImpl::fillColumns()
|
|||||||
Poco::UInt32 colCount = columnsReturned();
|
Poco::UInt32 colCount = columnsReturned();
|
||||||
|
|
||||||
for (int i = 0; i < colCount; ++i)
|
for (int i = 0; i < colCount; ++i)
|
||||||
_columnPtrs.push_back(new ODBCColumn(_stmt, i));
|
_columnPtrs.push_back(new ODBCMetaColumn(_stmt, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/ODBC/Preparation.h"
|
#include "Poco/Data/ODBC/Preparation.h"
|
||||||
#include "Poco/Data/ODBC/ODBCColumn.h"
|
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
@@ -154,7 +154,7 @@ std::size_t Preparation::maxDataSize(std::size_t pos) const
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
sz = ODBCColumn(_rStmt, pos).length();
|
sz = ODBCMetaColumn(_rStmt, pos).length();
|
||||||
}
|
}
|
||||||
catch (StatementException&) { }
|
catch (StatementException&) { }
|
||||||
|
|
||||||
|
|||||||
@@ -588,6 +588,7 @@ CppUnit::Test* ODBCDB2Test::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testLimitZero);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testLimitZero);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testPrepare);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testPrepare);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testBulk);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testBulk);
|
||||||
|
CppUnit_addTest(pSuite, ODBCDB2Test, testBulkPerformance);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testSetSimple);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testSetSimple);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testSetComplex);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testSetComplex);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testSetComplexUnique);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testSetComplexUnique);
|
||||||
@@ -618,6 +619,7 @@ CppUnit::Test* ODBCDB2Test::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testTuple);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testTuple);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testTupleVector);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testTupleVector);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalExtraction);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalExtraction);
|
||||||
|
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalBulkExtraction);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalStorageType);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testInternalStorageType);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedure);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedure);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedureAny);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testStoredProcedureAny);
|
||||||
|
|||||||
@@ -406,6 +406,7 @@ CppUnit::Test* ODBCMySQLTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testLimitZero);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testLimitZero);
|
||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testPrepare);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testPrepare);
|
||||||
//CppUnit_addTest(pSuite, ODBCMySQLTest, testBulk);
|
//CppUnit_addTest(pSuite, ODBCMySQLTest, testBulk);
|
||||||
|
//CppUnit_addTest(pSuite, ODBCMySQLTest, testBulkPerformance);
|
||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testSetSimple);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testSetSimple);
|
||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testSetComplex);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testSetComplex);
|
||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testSetComplexUnique);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testSetComplexUnique);
|
||||||
@@ -438,6 +439,7 @@ CppUnit::Test* ODBCMySQLTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testStoredProcedure);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testStoredProcedure);
|
||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testStoredFunction);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testStoredFunction);
|
||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testInternalExtraction);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testInternalExtraction);
|
||||||
|
//CppUnit_addTest(pSuite, ODBCOracleTest, testInternalBulkExtraction);
|
||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testInternalStorageType);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testInternalStorageType);
|
||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testNull);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testNull);
|
||||||
CppUnit_addTest(pSuite, ODBCMySQLTest, testRowIterator);
|
CppUnit_addTest(pSuite, ODBCMySQLTest, testRowIterator);
|
||||||
|
|||||||
@@ -788,6 +788,7 @@ CppUnit::Test* ODBCOracleTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testLimitZero);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testLimitZero);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testPrepare);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testPrepare);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testBulk);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testBulk);
|
||||||
|
CppUnit_addTest(pSuite, ODBCOracleTest, testBulkPerformance);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testSetSimple);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testSetSimple);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testSetComplex);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testSetComplex);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testSetComplexUnique);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testSetComplexUnique);
|
||||||
@@ -823,6 +824,7 @@ CppUnit::Test* ODBCOracleTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredFunction);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testStoredFunction);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testCursorStoredFunction);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testCursorStoredFunction);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalExtraction);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalExtraction);
|
||||||
|
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalBulkExtraction);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalStorageType);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testInternalStorageType);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testNull);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testNull);
|
||||||
CppUnit_addTest(pSuite, ODBCOracleTest, testRowIterator);
|
CppUnit_addTest(pSuite, ODBCOracleTest, testRowIterator);
|
||||||
|
|||||||
@@ -522,7 +522,6 @@ void ODBCPostgreSQLTest::recreateMiscTable()
|
|||||||
dropObject("TABLE", "MiscTest");
|
dropObject("TABLE", "MiscTest");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// pgSQL fails with BLOB bulk operations
|
|
||||||
// Mammoth does not bind columns properly
|
// Mammoth does not bind columns properly
|
||||||
session() << "CREATE TABLE MiscTest "
|
session() << "CREATE TABLE MiscTest "
|
||||||
"(First VARCHAR(30),"
|
"(First VARCHAR(30),"
|
||||||
@@ -567,7 +566,12 @@ CppUnit::Test* ODBCPostgreSQLTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testLimitPrepare);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testLimitPrepare);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testLimitZero);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testLimitZero);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testPrepare);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testPrepare);
|
||||||
|
//On Linux, PostgreSQL driver returns SQL_NEED_DATA on SQLExecute (see ODBCStatementImpl::bindImpl() )
|
||||||
|
//this behavior is not expected and not handled for automatic binding
|
||||||
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testBulk);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testBulk);
|
||||||
|
#endif
|
||||||
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testBulkPerformance);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSetSimple);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSetSimple);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSetComplex);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSetComplex);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSetComplexUnique);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSetComplexUnique);
|
||||||
@@ -598,6 +602,11 @@ CppUnit::Test* ODBCPostgreSQLTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testTuple);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testTuple);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testTupleVector);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testTupleVector);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInternalExtraction);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInternalExtraction);
|
||||||
|
//On Linux, PostgreSQL driver returns SQL_NEED_DATA on SQLExecute (see ODBCStatementImpl::bindImpl() )
|
||||||
|
//this behavior is not expected and not handled for automatic binding
|
||||||
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInternalBulkExtraction);
|
||||||
|
#endif
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInternalStorageType);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInternalStorageType);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStoredFunction);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStoredFunction);
|
||||||
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStoredFunctionAny);
|
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testStoredFunctionAny);
|
||||||
|
|||||||
@@ -218,9 +218,6 @@ void ODBCSQLServerTest::testBulk()
|
|||||||
std::list<double>,
|
std::list<double>,
|
||||||
std::list<DateTime>,
|
std::list<DateTime>,
|
||||||
std::list<bool> >(100);
|
std::list<bool> >(100);
|
||||||
|
|
||||||
recreateMiscTable();
|
|
||||||
_pExecutor->doBulkPerformance(1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -696,6 +693,7 @@ CppUnit::Test* ODBCSQLServerTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testLimitZero);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testLimitZero);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testPrepare);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testPrepare);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testBulk);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testBulk);
|
||||||
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testBulkPerformance);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSetSimple);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSetSimple);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSetComplex);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSetComplex);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSetComplexUnique);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSetComplexUnique);
|
||||||
@@ -729,6 +727,7 @@ CppUnit::Test* ODBCSQLServerTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredProcedureDynamicAny);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredProcedureDynamicAny);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredFunction);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testStoredFunction);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalExtraction);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalExtraction);
|
||||||
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalBulkExtraction);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalStorageType);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testInternalStorageType);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testNull);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testNull);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testRowIterator);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testRowIterator);
|
||||||
|
|||||||
@@ -435,6 +435,15 @@ void ODBCTest::testBulk()
|
|||||||
std::list<BLOB>,
|
std::list<BLOB>,
|
||||||
std::list<double>,
|
std::list<double>,
|
||||||
std::list<DateTime> >(100);
|
std::list<DateTime> >(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCTest::testBulkPerformance()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
_pSession->setFeature("autoBind", true);
|
||||||
|
_pSession->setFeature("autoExtract", true);
|
||||||
|
|
||||||
recreateMiscTable();
|
recreateMiscTable();
|
||||||
_pExecutor->doBulkPerformance(1000);
|
_pExecutor->doBulkPerformance(1000);
|
||||||
@@ -894,6 +903,17 @@ void ODBCTest::testInternalExtraction()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCTest::testInternalBulkExtraction()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
recreatePersonTable();
|
||||||
|
_pSession->setFeature("autoBind", true);
|
||||||
|
_pSession->setFeature("autoExtract", true);
|
||||||
|
_pExecutor->internalBulkExtraction();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCTest::testInternalStorageType()
|
void ODBCTest::testInternalStorageType()
|
||||||
{
|
{
|
||||||
if (!_pSession) fail ("Test not available.");
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ public:
|
|||||||
virtual void testLimitZero();
|
virtual void testLimitZero();
|
||||||
virtual void testPrepare();
|
virtual void testPrepare();
|
||||||
virtual void testBulk();
|
virtual void testBulk();
|
||||||
|
virtual void testBulkPerformance();
|
||||||
|
|
||||||
virtual void testSetSimple();
|
virtual void testSetSimple();
|
||||||
virtual void testSetComplex();
|
virtual void testSetComplex();
|
||||||
@@ -128,6 +129,7 @@ public:
|
|||||||
virtual void testTupleVector();
|
virtual void testTupleVector();
|
||||||
|
|
||||||
virtual void testInternalExtraction();
|
virtual void testInternalExtraction();
|
||||||
|
virtual void testInternalBulkExtraction();
|
||||||
virtual void testInternalStorageType();
|
virtual void testInternalStorageType();
|
||||||
|
|
||||||
virtual void testStoredProcedure() { /* no-op */ };
|
virtual void testStoredProcedure() { /* no-op */ };
|
||||||
|
|||||||
@@ -2422,9 +2422,9 @@ void SQLExecutor::internalExtraction()
|
|||||||
i = rset.value("str0", 2);
|
i = rset.value("str0", 2);
|
||||||
assert (5 == i);
|
assert (5 == i);
|
||||||
|
|
||||||
const Column<int>& col = rset.column<int, std::deque<int> >(0);
|
const Column<std::deque<int> >& col = rset.column<std::deque<int>, InternalExtraction<std::deque<int> > >(0);
|
||||||
Column<int>::Iterator it = col.begin();
|
Column<std::deque<int> >::Iterator it = col.begin();
|
||||||
Column<int>::Iterator end = col.end();
|
Column<std::deque<int> >::Iterator end = col.end();
|
||||||
for (int i = 1; it != end; ++it, ++i)
|
for (int i = 1; it != end; ++it, ++i)
|
||||||
assert (*it == i);
|
assert (*it == i);
|
||||||
|
|
||||||
@@ -2456,7 +2456,7 @@ void SQLExecutor::internalExtraction()
|
|||||||
s = rset.value("cnt", 0).convert<std::string>();
|
s = rset.value("cnt", 0).convert<std::string>();
|
||||||
assert ("4" == s);
|
assert ("4" == s);
|
||||||
|
|
||||||
try { rset.column<int, std::vector<int> >(100); fail ("must fail"); }
|
try { rset.column<std::deque<int>, InternalExtraction<std::deque<int> > >(100); fail ("must fail"); }
|
||||||
catch (RangeException&) { }
|
catch (RangeException&) { }
|
||||||
|
|
||||||
try { rset.value<std::string>(0,0); fail ("must fail"); }
|
try { rset.value<std::string>(0,0); fail ("must fail"); }
|
||||||
@@ -2465,7 +2465,7 @@ void SQLExecutor::internalExtraction()
|
|||||||
stmt = (session() << "DELETE FROM Vectors", now);
|
stmt = (session() << "DELETE FROM Vectors", now);
|
||||||
rset = stmt;
|
rset = stmt;
|
||||||
|
|
||||||
try { rset.column<int, std::vector<int> >(0); fail ("must fail"); }
|
try { rset.column<std::deque<int>, InternalExtraction<std::deque<int> > >(0); fail ("must fail"); }
|
||||||
catch (RangeException&) { }
|
catch (RangeException&) { }
|
||||||
}
|
}
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
@@ -2473,6 +2473,65 @@ void SQLExecutor::internalExtraction()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SQLExecutor::internalBulkExtraction()
|
||||||
|
{
|
||||||
|
std::string funct = "internalBulkExtraction()";
|
||||||
|
int size = 100;
|
||||||
|
std::vector<std::string> lastName(size);
|
||||||
|
std::vector<std::string> firstName(size);
|
||||||
|
std::vector<std::string> address(size);
|
||||||
|
std::vector<int> age(size);
|
||||||
|
|
||||||
|
for (int i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
lastName[i] = "LN" + NumberFormatter::format(i);
|
||||||
|
firstName[i] = "FN" + NumberFormatter::format(i);
|
||||||
|
address[i] = "Addr" + NumberFormatter::format(i);
|
||||||
|
age[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
session() << "INSERT INTO Person VALUES (?,?,?,?)",
|
||||||
|
use(lastName, bulk),
|
||||||
|
use(firstName, bulk),
|
||||||
|
use(address, bulk),
|
||||||
|
use(age, bulk),
|
||||||
|
now;
|
||||||
|
}
|
||||||
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement stmt = (session() << "SELECT * FROM Person", bulk(size), now);
|
||||||
|
RecordSet rset(stmt);
|
||||||
|
assert (size == rset.rowCount());
|
||||||
|
assert ("LN0" == rset["LastName"]);
|
||||||
|
assert (0 == rset["Age"]);
|
||||||
|
rset.moveLast();
|
||||||
|
assert (std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]);
|
||||||
|
assert (size - 1 == rset["Age"]);
|
||||||
|
}
|
||||||
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement stmt = (session() << "SELECT * FROM Person", limit(size), bulk, now);
|
||||||
|
RecordSet rset(stmt);
|
||||||
|
assert (size == rset.rowCount());
|
||||||
|
assert ("LN0" == rset["LastName"]);
|
||||||
|
assert (0 == rset["Age"]);
|
||||||
|
rset.moveLast();
|
||||||
|
assert (std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]);
|
||||||
|
assert (size - 1 == rset["Age"]);
|
||||||
|
}
|
||||||
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SQLExecutor::internalStorageType()
|
void SQLExecutor::internalStorageType()
|
||||||
{
|
{
|
||||||
std::string funct = "internalStorageType()";
|
std::string funct = "internalStorageType()";
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
#include "Poco/Data/ODBC/ODBC.h"
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
#include "Poco/Data/ODBC/Utility.h"
|
#include "Poco/Data/ODBC/Utility.h"
|
||||||
|
#include "Poco/Data/ODBC/ODBCException.h"
|
||||||
#include "Poco/Data/Session.h"
|
#include "Poco/Data/Session.h"
|
||||||
#include "Poco/Data/BulkExtraction.h"
|
#include "Poco/Data/BulkExtraction.h"
|
||||||
#include "Poco/Data/BulkBinding.h"
|
#include "Poco/Data/BulkBinding.h"
|
||||||
@@ -51,7 +52,7 @@
|
|||||||
Poco::Data::ODBC::EnvironmentException ee(h); \
|
Poco::Data::ODBC::EnvironmentException ee(h); \
|
||||||
std::cout << ee.toString() << std::endl; \
|
std::cout << ee.toString() << std::endl; \
|
||||||
} \
|
} \
|
||||||
assert (SQL_SUCCEEDED(r));
|
assert (SQL_SUCCEEDED(r))
|
||||||
|
|
||||||
|
|
||||||
#define poco_odbc_check_dbc(r, h) \
|
#define poco_odbc_check_dbc(r, h) \
|
||||||
@@ -60,7 +61,7 @@
|
|||||||
Poco::Data::ODBC::ConnectionException ce(h); \
|
Poco::Data::ODBC::ConnectionException ce(h); \
|
||||||
std::cout << ce.toString() << std::endl; \
|
std::cout << ce.toString() << std::endl; \
|
||||||
} \
|
} \
|
||||||
assert (SQL_SUCCEEDED(r));
|
assert (SQL_SUCCEEDED(r))
|
||||||
|
|
||||||
|
|
||||||
#define poco_odbc_check_stmt(r, h) \
|
#define poco_odbc_check_stmt(r, h) \
|
||||||
@@ -69,7 +70,7 @@
|
|||||||
Poco::Data::ODBC::StatementException se(h); \
|
Poco::Data::ODBC::StatementException se(h); \
|
||||||
std::cout << se.toString() << std::endl; \
|
std::cout << se.toString() << std::endl; \
|
||||||
} \
|
} \
|
||||||
assert (SQL_SUCCEEDED(r));
|
assert (SQL_SUCCEEDED(r))
|
||||||
|
|
||||||
|
|
||||||
#define poco_odbc_check_desc(r, h) \
|
#define poco_odbc_check_desc(r, h) \
|
||||||
@@ -78,7 +79,17 @@
|
|||||||
Poco::Data::ODBC::DescriptorException de(h); \
|
Poco::Data::ODBC::DescriptorException de(h); \
|
||||||
std::cout << de.toString() << std::endl; \
|
std::cout << de.toString() << std::endl; \
|
||||||
} \
|
} \
|
||||||
assert (SQL_SUCCEEDED(r));
|
assert (SQL_SUCCEEDED(r))
|
||||||
|
|
||||||
|
|
||||||
|
#define poco_data_using_statements using Poco::Data::now; \
|
||||||
|
using Poco::Data::into; \
|
||||||
|
using Poco::Data::use; \
|
||||||
|
using Poco::Data::bulk; \
|
||||||
|
using Poco::Data::limit; \
|
||||||
|
using Poco::Data::BLOB; \
|
||||||
|
using Poco::Data::ODBC::ConnectionException; \
|
||||||
|
using Poco::Data::ODBC::StatementException
|
||||||
|
|
||||||
|
|
||||||
class SQLExecutor: public CppUnit::TestCase
|
class SQLExecutor: public CppUnit::TestCase
|
||||||
@@ -148,6 +159,8 @@ public:
|
|||||||
template <typename C1, typename C2, typename C3, typename C4, typename C5, typename C6>
|
template <typename C1, typename C2, typename C3, typename C4, typename C5, typename C6>
|
||||||
void doBulkWithBool(Poco::UInt32 size)
|
void doBulkWithBool(Poco::UInt32 size)
|
||||||
{
|
{
|
||||||
|
poco_data_using_statements;
|
||||||
|
|
||||||
std::string funct = "doBulkWithBool()";
|
std::string funct = "doBulkWithBool()";
|
||||||
C1 ints;
|
C1 ints;
|
||||||
C2 strings;
|
C2 strings;
|
||||||
@@ -287,6 +300,8 @@ public:
|
|||||||
template <typename C1, typename C2, typename C3, typename C4, typename C5>
|
template <typename C1, typename C2, typename C3, typename C4, typename C5>
|
||||||
void doBulk(Poco::UInt32 size)
|
void doBulk(Poco::UInt32 size)
|
||||||
{
|
{
|
||||||
|
poco_data_using_statements;
|
||||||
|
|
||||||
std::string funct = "doBulk()";
|
std::string funct = "doBulk()";
|
||||||
C1 ints;
|
C1 ints;
|
||||||
C2 strings;
|
C2 strings;
|
||||||
@@ -431,6 +446,8 @@ public:
|
|||||||
template <typename C1, typename C2>
|
template <typename C1, typename C2>
|
||||||
void blobContainer(int size)
|
void blobContainer(int size)
|
||||||
{
|
{
|
||||||
|
poco_data_using_statements;
|
||||||
|
|
||||||
std::string funct = "blobContainer()";
|
std::string funct = "blobContainer()";
|
||||||
C1 lastName(size, "lastname");
|
C1 lastName(size, "lastname");
|
||||||
C1 firstName(size, "firstname");
|
C1 firstName(size, "firstname");
|
||||||
@@ -464,6 +481,7 @@ public:
|
|||||||
void tupleVector();
|
void tupleVector();
|
||||||
|
|
||||||
void internalExtraction();
|
void internalExtraction();
|
||||||
|
void internalBulkExtraction();
|
||||||
void internalStorageType();
|
void internalStorageType();
|
||||||
void nulls();
|
void nulls();
|
||||||
void notNulls(const std::string& sqlState = "23502");
|
void notNulls(const std::string& sqlState = "23502");
|
||||||
|
|||||||
@@ -96,14 +96,14 @@ inline Bulk bulk(const T& limit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void bulk()
|
inline void bulk(char)
|
||||||
/// Dummy bulk function. Used for bulk binding creation
|
/// Dummy bulk function. Used for bulk binding creation
|
||||||
/// (see BulkBinding.h).
|
/// (see BulkBinding) and bulk extraction signalling to Statement.
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef void (*BulkFnType)();
|
typedef void (*BulkFnType)(char);
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
} } // namespace Poco::Data
|
||||||
|
|||||||
@@ -59,16 +59,18 @@ class BulkExtraction: public AbstractExtraction
|
|||||||
/// - std::list
|
/// - std::list
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef typename C::value_type T;
|
||||||
|
|
||||||
BulkExtraction(C& result, Poco::UInt32 limit):
|
BulkExtraction(C& result, Poco::UInt32 limit):
|
||||||
AbstractExtraction(limit, 0, true),
|
AbstractExtraction(limit, 0, true),
|
||||||
_rResult(result),
|
_rResult(result),
|
||||||
_default(1)
|
_default()
|
||||||
{
|
{
|
||||||
if (static_cast<Poco::UInt32>(result.size()) != limit)
|
if (static_cast<Poco::UInt32>(result.size()) != limit)
|
||||||
result.resize(limit);
|
result.resize(limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
BulkExtraction(C& result, const C& def, Poco::UInt32 limit):
|
BulkExtraction(C& result, const T& def, Poco::UInt32 limit):
|
||||||
AbstractExtraction(limit, 0, true),
|
AbstractExtraction(limit, 0, true),
|
||||||
_rResult(result),
|
_rResult(result),
|
||||||
_default(def)
|
_default(def)
|
||||||
@@ -139,7 +141,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
C& _rResult;
|
C& _rResult;
|
||||||
C _default;
|
T _default;
|
||||||
std::deque<bool> _nulls;
|
std::deque<bool> _nulls;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -152,15 +154,15 @@ class InternalBulkExtraction: public BulkExtraction<C>
|
|||||||
/// to automaticaly create internal BulkExtraction in cases when statement returns data and no external storage
|
/// to automaticaly create internal BulkExtraction in cases when statement returns data and no external storage
|
||||||
/// was supplied. It is later used by RecordSet to retrieve the fetched data after statement execution.
|
/// was supplied. It is later used by RecordSet to retrieve the fetched data after statement execution.
|
||||||
/// It takes ownership of the Column pointer supplied as constructor argument. Column object, in turn
|
/// It takes ownership of the Column pointer supplied as constructor argument. Column object, in turn
|
||||||
/// owns the data vector pointer.
|
/// owns the data container pointer.
|
||||||
///
|
///
|
||||||
/// InternalBulkExtraction objects can not be copied or assigned.
|
/// InternalBulkExtraction objects can not be copied or assigned.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename C::value_type T;
|
typedef typename C::value_type T;
|
||||||
|
|
||||||
explicit InternalBulkExtraction(C& result, Column<T,C>* pColumn, Poco::UInt32 limit):
|
explicit InternalBulkExtraction(C& result, Column<C>* pColumn, Poco::UInt32 limit):
|
||||||
BulkExtraction<C>(result, _default, limit),
|
BulkExtraction<C>(result, T(), limit),
|
||||||
_pColumn(pColumn)
|
_pColumn(pColumn)
|
||||||
/// Creates InternalBulkExtraction.
|
/// Creates InternalBulkExtraction.
|
||||||
{
|
{
|
||||||
@@ -194,7 +196,7 @@ public:
|
|||||||
return BulkExtraction<C>::isNull(row);
|
return BulkExtraction<C>::isNull(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Column<T,C>& column() const
|
const Column<C>& column() const
|
||||||
{
|
{
|
||||||
return *_pColumn;
|
return *_pColumn;
|
||||||
}
|
}
|
||||||
@@ -204,8 +206,7 @@ private:
|
|||||||
InternalBulkExtraction(const InternalBulkExtraction&);
|
InternalBulkExtraction(const InternalBulkExtraction&);
|
||||||
InternalBulkExtraction& operator = (const InternalBulkExtraction&);
|
InternalBulkExtraction& operator = (const InternalBulkExtraction&);
|
||||||
|
|
||||||
Column<T,C>* _pColumn;
|
Column<C>* _pColumn;
|
||||||
C _default;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace Poco {
|
|||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
|
|
||||||
template <class T, class C = std::deque<T> >
|
template <class C>
|
||||||
class Column
|
class Column
|
||||||
/// Column class is column data container.
|
/// Column class is column data container.
|
||||||
/// Data (a pointer to container) is assigned to the class
|
/// Data (a pointer to container) is assigned to the class
|
||||||
@@ -65,8 +65,9 @@ public:
|
|||||||
typedef typename Container::const_iterator Iterator;
|
typedef typename Container::const_iterator Iterator;
|
||||||
typedef typename Container::const_reverse_iterator RIterator;
|
typedef typename Container::const_reverse_iterator RIterator;
|
||||||
typedef typename Container::size_type Size;
|
typedef typename Container::size_type Size;
|
||||||
|
typedef typename Container::value_type Type;
|
||||||
|
|
||||||
Column(const MetaColumn& metaColumn, C* pData): _metaColumn(metaColumn), _pData(pData)
|
Column(const MetaColumn& metaColumn, Container* pData): _metaColumn(metaColumn), _pData(pData)
|
||||||
/// Creates the Column.
|
/// Creates the Column.
|
||||||
{
|
{
|
||||||
poco_check_ptr (_pData);
|
poco_check_ptr (_pData);
|
||||||
@@ -104,7 +105,7 @@ public:
|
|||||||
return *_pData;
|
return *_pData;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& value(std::size_t row) const
|
const Type& value(std::size_t row) const
|
||||||
/// Returns the field value in specified row.
|
/// Returns the field value in specified row.
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -117,7 +118,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& operator [] (std::size_t row) const
|
const Type& operator [] (std::size_t row) const
|
||||||
/// Returns the field value in specified row.
|
/// Returns the field value in specified row.
|
||||||
{
|
{
|
||||||
return value(row);
|
return value(row);
|
||||||
@@ -132,7 +133,7 @@ public:
|
|||||||
void reset()
|
void reset()
|
||||||
/// Clears and shrinks the storage.
|
/// Clears and shrinks the storage.
|
||||||
{
|
{
|
||||||
C().swap(*_pData);
|
Container().swap(*_pData);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& name() const
|
const std::string& name() const
|
||||||
@@ -187,7 +188,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class Column<bool, std::vector<bool> >
|
class Column<std::vector<bool> >
|
||||||
/// The std::vector<bool> specialization for the Column class.
|
/// The std::vector<bool> specialization for the Column class.
|
||||||
///
|
///
|
||||||
/// This specialization is necessary due to the nature of std::vector<bool>.
|
/// This specialization is necessary due to the nature of std::vector<bool>.
|
||||||
@@ -339,7 +340,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class Column<T, std::list<T> >
|
class Column<std::list<T> >
|
||||||
/// Column specialization for std::list
|
/// Column specialization for std::list
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -485,8 +486,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T, typename C>
|
template <typename C>
|
||||||
inline void swap(Column<T,C>& c1, Column<T,C>& c2)
|
inline void swap(Column<C>& c1, Column<C>& c2)
|
||||||
{
|
{
|
||||||
c1.swap(c2);
|
c1.swap(c2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -480,14 +480,14 @@ class InternalExtraction: public Extraction<C>
|
|||||||
/// to automaticaly create internal Extraction in cases when statement returns data and no external storage
|
/// to automaticaly create internal Extraction in cases when statement returns data and no external storage
|
||||||
/// was supplied. It is later used by RecordSet to retrieve the fetched data after statement execution.
|
/// was supplied. It is later used by RecordSet to retrieve the fetched data after statement execution.
|
||||||
/// It takes ownership of the Column pointer supplied as constructor argument. Column object, in turn
|
/// It takes ownership of the Column pointer supplied as constructor argument. Column object, in turn
|
||||||
/// owns the data vector pointer.
|
/// owns the data container pointer.
|
||||||
///
|
///
|
||||||
/// InternalExtraction objects can not be copied or assigned.
|
/// InternalExtraction objects can not be copied or assigned.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename C::value_type T;
|
typedef typename C::value_type T;
|
||||||
|
|
||||||
explicit InternalExtraction(C& result, Column<T,C>* pColumn, const Position& pos = Position(0)):
|
explicit InternalExtraction(C& result, Column<C>* pColumn, const Position& pos = Position(0)):
|
||||||
Extraction<C>(result, T(), pos),
|
Extraction<C>(result, T(), pos),
|
||||||
_pColumn(pColumn)
|
_pColumn(pColumn)
|
||||||
/// Creates InternalExtraction.
|
/// Creates InternalExtraction.
|
||||||
@@ -522,7 +522,7 @@ public:
|
|||||||
return Extraction<C>::isNull(row);
|
return Extraction<C>::isNull(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Column<T,C>& column() const
|
const Column<C>& column() const
|
||||||
{
|
{
|
||||||
return *_pColumn;
|
return *_pColumn;
|
||||||
}
|
}
|
||||||
@@ -532,7 +532,7 @@ private:
|
|||||||
InternalExtraction(const InternalExtraction&);
|
InternalExtraction(const InternalExtraction&);
|
||||||
InternalExtraction& operator = (const InternalExtraction&);
|
InternalExtraction& operator = (const InternalExtraction&);
|
||||||
|
|
||||||
Column<T,C>* _pColumn;
|
Column<C>* _pColumn;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/Extraction.h"
|
#include "Poco/Data/Extraction.h"
|
||||||
|
#include "Poco/Data/BulkExtraction.h"
|
||||||
#include "Poco/Data/Statement.h"
|
#include "Poco/Data/Statement.h"
|
||||||
#include "Poco/Data/RowIterator.h"
|
#include "Poco/Data/RowIterator.h"
|
||||||
#include "Poco/Data/BLOB.h"
|
#include "Poco/Data/BLOB.h"
|
||||||
@@ -100,18 +101,19 @@ public:
|
|||||||
std::size_t columnCount() const;
|
std::size_t columnCount() const;
|
||||||
/// Returns the number of rows in the recordset.
|
/// Returns the number of rows in the recordset.
|
||||||
|
|
||||||
template <class T, class C>
|
template <class C, class E>
|
||||||
const Column<T,C>& column(const std::string& name) const
|
const Column<C>& column(const std::string& name) const
|
||||||
/// Returns the reference to the first Column with the specified name.
|
/// Returns the reference to the first Column with the specified name.
|
||||||
{
|
{
|
||||||
return column<T,C>(columnPosition<T,C>(name));
|
return column<C,E>(columnPosition<C,E>(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class C>
|
template <class C, class E>
|
||||||
const Column<T,C>& column(std::size_t pos) const
|
const Column<C>& column(std::size_t pos) const
|
||||||
/// Returns the reference to column at specified location.
|
/// Returns the reference to column at specified location.
|
||||||
{
|
{
|
||||||
typedef const InternalExtraction<C>* ExtractionVecPtr;
|
typedef typename C::value_type T;
|
||||||
|
typedef const E* ExtractionVecPtr;
|
||||||
|
|
||||||
const AbstractExtractionVec& rExtractions = extractions();
|
const AbstractExtractionVec& rExtractions = extractions();
|
||||||
|
|
||||||
@@ -144,12 +146,30 @@ public:
|
|||||||
switch (storage())
|
switch (storage())
|
||||||
{
|
{
|
||||||
case STORAGE_VECTOR:
|
case STORAGE_VECTOR:
|
||||||
return column<T, std::vector<T> >(col).value(row);
|
{
|
||||||
|
typedef std::vector<T> C;
|
||||||
|
if (isBulkExtraction())
|
||||||
|
return column<C, InternalBulkExtraction<C> >(col).value(row);
|
||||||
|
else
|
||||||
|
return column<C, InternalExtraction<C> >(col).value(row);
|
||||||
|
}
|
||||||
case STORAGE_LIST:
|
case STORAGE_LIST:
|
||||||
return column<T, std::list<T> >(col).value(row);
|
{
|
||||||
|
typedef std::list<T> C;
|
||||||
|
if (isBulkExtraction())
|
||||||
|
return column<C, InternalBulkExtraction<C> >(col).value(row);
|
||||||
|
else
|
||||||
|
return column<C, InternalExtraction<C> >(col).value(row);
|
||||||
|
}
|
||||||
case STORAGE_DEQUE:
|
case STORAGE_DEQUE:
|
||||||
case STORAGE_UNKNOWN:
|
case STORAGE_UNKNOWN:
|
||||||
return column<T, std::deque<T> >(col).value(row);
|
{
|
||||||
|
typedef std::deque<T> C;
|
||||||
|
if (isBulkExtraction())
|
||||||
|
return column<C, InternalBulkExtraction<C> >(col).value(row);
|
||||||
|
else
|
||||||
|
return column<C, InternalExtraction<C> >(col).value(row);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw IllegalStateException("Invalid storage setting.");
|
throw IllegalStateException("Invalid storage setting.");
|
||||||
}
|
}
|
||||||
@@ -162,12 +182,30 @@ public:
|
|||||||
switch (storage())
|
switch (storage())
|
||||||
{
|
{
|
||||||
case STORAGE_VECTOR:
|
case STORAGE_VECTOR:
|
||||||
return column<T, std::vector<T> >(name).value(row);
|
{
|
||||||
|
typedef std::vector<T> C;
|
||||||
|
if (isBulkExtraction())
|
||||||
|
return column<C, InternalBulkExtraction<C> >(name).value(row);
|
||||||
|
else
|
||||||
|
return column<C, InternalExtraction<C> >(name).value(row);
|
||||||
|
}
|
||||||
case STORAGE_LIST:
|
case STORAGE_LIST:
|
||||||
return column<T, std::list<T> >(name).value(row);
|
{
|
||||||
|
typedef std::list<T> C;
|
||||||
|
if (isBulkExtraction())
|
||||||
|
return column<C, InternalBulkExtraction<C> >(name).value(row);
|
||||||
|
else
|
||||||
|
return column<C, InternalExtraction<C> >(name).value(row);
|
||||||
|
}
|
||||||
case STORAGE_DEQUE:
|
case STORAGE_DEQUE:
|
||||||
case STORAGE_UNKNOWN:
|
case STORAGE_UNKNOWN:
|
||||||
return column<T, std::deque<T> >(name).value(row);
|
{
|
||||||
|
typedef std::deque<T> C;
|
||||||
|
if (isBulkExtraction())
|
||||||
|
return column<C, InternalBulkExtraction<C> >(name).value(row);
|
||||||
|
else
|
||||||
|
return column<C, InternalExtraction<C> >(name).value(row);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw IllegalStateException("Invalid storage setting.");
|
throw IllegalStateException("Invalid storage setting.");
|
||||||
}
|
}
|
||||||
@@ -259,11 +297,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
RecordSet();
|
RecordSet();
|
||||||
|
|
||||||
template<class T, class C>
|
template<class C, class E>
|
||||||
std::size_t columnPosition(const std::string& name) const
|
std::size_t columnPosition(const std::string& name) const
|
||||||
/// Returns the position of the column with specified name.
|
/// Returns the position of the column with specified name.
|
||||||
{
|
{
|
||||||
typedef const InternalExtraction<C>* ExtractionVecPtr;
|
typedef typename C::value_type T;
|
||||||
|
typedef const E* ExtractionVecPtr;
|
||||||
|
|
||||||
bool typeFound = false;
|
bool typeFound = false;
|
||||||
|
|
||||||
@@ -278,7 +317,7 @@ private:
|
|||||||
if (pExtraction)
|
if (pExtraction)
|
||||||
{
|
{
|
||||||
typeFound = true;
|
typeFound = true;
|
||||||
const Column<T,C>& col = pExtraction->column();
|
const Column<C>& col = pExtraction->column();
|
||||||
if (0 == Poco::icompare(name, col.name()))
|
if (0 == Poco::icompare(name, col.name()))
|
||||||
return col.position();
|
return col.position();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,14 +181,19 @@ public:
|
|||||||
|
|
||||||
Statement& operator , (const Bulk& bulk);
|
Statement& operator , (const Bulk& bulk);
|
||||||
/// Sets the bulk execution mode (both binding and extraction) for this
|
/// Sets the bulk execution mode (both binding and extraction) for this
|
||||||
/// statement.Statement must not have any extracors or binders set at the
|
/// statement.Statement must not have any extractors or binders set at the
|
||||||
/// time when this operator is applied.
|
/// time when this operator is applied.
|
||||||
/// Failure to adhere to the above constraint shall result in
|
/// Failure to adhere to the above constraint shall result in
|
||||||
/// InvalidAccessException.
|
/// InvalidAccessException.
|
||||||
/// Additionally, any binding buffers passed to the statement later
|
|
||||||
/// through use() or in() must be of the same size (determined by size
|
Statement& operator , (BulkFnType);
|
||||||
/// of the bulk passed to this function). Since they are resized automatically
|
/// Sets the bulk execution mode (both binding and extraction) for this
|
||||||
/// by the framework, the extraction buffers do not have to adhere to this.
|
/// statement.Statement must not have any extractors or binders set at the
|
||||||
|
/// time when this operator is applied.
|
||||||
|
/// Additionally, this function requires limit to be set in order to
|
||||||
|
/// determine the bulk size.
|
||||||
|
/// Failure to adhere to the above constraints shall result in
|
||||||
|
/// InvalidAccessException.
|
||||||
|
|
||||||
Statement& operator , (const Limit& extrLimit);
|
Statement& operator , (const Limit& extrLimit);
|
||||||
/// Sets a limit on the maximum number of rows a select is allowed to return.
|
/// Sets a limit on the maximum number of rows a select is allowed to return.
|
||||||
@@ -277,6 +282,9 @@ protected:
|
|||||||
bool isNull(std::size_t col, std::size_t row) const;
|
bool isNull(std::size_t col, std::size_t row) const;
|
||||||
/// Returns true if the current row value at column pos is null.
|
/// Returns true if the current row value at column pos is null.
|
||||||
|
|
||||||
|
bool isBulkExtraction() const;
|
||||||
|
/// Returns true if this statement extracts data in bulk.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef Poco::SharedPtr<StatementImpl> StatementImplPtr;
|
typedef Poco::SharedPtr<StatementImpl> StatementImplPtr;
|
||||||
|
|
||||||
@@ -443,6 +451,12 @@ inline bool Statement::isNull(std::size_t col, std::size_t row) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Statement::isBulkExtraction() const
|
||||||
|
{
|
||||||
|
return _pImpl->isBulkExtraction();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Statement::isAsync() const
|
inline bool Statement::isAsync() const
|
||||||
{
|
{
|
||||||
return _async;
|
return _async;
|
||||||
|
|||||||
@@ -295,18 +295,16 @@ private:
|
|||||||
template <class C>
|
template <class C>
|
||||||
InternalExtraction<C>* createExtract(const MetaColumn& mc)
|
InternalExtraction<C>* createExtract(const MetaColumn& mc)
|
||||||
{
|
{
|
||||||
typedef typename C::value_type T;
|
|
||||||
C* pData = new C;
|
C* pData = new C;
|
||||||
Column<T,C>* pCol = new Column<T,C>(mc, pData);
|
Column<C>* pCol = new Column<C>(mc, pData);
|
||||||
return new InternalExtraction<C>(*pData, pCol);
|
return new InternalExtraction<C>(*pData, pCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class C>
|
template <class C>
|
||||||
InternalBulkExtraction<C>* createBulkExtract(const MetaColumn& mc)
|
InternalBulkExtraction<C>* createBulkExtract(const MetaColumn& mc)
|
||||||
{
|
{
|
||||||
typedef typename C::value_type T;
|
|
||||||
C* pData = new C;
|
C* pData = new C;
|
||||||
Column<T,C>* pCol = new Column<T,C>(mc, pData);
|
Column<C>* pCol = new Column<C>(mc, pData);
|
||||||
return new InternalBulkExtraction<C>(*pData, pCol, getExtractionLimit());
|
return new InternalBulkExtraction<C>(*pData, pCol, getExtractionLimit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -160,13 +160,12 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <class C>
|
template <class T>
|
||||||
class TypeHandler<std::deque<C> >: public AbstractTypeHandler
|
class TypeHandler<std::deque<T> >: public AbstractTypeHandler
|
||||||
/// Specialization of type handler for std::deque.
|
/// Specialization of type handler for std::deque.
|
||||||
/// Used by bulk extraction.
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void bind(std::size_t pos, const std::deque<C>& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
|
static void bind(std::size_t pos, const std::deque<T>& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
|
||||||
{
|
{
|
||||||
poco_assert_dbg (pBinder != 0);
|
poco_assert_dbg (pBinder != 0);
|
||||||
pBinder->bind(pos, obj, dir);
|
pBinder->bind(pos, obj, dir);
|
||||||
@@ -177,21 +176,14 @@ public:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void extract(std::size_t pos, std::deque<C>& obj, const std::deque<C>& defVal, AbstractExtractor* pExt)
|
static void extract(std::size_t pos, std::deque<T>& obj, const T& defVal, AbstractExtractor* pExt)
|
||||||
{
|
{
|
||||||
poco_assert_dbg (pExt != 0);
|
poco_assert_dbg (pExt != 0);
|
||||||
if (!pExt->extract(pos, obj))
|
if (!pExt->extract(pos, obj))
|
||||||
{
|
obj.assign(obj.size(), defVal);
|
||||||
if (defVal.size() == 1)
|
|
||||||
obj.assign(obj.size(), defVal.front());
|
|
||||||
else if (defVal.size() > 1)
|
|
||||||
obj.assign(defVal.begin(), defVal.end());
|
|
||||||
else
|
|
||||||
throw InvalidArgumentException("Size of default value container must not be zero.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare(std::size_t pos, std::deque<C>& obj, AbstractPreparation* pPrepare)
|
static void prepare(std::size_t pos, std::deque<T>& obj, AbstractPreparation* pPrepare)
|
||||||
{
|
{
|
||||||
poco_assert_dbg (pPrepare != 0);
|
poco_assert_dbg (pPrepare != 0);
|
||||||
pPrepare->prepare(pos, obj);
|
pPrepare->prepare(pos, obj);
|
||||||
@@ -203,15 +195,12 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <class C>
|
template <class T>
|
||||||
class TypeHandler<std::vector<C> >: public AbstractTypeHandler
|
class TypeHandler<std::vector<T> >: public AbstractTypeHandler
|
||||||
/// Specialization of type handler for std::vector.
|
/// Specialization of type handler for std::vector.
|
||||||
/// Used by bulk extraction.
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename std::vector<C>::value_type T;
|
static void bind(std::size_t pos, const std::vector<T>& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
|
||||||
|
|
||||||
static void bind(std::size_t pos, const std::vector<C>& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
|
|
||||||
{
|
{
|
||||||
poco_assert_dbg (pBinder != 0);
|
poco_assert_dbg (pBinder != 0);
|
||||||
pBinder->bind(pos, obj, dir);
|
pBinder->bind(pos, obj, dir);
|
||||||
@@ -222,21 +211,14 @@ public:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void extract(std::size_t pos, std::vector<C>& obj, const std::vector<C>& defVal, AbstractExtractor* pExt)
|
static void extract(std::size_t pos, std::vector<T>& obj, const T& defVal, AbstractExtractor* pExt)
|
||||||
{
|
{
|
||||||
poco_assert_dbg (pExt != 0);
|
poco_assert_dbg (pExt != 0);
|
||||||
if (!pExt->extract(pos, obj))
|
if (!pExt->extract(pos, obj))
|
||||||
{
|
obj.assign(obj.size(), defVal);
|
||||||
if (defVal.size() == 1)
|
|
||||||
obj.assign(obj.size(), defVal.front());
|
|
||||||
else if (defVal.size() > 1)
|
|
||||||
obj.assign(defVal.begin(), defVal.end());
|
|
||||||
else
|
|
||||||
throw InvalidArgumentException("Size of default value container must not be zero.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare(std::size_t pos, std::vector<C>& obj, AbstractPreparation* pPrepare)
|
static void prepare(std::size_t pos, std::vector<T>& obj, AbstractPreparation* pPrepare)
|
||||||
{
|
{
|
||||||
poco_assert_dbg (pPrepare != 0);
|
poco_assert_dbg (pPrepare != 0);
|
||||||
pPrepare->prepare(pos, obj);
|
pPrepare->prepare(pos, obj);
|
||||||
@@ -248,13 +230,12 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <class C>
|
template <class T>
|
||||||
class TypeHandler<std::list<C> >: public AbstractTypeHandler
|
class TypeHandler<std::list<T> >: public AbstractTypeHandler
|
||||||
/// Specialization of type handler for std::list.
|
/// Specialization of type handler for std::list.
|
||||||
/// Used by bulk extraction.
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void bind(std::size_t pos, const std::list<C>& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
|
static void bind(std::size_t pos, const std::list<T>& obj, AbstractBinder* pBinder, AbstractBinder::Direction dir)
|
||||||
{
|
{
|
||||||
poco_assert_dbg (pBinder != 0);
|
poco_assert_dbg (pBinder != 0);
|
||||||
pBinder->bind(pos, obj, dir);
|
pBinder->bind(pos, obj, dir);
|
||||||
@@ -265,21 +246,14 @@ public:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void extract(std::size_t pos, std::list<C>& obj, const std::list<C>& defVal, AbstractExtractor* pExt)
|
static void extract(std::size_t pos, std::list<T>& obj, const T& defVal, AbstractExtractor* pExt)
|
||||||
{
|
{
|
||||||
poco_assert_dbg (pExt != 0);
|
poco_assert_dbg (pExt != 0);
|
||||||
if (!pExt->extract(pos, obj))
|
if (!pExt->extract(pos, obj))
|
||||||
{
|
obj.assign(obj.size(), defVal);
|
||||||
if (defVal.size() == 1)
|
|
||||||
obj.assign(obj.size(), defVal.front());
|
|
||||||
else if (defVal.size() > 1)
|
|
||||||
obj.assign(defVal.begin(), defVal.end());
|
|
||||||
else
|
|
||||||
throw InvalidArgumentException("Size of default value container must not be zero.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare(std::size_t pos, std::list<C>& obj, AbstractPreparation* pPrepare)
|
static void prepare(std::size_t pos, std::list<T>& obj, AbstractPreparation* pPrepare)
|
||||||
{
|
{
|
||||||
poco_assert_dbg (pPrepare != 0);
|
poco_assert_dbg (pPrepare != 0);
|
||||||
pPrepare->prepare(pos, obj);
|
pPrepare->prepare(pos, obj);
|
||||||
|
|||||||
@@ -269,7 +269,6 @@ Statement& Statement::operator , (const Bulk& bulk)
|
|||||||
_pImpl->bulkExtractionAllowed() &&
|
_pImpl->bulkExtractionAllowed() &&
|
||||||
_pImpl->bulkBindingAllowed())
|
_pImpl->bulkBindingAllowed())
|
||||||
{
|
{
|
||||||
Limit l(_pImpl->getExtractionLimit(), false, false);
|
|
||||||
_pImpl->setBulkExtraction(bulk);
|
_pImpl->setBulkExtraction(bulk);
|
||||||
_pImpl->setBulkBinding();
|
_pImpl->setBulkBinding();
|
||||||
}
|
}
|
||||||
@@ -280,4 +279,23 @@ Statement& Statement::operator , (const Bulk& bulk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Statement& Statement::operator , (BulkFnType)
|
||||||
|
{
|
||||||
|
const Limit& limit(_pImpl->extractionLimit());
|
||||||
|
if (limit.isHardLimit() ||
|
||||||
|
limit.isLowerLimit() ||
|
||||||
|
Limit::LIMIT_UNLIMITED == limit.value())
|
||||||
|
{
|
||||||
|
throw InvalidAccessException("Bulk is only allowed with limited extraction,"
|
||||||
|
"non-hard and zero-based limits.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Bulk bulk(limit);
|
||||||
|
_pImpl->setBulkExtraction(bulk);
|
||||||
|
_pImpl->setBulkBinding();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
} } // namespace Poco::Data
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ void DataTest::testColumnVector()
|
|||||||
pData->push_back(4);
|
pData->push_back(4);
|
||||||
pData->push_back(5);
|
pData->push_back(5);
|
||||||
|
|
||||||
Column<int, std::vector<int> > c(mc, pData);
|
Column<std::vector<int> > c(mc, pData);
|
||||||
|
|
||||||
assert (c.rowCount() == 5);
|
assert (c.rowCount() == 5);
|
||||||
assert (c[0] == 1);
|
assert (c[0] == 1);
|
||||||
@@ -401,7 +401,7 @@ void DataTest::testColumnVector()
|
|||||||
}
|
}
|
||||||
catch (RangeException&) { }
|
catch (RangeException&) { }
|
||||||
|
|
||||||
Column<int, std::vector<int> > c1 = c;
|
Column<std::vector<int> > c1 = c;
|
||||||
|
|
||||||
assert (c1.rowCount() == 5);
|
assert (c1.rowCount() == 5);
|
||||||
assert (c1[0] == 1);
|
assert (c1[0] == 1);
|
||||||
@@ -410,7 +410,7 @@ void DataTest::testColumnVector()
|
|||||||
assert (c1[3] == 4);
|
assert (c1[3] == 4);
|
||||||
assert (c1[4] == 5);
|
assert (c1[4] == 5);
|
||||||
|
|
||||||
Column<int, std::vector<int> > c2(c1);
|
Column<std::vector<int> > c2(c1);
|
||||||
|
|
||||||
assert (c2.rowCount() == 5);
|
assert (c2.rowCount() == 5);
|
||||||
assert (c2[0] == 1);
|
assert (c2[0] == 1);
|
||||||
@@ -445,8 +445,8 @@ void DataTest::testColumnVector()
|
|||||||
pV2->push_back(3);
|
pV2->push_back(3);
|
||||||
pV2->push_back(2);
|
pV2->push_back(2);
|
||||||
pV2->push_back(1);
|
pV2->push_back(1);
|
||||||
Column<int, std::vector<int> > c3(mc, pV1);
|
Column<std::vector<int> > c3(mc, pV1);
|
||||||
Column<int, std::vector<int> > c4(mc, pV2);
|
Column<std::vector<int> > c4(mc, pV2);
|
||||||
|
|
||||||
Poco::Data::swap(c3, c4);
|
Poco::Data::swap(c3, c4);
|
||||||
assert (c3[0] == 5);
|
assert (c3[0] == 5);
|
||||||
@@ -487,7 +487,7 @@ void DataTest::testColumnVectorBool()
|
|||||||
pData->push_back(false);
|
pData->push_back(false);
|
||||||
pData->push_back(true);
|
pData->push_back(true);
|
||||||
|
|
||||||
Column<bool, std::vector<bool> > c(mc, pData);
|
Column<std::vector<bool> > c(mc, pData);
|
||||||
|
|
||||||
assert (c.rowCount() == 5);
|
assert (c.rowCount() == 5);
|
||||||
assert (c[0] == true);
|
assert (c[0] == true);
|
||||||
@@ -504,7 +504,7 @@ void DataTest::testColumnVectorBool()
|
|||||||
}
|
}
|
||||||
catch (RangeException&) { }
|
catch (RangeException&) { }
|
||||||
|
|
||||||
Column<bool, std::vector<bool> > c1 = c;
|
Column<std::vector<bool> > c1 = c;
|
||||||
|
|
||||||
assert (c1.rowCount() == 5);
|
assert (c1.rowCount() == 5);
|
||||||
assert (c1[0] == true);
|
assert (c1[0] == true);
|
||||||
@@ -513,7 +513,7 @@ void DataTest::testColumnVectorBool()
|
|||||||
assert (c1[3] == false);
|
assert (c1[3] == false);
|
||||||
assert (c1[4] == true);
|
assert (c1[4] == true);
|
||||||
|
|
||||||
Column<bool, std::vector<bool> > c2(c1);
|
Column<std::vector<bool> > c2(c1);
|
||||||
|
|
||||||
assert (c2.rowCount() == 5);
|
assert (c2.rowCount() == 5);
|
||||||
assert (c2[0] == true);
|
assert (c2[0] == true);
|
||||||
@@ -541,7 +541,7 @@ void DataTest::testColumnVectorBool()
|
|||||||
void DataTest::testColumnDeque()
|
void DataTest::testColumnDeque()
|
||||||
{
|
{
|
||||||
typedef std::deque<int> ContainerType;
|
typedef std::deque<int> ContainerType;
|
||||||
typedef Column<int> ColumnType;
|
typedef Column<ContainerType> ColumnType;
|
||||||
|
|
||||||
MetaColumn mc(0, "mc", MetaColumn::FDT_DOUBLE, 2, 3, true);
|
MetaColumn mc(0, "mc", MetaColumn::FDT_DOUBLE, 2, 3, true);
|
||||||
|
|
||||||
@@ -624,8 +624,8 @@ void DataTest::testColumnDeque()
|
|||||||
pV2->push_back(3);
|
pV2->push_back(3);
|
||||||
pV2->push_back(2);
|
pV2->push_back(2);
|
||||||
pV2->push_back(1);
|
pV2->push_back(1);
|
||||||
Column<int> c3(mc, pV1);
|
Column<ContainerType> c3(mc, pV1);
|
||||||
Column<int> c4(mc, pV2);
|
Column<ContainerType> c4(mc, pV2);
|
||||||
|
|
||||||
Poco::Data::swap(c3, c4);
|
Poco::Data::swap(c3, c4);
|
||||||
assert (c3[0] == 5);
|
assert (c3[0] == 5);
|
||||||
@@ -658,7 +658,7 @@ void DataTest::testColumnDeque()
|
|||||||
void DataTest::testColumnList()
|
void DataTest::testColumnList()
|
||||||
{
|
{
|
||||||
typedef std::list<int> ContainerType;
|
typedef std::list<int> ContainerType;
|
||||||
typedef Column<int, ContainerType> ColumnType;
|
typedef Column<ContainerType> ColumnType;
|
||||||
|
|
||||||
MetaColumn mc(0, "mc", MetaColumn::FDT_DOUBLE, 2, 3, true);
|
MetaColumn mc(0, "mc", MetaColumn::FDT_DOUBLE, 2, 3, true);
|
||||||
|
|
||||||
@@ -739,8 +739,8 @@ void DataTest::testColumnList()
|
|||||||
pV2->push_back(3);
|
pV2->push_back(3);
|
||||||
pV2->push_back(2);
|
pV2->push_back(2);
|
||||||
pV2->push_back(1);
|
pV2->push_back(1);
|
||||||
Column<int, ContainerType> c3(mc, pV1);
|
Column<ContainerType> c3(mc, pV1);
|
||||||
Column<int, ContainerType> c4(mc, pV2);
|
Column<ContainerType> c4(mc, pV2);
|
||||||
|
|
||||||
Poco::Data::swap(c3, c4);
|
Poco::Data::swap(c3, c4);
|
||||||
assert (c3[0] == 5);
|
assert (c3[0] == 5);
|
||||||
|
|||||||
Reference in New Issue
Block a user