mirror of
https://github.com/pocoproject/poco.git
synced 2025-04-20 16:03:34 +02:00
Merge pull request #1778 from pocoproject/internal-ext-fix
ODBC RecordSet (internal extraction) broken #1775
This commit is contained in:
commit
a33057d8fe
@ -793,8 +793,8 @@ void MySQLTest::recreatePersonTimeTable()
|
|||||||
|
|
||||||
void MySQLTest::recreateIntsTable()
|
void MySQLTest::recreateIntsTable()
|
||||||
{
|
{
|
||||||
dropTable("Strings");
|
dropTable("Ints");
|
||||||
try { *_pSession << "CREATE TABLE Strings (str INTEGER)", now; }
|
try { *_pSession << "CREATE TABLE Ints (str INTEGER)", now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateIntsTable()"); }
|
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateIntsTable()"); }
|
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,6 @@ public:
|
|||||||
std::size_t maxFieldSize,
|
std::size_t maxFieldSize,
|
||||||
ParameterBinding dataBinding,
|
ParameterBinding dataBinding,
|
||||||
TypeInfo* pDataTypes,
|
TypeInfo* pDataTypes,
|
||||||
ODBCMetaColumn::NumericConversion numericConversion,
|
|
||||||
bool insertOnly);
|
bool insertOnly);
|
||||||
/// Creates the Binder.
|
/// Creates the Binder.
|
||||||
|
|
||||||
@ -1043,7 +1042,6 @@ private:
|
|||||||
std::size_t _maxCharColLength;
|
std::size_t _maxCharColLength;
|
||||||
std::size_t _maxWCharColLength;
|
std::size_t _maxWCharColLength;
|
||||||
std::size_t _maxVarBinColSize;
|
std::size_t _maxVarBinColSize;
|
||||||
ODBCMetaColumn::NumericConversion _numericConversion;
|
|
||||||
NullCbMap _nullCbMap;
|
NullCbMap _nullCbMap;
|
||||||
bool _insertOnly;
|
bool _insertOnly;
|
||||||
};
|
};
|
||||||
|
@ -514,7 +514,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.
|
||||||
{
|
{
|
||||||
ODBCMetaColumn column(_rStmt, pos, _pPreparator->numericConversion());
|
ODBCMetaColumn column(_rStmt, pos);
|
||||||
|
|
||||||
switch (column.type())
|
switch (column.type())
|
||||||
{
|
{
|
||||||
@ -720,7 +720,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 = ODBCMetaColumn(_rStmt, pos, _pPreparator->numericConversion()).length();
|
std::size_t size = ODBCMetaColumn(_rStmt, pos).length();
|
||||||
std::size_t maxSize = _pPreparator->maxDataSize(pos);
|
std::size_t maxSize = _pPreparator->maxDataSize(pos);
|
||||||
if (size > maxSize) size = maxSize;
|
if (size > maxSize) size = maxSize;
|
||||||
return (SQLINTEGER) size;
|
return (SQLINTEGER) size;
|
||||||
|
@ -40,14 +40,7 @@ class ODBC_API ODBCMetaColumn: public MetaColumn
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum NumericConversion
|
ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position);
|
||||||
{
|
|
||||||
NC_BEST_FIT = 0,
|
|
||||||
NC_FORCE_STRING = 1,
|
|
||||||
NC_BEST_FIT_DBL_LIMIT = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position, NumericConversion numericConversion);
|
|
||||||
/// Creates the ODBCMetaColumn.
|
/// Creates the ODBCMetaColumn.
|
||||||
|
|
||||||
~ODBCMetaColumn();
|
~ODBCMetaColumn();
|
||||||
@ -81,7 +74,6 @@ private:
|
|||||||
SQLLEN _dataLength;
|
SQLLEN _dataLength;
|
||||||
const StatementHandle& _rStmt;
|
const StatementHandle& _rStmt;
|
||||||
ColumnDescription _columnDesc;
|
ColumnDescription _columnDesc;
|
||||||
NumericConversion _numericConversion;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,7 +160,6 @@ private:
|
|||||||
bool _prepared;
|
bool _prepared;
|
||||||
mutable std::size_t _affectedRowCount;
|
mutable std::size_t _affectedRowCount;
|
||||||
bool _canCompile;
|
bool _canCompile;
|
||||||
ODBCMetaColumn::NumericConversion _numericConversion;
|
|
||||||
bool _isPostgres;
|
bool _isPostgres;
|
||||||
bool _insertHint;
|
bool _insertHint;
|
||||||
};
|
};
|
||||||
|
@ -102,7 +102,6 @@ public:
|
|||||||
const std::string& statement,
|
const std::string& statement,
|
||||||
std::size_t maxFieldSize,
|
std::size_t maxFieldSize,
|
||||||
DataExtraction dataExtraction,
|
DataExtraction dataExtraction,
|
||||||
ODBCMetaColumn::NumericConversion numericConversion ,
|
|
||||||
bool isPostgres
|
bool isPostgres
|
||||||
);
|
);
|
||||||
/// Creates the Preparator.
|
/// Creates the Preparator.
|
||||||
@ -419,9 +418,6 @@ public:
|
|||||||
DataExtraction getDataExtraction() const;
|
DataExtraction getDataExtraction() const;
|
||||||
/// Returns data extraction mode.
|
/// Returns data extraction mode.
|
||||||
|
|
||||||
ODBCMetaColumn::NumericConversion numericConversion() const;
|
|
||||||
/// Tells if numeric values are always converted to string
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::vector<Poco::Any> ValueVec;
|
typedef std::vector<Poco::Any> ValueVec;
|
||||||
typedef std::vector<SQLLEN> LengthVec;
|
typedef std::vector<SQLLEN> LengthVec;
|
||||||
@ -435,7 +431,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.
|
||||||
{
|
{
|
||||||
ODBCMetaColumn col(_rStmt, pos, _numericConversion);
|
ODBCMetaColumn col(_rStmt, pos);
|
||||||
|
|
||||||
switch (col.type())
|
switch (col.type())
|
||||||
{
|
{
|
||||||
@ -687,7 +683,6 @@ private:
|
|||||||
mutable IndexMap _varLengthArrays;
|
mutable IndexMap _varLengthArrays;
|
||||||
std::size_t _maxFieldSize;
|
std::size_t _maxFieldSize;
|
||||||
DataExtraction _dataExtraction;
|
DataExtraction _dataExtraction;
|
||||||
ODBCMetaColumn::NumericConversion _numericConversion;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1274,12 +1269,6 @@ inline Poco::Any& Preparator::at(std::size_t pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline ODBCMetaColumn::NumericConversion Preparator::numericConversion() const
|
|
||||||
{
|
|
||||||
return _numericConversion;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } } // namespace Poco::Data::ODBC
|
} } } // namespace Poco::Data::ODBC
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,7 +45,6 @@ class ODBC_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const std::size_t ODBC_MAX_FIELD_SIZE = 1024u;
|
static const std::size_t ODBC_MAX_FIELD_SIZE = 1024u;
|
||||||
static const char* const NUMERIC_CONVERSION_PROPERTY;
|
|
||||||
|
|
||||||
enum TransactionCapability
|
enum TransactionCapability
|
||||||
{
|
{
|
||||||
@ -168,22 +167,10 @@ public:
|
|||||||
Poco::Any dataTypeInfo(const std::string& rName="");
|
Poco::Any dataTypeInfo(const std::string& rName="");
|
||||||
/// Returns the data types information.
|
/// Returns the data types information.
|
||||||
|
|
||||||
ODBCMetaColumn::NumericConversion numericConversion() const;
|
|
||||||
/// Tells if NUMERIC values to be always
|
|
||||||
/// converted to string
|
|
||||||
|
|
||||||
void setNumericConversion(ODBCMetaColumn::NumericConversion value);
|
|
||||||
/// Sets flag to tell if NUMERIC values are always returned as
|
|
||||||
/// string
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setDataTypeInfo(const std::string& rName, const Poco::Any& rValue);
|
void setDataTypeInfo(const std::string& rName, const Poco::Any& rValue);
|
||||||
/// No-op. Throws InvalidAccessException.
|
/// No-op. Throws InvalidAccessException.
|
||||||
|
|
||||||
void setNumericConversion(const std::string&, const Poco::Any& rValue);
|
|
||||||
|
|
||||||
Poco::Any numericConversion(const std::string& nm);
|
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
static const int FUNCTIONS = SQL_API_ODBC3_ALL_FUNCTIONS_SIZE;
|
static const int FUNCTIONS = SQL_API_ODBC3_ALL_FUNCTIONS_SIZE;
|
||||||
@ -199,7 +186,6 @@ private:
|
|||||||
Poco::Any _maxFieldSize;
|
Poco::Any _maxFieldSize;
|
||||||
bool _autoBind;
|
bool _autoBind;
|
||||||
bool _autoExtract;
|
bool _autoExtract;
|
||||||
ODBCMetaColumn::NumericConversion _numericConversion;
|
|
||||||
TypeInfo _dataTypes;
|
TypeInfo _dataTypes;
|
||||||
char _canTransact;
|
char _canTransact;
|
||||||
bool _inTransaction;
|
bool _inTransaction;
|
||||||
@ -302,30 +288,6 @@ inline int SessionImpl::queryTimeout() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline ODBCMetaColumn::NumericConversion SessionImpl::numericConversion() const
|
|
||||||
{
|
|
||||||
return _numericConversion;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Poco::Any SessionImpl::numericConversion(const std::string&)
|
|
||||||
{
|
|
||||||
return numericConversion();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void SessionImpl::setNumericConversion(ODBCMetaColumn::NumericConversion value)
|
|
||||||
{
|
|
||||||
_numericConversion = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void SessionImpl::setNumericConversion(const std::string&, const Poco::Any& rValue)
|
|
||||||
{
|
|
||||||
setNumericConversion( Poco::AnyCast<ODBCMetaColumn::NumericConversion>(rValue) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } } // namespace Poco::Data::ODBC
|
} } } // namespace Poco::Data::ODBC
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@ Binder::Binder(const StatementHandle& rStmt,
|
|||||||
std::size_t maxFieldSize,
|
std::size_t maxFieldSize,
|
||||||
Binder::ParameterBinding dataBinding,
|
Binder::ParameterBinding dataBinding,
|
||||||
TypeInfo* pDataTypes,
|
TypeInfo* pDataTypes,
|
||||||
ODBCMetaColumn::NumericConversion numericConversion,
|
|
||||||
bool insertOnly) :
|
bool insertOnly) :
|
||||||
_rStmt(rStmt),
|
_rStmt(rStmt),
|
||||||
_paramBinding(dataBinding),
|
_paramBinding(dataBinding),
|
||||||
@ -54,7 +53,6 @@ Binder::Binder(const StatementHandle& rStmt,
|
|||||||
_maxCharColLength(1024),
|
_maxCharColLength(1024),
|
||||||
_maxWCharColLength(1024),
|
_maxWCharColLength(1024),
|
||||||
_maxVarBinColSize(1024),
|
_maxVarBinColSize(1024),
|
||||||
_numericConversion(numericConversion),
|
|
||||||
_insertOnly(insertOnly)
|
_insertOnly(insertOnly)
|
||||||
{
|
{
|
||||||
getProp(*_pTypeInfo, SQL_WVARCHAR, _maxWCharColLength);
|
getProp(*_pTypeInfo, SQL_WVARCHAR, _maxWCharColLength);
|
||||||
@ -566,7 +564,7 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ODBCMetaColumn c(_rStmt, pos, _numericConversion);
|
ODBCMetaColumn c(_rStmt, pos);
|
||||||
_parameters[pos] = ParamDescriptor(static_cast<SQLINTEGER>(c.length()), cDataType, static_cast<SQLSMALLINT>(c.precision()));
|
_parameters[pos] = ParamDescriptor(static_cast<SQLINTEGER>(c.length()), cDataType, static_cast<SQLSMALLINT>(c.precision()));
|
||||||
}
|
}
|
||||||
catch (StatementException&) {}
|
catch (StatementException&) {}
|
||||||
@ -587,7 +585,7 @@ void Binder::getColumnOrParameterSize(std::size_t pos, SQLINTEGER& size)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ODBCMetaColumn col(_rStmt, pos, _numericConversion);
|
ODBCMetaColumn col(_rStmt, pos);
|
||||||
colSize = col.length();
|
colSize = col.length();
|
||||||
}
|
}
|
||||||
catch (StatementException&) { }
|
catch (StatementException&) { }
|
||||||
|
@ -23,10 +23,9 @@ namespace Data {
|
|||||||
namespace ODBC {
|
namespace ODBC {
|
||||||
|
|
||||||
|
|
||||||
ODBCMetaColumn::ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position, NumericConversion numericConversion) :
|
ODBCMetaColumn::ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position) :
|
||||||
MetaColumn(position),
|
MetaColumn(position),
|
||||||
_rStmt(rStmt),
|
_rStmt(rStmt)
|
||||||
_numericConversion(numericConversion)
|
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@ -117,44 +116,17 @@ void ODBCMetaColumn::init()
|
|||||||
|
|
||||||
case SQL_NUMERIC:
|
case SQL_NUMERIC:
|
||||||
case SQL_DECIMAL:
|
case SQL_DECIMAL:
|
||||||
{
|
|
||||||
bool toString = false;
|
|
||||||
switch (_numericConversion)
|
|
||||||
{
|
|
||||||
case NC_BEST_FIT:
|
|
||||||
case NC_BEST_FIT_DBL_LIMIT:
|
|
||||||
if (0 == _columnDesc.decimalDigits)
|
if (0 == _columnDesc.decimalDigits)
|
||||||
{
|
{
|
||||||
if (_columnDesc.size <= 9)
|
#ifdef POCO_64_BIT
|
||||||
setType(MetaColumn::FDT_INT32);
|
|
||||||
else if (_columnDesc.size <= 18)
|
|
||||||
setType(MetaColumn::FDT_INT64);
|
setType(MetaColumn::FDT_INT64);
|
||||||
else if (_numericConversion != NC_BEST_FIT_DBL_LIMIT)
|
|
||||||
toString = true;
|
|
||||||
else
|
|
||||||
setType(MetaColumn::FDT_DOUBLE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// we can't have more than 16 digits in double, but we may be asked to
|
|
||||||
if (_columnDesc.size > 16 && _numericConversion != NC_BEST_FIT_DBL_LIMIT)
|
|
||||||
toString = true;
|
|
||||||
else
|
|
||||||
setType(MetaColumn::FDT_DOUBLE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NC_FORCE_STRING:
|
|
||||||
toString = true;
|
|
||||||
}
|
|
||||||
if (toString)
|
|
||||||
{
|
|
||||||
setLength(_columnDesc.size + 4);
|
|
||||||
#if defined(UNICODE)
|
|
||||||
setType(MetaColumn::FDT_WSTRING);
|
|
||||||
#else
|
#else
|
||||||
setType(MetaColumn::FDT_STRING);
|
setType(MetaColumn::FDT_INT32);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setType(MetaColumn::FDT_DOUBLE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -47,7 +47,6 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
|
|||||||
_prepared(false),
|
_prepared(false),
|
||||||
_affectedRowCount(0),
|
_affectedRowCount(0),
|
||||||
_canCompile(true),
|
_canCompile(true),
|
||||||
_numericConversion(rSession.numericConversion()),
|
|
||||||
_isPostgres(false),
|
_isPostgres(false),
|
||||||
_insertHint(false)
|
_insertHint(false)
|
||||||
{
|
{
|
||||||
@ -111,9 +110,8 @@ void ODBCStatementImpl::compileImpl()
|
|||||||
}
|
}
|
||||||
|
|
||||||
const std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
|
const std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
|
||||||
const ODBCMetaColumn::NumericConversion numericConversion = dynamic_cast<SessionImpl&>(session()).numericConversion();
|
|
||||||
|
|
||||||
_pBinder = new Binder(_stmt, maxFieldSize, bind, pDT, numericConversion, _insertHint);
|
_pBinder = new Binder(_stmt, maxFieldSize, bind, pDT, _insertHint);
|
||||||
|
|
||||||
makeInternalExtractors();
|
makeInternalExtractors();
|
||||||
doPrepare();
|
doPrepare();
|
||||||
@ -156,7 +154,7 @@ bool ODBCStatementImpl::addPreparator(bool addAlways)
|
|||||||
|
|
||||||
std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
|
std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
|
||||||
|
|
||||||
prep = new Preparator(_stmt, statement, maxFieldSize, ext, _numericConversion, _isPostgres);
|
prep = new Preparator(_stmt, statement, maxFieldSize, ext, _isPostgres);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
prep = new Preparator(*_preparations[0]);
|
prep = new Preparator(*_preparations[0]);
|
||||||
@ -340,19 +338,23 @@ bool ODBCStatementImpl::hasNext()
|
|||||||
if (!nextRowReady())
|
if (!nextRowReady())
|
||||||
{
|
{
|
||||||
// have a loop here, as there could be one or more empty results
|
// have a loop here, as there could be one or more empty results
|
||||||
do {
|
do
|
||||||
if (hasMoreDataSets()) {
|
{
|
||||||
|
if (hasMoreDataSets())
|
||||||
|
{
|
||||||
activateNextDataSet();
|
activateNextDataSet();
|
||||||
if (!nextResultSet())
|
if (!nextResultSet())
|
||||||
return false;
|
return false;
|
||||||
addPreparator();
|
addPreparator();
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if (nextResultSet()) {
|
{
|
||||||
|
if (nextResultSet())
|
||||||
|
{
|
||||||
if (!addPreparator(false)) // skip the result set if it has no columns
|
if (!addPreparator(false)) // skip the result set if it has no columns
|
||||||
continue;
|
continue;
|
||||||
fillColumns(currentDataSet() + 1);
|
fillColumns(currentDataSet() + 1);
|
||||||
makeExtractors(_preparations.back()->columns(), static_cast<Position::PositionType>(currentDataSet() + 1));
|
makeExtractors(_preparations.back()->columns(), static_cast<Position::Type>(currentDataSet() + 1));
|
||||||
activateNextDataSet();
|
activateNextDataSet();
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
@ -469,7 +471,7 @@ void ODBCStatementImpl::fillColumns(size_t dataSetPos)
|
|||||||
_columnPtrs.resize(dataSetPos + 1);
|
_columnPtrs.resize(dataSetPos + 1);
|
||||||
|
|
||||||
for (int i = 0; i < colCount; ++i)
|
for (int i = 0; i < colCount; ++i)
|
||||||
_columnPtrs[dataSetPos].push_back(new ODBCMetaColumn(_stmt, i, _numericConversion));
|
_columnPtrs[dataSetPos].push_back(new ODBCMetaColumn(_stmt, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,12 +31,10 @@ Preparator::Preparator(const StatementHandle& rStmt,
|
|||||||
const std::string& statement,
|
const std::string& statement,
|
||||||
std::size_t maxFieldSize,
|
std::size_t maxFieldSize,
|
||||||
DataExtraction dataExtraction,
|
DataExtraction dataExtraction,
|
||||||
ODBCMetaColumn::NumericConversion numericConversion,
|
|
||||||
bool isPostgres) :
|
bool isPostgres) :
|
||||||
_rStmt(rStmt),
|
_rStmt(rStmt),
|
||||||
_maxFieldSize(maxFieldSize),
|
_maxFieldSize(maxFieldSize),
|
||||||
_dataExtraction(dataExtraction),
|
_dataExtraction(dataExtraction)
|
||||||
_numericConversion(numericConversion)
|
|
||||||
{
|
{
|
||||||
SQLCHAR* pStr = (SQLCHAR*) statement.c_str();
|
SQLCHAR* pStr = (SQLCHAR*) statement.c_str();
|
||||||
if (Utility::isError(Poco::Data::ODBC::SQLPrepare(_rStmt, pStr, (SQLINTEGER) statement.length())))
|
if (Utility::isError(Poco::Data::ODBC::SQLPrepare(_rStmt, pStr, (SQLINTEGER) statement.length())))
|
||||||
@ -57,8 +55,7 @@ Preparator::Preparator(const StatementHandle& rStmt,
|
|||||||
Preparator::Preparator(const Preparator& other):
|
Preparator::Preparator(const Preparator& other):
|
||||||
_rStmt(other._rStmt),
|
_rStmt(other._rStmt),
|
||||||
_maxFieldSize(other._maxFieldSize),
|
_maxFieldSize(other._maxFieldSize),
|
||||||
_dataExtraction(other._dataExtraction),
|
_dataExtraction(other._dataExtraction)
|
||||||
_numericConversion(other._numericConversion)
|
|
||||||
{
|
{
|
||||||
resize();
|
resize();
|
||||||
}
|
}
|
||||||
@ -169,7 +166,7 @@ std::size_t Preparator::maxDataSize(std::size_t pos) const
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ODBCMetaColumn mc(_rStmt, pos, _numericConversion);
|
ODBCMetaColumn mc(_rStmt, pos);
|
||||||
sz = mc.length();
|
sz = mc.length();
|
||||||
|
|
||||||
// accommodate for terminating zero (non-bulk only!)
|
// accommodate for terminating zero (non-bulk only!)
|
||||||
|
@ -29,8 +29,6 @@ namespace Data {
|
|||||||
namespace ODBC {
|
namespace ODBC {
|
||||||
|
|
||||||
|
|
||||||
const char* const SessionImpl::NUMERIC_CONVERSION_PROPERTY= "numericConversion";
|
|
||||||
|
|
||||||
SessionImpl::SessionImpl(const std::string& connect,
|
SessionImpl::SessionImpl(const std::string& connect,
|
||||||
std::size_t loginTimeout,
|
std::size_t loginTimeout,
|
||||||
std::size_t maxFieldSize,
|
std::size_t maxFieldSize,
|
||||||
@ -41,7 +39,6 @@ SessionImpl::SessionImpl(const std::string& connect,
|
|||||||
_maxFieldSize(maxFieldSize),
|
_maxFieldSize(maxFieldSize),
|
||||||
_autoBind(autoBind),
|
_autoBind(autoBind),
|
||||||
_autoExtract(autoExtract),
|
_autoExtract(autoExtract),
|
||||||
_numericConversion(ODBCMetaColumn::NC_BEST_FIT),
|
|
||||||
_canTransact(ODBC_TXN_CAPABILITY_UNKNOWN),
|
_canTransact(ODBC_TXN_CAPABILITY_UNKNOWN),
|
||||||
_inTransaction(false),
|
_inTransaction(false),
|
||||||
_queryTimeout(-1)
|
_queryTimeout(-1)
|
||||||
@ -69,9 +66,6 @@ SessionImpl::SessionImpl(const std::string& connect,
|
|||||||
|
|
||||||
void SessionImpl::init()
|
void SessionImpl::init()
|
||||||
{
|
{
|
||||||
addProperty(NUMERIC_CONVERSION_PROPERTY,
|
|
||||||
&SessionImpl::setNumericConversion,
|
|
||||||
&SessionImpl::numericConversion);
|
|
||||||
setFeature("bulk", true);
|
setFeature("bulk", true);
|
||||||
open();
|
open();
|
||||||
setProperty("handle", _db.handle());
|
setProperty("handle", _db.handle());
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
<Filter>_Suite\Header Files</Filter>
|
<Filter>_Suite\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="src\ODBCSybaseTest.h">
|
<ClInclude Include="src\ODBCSybaseTest.h">
|
||||||
<Filter>ODBC</Filter>
|
<Filter>ODBC\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -96,7 +96,7 @@
|
|||||||
<Filter>_Driver\Source Files</Filter>
|
<Filter>_Driver\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="src\ODBCSybaseTest.cpp">
|
<ClCompile Include="src\ODBCSybaseTest.cpp">
|
||||||
<Filter>ODBC</Filter>
|
<Filter>ODBC\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -578,17 +578,6 @@ void ODBCDB2Test::recreateNullableTable()
|
|||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void ODBCDB2Test::recreateNumericTable()
|
|
||||||
{
|
|
||||||
dropObject("TABLE", ExecUtil::numeric_tbl());
|
|
||||||
try {
|
|
||||||
session() << "CREATE TABLE " << ExecUtil::numeric_tbl() <<
|
|
||||||
" (id integer, num8 NUMERIC(8), num16_3 NUMERIC(16,3), num18 NUMERIC(18), num18_8 NUMERIC(18,8), num22 NUMERIC(22))", now;
|
|
||||||
}
|
|
||||||
catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail("recreateNumericTable()"); }
|
|
||||||
catch (StatementException& se){ std::cout << se.toString() << std::endl; fail("recreateNumericTable()"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ODBCDB2Test::recreatePersonTable()
|
void ODBCDB2Test::recreatePersonTable()
|
||||||
{
|
{
|
||||||
@ -637,8 +626,8 @@ void ODBCDB2Test::recreatePersonDateTimeTable()
|
|||||||
|
|
||||||
void ODBCDB2Test::recreateIntsTable()
|
void ODBCDB2Test::recreateIntsTable()
|
||||||
{
|
{
|
||||||
dropObject("TABLE", ExecUtil::strings());
|
dropObject("TABLE", ExecUtil::ints());
|
||||||
try { session() << "CREATE TABLE " << ExecUtil::strings() << " (str INTEGER)", now; }
|
try { session() << "CREATE TABLE " << ExecUtil::ints() << " (str INTEGER)", now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
}
|
}
|
||||||
@ -835,7 +824,6 @@ CppUnit::Test* ODBCDB2Test::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testTransactor);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testTransactor);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testNullable);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testNullable);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testReconnect);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testReconnect);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testNumeric);
|
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testXMLColumn);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testXMLColumn);
|
||||||
CppUnit_addTest(pSuite, ODBCDB2Test, testInsertStatReuse);
|
CppUnit_addTest(pSuite, ODBCDB2Test, testInsertStatReuse);
|
||||||
|
|
||||||
|
@ -62,7 +62,6 @@ private:
|
|||||||
void recreateNullsTable(const std::string& notNull = "");
|
void recreateNullsTable(const std::string& notNull = "");
|
||||||
void recreateMiscTable();
|
void recreateMiscTable();
|
||||||
void recreateLogTable();
|
void recreateLogTable();
|
||||||
void recreateNumericTable();
|
|
||||||
|
|
||||||
static ODBCTest::SessionPtr _pSession;
|
static ODBCTest::SessionPtr _pSession;
|
||||||
static ODBCTest::ExecPtr _pExecutor;
|
static ODBCTest::ExecPtr _pExecutor;
|
||||||
|
@ -304,8 +304,8 @@ void ODBCMySQLTest::recreatePersonDateTimeTable()
|
|||||||
|
|
||||||
void ODBCMySQLTest::recreateIntsTable()
|
void ODBCMySQLTest::recreateIntsTable()
|
||||||
{
|
{
|
||||||
dropObject("TABLE", ExecUtil::strings());
|
dropObject("TABLE", ExecUtil::ints());
|
||||||
try { *_pSession << "CREATE TABLE " << ExecUtil::strings() << " (str INTEGER)", now; }
|
try { *_pSession << "CREATE TABLE " << ExecUtil::ints() << " (str INTEGER)", now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ using Poco::DynamicAny;
|
|||||||
using Poco::DateTime;
|
using Poco::DateTime;
|
||||||
|
|
||||||
|
|
||||||
#define ORACLE_ODBC_DRIVER "Oracle in XE"
|
#define ORACLE_ODBC_DRIVER "Oracle in OraClient12Home1_32bit"//XE"
|
||||||
#define ORACLE_DSN "PocoDataOracleTest"
|
#define ORACLE_DSN "PocoDataOracleTest"
|
||||||
#define ORACLE_SERVER POCO_ODBC_TEST_DATABASE_SERVER
|
#define ORACLE_SERVER POCO_ODBC_TEST_DATABASE_SERVER
|
||||||
#define ORACLE_PORT "1521"
|
#define ORACLE_PORT "1521"
|
||||||
@ -169,6 +169,25 @@ void ODBCOracleTest::testBarebone()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCOracleTest::testInternalExtraction()
|
||||||
|
{
|
||||||
|
if (!_pSession) fail ("Test not available.");
|
||||||
|
|
||||||
|
for (int i = 0; i < 8;)
|
||||||
|
{
|
||||||
|
recreateVectorsTable();
|
||||||
|
_pSession->setFeature("autoBind", bindValue(i));
|
||||||
|
_pSession->setFeature("autoExtract", bindValue(i+1));
|
||||||
|
#ifdef POCO_64_BIT
|
||||||
|
_pExecutor->internalExtraction<double>(0.);
|
||||||
|
#else
|
||||||
|
_pExecutor->internalExtraction(0);
|
||||||
|
#endif
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCOracleTest::testBLOB()
|
void ODBCOracleTest::testBLOB()
|
||||||
{
|
{
|
||||||
const std::size_t maxFldSize = 1000000;
|
const std::size_t maxFldSize = 1000000;
|
||||||
@ -598,18 +617,18 @@ void ODBCOracleTest::testAutoTransaction()
|
|||||||
recreateIntsTable();
|
recreateIntsTable();
|
||||||
|
|
||||||
session().setFeature("autoCommit", true);
|
session().setFeature("autoCommit", true);
|
||||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (1)", now;
|
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (1)", now;
|
||||||
localSession << "SELECT count(*) FROM " << ExecUtil::person() , into(count), now;
|
localSession << "SELECT count(*) FROM " << ExecUtil::ints() , into(count), now;
|
||||||
assert (1 == count);
|
assert (1 == count);
|
||||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (2)", now;
|
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (2)", now;
|
||||||
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
|
localSession << "SELECT count(*) FROM " << ExecUtil::ints(), into(count), now;
|
||||||
assert (2 == count);
|
assert (2 == count);
|
||||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (3)", now;
|
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (3)", now;
|
||||||
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
|
localSession << "SELECT count(*) FROM " << ExecUtil::ints(), into(count), now;
|
||||||
assert (3 == count);
|
assert (3 == count);
|
||||||
|
|
||||||
session() << "DELETE FROM " << ExecUtil::strings(), now;
|
session() << "DELETE FROM " << ExecUtil::ints(), now;
|
||||||
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
|
localSession << "SELECT count(*) FROM " << ExecUtil::ints(), into(count), now;
|
||||||
assert (0 == count);
|
assert (0 == count);
|
||||||
|
|
||||||
session().setFeature("autoCommit", false);
|
session().setFeature("autoCommit", false);
|
||||||
@ -617,26 +636,26 @@ void ODBCOracleTest::testAutoTransaction()
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
AutoTransaction at(session());
|
AutoTransaction at(session());
|
||||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (1)", now;
|
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (1)", now;
|
||||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (2)", now;
|
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (2)", now;
|
||||||
session() << "BAD QUERY", now;
|
session() << "BAD QUERY", now;
|
||||||
} catch (Poco::Exception&) {}
|
} catch (Poco::Exception&) {}
|
||||||
|
|
||||||
session() << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
|
session() << "SELECT count(*) FROM " << ExecUtil::ints(), into(count), now;
|
||||||
assert (0 == count);
|
assert (0 == count);
|
||||||
|
|
||||||
AutoTransaction at(session());
|
AutoTransaction at(session());
|
||||||
|
|
||||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (1)", now;
|
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (1)", now;
|
||||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (2)", now;
|
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (2)", now;
|
||||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (3)", now;
|
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (3)", now;
|
||||||
|
|
||||||
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
|
localSession << "SELECT count(*) FROM " << ExecUtil::ints(), into(count), now;
|
||||||
assert (0 == count);
|
assert (0 == count);
|
||||||
|
|
||||||
at.commit();
|
at.commit();
|
||||||
|
|
||||||
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
|
localSession << "SELECT count(*) FROM " << ExecUtil::ints(), into(count), now;
|
||||||
assert (3 == count);
|
assert (3 == count);
|
||||||
|
|
||||||
session().setFeature("autoCommit", ac);
|
session().setFeature("autoCommit", ac);
|
||||||
@ -726,8 +745,8 @@ void ODBCOracleTest::recreatePersonDateTable()
|
|||||||
|
|
||||||
void ODBCOracleTest::recreateIntsTable()
|
void ODBCOracleTest::recreateIntsTable()
|
||||||
{
|
{
|
||||||
dropObject("TABLE", ExecUtil::strings());
|
dropObject("TABLE", ExecUtil::ints());
|
||||||
try { *_pSession << "CREATE TABLE " << ExecUtil::strings() <<" (str INTEGER)", now; }
|
try { *_pSession << "CREATE TABLE " << ExecUtil::ints() <<" (str INTEGER)", now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,8 @@ public:
|
|||||||
|
|
||||||
void testBareboneODBC();
|
void testBareboneODBC();
|
||||||
|
|
||||||
|
void testInternalExtraction();
|
||||||
|
|
||||||
void testBLOB();
|
void testBLOB();
|
||||||
|
|
||||||
void testMultipleResults();
|
void testMultipleResults();
|
||||||
|
@ -482,8 +482,8 @@ void ODBCPostgreSQLTest::recreatePersonTimeTable()
|
|||||||
|
|
||||||
void ODBCPostgreSQLTest::recreateIntsTable()
|
void ODBCPostgreSQLTest::recreateIntsTable()
|
||||||
{
|
{
|
||||||
dropObject("TABLE", ExecUtil::strings());
|
dropObject("TABLE", ExecUtil::ints());
|
||||||
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str INTEGER)", now; }
|
try { session() << "CREATE TABLE " << ExecUtil::ints() <<" (str INTEGER)", now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
}
|
}
|
||||||
|
@ -589,8 +589,8 @@ void ODBCSQLServerTest::recreatePersonDateTimeTable()
|
|||||||
|
|
||||||
void ODBCSQLServerTest::recreateIntsTable()
|
void ODBCSQLServerTest::recreateIntsTable()
|
||||||
{
|
{
|
||||||
dropObject("TABLE", ExecUtil::strings());
|
dropObject("TABLE", ExecUtil::ints());
|
||||||
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str INTEGER)", now; }
|
try { session() << "CREATE TABLE " << ExecUtil::ints() <<" (str INTEGER)", now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
}
|
}
|
||||||
|
@ -205,8 +205,8 @@ void ODBCSQLiteTest::recreatePersonDateTimeTable()
|
|||||||
|
|
||||||
void ODBCSQLiteTest::recreateIntsTable()
|
void ODBCSQLiteTest::recreateIntsTable()
|
||||||
{
|
{
|
||||||
dropObject("TABLE", ExecUtil::strings());
|
dropObject("TABLE", ExecUtil::ints());
|
||||||
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str INTEGER)", now; }
|
try { session() << "CREATE TABLE " << ExecUtil::ints() <<" (str INTEGER)", now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
}
|
}
|
||||||
|
@ -153,17 +153,6 @@ void SybaseODBC::recreateNullableTable()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SybaseODBC::recreateNumericTable()
|
|
||||||
{
|
|
||||||
dropObject("TABLE", ExecUtil::numeric_tbl());
|
|
||||||
try {
|
|
||||||
session() << "CREATE TABLE " << ExecUtil::numeric_tbl() <<
|
|
||||||
" (id integer, num8 NUMERIC(8), num16_3 NUMERIC(16,3), num18 NUMERIC(18), num18_8 NUMERIC(18,8), num22 NUMERIC(22))", now;
|
|
||||||
}
|
|
||||||
catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail("recreateNumericTable()"); }
|
|
||||||
catch (StatementException& se){ std::cout << se.toString() << std::endl; fail("recreateNumericTable()"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
void SybaseODBC::recreatePersonTable()
|
void SybaseODBC::recreatePersonTable()
|
||||||
{
|
{
|
||||||
doPersonTable();
|
doPersonTable();
|
||||||
@ -216,8 +205,8 @@ void SybaseODBC::recreatePersonDateTimeTable()
|
|||||||
|
|
||||||
void SybaseODBC::recreateIntsTable()
|
void SybaseODBC::recreateIntsTable()
|
||||||
{
|
{
|
||||||
dropObject("TABLE", ExecUtil::strings());
|
dropObject("TABLE", ExecUtil::ints());
|
||||||
try { session() << "CREATE TABLE " << ExecUtil::strings() << " (str INTEGER)", now; }
|
try { session() << "CREATE TABLE " << ExecUtil::ints() << " (str INTEGER)", now; }
|
||||||
catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail("recreateIntsTable()"); }
|
catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail("recreateIntsTable()"); }
|
||||||
catch (StatementException& se){ std::cout << se.toString() << std::endl; fail("recreateIntsTable()"); }
|
catch (StatementException& se){ std::cout << se.toString() << std::endl; fail("recreateIntsTable()"); }
|
||||||
}
|
}
|
||||||
@ -665,7 +654,6 @@ CppUnit::Test* SybaseODBC::suite()
|
|||||||
CppUnit_addTest(pSuite, SybaseODBC, testTransactor);
|
CppUnit_addTest(pSuite, SybaseODBC, testTransactor);
|
||||||
CppUnit_addTest(pSuite, SybaseODBC, testNullable);
|
CppUnit_addTest(pSuite, SybaseODBC, testNullable);
|
||||||
CppUnit_addTest(pSuite, SybaseODBC, testReconnect);
|
CppUnit_addTest(pSuite, SybaseODBC, testReconnect);
|
||||||
CppUnit_addTest(pSuite, SybaseODBC, testNumeric);
|
|
||||||
CppUnit_addTest(pSuite, SybaseODBC, testInsertStatReuse);
|
CppUnit_addTest(pSuite, SybaseODBC, testInsertStatReuse);
|
||||||
|
|
||||||
_pExecutor = 0;
|
_pExecutor = 0;
|
||||||
|
@ -56,7 +56,6 @@ private:
|
|||||||
void recreateNullsTable(const std::string& notNull = "");
|
void recreateNullsTable(const std::string& notNull = "");
|
||||||
void recreateMiscTable();
|
void recreateMiscTable();
|
||||||
void recreateLogTable();
|
void recreateLogTable();
|
||||||
void recreateNumericTable();
|
|
||||||
void testStoredProcedure();
|
void testStoredProcedure();
|
||||||
void testStoredProcedureDynamicAny();
|
void testStoredProcedureDynamicAny();
|
||||||
void testStoredProcedureAny();
|
void testStoredProcedureAny();
|
||||||
|
@ -960,7 +960,7 @@ void ODBCTest::testInternalExtraction()
|
|||||||
recreateVectorsTable();
|
recreateVectorsTable();
|
||||||
_pSession->setFeature("autoBind", bindValue(i));
|
_pSession->setFeature("autoBind", bindValue(i));
|
||||||
_pSession->setFeature("autoExtract", bindValue(i+1));
|
_pSession->setFeature("autoExtract", bindValue(i+1));
|
||||||
_pExecutor->internalExtraction();
|
_pExecutor->internalExtraction(0);
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1235,33 +1235,6 @@ void ODBCTest::testNullable()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ODBCTest::testNumeric()
|
|
||||||
{
|
|
||||||
if (!_pSession) fail("Test not available.");
|
|
||||||
|
|
||||||
recreateNumericTable();
|
|
||||||
std::vector<std::string> vals;
|
|
||||||
vals.push_back("12345678");
|
|
||||||
vals.push_back("123456789012.123");
|
|
||||||
vals.push_back("123456789012345678");
|
|
||||||
vals.push_back("1234567890.12345678");
|
|
||||||
vals.push_back("1234567890123456789012");
|
|
||||||
|
|
||||||
const std::string sqlStr = std::string("INSERT INTO ") + ExecUtil::numeric_tbl() +
|
|
||||||
"(id, num8, num16_3, num18, num18_8, num22) VALUES (1, " + str2NumExpr(vals[0],8,0) + " , " + str2NumExpr(vals[1],16,3) + ", " + str2NumExpr(vals[2], 18,0)
|
|
||||||
+ " , " + str2NumExpr(vals[3], 18, 8) + " , " + str2NumExpr(vals[4], 22, 0) + ")";
|
|
||||||
|
|
||||||
session() << sqlStr, now;
|
|
||||||
|
|
||||||
for (int i = 0; i < 8;)
|
|
||||||
{
|
|
||||||
_pSession->setFeature("autoBind", bindValue(i));
|
|
||||||
_pSession->setFeature("autoExtract", bindValue(i + 1));
|
|
||||||
_pExecutor->numericTypes(vals);
|
|
||||||
i += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ODBCTest::testInsertStatReuse()
|
void ODBCTest::testInsertStatReuse()
|
||||||
{
|
{
|
||||||
@ -1413,7 +1386,7 @@ ODBCTest::SessionPtr ODBCTest::init(const std::string& driver,
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::cout << "Conecting to [" << dbConnString << ']' << std::endl;
|
std::cout << "Connecting to [" << dbConnString << ']' << std::endl;
|
||||||
return new Session(Poco::Data::ODBC::Connector::KEY, dbConnString, 5);
|
return new Session(Poco::Data::ODBC::Connector::KEY, dbConnString, 5);
|
||||||
}catch (ConnectionFailedException& ex)
|
}catch (ConnectionFailedException& ex)
|
||||||
{
|
{
|
||||||
|
@ -154,7 +154,6 @@ public:
|
|||||||
virtual void testUnicode();
|
virtual void testUnicode();
|
||||||
|
|
||||||
virtual void testReconnect();
|
virtual void testReconnect();
|
||||||
virtual void testNumeric();
|
|
||||||
virtual void testSyntaxError();
|
virtual void testSyntaxError();
|
||||||
virtual void testInsertStatReuse();
|
virtual void testInsertStatReuse();
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
#include "Poco/Data/Time.h"
|
#include "Poco/Data/Time.h"
|
||||||
#include "Poco/Data/LOB.h"
|
#include "Poco/Data/LOB.h"
|
||||||
#include "Poco/Data/StatementImpl.h"
|
#include "Poco/Data/StatementImpl.h"
|
||||||
#include "Poco/Data/RecordSet.h"
|
|
||||||
#include "Poco/Data/RowIterator.h"
|
#include "Poco/Data/RowIterator.h"
|
||||||
#include "Poco/Data/RowFilter.h"
|
#include "Poco/Data/RowFilter.h"
|
||||||
#include "Poco/Data/BulkExtraction.h"
|
#include "Poco/Data/BulkExtraction.h"
|
||||||
@ -1518,7 +1517,7 @@ void SQLExecutor::insertSingleBulk()
|
|||||||
{
|
{
|
||||||
std::string funct = "insertSingleBulk()";
|
std::string funct = "insertSingleBulk()";
|
||||||
int x = 0;
|
int x = 0;
|
||||||
Statement stmt((session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (?)", use(x)));
|
Statement stmt((session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (?)", use(x)));
|
||||||
|
|
||||||
for (x = 0; x < 100; ++x)
|
for (x = 0; x < 100; ++x)
|
||||||
{
|
{
|
||||||
@ -1526,12 +1525,12 @@ void SQLExecutor::insertSingleBulk()
|
|||||||
assert (1 == i);
|
assert (1 == i);
|
||||||
}
|
}
|
||||||
int count = 0;
|
int count = 0;
|
||||||
try { session() << "SELECT COUNT(*) FROM " << ExecUtil::strings(), into(count), now; }
|
try { session() << "SELECT COUNT(*) FROM " << ExecUtil::ints(), into(count), now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
assert (count == 100);
|
assert (count == 100);
|
||||||
|
|
||||||
try { session() << "SELECT SUM(str) FROM " << ExecUtil::strings(), into(count), now; }
|
try { session() << "SELECT SUM(str) FROM " << ExecUtil::ints(), into(count), now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
assert (count == ((0+99)*100/2));
|
assert (count == ((0+99)*100/2));
|
||||||
@ -1592,16 +1591,16 @@ void SQLExecutor::insertSingleBulkVec()
|
|||||||
for (int x = 0; x < 100; ++x)
|
for (int x = 0; x < 100; ++x)
|
||||||
data.push_back(x);
|
data.push_back(x);
|
||||||
|
|
||||||
Statement stmt((session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (?)", use(data)));
|
Statement stmt((session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (?)", use(data)));
|
||||||
stmt.execute();
|
stmt.execute();
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
try { session() << "SELECT COUNT(*) FROM " << ExecUtil::strings(), into(count), now; }
|
try { session() << "SELECT COUNT(*) FROM " << ExecUtil::ints(), into(count), now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
|
|
||||||
assert (count == 100);
|
assert (count == 100);
|
||||||
try { session() << "SELECT SUM(str) FROM " << ExecUtil::strings(), into(count), now; }
|
try { session() << "SELECT SUM(str) FROM " << ExecUtil::ints(), into(count), now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
assert (count == ((0+99)*100/2));
|
assert (count == ((0+99)*100/2));
|
||||||
@ -1617,12 +1616,12 @@ void SQLExecutor::limits()
|
|||||||
data.push_back(x);
|
data.push_back(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
try { session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (?)", use(data), now; }
|
try { session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (?)", use(data), now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
|
|
||||||
std::vector<int> retData;
|
std::vector<int> retData;
|
||||||
try { session() << "SELECT * FROM " << ExecUtil::strings(), into(retData), limit(50), now; }
|
try { session() << "SELECT * FROM " << ExecUtil::ints(), into(retData), limit(50), now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
assert (retData.size() == 50);
|
assert (retData.size() == 50);
|
||||||
@ -1642,12 +1641,12 @@ void SQLExecutor::limitZero()
|
|||||||
data.push_back(x);
|
data.push_back(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
try { session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (?)", use(data), now; }
|
try { session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (?)", use(data), now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
|
|
||||||
std::vector<int> retData;
|
std::vector<int> retData;
|
||||||
try { session() << "SELECT * FROM " << ExecUtil::strings(), into(retData), limit(0), now; }// stupid test, but at least we shouldn't crash
|
try { session() << "SELECT * FROM " << ExecUtil::ints(), into(retData), limit(0), now; }// stupid test, but at least we shouldn't crash
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
assert (retData.size() == 0);
|
assert (retData.size() == 0);
|
||||||
@ -1663,12 +1662,12 @@ void SQLExecutor::limitOnce()
|
|||||||
data.push_back(x);
|
data.push_back(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
try { session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (?)", use(data), now; }
|
try { session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (?)", use(data), now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
|
|
||||||
std::vector<int> retData;
|
std::vector<int> retData;
|
||||||
Statement stmt = (session() << "SELECT * FROM " << ExecUtil::strings(), into(retData), limit(50), now);
|
Statement stmt = (session() << "SELECT * FROM " << ExecUtil::ints(), into(retData), limit(50), now);
|
||||||
assert (!stmt.done());
|
assert (!stmt.done());
|
||||||
assert (retData.size() == 50);
|
assert (retData.size() == 50);
|
||||||
stmt.execute();
|
stmt.execute();
|
||||||
@ -1696,14 +1695,14 @@ void SQLExecutor::limitPrepare()
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Statement stmt = (session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (?)", use(data));
|
Statement stmt = (session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (?)", use(data));
|
||||||
assert (100 == stmt.execute());
|
assert (100 == stmt.execute());
|
||||||
}
|
}
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
|
|
||||||
std::vector<int> retData;
|
std::vector<int> retData;
|
||||||
Statement stmt = (session() << "SELECT * FROM " << ExecUtil::strings(), into(retData), limit(50));
|
Statement stmt = (session() << "SELECT * FROM " << ExecUtil::ints(), into(retData), limit(50));
|
||||||
assert (retData.size() == 0);
|
assert (retData.size() == 0);
|
||||||
assert (!stmt.done());
|
assert (!stmt.done());
|
||||||
|
|
||||||
@ -1739,84 +1738,17 @@ void SQLExecutor::prepare()
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Statement stmt((session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (?)", use(data)));
|
Statement stmt((session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (?)", use(data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// stmt should not have been executed when destroyed
|
// stmt should not have been executed when destroyed
|
||||||
int count = 100;
|
int count = 100;
|
||||||
try { session() << "SELECT COUNT(*) FROM " << ExecUtil::strings(), into(count), now; }
|
try { session() << "SELECT COUNT(*) FROM " << ExecUtil::ints(), into(count), now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
assert (count == 0);
|
assert (count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SQLExecutor::numericTypes(const std::vector<std::string>& vals)
|
|
||||||
{
|
|
||||||
std::string funct = "numericTypes()";
|
|
||||||
try {
|
|
||||||
|
|
||||||
session().setProperty(Poco::Data::ODBC::SessionImpl::NUMERIC_CONVERSION_PROPERTY, Poco::Data::ODBC::ODBCMetaColumn::NC_BEST_FIT);
|
|
||||||
|
|
||||||
{
|
|
||||||
Statement stat(session());
|
|
||||||
stat << "SELECT * FROM " << ExecUtil::numeric_tbl(), now;
|
|
||||||
RecordSet rs(stat);
|
|
||||||
|
|
||||||
assert(vals.size() + 1 == rs.columnCount());
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_INT32 == rs.columnType(0));
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_INT32 == rs.columnType(1));
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_DOUBLE == rs.columnType(2));
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_INT64 == rs.columnType(3));
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_STRING == rs.columnType(4));
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_STRING == rs.columnType(5));
|
|
||||||
for (size_t i = 0; i < vals.size(); ++i)
|
|
||||||
{
|
|
||||||
std::string v = rs.value(i + 1).convert<std::string>();
|
|
||||||
assert(vals[i] == v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
session().setProperty(Poco::Data::ODBC::SessionImpl::NUMERIC_CONVERSION_PROPERTY, Poco::Data::ODBC::ODBCMetaColumn::NC_FORCE_STRING);
|
|
||||||
{
|
|
||||||
Statement stat(session());
|
|
||||||
stat << "SELECT * FROM " << ExecUtil::numeric_tbl(), now;
|
|
||||||
RecordSet rs(stat);
|
|
||||||
|
|
||||||
assert(vals.size() + 1 == rs.columnCount());
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_INT32 == rs.columnType(0));
|
|
||||||
for (size_t i = 0; i < vals.size(); ++i)
|
|
||||||
{
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_STRING == rs.columnType(i + 1));
|
|
||||||
std::string v = rs.value<std::string>(i + 1);
|
|
||||||
assert(vals[i] == v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
session().setProperty(Poco::Data::ODBC::SessionImpl::NUMERIC_CONVERSION_PROPERTY, Poco::Data::ODBC::ODBCMetaColumn::NC_BEST_FIT_DBL_LIMIT);
|
|
||||||
{
|
|
||||||
Statement stat(session());
|
|
||||||
stat << "SELECT * FROM " << ExecUtil::numeric_tbl(), now;
|
|
||||||
RecordSet rs(stat);
|
|
||||||
|
|
||||||
assert(vals.size() + 1 == rs.columnCount());
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_INT32 == rs.columnType(0));
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_INT32 == rs.columnType(1));
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_DOUBLE == rs.columnType(2));
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_INT64 == rs.columnType(3));
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_DOUBLE == rs.columnType(4)); //conversion would be done with precision loss
|
|
||||||
assert(Poco::Data::ODBC::ODBCMetaColumn::FDT_DOUBLE == rs.columnType(5)); //conversion would be done with precision loss
|
|
||||||
for (size_t i = 0; i < vals.size(); ++i)
|
|
||||||
{
|
|
||||||
std::string v = rs.value(i + 1).convert<std::string>();
|
|
||||||
if (i < 3) // we've lost precision, so can't compare values
|
|
||||||
assert(vals[i] == v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); }
|
|
||||||
catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); }
|
|
||||||
}
|
|
||||||
|
|
||||||
void SQLExecutor::doBulkPerformance(Poco::UInt32 size)
|
void SQLExecutor::doBulkPerformance(Poco::UInt32 size)
|
||||||
{
|
{
|
||||||
@ -2800,128 +2732,6 @@ void SQLExecutor::tupleVector()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SQLExecutor::internalExtraction()
|
|
||||||
{
|
|
||||||
std::string funct = "internalExtraction()";
|
|
||||||
std::vector<Tuple<int, double, std::string> > v;
|
|
||||||
v.push_back(Tuple<int, double, std::string>(1, 1.5f, "3"));
|
|
||||||
v.push_back(Tuple<int, double, std::string>(2, 2.5f, "4"));
|
|
||||||
v.push_back(Tuple<int, double, std::string>(3, 3.5f, "5"));
|
|
||||||
v.push_back(Tuple<int, double, std::string>(4, 4.5f, "6"));
|
|
||||||
|
|
||||||
try { session() << "INSERT INTO " << ExecUtil::vectors() << " VALUES (?,?,?)", use(v), 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 " << ExecUtil::vectors() , now);
|
|
||||||
RecordSet rset(stmt);
|
|
||||||
|
|
||||||
assert (3 == rset.columnCount());
|
|
||||||
assert (4 == rset.rowCount());
|
|
||||||
|
|
||||||
int curVal = 3;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
assert (rset["str0"] == curVal);
|
|
||||||
++curVal;
|
|
||||||
} while (rset.moveNext());
|
|
||||||
|
|
||||||
rset.moveFirst();
|
|
||||||
assert (rset["str0"] == "3");
|
|
||||||
rset.moveLast();
|
|
||||||
assert(rset["str0"] == "6");
|
|
||||||
|
|
||||||
RecordSet rset2(rset);
|
|
||||||
assert (3 == rset2.columnCount());
|
|
||||||
assert (4 == rset2.rowCount());
|
|
||||||
|
|
||||||
int i = rset.value<int>(0,0);
|
|
||||||
assert (1 == i);
|
|
||||||
|
|
||||||
std::string s = rset.value(0,0).convert<std::string>();
|
|
||||||
assert ("1" == s);
|
|
||||||
|
|
||||||
int a = rset.value<int>(0,2);
|
|
||||||
assert (3 == a);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
double d = rset.value<double>(1,1);
|
|
||||||
assert (2.5 == d);
|
|
||||||
}
|
|
||||||
catch (BadCastException&)
|
|
||||||
{
|
|
||||||
float f = rset.value<float>(1,1);
|
|
||||||
assert (2.5 == f);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
s = rset.value<std::string>(2, 2);
|
|
||||||
}
|
|
||||||
catch (BadCastException&)
|
|
||||||
{
|
|
||||||
UTF16String us = rset.value<Poco::UTF16String>(2, 2);
|
|
||||||
Poco::UnicodeConverter::convert(us, s);
|
|
||||||
}
|
|
||||||
assert("5" == s);
|
|
||||||
|
|
||||||
i = rset.value("str0", 2);
|
|
||||||
assert (5 == i);
|
|
||||||
|
|
||||||
const Column<std::deque<int> >& col = rset.column<std::deque<int> >(0);
|
|
||||||
Column<std::deque<int> >::Iterator it = col.begin();
|
|
||||||
Column<std::deque<int> >::Iterator end = col.end();
|
|
||||||
for (int i = 1; it != end; ++it, ++i)
|
|
||||||
assert (*it == i);
|
|
||||||
|
|
||||||
rset = (session() << "SELECT COUNT(*) AS cnt FROM " << ExecUtil::vectors(), now);
|
|
||||||
|
|
||||||
//various results for COUNT(*) are received from different drivers
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//this is what most drivers will return
|
|
||||||
int i = rset.value<int>(0,0);
|
|
||||||
assert (4 == i);
|
|
||||||
}
|
|
||||||
catch(BadCastException&)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//this is for Oracle
|
|
||||||
double i = rset.value<double>(0,0);
|
|
||||||
assert (4 == int(i));
|
|
||||||
}
|
|
||||||
catch(BadCastException&)
|
|
||||||
{
|
|
||||||
//this is for PostgreSQL
|
|
||||||
Poco::Int64 big = rset.value<Poco::Int64>(0,0);
|
|
||||||
assert (4 == big);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s = rset.value("cnt", 0).convert<std::string>();
|
|
||||||
assert ("4" == s);
|
|
||||||
|
|
||||||
try { rset.column<std::deque<int> >(100); fail ("must fail"); }
|
|
||||||
catch (RangeException&) { }
|
|
||||||
|
|
||||||
try { rset.value<std::string>(0,0); fail ("must fail"); }
|
|
||||||
catch (BadCastException&) { }
|
|
||||||
|
|
||||||
stmt = (session() << "DELETE FROM " << ExecUtil::vectors(), now);
|
|
||||||
rset = stmt;
|
|
||||||
|
|
||||||
try { rset.column<std::deque<int> >(0); fail ("must fail"); }
|
|
||||||
catch (RangeException&) { }
|
|
||||||
}
|
|
||||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
|
||||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SQLExecutor::filter(const std::string& query, const std::string& intFldName)
|
void SQLExecutor::filter(const std::string& query, const std::string& intFldName)
|
||||||
{
|
{
|
||||||
std::string funct = "filter()";
|
std::string funct = "filter()";
|
||||||
@ -3455,12 +3265,12 @@ void SQLExecutor::asynchronous(int rowCount)
|
|||||||
if (!_connInitSql.empty()) tmp << _connInitSql, now;
|
if (!_connInitSql.empty()) tmp << _connInitSql, now;
|
||||||
|
|
||||||
std::vector<int> data(rowCount);
|
std::vector<int> data(rowCount);
|
||||||
Statement stmt = (tmp << "INSERT INTO " << ExecUtil::strings() << " VALUES(?)", use(data));
|
Statement stmt = (tmp << "INSERT INTO " << ExecUtil::ints() << " VALUES(?)", use(data));
|
||||||
Statement::Result result = stmt.executeAsync();
|
Statement::Result result = stmt.executeAsync();
|
||||||
assert (!stmt.isAsync());
|
assert (!stmt.isAsync());
|
||||||
result.wait();
|
result.wait();
|
||||||
|
|
||||||
Statement stmt1 = (tmp << "SELECT * FROM " << ExecUtil::strings(), into(data), async, now);
|
Statement stmt1 = (tmp << "SELECT * FROM " << ExecUtil::ints(), into(data), async, now);
|
||||||
assert (stmt1.isAsync());
|
assert (stmt1.isAsync());
|
||||||
assert (stmt1.wait() == rowCount);
|
assert (stmt1.wait() == rowCount);
|
||||||
|
|
||||||
@ -3478,7 +3288,7 @@ void SQLExecutor::asynchronous(int rowCount)
|
|||||||
}
|
}
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
stmt = tmp << "SELECT * FROM " << ExecUtil::strings(), into(data), async, now;
|
stmt = tmp << "SELECT * FROM " << ExecUtil::ints(), into(data), async, now;
|
||||||
assert (stmt.isAsync());
|
assert (stmt.isAsync());
|
||||||
stmt.wait();
|
stmt.wait();
|
||||||
assert (stmt.execute() == 0);
|
assert (stmt.execute() == 0);
|
||||||
@ -3502,7 +3312,7 @@ void SQLExecutor::asynchronous(int rowCount)
|
|||||||
assert (!stmt.isAsync());
|
assert (!stmt.isAsync());
|
||||||
assert (stmt.execute() == rowCount);
|
assert (stmt.execute() == rowCount);
|
||||||
|
|
||||||
stmt = tmp << "SELECT * FROM " << ExecUtil::strings(), into(data), sync, now;
|
stmt = tmp << "SELECT * FROM " << ExecUtil::ints(), into(data), sync, now;
|
||||||
assert (!stmt.isAsync());
|
assert (!stmt.isAsync());
|
||||||
assert (stmt.wait() == 0);
|
assert (stmt.wait() == 0);
|
||||||
assert (stmt.execute() == rowCount);
|
assert (stmt.execute() == rowCount);
|
||||||
@ -3514,7 +3324,7 @@ void SQLExecutor::asynchronous(int rowCount)
|
|||||||
assert (0 == rowCount % 10);
|
assert (0 == rowCount % 10);
|
||||||
int step = (int) (rowCount/10);
|
int step = (int) (rowCount/10);
|
||||||
data.clear();
|
data.clear();
|
||||||
Statement stmt2 = (tmp << "SELECT * FROM " << ExecUtil::strings(), into(data), async, limit(step));
|
Statement stmt2 = (tmp << "SELECT * FROM " << ExecUtil::ints(), into(data), async, limit(step));
|
||||||
assert (data.size() == 0);
|
assert (data.size() == 0);
|
||||||
assert (!stmt2.done());
|
assert (!stmt2.done());
|
||||||
std::size_t rows = 0;
|
std::size_t rows = 0;
|
||||||
@ -3529,7 +3339,7 @@ void SQLExecutor::asynchronous(int rowCount)
|
|||||||
assert (stmt2.done());
|
assert (stmt2.done());
|
||||||
assert (rowCount == data.size());
|
assert (rowCount == data.size());
|
||||||
|
|
||||||
stmt2 = tmp << "SELECT * FROM " << ExecUtil::strings(), reset;
|
stmt2 = tmp << "SELECT * FROM " << ExecUtil::ints(), reset;
|
||||||
assert (!stmt2.isAsync());
|
assert (!stmt2.isAsync());
|
||||||
assert ("deque" == stmt2.getStorage());
|
assert ("deque" == stmt2.getStorage());
|
||||||
assert (stmt2.execute() == rowCount);
|
assert (stmt2.execute() == rowCount);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#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"
|
||||||
|
#include "Poco/Data/RecordSet.h"
|
||||||
#include "Poco/NumberFormatter.h"
|
#include "Poco/NumberFormatter.h"
|
||||||
#include "Poco/String.h"
|
#include "Poco/String.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
@ -87,6 +88,11 @@ struct ExecUtil
|
|||||||
return mangleTable("Strings");
|
return mangleTable("Strings");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string ints()
|
||||||
|
{
|
||||||
|
return mangleTable("Ints");
|
||||||
|
}
|
||||||
|
|
||||||
static std::string tuples()
|
static std::string tuples()
|
||||||
{
|
{
|
||||||
return mangleTable("Tuples");
|
return mangleTable("Tuples");
|
||||||
@ -141,11 +147,6 @@ struct ExecUtil
|
|||||||
{
|
{
|
||||||
return mangleTable("Test");
|
return mangleTable("Test");
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string numeric_tbl()
|
|
||||||
{
|
|
||||||
return mangleTable("numer_t");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -222,7 +223,6 @@ public:
|
|||||||
void limitPrepare();
|
void limitPrepare();
|
||||||
void limitZero();
|
void limitZero();
|
||||||
void prepare();
|
void prepare();
|
||||||
void numericTypes(const std::vector<std::string>& vals);
|
|
||||||
void insertStatReuse();
|
void insertStatReuse();
|
||||||
|
|
||||||
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>
|
||||||
@ -562,13 +562,153 @@ public:
|
|||||||
void tuples();
|
void tuples();
|
||||||
void tupleVector();
|
void tupleVector();
|
||||||
|
|
||||||
void internalExtraction();
|
template <typename IntType =
|
||||||
|
#ifdef POCO_64_BIT
|
||||||
|
Poco::Int64 IntType
|
||||||
|
#else
|
||||||
|
Poco::Int32 IntType
|
||||||
|
#endif
|
||||||
|
>
|
||||||
|
void internalExtraction(IntType)
|
||||||
|
{
|
||||||
|
using Poco::Data::RecordSet;
|
||||||
|
using Poco::Data::Column;
|
||||||
|
using Poco::UTF16String;
|
||||||
|
using Poco::BadCastException;
|
||||||
|
using Poco::RangeException;
|
||||||
|
|
||||||
|
std::string funct = "internalExtraction()";
|
||||||
|
std::vector<Tuple<int, double, std::string> > v;
|
||||||
|
v.push_back(Tuple<int, double, std::string>(1, 1.5, "3"));
|
||||||
|
v.push_back(Tuple<int, double, std::string>(2, 2.5, "4"));
|
||||||
|
v.push_back(Tuple<int, double, std::string>(3, 3.5, "5"));
|
||||||
|
v.push_back(Tuple<int, double, std::string>(4, 4.5, "6"));
|
||||||
|
|
||||||
|
try { session() << "INSERT INTO " << ExecUtil::vectors() << " VALUES (?,?,?)", use(v), 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 " << ExecUtil::vectors() , now);
|
||||||
|
RecordSet rset(stmt);
|
||||||
|
|
||||||
|
assert (3 == rset.columnCount());
|
||||||
|
assert (4 == rset.rowCount());
|
||||||
|
|
||||||
|
int curVal = 3;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
assert (rset["str0"] == curVal);
|
||||||
|
++curVal;
|
||||||
|
} while (rset.moveNext());
|
||||||
|
|
||||||
|
rset.moveFirst();
|
||||||
|
assert (rset["str0"] == "3");
|
||||||
|
rset.moveLast();
|
||||||
|
assert(rset["str0"] == "6");
|
||||||
|
|
||||||
|
RecordSet rset2(rset);
|
||||||
|
assert (3 == rset2.columnCount());
|
||||||
|
assert (4 == rset2.rowCount());
|
||||||
|
|
||||||
|
IntType i;
|
||||||
|
try {
|
||||||
|
i = rset.value<IntType>(0, 0);
|
||||||
|
assert(1 == i);
|
||||||
|
}
|
||||||
|
catch (Poco::BadCastException& ex)
|
||||||
|
{
|
||||||
|
std::cout << ex.displayText() << std::endl;
|
||||||
|
}
|
||||||
|
std::string s = rset.value(0,0).convert<std::string>();
|
||||||
|
assert ("1" == s);
|
||||||
|
|
||||||
|
IntType a = rset.value<IntType>(0,2);
|
||||||
|
assert (3 == a);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
double d = rset.value<double>(1,1);
|
||||||
|
assert (2.5 == d);
|
||||||
|
}
|
||||||
|
catch (BadCastException&)
|
||||||
|
{
|
||||||
|
float f = rset.value<float>(1,1);
|
||||||
|
assert (2.5 == f);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
s = rset.value<std::string>(2, 2);
|
||||||
|
}
|
||||||
|
catch (BadCastException&)
|
||||||
|
{
|
||||||
|
UTF16String us = rset.value<Poco::UTF16String>(2, 2);
|
||||||
|
Poco::UnicodeConverter::convert(us, s);
|
||||||
|
}
|
||||||
|
assert("5" == s);
|
||||||
|
|
||||||
|
i = rset.value("str0", 2);
|
||||||
|
assert (5 == i);
|
||||||
|
|
||||||
|
const Column<std::deque<IntType> >& col = rset.column<std::deque<IntType> >(0);
|
||||||
|
Column<std::deque<IntType> >::Iterator it = col.begin();
|
||||||
|
Column<std::deque<IntType> >::Iterator end = col.end();
|
||||||
|
for (int i = 1; it != end; ++it, ++i)
|
||||||
|
assert (*it == i);
|
||||||
|
|
||||||
|
rset = (session() << "SELECT COUNT(*) AS cnt FROM " << ExecUtil::vectors(), now);
|
||||||
|
|
||||||
|
//various results for COUNT(*) are received from different drivers
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//this is what most drivers will return
|
||||||
|
int i = rset.value<int>(0,0);
|
||||||
|
assert (4 == i);
|
||||||
|
}
|
||||||
|
catch(BadCastException&)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//this is for Oracle
|
||||||
|
double i = rset.value<double>(0,0);
|
||||||
|
assert (4 == int(i));
|
||||||
|
}
|
||||||
|
catch(BadCastException&)
|
||||||
|
{
|
||||||
|
//this is for PostgreSQL
|
||||||
|
Poco::Int64 big = rset.value<Poco::Int64>(0,0);
|
||||||
|
assert (4 == big);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s = rset.value("cnt", 0).convert<std::string>();
|
||||||
|
assert ("4" == s);
|
||||||
|
|
||||||
|
try { rset.column<std::deque<IntType> >(100); fail ("must fail"); }
|
||||||
|
catch (RangeException&) { }
|
||||||
|
|
||||||
|
try { rset.value<std::string>(0,0); fail ("must fail"); }
|
||||||
|
catch (BadCastException&) { }
|
||||||
|
|
||||||
|
stmt = (session() << "DELETE FROM " << ExecUtil::vectors(), now);
|
||||||
|
rset = stmt;
|
||||||
|
|
||||||
|
try { rset.column<std::deque<IntType> >(0); fail ("must fail"); }
|
||||||
|
catch (RangeException&) { }
|
||||||
|
}
|
||||||
|
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||||
|
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||||
|
}
|
||||||
|
|
||||||
void filter(const std::string& query =
|
void filter(const std::string& query =
|
||||||
"SELECT * FROM " + ExecUtil::vectors() + " ORDER BY i0 ASC",
|
"SELECT * FROM " + ExecUtil::vectors() + " ORDER BY int0 ASC",
|
||||||
const std::string& intFldName = "i0");
|
const std::string& intFldName = "int0");
|
||||||
|
|
||||||
void internalBulkExtraction();
|
void internalBulkExtraction();
|
||||||
void internalBulkExtractionUTF16();
|
void internalBulkExtractionUTF16();
|
||||||
|
|
||||||
void internalStorageType();
|
void internalStorageType();
|
||||||
void nulls(bool emptyStrIsSpace = false);
|
void nulls(bool emptyStrIsSpace = false);
|
||||||
void notNulls(const std::string& sqlState = "23502");
|
void notNulls(const std::string& sqlState = "23502");
|
||||||
|
@ -952,8 +952,8 @@ void PostgreSQLTest::recreatePersonTimeTable()
|
|||||||
|
|
||||||
void PostgreSQLTest::recreateIntsTable()
|
void PostgreSQLTest::recreateIntsTable()
|
||||||
{
|
{
|
||||||
dropTable("Strings");
|
dropTable("Ints");
|
||||||
try { *_pSession << "CREATE TABLE Strings (str INTEGER)", now; }
|
try { *_pSession << "CREATE TABLE " << ExecUtil::ints() << " (str INTEGER)", now; }
|
||||||
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateIntsTable()"); }
|
catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateIntsTable()"); }
|
catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateIntsTable()"); }
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
typedef SharedPtr<AbstractExtractor> ExtractorPtr;
|
typedef SharedPtr<AbstractExtractor> ExtractorPtr;
|
||||||
typedef SharedPtr<AbstractPreparator> PreparatorPtr;
|
typedef SharedPtr<AbstractPreparator> PreparatorPtr;
|
||||||
|
|
||||||
AbstractExtraction(Poco::UInt32 limit = Limit::LIMIT_UNLIMITED,
|
AbstractExtraction(const std::string& type, Poco::UInt32 limit = Limit::LIMIT_UNLIMITED,
|
||||||
Poco::UInt32 position = 0, bool bulk = false);
|
Poco::UInt32 position = 0, bool bulk = false);
|
||||||
/// Creates the AbstractExtraction. A limit value equal to EXTRACT_UNLIMITED (0xffffffffu)
|
/// Creates the AbstractExtraction. A limit value equal to EXTRACT_UNLIMITED (0xffffffffu)
|
||||||
/// means that we extract as much data as possible during one execute.
|
/// means that we extract as much data as possible during one execute.
|
||||||
@ -153,6 +153,11 @@ public:
|
|||||||
/// - string is empty
|
/// - string is empty
|
||||||
/// - getEmptyStringIsNull() returns true
|
/// - getEmptyStringIsNull() returns true
|
||||||
|
|
||||||
|
const std::string& type() const
|
||||||
|
{
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename S>
|
template <typename S>
|
||||||
bool isStringNull(const S& str, bool deflt)
|
bool isStringNull(const S& str, bool deflt)
|
||||||
@ -165,6 +170,7 @@ private:
|
|||||||
return deflt;
|
return deflt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string _type;
|
||||||
ExtractorPtr _pExtractor;
|
ExtractorPtr _pExtractor;
|
||||||
Poco::UInt32 _limit;
|
Poco::UInt32 _limit;
|
||||||
Poco::UInt32 _position;
|
Poco::UInt32 _position;
|
||||||
@ -176,11 +182,6 @@ private:
|
|||||||
|
|
||||||
typedef std::vector<AbstractExtraction::Ptr> AbstractExtractionVec;
|
typedef std::vector<AbstractExtraction::Ptr> AbstractExtractionVec;
|
||||||
typedef std::vector<AbstractExtractionVec> AbstractExtractionVecVec;
|
typedef std::vector<AbstractExtractionVec> AbstractExtractionVecVec;
|
||||||
typedef std::deque<AbstractExtraction::Ptr> AbstractExtractionDeq;
|
|
||||||
typedef std::vector<AbstractExtractionDeq> AbstractExtractionDeqVec;
|
|
||||||
typedef std::list<AbstractExtraction::Ptr> AbstractExtractionLst;
|
|
||||||
typedef std::vector<AbstractExtractionLst> AbstractExtractionLstVec;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// inlines
|
// inlines
|
||||||
|
@ -47,7 +47,7 @@ public:
|
|||||||
typedef SharedPtr<Type> Ptr;
|
typedef SharedPtr<Type> Ptr;
|
||||||
|
|
||||||
BulkExtraction(C& rResult, Poco::UInt32 limit, const Position& pos = Position(0)):
|
BulkExtraction(C& rResult, Poco::UInt32 limit, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(limit, pos.value(), true),
|
AbstractExtraction(typeid(C).name(), limit, pos.value(), true),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default()
|
_default()
|
||||||
{
|
{
|
||||||
@ -56,7 +56,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
BulkExtraction(C& rResult, const CValType& def, Poco::UInt32 limit, const Position& pos = Position(0)):
|
BulkExtraction(C& rResult, const CValType& def, Poco::UInt32 limit, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(limit, pos.value(), true),
|
AbstractExtraction(typeid(C).name(), limit, pos.value(), true),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default(def)
|
_default(def)
|
||||||
{
|
{
|
||||||
|
@ -87,7 +87,7 @@ public:
|
|||||||
typedef SharedPtr<Type> Ptr;
|
typedef SharedPtr<Type> Ptr;
|
||||||
|
|
||||||
Extraction(T& rResult, const Position& pos = Position(0)):
|
Extraction(T& rResult, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(T).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default(),
|
_default(),
|
||||||
_extracted(false),
|
_extracted(false),
|
||||||
@ -98,7 +98,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Extraction(T& rResult, const T& def, const Position& pos = Position(0)):
|
Extraction(T& rResult, const T& def, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(T).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default(def),
|
_default(def),
|
||||||
_extracted(false),
|
_extracted(false),
|
||||||
@ -179,7 +179,7 @@ public:
|
|||||||
typedef SharedPtr<Type> Ptr;
|
typedef SharedPtr<Type> Ptr;
|
||||||
|
|
||||||
Extraction(std::vector<T>& rResult, const Position& pos = Position(0)):
|
Extraction(std::vector<T>& rResult, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::vector<T>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default()
|
_default()
|
||||||
{
|
{
|
||||||
@ -187,7 +187,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Extraction(std::vector<T>& rResult, const T& def, const Position& pos = Position(0)):
|
Extraction(std::vector<T>& rResult, const T& def, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::vector<T>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default(def)
|
_default(def)
|
||||||
{
|
{
|
||||||
@ -269,7 +269,7 @@ public:
|
|||||||
typedef SharedPtr<Type> Ptr;
|
typedef SharedPtr<Type> Ptr;
|
||||||
|
|
||||||
Extraction(std::vector<bool>& rResult, const Position& pos = Position(0)):
|
Extraction(std::vector<bool>& rResult, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::vector<bool>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default()
|
_default()
|
||||||
{
|
{
|
||||||
@ -277,7 +277,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Extraction(std::vector<bool>& rResult, const bool& def, const Position& pos = Position(0)):
|
Extraction(std::vector<bool>& rResult, const bool& def, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::vector<bool>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default(def)
|
_default(def)
|
||||||
{
|
{
|
||||||
@ -361,7 +361,7 @@ public:
|
|||||||
typedef SharedPtr<Type> Ptr;
|
typedef SharedPtr<Type> Ptr;
|
||||||
|
|
||||||
Extraction(std::list<T>& rResult, const Position& pos = Position(0)):
|
Extraction(std::list<T>& rResult, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::list<T>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default()
|
_default()
|
||||||
{
|
{
|
||||||
@ -369,7 +369,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Extraction(std::list<T>& rResult, const T& def, const Position& pos = Position(0)):
|
Extraction(std::list<T>& rResult, const T& def, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::list<T>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default(def)
|
_default(def)
|
||||||
{
|
{
|
||||||
@ -451,7 +451,7 @@ public:
|
|||||||
typedef SharedPtr<Type> Ptr;
|
typedef SharedPtr<Type> Ptr;
|
||||||
|
|
||||||
Extraction(std::deque<T>& rResult, const Position& pos = Position(0)):
|
Extraction(std::deque<T>& rResult, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::deque<T>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default()
|
_default()
|
||||||
{
|
{
|
||||||
@ -459,7 +459,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Extraction(std::deque<T>& rResult, const T& def, const Position& pos = Position(0)):
|
Extraction(std::deque<T>& rResult, const T& def, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::deque<T>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default(def)
|
_default(def)
|
||||||
{
|
{
|
||||||
@ -611,7 +611,7 @@ public:
|
|||||||
typedef typename ValType::iterator Iterator;
|
typedef typename ValType::iterator Iterator;
|
||||||
|
|
||||||
Extraction(std::set<T>& rResult, const Position& pos = Position(0)):
|
Extraction(std::set<T>& rResult, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::set<T>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default()
|
_default()
|
||||||
{
|
{
|
||||||
@ -619,7 +619,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Extraction(std::set<T>& rResult, const T& def, const Position& pos = Position(0)):
|
Extraction(std::set<T>& rResult, const T& def, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::set<T>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default(def)
|
_default(def)
|
||||||
{
|
{
|
||||||
@ -675,7 +675,7 @@ public:
|
|||||||
typedef SharedPtr<Type> Ptr;
|
typedef SharedPtr<Type> Ptr;
|
||||||
|
|
||||||
Extraction(std::multiset<T>& rResult, const Position& pos = Position(0)):
|
Extraction(std::multiset<T>& rResult, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::multiset<T>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default()
|
_default()
|
||||||
{
|
{
|
||||||
@ -683,7 +683,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Extraction(std::multiset<T>& rResult, const T& def, const Position& pos = Position(0)):
|
Extraction(std::multiset<T>& rResult, const T& def, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::multiset<T>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default(def)
|
_default(def)
|
||||||
{
|
{
|
||||||
@ -739,7 +739,7 @@ public:
|
|||||||
typedef SharedPtr<Type> Ptr;
|
typedef SharedPtr<Type> Ptr;
|
||||||
|
|
||||||
Extraction(std::map<K, V>& rResult, const Position& pos = Position(0)):
|
Extraction(std::map<K, V>& rResult, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::map<K, V>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default()
|
_default()
|
||||||
{
|
{
|
||||||
@ -747,7 +747,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Extraction(std::map<K, V>& rResult, const V& def, const Position& pos = Position(0)):
|
Extraction(std::map<K, V>& rResult, const V& def, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::map<K, V>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default(def)
|
_default(def)
|
||||||
{
|
{
|
||||||
@ -803,7 +803,7 @@ public:
|
|||||||
typedef SharedPtr<Type> Ptr;
|
typedef SharedPtr<Type> Ptr;
|
||||||
|
|
||||||
Extraction(std::multimap<K, V>& rResult, const Position& pos = Position(0)):
|
Extraction(std::multimap<K, V>& rResult, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::multimap<K, V>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default()
|
_default()
|
||||||
{
|
{
|
||||||
@ -811,7 +811,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Extraction(std::multimap<K, V>& rResult, const V& def, const Position& pos = Position(0)):
|
Extraction(std::multimap<K, V>& rResult, const V& def, const Position& pos = Position(0)):
|
||||||
AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()),
|
AbstractExtraction(typeid(std::multimap<K, V>).name(), Limit::LIMIT_UNLIMITED, pos.value()),
|
||||||
_rResult(rResult),
|
_rResult(rResult),
|
||||||
_default(def)
|
_default(def)
|
||||||
{
|
{
|
||||||
|
@ -32,28 +32,28 @@ class Data_API Position
|
|||||||
/// indicate the recordset position in batch SQL statements.
|
/// indicate the recordset position in batch SQL statements.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef Poco::UInt32 PositionType;
|
typedef Poco::UInt32 Type;
|
||||||
|
|
||||||
Position(PositionType value);
|
Position(Type value);
|
||||||
/// Creates the Position.
|
/// Creates the Position.
|
||||||
|
|
||||||
~Position();
|
~Position();
|
||||||
/// Destroys the Position.
|
/// Destroys the Position.
|
||||||
|
|
||||||
PositionType value() const;
|
Type value() const;
|
||||||
/// Returns the position value.
|
/// Returns the position value.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Position();
|
Position();
|
||||||
|
|
||||||
PositionType _value;
|
Type _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// inlines
|
/// inlines
|
||||||
///
|
///
|
||||||
inline Position::PositionType Position::value() const
|
inline Position::Type Position::value() const
|
||||||
{
|
{
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
@ -438,7 +438,8 @@ private:
|
|||||||
if (typeFound)
|
if (typeFound)
|
||||||
throw NotFoundException(Poco::format("Column name: %s", name));
|
throw NotFoundException(Poco::format("Column name: %s", name));
|
||||||
else
|
else
|
||||||
throw NotFoundException(Poco::format("Column type: %s, name: %s", std::string(typeid(T).name()), name));
|
throw NotFoundException(Poco::format("Column type: %s, Container type: %s, name: %s",
|
||||||
|
std::string(typeid(T).name()), std::string(typeid(ExtractionVecPtr).name()), name));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class C, class E>
|
template <class C, class E>
|
||||||
@ -469,9 +470,13 @@ private:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw Poco::BadCastException(Poco::format("Type cast failed!\nColumn: %z\nTarget type:\t%s",
|
throw Poco::BadCastException(Poco::format("RecordSet::columnImpl(%z) type cast failed!\nTarget type:\t%s"
|
||||||
|
"\nTarget container type:\t%s\nSource container type:\t%s\nSource abstraction type:\t%s",
|
||||||
pos,
|
pos,
|
||||||
std::string(typeid(T).name())));
|
std::string(typeid(T).name()),
|
||||||
|
std::string(typeid(ExtractionVecPtr).name()),
|
||||||
|
rExtractions[pos]->type(),
|
||||||
|
std::string(typeid(rExtractions[pos].get()).name())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,12 +85,15 @@ public:
|
|||||||
~RowFilter();
|
~RowFilter();
|
||||||
/// Destroys the RowFilter.
|
/// Destroys the RowFilter.
|
||||||
|
|
||||||
void addFilter(const Ptr& pFilter, LogicOperator comparison);
|
void addFilter(Ptr pFilter, LogicOperator comparison);
|
||||||
/// Appends another filter to this one.
|
/// Appends another filter to this one.
|
||||||
|
|
||||||
void removeFilter(const Ptr& pFilter);
|
void removeFilter(Ptr pFilter);
|
||||||
/// Removes filter from this filter.
|
/// Removes filter from this filter.
|
||||||
|
|
||||||
|
bool has(Ptr pFilter) const;
|
||||||
|
/// Returns true if this filter is parent of pFilter;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void add(const std::string& name, Comparison comparison, const T& value, LogicOperator op = OP_OR)
|
void add(const std::string& name, Comparison comparison, const T& value, LogicOperator op = OP_OR)
|
||||||
/// Adds value to the filter.
|
/// Adds value to the filter.
|
||||||
@ -185,6 +188,12 @@ private:
|
|||||||
///
|
///
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::has(Ptr pFilter) const
|
||||||
|
{
|
||||||
|
return _filterMap.find(pFilter) != _filterMap.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool RowFilter::isEmpty() const
|
inline bool RowFilter::isEmpty() const
|
||||||
{
|
{
|
||||||
return _comparisonMap.size() == 0;
|
return _comparisonMap.size() == 0;
|
||||||
|
@ -21,9 +21,10 @@ namespace Poco {
|
|||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
|
|
||||||
AbstractExtraction::AbstractExtraction(Poco::UInt32 limit,
|
AbstractExtraction::AbstractExtraction(const std::string& type, Poco::UInt32 limit,
|
||||||
Poco::UInt32 extractionPosition,
|
Poco::UInt32 extractionPosition,
|
||||||
bool bulk):
|
bool bulk):
|
||||||
|
_type(type),
|
||||||
_pExtractor(0),
|
_pExtractor(0),
|
||||||
_limit(limit),
|
_limit(limit),
|
||||||
_position(extractionPosition),
|
_position(extractionPosition),
|
||||||
|
@ -29,6 +29,7 @@ RowFilter::RowFilter(RecordSet* pRecordSet): _pRecordSet(pRecordSet), _not(false
|
|||||||
{
|
{
|
||||||
poco_check_ptr(pRecordSet);
|
poco_check_ptr(pRecordSet);
|
||||||
init();
|
init();
|
||||||
|
duplicate();
|
||||||
_pRecordSet->filter(this);
|
_pRecordSet->filter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ RowFilter::RowFilter(Ptr pParent, LogicOperator op): _pRecordSet(0),
|
|||||||
{
|
{
|
||||||
poco_check_ptr(_pParent.get());
|
poco_check_ptr(_pParent.get());
|
||||||
init();
|
init();
|
||||||
|
duplicate();
|
||||||
_pParent->addFilter(this, op);
|
_pParent->addFilter(this, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +64,9 @@ RowFilter::~RowFilter()
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_pRecordSet) _pRecordSet->filter(0);
|
if (_pRecordSet) _pRecordSet->filter(0);
|
||||||
if (_pParent.get()) _pParent->removeFilter(this);
|
if (_pParent && _pParent->has(this))
|
||||||
|
_pParent->removeFilter(this);
|
||||||
|
release();
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@ -162,7 +166,7 @@ RowFilter::Comparison RowFilter::getComparison(const std::string& comp) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RowFilter::addFilter(const Ptr& pFilter, LogicOperator comparison)
|
void RowFilter::addFilter(Ptr pFilter, LogicOperator comparison)
|
||||||
{
|
{
|
||||||
poco_check_ptr (_pRecordSet);
|
poco_check_ptr (_pRecordSet);
|
||||||
|
|
||||||
@ -172,13 +176,14 @@ void RowFilter::addFilter(const Ptr& pFilter, LogicOperator comparison)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RowFilter::removeFilter(const Ptr& pFilter)
|
void RowFilter::removeFilter(Ptr pFilter)
|
||||||
{
|
{
|
||||||
poco_check_ptr (_pRecordSet);
|
poco_check_ptr (_pRecordSet);
|
||||||
|
|
||||||
pFilter->_pRecordSet = 0;
|
|
||||||
_pRecordSet->moveFirst();
|
_pRecordSet->moveFirst();
|
||||||
_filterMap.erase(pFilter);
|
_filterMap.erase(pFilter);
|
||||||
|
pFilter->_pRecordSet = 0;
|
||||||
|
pFilter->_pParent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -319,7 +319,7 @@ void StatementImpl::setStorage(const std::string& storage)
|
|||||||
void StatementImpl::makeExtractors(std::size_t count)
|
void StatementImpl::makeExtractors(std::size_t count)
|
||||||
{
|
{
|
||||||
// type cast is needed when size_t is 64 bit
|
// type cast is needed when size_t is 64 bit
|
||||||
makeExtractors(count, static_cast<Position::PositionType>(currentDataSet()));
|
makeExtractors(count, static_cast<Position::Type>(currentDataSet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatementImpl::makeExtractors(std::size_t count, const Position& position)
|
void StatementImpl::makeExtractors(std::size_t count, const Position& position)
|
||||||
|
@ -208,6 +208,11 @@ namespace Poco {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(POCO_PTR_IS_64_BIT) && (POCO_PTR_IS_64_BIT == 1)
|
||||||
|
#define POCO_64_BIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user