mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-23 02:28:59 +01: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()
|
||||
{
|
||||
dropTable("Strings");
|
||||
try { *_pSession << "CREATE TABLE Strings (str INTEGER)", now; }
|
||||
dropTable("Ints");
|
||||
try { *_pSession << "CREATE TABLE Ints (str INTEGER)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.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,
|
||||
ParameterBinding dataBinding,
|
||||
TypeInfo* pDataTypes,
|
||||
ODBCMetaColumn::NumericConversion numericConversion,
|
||||
bool insertOnly);
|
||||
/// Creates the Binder.
|
||||
|
||||
@ -604,7 +603,7 @@ private:
|
||||
_charPtrs.resize(pos + 1, 0);
|
||||
|
||||
_charPtrs[pos] = (char*) std::calloc(val.size() * size, sizeof(char));
|
||||
|
||||
|
||||
std::size_t strSize;
|
||||
std::size_t offset = 0;
|
||||
typename C::const_iterator it = val.begin();
|
||||
@ -617,13 +616,13 @@ private:
|
||||
std::memcpy(_charPtrs[pos] + offset, it->c_str(), strSize);
|
||||
offset += size;
|
||||
}
|
||||
SQLSMALLINT sqlType = (isInBound(dir) && size < _maxCharColLength) ? SQL_VARCHAR : SQL_LONGVARCHAR;
|
||||
SQLSMALLINT sqlType = (isInBound(dir) && size < _maxCharColLength) ? SQL_VARCHAR : SQL_LONGVARCHAR;
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
toODBCDirection(dir),
|
||||
SQL_C_CHAR,
|
||||
sqlType,
|
||||
sqlType,
|
||||
(SQLUINTEGER) size - 1,
|
||||
0,
|
||||
_charPtrs[pos],
|
||||
@ -684,12 +683,12 @@ private:
|
||||
std::memcpy(_utf16CharPtrs[pos] + offset, it->data(), strSize);
|
||||
offset += (size / sizeof(UTF16Char));
|
||||
}
|
||||
SQLSMALLINT sqlType = (isInBound(dir) && size < _maxWCharColLength) ? SQL_WVARCHAR : SQL_WLONGVARCHAR;
|
||||
SQLSMALLINT sqlType = (isInBound(dir) && size < _maxWCharColLength) ? SQL_WVARCHAR : SQL_WLONGVARCHAR;
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT)pos + 1,
|
||||
toODBCDirection(dir),
|
||||
SQL_C_WCHAR,
|
||||
sqlType,
|
||||
sqlType,
|
||||
(SQLUINTEGER)size - 1,
|
||||
0,
|
||||
_utf16CharPtrs[pos],
|
||||
@ -754,13 +753,13 @@ private:
|
||||
std::memcpy(_charPtrs[pos] + offset, cIt->rawContent(), blobSize * sizeof(CharType));
|
||||
offset += size;
|
||||
}
|
||||
SQLSMALLINT sqlType = (isInBound(dir) && size <= _maxVarBinColSize) ? SQL_VARBINARY : SQL_LONGVARBINARY;
|
||||
SQLSMALLINT sqlType = (isInBound(dir) && size <= _maxVarBinColSize) ? SQL_VARBINARY : SQL_LONGVARBINARY;
|
||||
|
||||
if (Utility::isError(SQLBindParameter(_rStmt,
|
||||
(SQLUSMALLINT) pos + 1,
|
||||
SQL_PARAM_INPUT,
|
||||
SQL_C_BINARY,
|
||||
sqlType,
|
||||
sqlType,
|
||||
(SQLUINTEGER) size,
|
||||
0,
|
||||
_charPtrs[pos],
|
||||
@ -1043,7 +1042,6 @@ private:
|
||||
std::size_t _maxCharColLength;
|
||||
std::size_t _maxWCharColLength;
|
||||
std::size_t _maxVarBinColSize;
|
||||
ODBCMetaColumn::NumericConversion _numericConversion;
|
||||
NullCbMap _nullCbMap;
|
||||
bool _insertOnly;
|
||||
};
|
||||
|
@ -514,7 +514,7 @@ private:
|
||||
bool extractImpl(std::size_t pos, T& val)
|
||||
/// Utility function for extraction of Any and DynamicAny.
|
||||
{
|
||||
ODBCMetaColumn column(_rStmt, pos, _pPreparator->numericConversion());
|
||||
ODBCMetaColumn column(_rStmt, pos);
|
||||
|
||||
switch (column.type())
|
||||
{
|
||||
@ -720,7 +720,7 @@ inline bool Extractor::isNullLengthIndicator(SQLLEN val) 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);
|
||||
if (size > maxSize) size = maxSize;
|
||||
return (SQLINTEGER) size;
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
/// Creates HandleException
|
||||
{
|
||||
extendedMessage(_error.toString());
|
||||
}
|
||||
}
|
||||
|
||||
HandleException(const H& handle, const std::string& msg, const std::string& arg):
|
||||
ODBCException(msg, arg),
|
||||
|
@ -40,14 +40,7 @@ class ODBC_API ODBCMetaColumn: public MetaColumn
|
||||
{
|
||||
public:
|
||||
|
||||
enum NumericConversion
|
||||
{
|
||||
NC_BEST_FIT = 0,
|
||||
NC_FORCE_STRING = 1,
|
||||
NC_BEST_FIT_DBL_LIMIT = 2
|
||||
};
|
||||
|
||||
ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position, NumericConversion numericConversion);
|
||||
ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position);
|
||||
/// Creates the ODBCMetaColumn.
|
||||
|
||||
~ODBCMetaColumn();
|
||||
@ -81,7 +74,6 @@ private:
|
||||
SQLLEN _dataLength;
|
||||
const StatementHandle& _rStmt;
|
||||
ColumnDescription _columnDesc;
|
||||
NumericConversion _numericConversion;
|
||||
};
|
||||
|
||||
|
||||
|
@ -160,7 +160,6 @@ private:
|
||||
bool _prepared;
|
||||
mutable std::size_t _affectedRowCount;
|
||||
bool _canCompile;
|
||||
ODBCMetaColumn::NumericConversion _numericConversion;
|
||||
bool _isPostgres;
|
||||
bool _insertHint;
|
||||
};
|
||||
|
@ -102,7 +102,6 @@ public:
|
||||
const std::string& statement,
|
||||
std::size_t maxFieldSize,
|
||||
DataExtraction dataExtraction,
|
||||
ODBCMetaColumn::NumericConversion numericConversion ,
|
||||
bool isPostgres
|
||||
);
|
||||
/// Creates the Preparator.
|
||||
@ -419,9 +418,6 @@ public:
|
||||
DataExtraction getDataExtraction() const;
|
||||
/// Returns data extraction mode.
|
||||
|
||||
ODBCMetaColumn::NumericConversion numericConversion() const;
|
||||
/// Tells if numeric values are always converted to string
|
||||
|
||||
private:
|
||||
typedef std::vector<Poco::Any> ValueVec;
|
||||
typedef std::vector<SQLLEN> LengthVec;
|
||||
@ -435,7 +431,7 @@ private:
|
||||
void prepareImpl(std::size_t pos, const C* pVal = 0)
|
||||
/// Utility function to prepare Any and DynamicAny.
|
||||
{
|
||||
ODBCMetaColumn col(_rStmt, pos, _numericConversion);
|
||||
ODBCMetaColumn col(_rStmt, pos);
|
||||
|
||||
switch (col.type())
|
||||
{
|
||||
@ -687,7 +683,6 @@ private:
|
||||
mutable IndexMap _varLengthArrays;
|
||||
std::size_t _maxFieldSize;
|
||||
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
|
||||
|
||||
|
||||
|
@ -45,7 +45,6 @@ class ODBC_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
|
||||
{
|
||||
public:
|
||||
static const std::size_t ODBC_MAX_FIELD_SIZE = 1024u;
|
||||
static const char* const NUMERIC_CONVERSION_PROPERTY;
|
||||
|
||||
enum TransactionCapability
|
||||
{
|
||||
@ -168,22 +167,10 @@ public:
|
||||
Poco::Any dataTypeInfo(const std::string& rName="");
|
||||
/// 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:
|
||||
void setDataTypeInfo(const std::string& rName, const Poco::Any& rValue);
|
||||
/// No-op. Throws InvalidAccessException.
|
||||
|
||||
void setNumericConversion(const std::string&, const Poco::Any& rValue);
|
||||
|
||||
Poco::Any numericConversion(const std::string& nm);
|
||||
|
||||
void init();
|
||||
|
||||
static const int FUNCTIONS = SQL_API_ODBC3_ALL_FUNCTIONS_SIZE;
|
||||
@ -199,7 +186,6 @@ private:
|
||||
Poco::Any _maxFieldSize;
|
||||
bool _autoBind;
|
||||
bool _autoExtract;
|
||||
ODBCMetaColumn::NumericConversion _numericConversion;
|
||||
TypeInfo _dataTypes;
|
||||
char _canTransact;
|
||||
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
|
||||
|
||||
|
||||
|
@ -44,7 +44,6 @@ Binder::Binder(const StatementHandle& rStmt,
|
||||
std::size_t maxFieldSize,
|
||||
Binder::ParameterBinding dataBinding,
|
||||
TypeInfo* pDataTypes,
|
||||
ODBCMetaColumn::NumericConversion numericConversion,
|
||||
bool insertOnly) :
|
||||
_rStmt(rStmt),
|
||||
_paramBinding(dataBinding),
|
||||
@ -54,7 +53,6 @@ Binder::Binder(const StatementHandle& rStmt,
|
||||
_maxCharColLength(1024),
|
||||
_maxWCharColLength(1024),
|
||||
_maxVarBinColSize(1024),
|
||||
_numericConversion(numericConversion),
|
||||
_insertOnly(insertOnly)
|
||||
{
|
||||
getProp(*_pTypeInfo, SQL_WVARCHAR, _maxWCharColLength);
|
||||
@ -566,7 +564,7 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
|
||||
{
|
||||
try
|
||||
{
|
||||
ODBCMetaColumn c(_rStmt, pos, _numericConversion);
|
||||
ODBCMetaColumn c(_rStmt, pos);
|
||||
_parameters[pos] = ParamDescriptor(static_cast<SQLINTEGER>(c.length()), cDataType, static_cast<SQLSMALLINT>(c.precision()));
|
||||
}
|
||||
catch (StatementException&) {}
|
||||
@ -587,7 +585,7 @@ void Binder::getColumnOrParameterSize(std::size_t pos, SQLINTEGER& size)
|
||||
|
||||
try
|
||||
{
|
||||
ODBCMetaColumn col(_rStmt, pos, _numericConversion);
|
||||
ODBCMetaColumn col(_rStmt, pos);
|
||||
colSize = col.length();
|
||||
}
|
||||
catch (StatementException&) { }
|
||||
|
@ -23,10 +23,9 @@ namespace Data {
|
||||
namespace ODBC {
|
||||
|
||||
|
||||
ODBCMetaColumn::ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position, NumericConversion numericConversion) :
|
||||
ODBCMetaColumn::ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position) :
|
||||
MetaColumn(position),
|
||||
_rStmt(rStmt),
|
||||
_numericConversion(numericConversion)
|
||||
_rStmt(rStmt)
|
||||
{
|
||||
init();
|
||||
}
|
||||
@ -98,69 +97,42 @@ void ODBCMetaColumn::init()
|
||||
case SQL_WLONGVARCHAR:
|
||||
case -350: // IBM DB2 CLOB, which long unicode string
|
||||
setType(MetaColumn::FDT_WSTRING); break;
|
||||
|
||||
|
||||
case SQL_TINYINT:
|
||||
setType(MetaColumn::FDT_INT8); break;
|
||||
|
||||
|
||||
case SQL_SMALLINT:
|
||||
setType(MetaColumn::FDT_INT16); break;
|
||||
|
||||
case SQL_INTEGER:
|
||||
setType(MetaColumn::FDT_INT32); break;
|
||||
|
||||
|
||||
case SQL_BIGINT:
|
||||
setType(MetaColumn::FDT_INT64); break;
|
||||
|
||||
|
||||
case SQL_DOUBLE:
|
||||
case SQL_FLOAT:
|
||||
setType(MetaColumn::FDT_DOUBLE); break;
|
||||
|
||||
|
||||
case SQL_NUMERIC:
|
||||
case SQL_DECIMAL:
|
||||
{
|
||||
bool toString = false;
|
||||
switch (_numericConversion)
|
||||
if (0 == _columnDesc.decimalDigits)
|
||||
{
|
||||
case NC_BEST_FIT:
|
||||
case NC_BEST_FIT_DBL_LIMIT:
|
||||
if (0 == _columnDesc.decimalDigits)
|
||||
{
|
||||
if (_columnDesc.size <= 9)
|
||||
setType(MetaColumn::FDT_INT32);
|
||||
else if (_columnDesc.size <= 18)
|
||||
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);
|
||||
#ifdef POCO_64_BIT
|
||||
setType(MetaColumn::FDT_INT64);
|
||||
#else
|
||||
setType(MetaColumn::FDT_STRING);
|
||||
setType(MetaColumn::FDT_INT32);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
else
|
||||
{
|
||||
setType(MetaColumn::FDT_DOUBLE);
|
||||
}
|
||||
break;
|
||||
|
||||
case SQL_REAL:
|
||||
setType(MetaColumn::FDT_FLOAT); break;
|
||||
|
||||
|
||||
case SQL_BINARY:
|
||||
case SQL_VARBINARY:
|
||||
case SQL_LONGVARBINARY:
|
||||
@ -176,10 +148,10 @@ void ODBCMetaColumn::init()
|
||||
|
||||
case SQL_TYPE_TIME:
|
||||
setType(MetaColumn::FDT_TIME); break;
|
||||
|
||||
|
||||
case SQL_TYPE_TIMESTAMP:
|
||||
setType(MetaColumn::FDT_TIMESTAMP); break;
|
||||
|
||||
|
||||
default:
|
||||
throw DataFormatException("Unsupported data type.");
|
||||
}
|
||||
|
@ -47,7 +47,6 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
|
||||
_prepared(false),
|
||||
_affectedRowCount(0),
|
||||
_canCompile(true),
|
||||
_numericConversion(rSession.numericConversion()),
|
||||
_isPostgres(false),
|
||||
_insertHint(false)
|
||||
{
|
||||
@ -111,9 +110,8 @@ void ODBCStatementImpl::compileImpl()
|
||||
}
|
||||
|
||||
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();
|
||||
doPrepare();
|
||||
@ -156,7 +154,7 @@ bool ODBCStatementImpl::addPreparator(bool addAlways)
|
||||
|
||||
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
|
||||
prep = new Preparator(*_preparations[0]);
|
||||
@ -339,20 +337,24 @@ bool ODBCStatementImpl::hasNext()
|
||||
|
||||
if (!nextRowReady())
|
||||
{
|
||||
// have a loop here, as there could be one or more empty results
|
||||
do {
|
||||
if (hasMoreDataSets()) {
|
||||
// have a loop here, as there could be one or more empty results
|
||||
do
|
||||
{
|
||||
if (hasMoreDataSets())
|
||||
{
|
||||
activateNextDataSet();
|
||||
if (!nextResultSet())
|
||||
return false;
|
||||
addPreparator();
|
||||
}
|
||||
else {
|
||||
if (nextResultSet()) {
|
||||
else
|
||||
{
|
||||
if (nextResultSet())
|
||||
{
|
||||
if (!addPreparator(false)) // skip the result set if it has no columns
|
||||
continue;
|
||||
fillColumns(currentDataSet() + 1);
|
||||
makeExtractors(_preparations.back()->columns(), static_cast<Position::PositionType>(currentDataSet() + 1));
|
||||
makeExtractors(_preparations.back()->columns(), static_cast<Position::Type>(currentDataSet() + 1));
|
||||
activateNextDataSet();
|
||||
}
|
||||
else return false;
|
||||
@ -451,8 +453,8 @@ void ODBCStatementImpl::checkError(SQLRETURN rc, const std::string& msg)
|
||||
if (Utility::isError(rc))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << std::endl << "Requested SQL statement: " << toString() << std::endl;
|
||||
os << "Native SQL statement: " << nativeSQL() << std::endl;
|
||||
os << std::endl << "Requested SQL statement: " << toString() << std::endl;
|
||||
os << "Native SQL statement: " << nativeSQL() << std::endl;
|
||||
std::string str(msg); str += os.str();
|
||||
|
||||
throw StatementException(_stmt, str);
|
||||
@ -469,7 +471,7 @@ void ODBCStatementImpl::fillColumns(size_t dataSetPos)
|
||||
_columnPtrs.resize(dataSetPos + 1);
|
||||
|
||||
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,
|
||||
std::size_t maxFieldSize,
|
||||
DataExtraction dataExtraction,
|
||||
ODBCMetaColumn::NumericConversion numericConversion,
|
||||
bool isPostgres) :
|
||||
_rStmt(rStmt),
|
||||
_maxFieldSize(maxFieldSize),
|
||||
_dataExtraction(dataExtraction),
|
||||
_numericConversion(numericConversion)
|
||||
_dataExtraction(dataExtraction)
|
||||
{
|
||||
SQLCHAR* pStr = (SQLCHAR*) statement.c_str();
|
||||
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):
|
||||
_rStmt(other._rStmt),
|
||||
_maxFieldSize(other._maxFieldSize),
|
||||
_dataExtraction(other._dataExtraction),
|
||||
_numericConversion(other._numericConversion)
|
||||
_dataExtraction(other._dataExtraction)
|
||||
{
|
||||
resize();
|
||||
}
|
||||
@ -169,7 +166,7 @@ std::size_t Preparator::maxDataSize(std::size_t pos) const
|
||||
|
||||
try
|
||||
{
|
||||
ODBCMetaColumn mc(_rStmt, pos, _numericConversion);
|
||||
ODBCMetaColumn mc(_rStmt, pos);
|
||||
sz = mc.length();
|
||||
|
||||
// accommodate for terminating zero (non-bulk only!)
|
||||
|
@ -29,8 +29,6 @@ namespace Data {
|
||||
namespace ODBC {
|
||||
|
||||
|
||||
const char* const SessionImpl::NUMERIC_CONVERSION_PROPERTY= "numericConversion";
|
||||
|
||||
SessionImpl::SessionImpl(const std::string& connect,
|
||||
std::size_t loginTimeout,
|
||||
std::size_t maxFieldSize,
|
||||
@ -41,7 +39,6 @@ SessionImpl::SessionImpl(const std::string& connect,
|
||||
_maxFieldSize(maxFieldSize),
|
||||
_autoBind(autoBind),
|
||||
_autoExtract(autoExtract),
|
||||
_numericConversion(ODBCMetaColumn::NC_BEST_FIT),
|
||||
_canTransact(ODBC_TXN_CAPABILITY_UNKNOWN),
|
||||
_inTransaction(false),
|
||||
_queryTimeout(-1)
|
||||
@ -69,9 +66,6 @@ SessionImpl::SessionImpl(const std::string& connect,
|
||||
|
||||
void SessionImpl::init()
|
||||
{
|
||||
addProperty(NUMERIC_CONVERSION_PROPERTY,
|
||||
&SessionImpl::setNumericConversion,
|
||||
&SessionImpl::numericConversion);
|
||||
setFeature("bulk", true);
|
||||
open();
|
||||
setProperty("handle", _db.handle());
|
||||
|
@ -58,7 +58,7 @@
|
||||
<Filter>_Suite\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\ODBCSybaseTest.h">
|
||||
<Filter>ODBC</Filter>
|
||||
<Filter>ODBC\Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -96,7 +96,7 @@
|
||||
<Filter>_Driver\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ODBCSybaseTest.cpp">
|
||||
<Filter>ODBC</Filter>
|
||||
<Filter>ODBC\Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -578,17 +578,6 @@ void ODBCDB2Test::recreateNullableTable()
|
||||
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()
|
||||
{
|
||||
@ -637,8 +626,8 @@ void ODBCDB2Test::recreatePersonDateTimeTable()
|
||||
|
||||
void ODBCDB2Test::recreateIntsTable()
|
||||
{
|
||||
dropObject("TABLE", ExecUtil::strings());
|
||||
try { session() << "CREATE TABLE " << ExecUtil::strings() << " (str INTEGER)", now; }
|
||||
dropObject("TABLE", ExecUtil::ints());
|
||||
try { session() << "CREATE TABLE " << ExecUtil::ints() << " (str INTEGER)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.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, testNullable);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testReconnect);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testNumeric);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testXMLColumn);
|
||||
CppUnit_addTest(pSuite, ODBCDB2Test, testInsertStatReuse);
|
||||
|
||||
|
@ -62,15 +62,14 @@ private:
|
||||
void recreateNullsTable(const std::string& notNull = "");
|
||||
void recreateMiscTable();
|
||||
void recreateLogTable();
|
||||
void recreateNumericTable();
|
||||
|
||||
static ODBCTest::SessionPtr _pSession;
|
||||
static ODBCTest::ExecPtr _pExecutor;
|
||||
static std::string _driver;
|
||||
static std::string _dsn;
|
||||
static std::string _uid;
|
||||
static std::string _pwd;
|
||||
static std::string _connectString;
|
||||
static ODBCTest::SessionPtr _pSession;
|
||||
static ODBCTest::ExecPtr _pExecutor;
|
||||
static std::string _driver;
|
||||
static std::string _dsn;
|
||||
static std::string _uid;
|
||||
static std::string _pwd;
|
||||
static std::string _connectString;
|
||||
};
|
||||
|
||||
|
||||
|
@ -304,8 +304,8 @@ void ODBCMySQLTest::recreatePersonDateTimeTable()
|
||||
|
||||
void ODBCMySQLTest::recreateIntsTable()
|
||||
{
|
||||
dropObject("TABLE", ExecUtil::strings());
|
||||
try { *_pSession << "CREATE TABLE " << ExecUtil::strings() << " (str INTEGER)", now; }
|
||||
dropObject("TABLE", ExecUtil::ints());
|
||||
try { *_pSession << "CREATE TABLE " << ExecUtil::ints() << " (str INTEGER)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.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;
|
||||
|
||||
|
||||
#define ORACLE_ODBC_DRIVER "Oracle in XE"
|
||||
#define ORACLE_ODBC_DRIVER "Oracle in OraClient12Home1_32bit"//XE"
|
||||
#define ORACLE_DSN "PocoDataOracleTest"
|
||||
#define ORACLE_SERVER POCO_ODBC_TEST_DATABASE_SERVER
|
||||
#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()
|
||||
{
|
||||
const std::size_t maxFldSize = 1000000;
|
||||
@ -598,18 +617,18 @@ void ODBCOracleTest::testAutoTransaction()
|
||||
recreateIntsTable();
|
||||
|
||||
session().setFeature("autoCommit", true);
|
||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (1)", now;
|
||||
localSession << "SELECT count(*) FROM " << ExecUtil::person() , into(count), now;
|
||||
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (1)", now;
|
||||
localSession << "SELECT count(*) FROM " << ExecUtil::ints() , into(count), now;
|
||||
assert (1 == count);
|
||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (2)", now;
|
||||
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
|
||||
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (2)", now;
|
||||
localSession << "SELECT count(*) FROM " << ExecUtil::ints(), into(count), now;
|
||||
assert (2 == count);
|
||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (3)", now;
|
||||
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
|
||||
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (3)", now;
|
||||
localSession << "SELECT count(*) FROM " << ExecUtil::ints(), into(count), now;
|
||||
assert (3 == count);
|
||||
|
||||
session() << "DELETE FROM " << ExecUtil::strings(), now;
|
||||
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
|
||||
session() << "DELETE FROM " << ExecUtil::ints(), now;
|
||||
localSession << "SELECT count(*) FROM " << ExecUtil::ints(), into(count), now;
|
||||
assert (0 == count);
|
||||
|
||||
session().setFeature("autoCommit", false);
|
||||
@ -617,26 +636,26 @@ void ODBCOracleTest::testAutoTransaction()
|
||||
try
|
||||
{
|
||||
AutoTransaction at(session());
|
||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (1)", now;
|
||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (2)", now;
|
||||
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (1)", now;
|
||||
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (2)", now;
|
||||
session() << "BAD QUERY", now;
|
||||
} catch (Poco::Exception&) {}
|
||||
|
||||
session() << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
|
||||
session() << "SELECT count(*) FROM " << ExecUtil::ints(), into(count), now;
|
||||
assert (0 == count);
|
||||
|
||||
AutoTransaction at(session());
|
||||
|
||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (1)", now;
|
||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (2)", now;
|
||||
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (3)", now;
|
||||
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (1)", now;
|
||||
session() << "INSERT INTO " << ExecUtil::ints() << " VALUES (2)", 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);
|
||||
|
||||
at.commit();
|
||||
|
||||
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
|
||||
localSession << "SELECT count(*) FROM " << ExecUtil::ints(), into(count), now;
|
||||
assert (3 == count);
|
||||
|
||||
session().setFeature("autoCommit", ac);
|
||||
@ -726,8 +745,8 @@ void ODBCOracleTest::recreatePersonDateTable()
|
||||
|
||||
void ODBCOracleTest::recreateIntsTable()
|
||||
{
|
||||
dropObject("TABLE", ExecUtil::strings());
|
||||
try { *_pSession << "CREATE TABLE " << ExecUtil::strings() <<" (str INTEGER)", now; }
|
||||
dropObject("TABLE", ExecUtil::ints());
|
||||
try { *_pSession << "CREATE TABLE " << ExecUtil::ints() <<" (str INTEGER)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ public:
|
||||
|
||||
void testBareboneODBC();
|
||||
|
||||
void testInternalExtraction();
|
||||
|
||||
void testBLOB();
|
||||
|
||||
void testMultipleResults();
|
||||
|
@ -482,8 +482,8 @@ void ODBCPostgreSQLTest::recreatePersonTimeTable()
|
||||
|
||||
void ODBCPostgreSQLTest::recreateIntsTable()
|
||||
{
|
||||
dropObject("TABLE", ExecUtil::strings());
|
||||
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str INTEGER)", now; }
|
||||
dropObject("TABLE", ExecUtil::ints());
|
||||
try { session() << "CREATE TABLE " << ExecUtil::ints() <<" (str INTEGER)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.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()
|
||||
{
|
||||
dropObject("TABLE", ExecUtil::strings());
|
||||
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str INTEGER)", now; }
|
||||
dropObject("TABLE", ExecUtil::ints());
|
||||
try { session() << "CREATE TABLE " << ExecUtil::ints() <<" (str INTEGER)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.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()
|
||||
{
|
||||
dropObject("TABLE", ExecUtil::strings());
|
||||
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str INTEGER)", now; }
|
||||
dropObject("TABLE", ExecUtil::ints());
|
||||
try { session() << "CREATE TABLE " << ExecUtil::ints() <<" (str INTEGER)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.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()
|
||||
{
|
||||
doPersonTable();
|
||||
@ -216,8 +205,8 @@ void SybaseODBC::recreatePersonDateTimeTable()
|
||||
|
||||
void SybaseODBC::recreateIntsTable()
|
||||
{
|
||||
dropObject("TABLE", ExecUtil::strings());
|
||||
try { session() << "CREATE TABLE " << ExecUtil::strings() << " (str INTEGER)", now; }
|
||||
dropObject("TABLE", ExecUtil::ints());
|
||||
try { session() << "CREATE TABLE " << ExecUtil::ints() << " (str INTEGER)", now; }
|
||||
catch (ConnectionException& ce){ std::cout << ce.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, testNullable);
|
||||
CppUnit_addTest(pSuite, SybaseODBC, testReconnect);
|
||||
CppUnit_addTest(pSuite, SybaseODBC, testNumeric);
|
||||
CppUnit_addTest(pSuite, SybaseODBC, testInsertStatReuse);
|
||||
|
||||
_pExecutor = 0;
|
||||
|
@ -56,7 +56,6 @@ private:
|
||||
void recreateNullsTable(const std::string& notNull = "");
|
||||
void recreateMiscTable();
|
||||
void recreateLogTable();
|
||||
void recreateNumericTable();
|
||||
void testStoredProcedure();
|
||||
void testStoredProcedureDynamicAny();
|
||||
void testStoredProcedureAny();
|
||||
|
@ -960,7 +960,7 @@ void ODBCTest::testInternalExtraction()
|
||||
recreateVectorsTable();
|
||||
_pSession->setFeature("autoBind", bindValue(i));
|
||||
_pSession->setFeature("autoExtract", bindValue(i+1));
|
||||
_pExecutor->internalExtraction();
|
||||
_pExecutor->internalExtraction(0);
|
||||
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()
|
||||
{
|
||||
@ -1413,7 +1386,7 @@ ODBCTest::SessionPtr ODBCTest::init(const std::string& driver,
|
||||
|
||||
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);
|
||||
}catch (ConnectionFailedException& ex)
|
||||
{
|
||||
|
@ -154,7 +154,6 @@ public:
|
||||
virtual void testUnicode();
|
||||
|
||||
virtual void testReconnect();
|
||||
virtual void testNumeric();
|
||||
virtual void testSyntaxError();
|
||||
virtual void testInsertStatReuse();
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "Poco/Data/Time.h"
|
||||
#include "Poco/Data/LOB.h"
|
||||
#include "Poco/Data/StatementImpl.h"
|
||||
#include "Poco/Data/RecordSet.h"
|
||||
#include "Poco/Data/RowIterator.h"
|
||||
#include "Poco/Data/RowFilter.h"
|
||||
#include "Poco/Data/BulkExtraction.h"
|
||||
@ -1518,7 +1517,7 @@ void SQLExecutor::insertSingleBulk()
|
||||
{
|
||||
std::string funct = "insertSingleBulk()";
|
||||
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)
|
||||
{
|
||||
@ -1526,12 +1525,12 @@ void SQLExecutor::insertSingleBulk()
|
||||
assert (1 == i);
|
||||
}
|
||||
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(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
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(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
assert (count == ((0+99)*100/2));
|
||||
@ -1592,16 +1591,16 @@ void SQLExecutor::insertSingleBulkVec()
|
||||
for (int x = 0; x < 100; ++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();
|
||||
|
||||
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(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
|
||||
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(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
assert (count == ((0+99)*100/2));
|
||||
@ -1617,12 +1616,12 @@ void SQLExecutor::limits()
|
||||
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(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
|
||||
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(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
assert (retData.size() == 50);
|
||||
@ -1642,12 +1641,12 @@ void SQLExecutor::limitZero()
|
||||
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(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
|
||||
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(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
assert (retData.size() == 0);
|
||||
@ -1663,12 +1662,12 @@ void SQLExecutor::limitOnce()
|
||||
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(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
|
||||
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 (retData.size() == 50);
|
||||
stmt.execute();
|
||||
@ -1696,14 +1695,14 @@ void SQLExecutor::limitPrepare()
|
||||
|
||||
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());
|
||||
}
|
||||
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
|
||||
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
|
||||
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 (!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
|
||||
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(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
std::string funct = "filter()";
|
||||
@ -3455,12 +3265,12 @@ void SQLExecutor::asynchronous(int rowCount)
|
||||
if (!_connInitSql.empty()) tmp << _connInitSql, now;
|
||||
|
||||
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();
|
||||
assert (!stmt.isAsync());
|
||||
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.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());
|
||||
stmt.wait();
|
||||
assert (stmt.execute() == 0);
|
||||
@ -3502,7 +3312,7 @@ void SQLExecutor::asynchronous(int rowCount)
|
||||
assert (!stmt.isAsync());
|
||||
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.wait() == 0);
|
||||
assert (stmt.execute() == rowCount);
|
||||
@ -3514,7 +3324,7 @@ void SQLExecutor::asynchronous(int rowCount)
|
||||
assert (0 == rowCount % 10);
|
||||
int step = (int) (rowCount/10);
|
||||
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 (!stmt2.done());
|
||||
std::size_t rows = 0;
|
||||
@ -3529,7 +3339,7 @@ void SQLExecutor::asynchronous(int rowCount)
|
||||
assert (stmt2.done());
|
||||
assert (rowCount == data.size());
|
||||
|
||||
stmt2 = tmp << "SELECT * FROM " << ExecUtil::strings(), reset;
|
||||
stmt2 = tmp << "SELECT * FROM " << ExecUtil::ints(), reset;
|
||||
assert (!stmt2.isAsync());
|
||||
assert ("deque" == stmt2.getStorage());
|
||||
assert (stmt2.execute() == rowCount);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/Data/BulkExtraction.h"
|
||||
#include "Poco/Data/BulkBinding.h"
|
||||
#include "Poco/Data/RecordSet.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/Exception.h"
|
||||
@ -75,76 +76,76 @@
|
||||
|
||||
struct ExecUtil
|
||||
{
|
||||
static std::string mangleTable(const std::string& name);
|
||||
static std::string mangleTable(const std::string& name);
|
||||
|
||||
static std::string person()
|
||||
{
|
||||
return mangleTable("Person");
|
||||
}
|
||||
|
||||
static std::string strings()
|
||||
{
|
||||
return mangleTable("Strings");
|
||||
}
|
||||
|
||||
static std::string tuples()
|
||||
{
|
||||
return mangleTable("Tuples");
|
||||
}
|
||||
|
||||
static std::string vectors()
|
||||
{
|
||||
return mangleTable("Vectors");
|
||||
}
|
||||
|
||||
static std::string anys()
|
||||
{
|
||||
return mangleTable("Anys");
|
||||
}
|
||||
|
||||
static std::string nulltest()
|
||||
{
|
||||
return mangleTable("NullTest");
|
||||
}
|
||||
|
||||
static std::string misctest()
|
||||
{
|
||||
return mangleTable("MiscTest");
|
||||
}
|
||||
|
||||
static std::string nullabletest()
|
||||
{
|
||||
return mangleTable("NullableTest");
|
||||
}
|
||||
|
||||
static std::string pocolog()
|
||||
{
|
||||
return mangleTable("POCO_LOG");
|
||||
}
|
||||
|
||||
static std::string pocolog_a()
|
||||
{
|
||||
return mangleTable("POCO_LOG_A");
|
||||
}
|
||||
|
||||
static std::string stored_func()
|
||||
{
|
||||
return mangleTable("storedFunc");
|
||||
}
|
||||
|
||||
static std::string stored_proc()
|
||||
{
|
||||
return mangleTable("storedProc");
|
||||
}
|
||||
|
||||
static std::string test_tbl()
|
||||
{
|
||||
return mangleTable("Test");
|
||||
}
|
||||
|
||||
static std::string numeric_tbl()
|
||||
static std::string person()
|
||||
{
|
||||
return mangleTable("numer_t");
|
||||
return mangleTable("Person");
|
||||
}
|
||||
|
||||
static std::string strings()
|
||||
{
|
||||
return mangleTable("Strings");
|
||||
}
|
||||
|
||||
static std::string ints()
|
||||
{
|
||||
return mangleTable("Ints");
|
||||
}
|
||||
|
||||
static std::string tuples()
|
||||
{
|
||||
return mangleTable("Tuples");
|
||||
}
|
||||
|
||||
static std::string vectors()
|
||||
{
|
||||
return mangleTable("Vectors");
|
||||
}
|
||||
|
||||
static std::string anys()
|
||||
{
|
||||
return mangleTable("Anys");
|
||||
}
|
||||
|
||||
static std::string nulltest()
|
||||
{
|
||||
return mangleTable("NullTest");
|
||||
}
|
||||
|
||||
static std::string misctest()
|
||||
{
|
||||
return mangleTable("MiscTest");
|
||||
}
|
||||
|
||||
static std::string nullabletest()
|
||||
{
|
||||
return mangleTable("NullableTest");
|
||||
}
|
||||
|
||||
static std::string pocolog()
|
||||
{
|
||||
return mangleTable("POCO_LOG");
|
||||
}
|
||||
|
||||
static std::string pocolog_a()
|
||||
{
|
||||
return mangleTable("POCO_LOG_A");
|
||||
}
|
||||
|
||||
static std::string stored_func()
|
||||
{
|
||||
return mangleTable("storedFunc");
|
||||
}
|
||||
|
||||
static std::string stored_proc()
|
||||
{
|
||||
return mangleTable("storedProc");
|
||||
}
|
||||
|
||||
static std::string test_tbl()
|
||||
{
|
||||
return mangleTable("Test");
|
||||
}
|
||||
};
|
||||
|
||||
@ -222,7 +223,6 @@ public:
|
||||
void limitPrepare();
|
||||
void limitZero();
|
||||
void prepare();
|
||||
void numericTypes(const std::vector<std::string>& vals);
|
||||
void insertStatReuse();
|
||||
|
||||
template <typename C1, typename C2, typename C3, typename C4, typename C5, typename C6>
|
||||
@ -562,13 +562,153 @@ public:
|
||||
void tuples();
|
||||
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 =
|
||||
"SELECT * FROM " + ExecUtil::vectors() + " ORDER BY i0 ASC",
|
||||
const std::string& intFldName = "i0");
|
||||
"SELECT * FROM " + ExecUtil::vectors() + " ORDER BY int0 ASC",
|
||||
const std::string& intFldName = "int0");
|
||||
|
||||
void internalBulkExtraction();
|
||||
void internalBulkExtractionUTF16();
|
||||
|
||||
void internalStorageType();
|
||||
void nulls(bool emptyStrIsSpace = false);
|
||||
void notNulls(const std::string& sqlState = "23502");
|
||||
|
@ -952,8 +952,8 @@ void PostgreSQLTest::recreatePersonTimeTable()
|
||||
|
||||
void PostgreSQLTest::recreateIntsTable()
|
||||
{
|
||||
dropTable("Strings");
|
||||
try { *_pSession << "CREATE TABLE Strings (str INTEGER)", now; }
|
||||
dropTable("Ints");
|
||||
try { *_pSession << "CREATE TABLE " << ExecUtil::ints() << " (str INTEGER)", now; }
|
||||
catch(ConnectionException& ce){ std::cout << ce.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<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);
|
||||
/// Creates the AbstractExtraction. A limit value equal to EXTRACT_UNLIMITED (0xffffffffu)
|
||||
/// means that we extract as much data as possible during one execute.
|
||||
@ -153,6 +153,11 @@ public:
|
||||
/// - string is empty
|
||||
/// - getEmptyStringIsNull() returns true
|
||||
|
||||
const std::string& type() const
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename S>
|
||||
bool isStringNull(const S& str, bool deflt)
|
||||
@ -165,6 +170,7 @@ private:
|
||||
return deflt;
|
||||
}
|
||||
|
||||
std::string _type;
|
||||
ExtractorPtr _pExtractor;
|
||||
Poco::UInt32 _limit;
|
||||
Poco::UInt32 _position;
|
||||
@ -176,11 +182,6 @@ private:
|
||||
|
||||
typedef std::vector<AbstractExtraction::Ptr> AbstractExtractionVec;
|
||||
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
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
typedef SharedPtr<Type> Ptr;
|
||||
|
||||
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),
|
||||
_default()
|
||||
{
|
||||
@ -56,7 +56,7 @@ public:
|
||||
}
|
||||
|
||||
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),
|
||||
_default(def)
|
||||
{
|
||||
|
@ -87,7 +87,7 @@ public:
|
||||
typedef SharedPtr<Type> Ptr;
|
||||
|
||||
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),
|
||||
_default(),
|
||||
_extracted(false),
|
||||
@ -98,7 +98,7 @@ public:
|
||||
}
|
||||
|
||||
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),
|
||||
_default(def),
|
||||
_extracted(false),
|
||||
@ -179,7 +179,7 @@ public:
|
||||
typedef SharedPtr<Type> Ptr;
|
||||
|
||||
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),
|
||||
_default()
|
||||
{
|
||||
@ -187,7 +187,7 @@ public:
|
||||
}
|
||||
|
||||
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),
|
||||
_default(def)
|
||||
{
|
||||
@ -269,7 +269,7 @@ public:
|
||||
typedef SharedPtr<Type> Ptr;
|
||||
|
||||
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),
|
||||
_default()
|
||||
{
|
||||
@ -277,7 +277,7 @@ public:
|
||||
}
|
||||
|
||||
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),
|
||||
_default(def)
|
||||
{
|
||||
@ -361,7 +361,7 @@ public:
|
||||
typedef SharedPtr<Type> Ptr;
|
||||
|
||||
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),
|
||||
_default()
|
||||
{
|
||||
@ -369,7 +369,7 @@ public:
|
||||
}
|
||||
|
||||
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),
|
||||
_default(def)
|
||||
{
|
||||
@ -451,7 +451,7 @@ public:
|
||||
typedef SharedPtr<Type> Ptr;
|
||||
|
||||
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),
|
||||
_default()
|
||||
{
|
||||
@ -459,7 +459,7 @@ public:
|
||||
}
|
||||
|
||||
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),
|
||||
_default(def)
|
||||
{
|
||||
@ -611,7 +611,7 @@ public:
|
||||
typedef typename ValType::iterator Iterator;
|
||||
|
||||
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),
|
||||
_default()
|
||||
{
|
||||
@ -619,7 +619,7 @@ public:
|
||||
}
|
||||
|
||||
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),
|
||||
_default(def)
|
||||
{
|
||||
@ -675,7 +675,7 @@ public:
|
||||
typedef SharedPtr<Type> Ptr;
|
||||
|
||||
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),
|
||||
_default()
|
||||
{
|
||||
@ -683,7 +683,7 @@ public:
|
||||
}
|
||||
|
||||
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),
|
||||
_default(def)
|
||||
{
|
||||
@ -739,7 +739,7 @@ public:
|
||||
typedef SharedPtr<Type> Ptr;
|
||||
|
||||
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),
|
||||
_default()
|
||||
{
|
||||
@ -747,7 +747,7 @@ public:
|
||||
}
|
||||
|
||||
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),
|
||||
_default(def)
|
||||
{
|
||||
@ -803,7 +803,7 @@ public:
|
||||
typedef SharedPtr<Type> Ptr;
|
||||
|
||||
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),
|
||||
_default()
|
||||
{
|
||||
@ -811,7 +811,7 @@ public:
|
||||
}
|
||||
|
||||
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),
|
||||
_default(def)
|
||||
{
|
||||
|
@ -32,28 +32,28 @@ class Data_API Position
|
||||
/// indicate the recordset position in batch SQL statements.
|
||||
{
|
||||
public:
|
||||
typedef Poco::UInt32 PositionType;
|
||||
typedef Poco::UInt32 Type;
|
||||
|
||||
Position(PositionType value);
|
||||
Position(Type value);
|
||||
/// Creates the Position.
|
||||
|
||||
~Position();
|
||||
/// Destroys the Position.
|
||||
|
||||
PositionType value() const;
|
||||
Type value() const;
|
||||
/// Returns the position value.
|
||||
|
||||
private:
|
||||
Position();
|
||||
|
||||
PositionType _value;
|
||||
Type _value;
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// inlines
|
||||
///
|
||||
inline Position::PositionType Position::value() const
|
||||
inline Position::Type Position::value() const
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
@ -438,7 +438,8 @@ private:
|
||||
if (typeFound)
|
||||
throw NotFoundException(Poco::format("Column name: %s", name));
|
||||
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>
|
||||
@ -469,9 +470,13 @@ private:
|
||||
}
|
||||
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,
|
||||
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();
|
||||
/// Destroys the RowFilter.
|
||||
|
||||
void addFilter(const Ptr& pFilter, LogicOperator comparison);
|
||||
void addFilter(Ptr pFilter, LogicOperator comparison);
|
||||
/// Appends another filter to this one.
|
||||
|
||||
void removeFilter(const Ptr& pFilter);
|
||||
void removeFilter(Ptr pFilter);
|
||||
/// Removes filter from this filter.
|
||||
|
||||
bool has(Ptr pFilter) const;
|
||||
/// Returns true if this filter is parent of pFilter;
|
||||
|
||||
template <typename T>
|
||||
void add(const std::string& name, Comparison comparison, const T& value, LogicOperator op = OP_OR)
|
||||
/// 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
|
||||
{
|
||||
return _comparisonMap.size() == 0;
|
||||
|
@ -21,9 +21,10 @@ namespace Poco {
|
||||
namespace Data {
|
||||
|
||||
|
||||
AbstractExtraction::AbstractExtraction(Poco::UInt32 limit,
|
||||
AbstractExtraction::AbstractExtraction(const std::string& type, Poco::UInt32 limit,
|
||||
Poco::UInt32 extractionPosition,
|
||||
bool bulk):
|
||||
bool bulk):
|
||||
_type(type),
|
||||
_pExtractor(0),
|
||||
_limit(limit),
|
||||
_position(extractionPosition),
|
||||
|
@ -29,6 +29,7 @@ RowFilter::RowFilter(RecordSet* pRecordSet): _pRecordSet(pRecordSet), _not(false
|
||||
{
|
||||
poco_check_ptr(pRecordSet);
|
||||
init();
|
||||
duplicate();
|
||||
_pRecordSet->filter(this);
|
||||
}
|
||||
|
||||
@ -39,6 +40,7 @@ RowFilter::RowFilter(Ptr pParent, LogicOperator op): _pRecordSet(0),
|
||||
{
|
||||
poco_check_ptr(_pParent.get());
|
||||
init();
|
||||
duplicate();
|
||||
_pParent->addFilter(this, op);
|
||||
}
|
||||
|
||||
@ -62,7 +64,9 @@ RowFilter::~RowFilter()
|
||||
try
|
||||
{
|
||||
if (_pRecordSet) _pRecordSet->filter(0);
|
||||
if (_pParent.get()) _pParent->removeFilter(this);
|
||||
if (_pParent && _pParent->has(this))
|
||||
_pParent->removeFilter(this);
|
||||
release();
|
||||
}
|
||||
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);
|
||||
|
||||
@ -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);
|
||||
|
||||
pFilter->_pRecordSet = 0;
|
||||
_pRecordSet->moveFirst();
|
||||
_filterMap.erase(pFilter);
|
||||
pFilter->_pRecordSet = 0;
|
||||
pFilter->_pParent = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -318,8 +318,8 @@ void StatementImpl::setStorage(const std::string& storage)
|
||||
|
||||
void StatementImpl::makeExtractors(std::size_t count)
|
||||
{
|
||||
// type cast is needed when size_t is 64 bit
|
||||
makeExtractors(count, static_cast<Position::PositionType>(currentDataSet()));
|
||||
// type cast is needed when size_t is 64 bit
|
||||
makeExtractors(count, static_cast<Position::Type>(currentDataSet()));
|
||||
}
|
||||
|
||||
void StatementImpl::makeExtractors(std::size_t count, const Position& position)
|
||||
|
@ -208,6 +208,11 @@ namespace Poco {
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(POCO_PTR_IS_64_BIT) && (POCO_PTR_IS_64_BIT == 1)
|
||||
#define POCO_64_BIT
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user