From b3704e2275f211619ea390d0be9330821a50172e Mon Sep 17 00:00:00 2001 From: Alex Fabijanic Date: Wed, 28 Jun 2017 17:21:49 +0200 Subject: [PATCH 1/4] add type diagnostics --- Data/ODBC/testsuite/TestSuite_x64_vs140.vcxproj.filters | 4 ++-- Data/include/Poco/Data/RecordSet.h | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Data/ODBC/testsuite/TestSuite_x64_vs140.vcxproj.filters b/Data/ODBC/testsuite/TestSuite_x64_vs140.vcxproj.filters index 704634f1a..3279de0c1 100644 --- a/Data/ODBC/testsuite/TestSuite_x64_vs140.vcxproj.filters +++ b/Data/ODBC/testsuite/TestSuite_x64_vs140.vcxproj.filters @@ -58,7 +58,7 @@ _Suite\Header Files - ODBC + ODBC\Header Files @@ -96,7 +96,7 @@ _Driver\Source Files - ODBC + ODBC\Source Files \ No newline at end of file diff --git a/Data/include/Poco/Data/RecordSet.h b/Data/include/Poco/Data/RecordSet.h index bba7ac653..c722927b2 100644 --- a/Data/include/Poco/Data/RecordSet.h +++ b/Data/include/Poco/Data/RecordSet.h @@ -469,9 +469,12 @@ private: } else { - throw Poco::BadCastException(Poco::format("Type cast failed!\nColumn: %z\nTarget type:\t%s", + throw Poco::BadCastException(Poco::format("Type cast failed!\nColumn: %z\nTarget type:\t%s" + "\nTarget container type:\t%s\nSource container type:\t%s", pos, - std::string(typeid(T).name()))); + std::string(typeid(T).name()), + std::string(typeid(ExtractionVecPtr).name()), + std::string(typeid(rExtractions[pos].get()).name()))); } } From 41e3f38c062a385587901e5917b98f9041049590 Mon Sep 17 00:00:00 2001 From: Alex Fabijanic Date: Thu, 29 Jun 2017 23:49:42 +0200 Subject: [PATCH 2/4] ODBC RecordSet (internal extraction) broken #1775; some style fixes --- Data/ODBC/include/Poco/Data/ODBC/Binder.h | 16 +- Data/ODBC/include/Poco/Data/ODBC/Extractor.h | 4 +- .../include/Poco/Data/ODBC/ODBCException.h | 2 +- .../include/Poco/Data/ODBC/ODBCMetaColumn.h | 10 +- .../Poco/Data/ODBC/ODBCStatementImpl.h | 1 - Data/ODBC/include/Poco/Data/ODBC/Preparator.h | 13 +- .../ODBC/include/Poco/Data/ODBC/SessionImpl.h | 38 -- Data/ODBC/src/Binder.cpp | 6 +- Data/ODBC/src/ODBCMetaColumn.cpp | 68 +-- Data/ODBC/src/ODBCStatementImpl.cpp | 28 +- Data/ODBC/src/Preparator.cpp | 9 +- Data/ODBC/src/SessionImpl.cpp | 6 - Data/ODBC/testsuite/src/ODBCDB2Test.cpp | 12 - Data/ODBC/testsuite/src/ODBCDB2Test.h | 15 +- Data/ODBC/testsuite/src/ODBCOracleTest.cpp | 36 +- Data/ODBC/testsuite/src/ODBCOracleTest.h | 3 + Data/ODBC/testsuite/src/ODBCSybaseTest.cpp | 12 - Data/ODBC/testsuite/src/ODBCSybaseTest.h | 1 - Data/ODBC/testsuite/src/ODBCTest.cpp | 35 +- Data/ODBC/testsuite/src/ODBCTest.h | 1 - Data/ODBC/testsuite/src/SQLExecutor.cpp | 194 +------- Data/ODBC/testsuite/src/SQLExecutor.h | 419 +++++++++++++++--- Data/include/Poco/Data/AbstractExtraction.h | 13 +- Data/include/Poco/Data/BulkExtraction.h | 4 +- Data/include/Poco/Data/Extraction.h | 36 +- Data/include/Poco/Data/Position.h | 10 +- Data/include/Poco/Data/RecordSet.h | 8 +- Data/src/AbstractExtraction.cpp | 5 +- Data/src/StatementImpl.cpp | 4 +- Foundation/include/Poco/Types.h | 5 + 30 files changed, 497 insertions(+), 517 deletions(-) diff --git a/Data/ODBC/include/Poco/Data/ODBC/Binder.h b/Data/ODBC/include/Poco/Data/ODBC/Binder.h index 0d97d08c9..065456d29 100644 --- a/Data/ODBC/include/Poco/Data/ODBC/Binder.h +++ b/Data/ODBC/include/Poco/Data/ODBC/Binder.h @@ -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; }; diff --git a/Data/ODBC/include/Poco/Data/ODBC/Extractor.h b/Data/ODBC/include/Poco/Data/ODBC/Extractor.h index 6e6e402a5..93e728f12 100644 --- a/Data/ODBC/include/Poco/Data/ODBC/Extractor.h +++ b/Data/ODBC/include/Poco/Data/ODBC/Extractor.h @@ -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; diff --git a/Data/ODBC/include/Poco/Data/ODBC/ODBCException.h b/Data/ODBC/include/Poco/Data/ODBC/ODBCException.h index 0fa5402f3..5f7f981f1 100644 --- a/Data/ODBC/include/Poco/Data/ODBC/ODBCException.h +++ b/Data/ODBC/include/Poco/Data/ODBC/ODBCException.h @@ -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), diff --git a/Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h b/Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h index 3d8b3994a..17cab2120 100644 --- a/Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h +++ b/Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h @@ -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; }; diff --git a/Data/ODBC/include/Poco/Data/ODBC/ODBCStatementImpl.h b/Data/ODBC/include/Poco/Data/ODBC/ODBCStatementImpl.h index 48c9089cd..7ae4dc863 100644 --- a/Data/ODBC/include/Poco/Data/ODBC/ODBCStatementImpl.h +++ b/Data/ODBC/include/Poco/Data/ODBC/ODBCStatementImpl.h @@ -160,7 +160,6 @@ private: bool _prepared; mutable std::size_t _affectedRowCount; bool _canCompile; - ODBCMetaColumn::NumericConversion _numericConversion; bool _isPostgres; bool _insertHint; }; diff --git a/Data/ODBC/include/Poco/Data/ODBC/Preparator.h b/Data/ODBC/include/Poco/Data/ODBC/Preparator.h index d2c738d99..86310f812 100644 --- a/Data/ODBC/include/Poco/Data/ODBC/Preparator.h +++ b/Data/ODBC/include/Poco/Data/ODBC/Preparator.h @@ -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 ValueVec; typedef std::vector 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 diff --git a/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h b/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h index 88ff7155d..a3dedec5a 100644 --- a/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h +++ b/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h @@ -45,7 +45,6 @@ class ODBC_API SessionImpl: public Poco::Data::AbstractSessionImpl { 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(rValue) ); -} - - } } } // namespace Poco::Data::ODBC diff --git a/Data/ODBC/src/Binder.cpp b/Data/ODBC/src/Binder.cpp index f16e7bd26..79cccc7dd 100644 --- a/Data/ODBC/src/Binder.cpp +++ b/Data/ODBC/src/Binder.cpp @@ -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(c.length()), cDataType, static_cast(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&) { } diff --git a/Data/ODBC/src/ODBCMetaColumn.cpp b/Data/ODBC/src/ODBCMetaColumn.cpp index 552ba4a09..6d9363859 100644 --- a/Data/ODBC/src/ODBCMetaColumn.cpp +++ b/Data/ODBC/src/ODBCMetaColumn.cpp @@ -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."); } diff --git a/Data/ODBC/src/ODBCStatementImpl.cpp b/Data/ODBC/src/ODBCStatementImpl.cpp index d8e5048bf..4bdd985e2 100644 --- a/Data/ODBC/src/ODBCStatementImpl.cpp +++ b/Data/ODBC/src/ODBCStatementImpl.cpp @@ -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(session().getProperty("maxFieldSize")); - const ODBCMetaColumn::NumericConversion numericConversion = dynamic_cast(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(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(currentDataSet() + 1)); + makeExtractors(_preparations.back()->columns(), static_cast(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)); } diff --git a/Data/ODBC/src/Preparator.cpp b/Data/ODBC/src/Preparator.cpp index 919e98ec5..213dc2194 100644 --- a/Data/ODBC/src/Preparator.cpp +++ b/Data/ODBC/src/Preparator.cpp @@ -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!) diff --git a/Data/ODBC/src/SessionImpl.cpp b/Data/ODBC/src/SessionImpl.cpp index a5c476102..b54a6a4aa 100644 --- a/Data/ODBC/src/SessionImpl.cpp +++ b/Data/ODBC/src/SessionImpl.cpp @@ -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()); diff --git a/Data/ODBC/testsuite/src/ODBCDB2Test.cpp b/Data/ODBC/testsuite/src/ODBCDB2Test.cpp index a0685d0da..9dd16d3d9 100644 --- a/Data/ODBC/testsuite/src/ODBCDB2Test.cpp +++ b/Data/ODBC/testsuite/src/ODBCDB2Test.cpp @@ -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() { @@ -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); diff --git a/Data/ODBC/testsuite/src/ODBCDB2Test.h b/Data/ODBC/testsuite/src/ODBCDB2Test.h index 8f620ba2d..f499d5031 100644 --- a/Data/ODBC/testsuite/src/ODBCDB2Test.h +++ b/Data/ODBC/testsuite/src/ODBCDB2Test.h @@ -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; }; diff --git a/Data/ODBC/testsuite/src/ODBCOracleTest.cpp b/Data/ODBC/testsuite/src/ODBCOracleTest.cpp index b1cfaa690..2139f2eac 100644 --- a/Data/ODBC/testsuite/src/ODBCOracleTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCOracleTest.cpp @@ -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,40 @@ 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(0.); +#else + _pExecutor->internalExtraction(0); +#endif + i += 2; + } +} + + +void ODBCOracleTest::testInternalBulkExtraction() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pSession->setFeature("autoBind", true); + _pSession->setFeature("autoExtract", true); +#ifdef POCO_ODBC_UNICODE + _pExecutor->internalBulkExtractionUTF16(0); +#else + _pExecutor->internalBulkExtraction(0); +#endif +} + + void ODBCOracleTest::testBLOB() { const std::size_t maxFldSize = 1000000; diff --git a/Data/ODBC/testsuite/src/ODBCOracleTest.h b/Data/ODBC/testsuite/src/ODBCOracleTest.h index 288db3ef8..be44bd45e 100644 --- a/Data/ODBC/testsuite/src/ODBCOracleTest.h +++ b/Data/ODBC/testsuite/src/ODBCOracleTest.h @@ -36,6 +36,9 @@ public: void testBareboneODBC(); + void testInternalExtraction(); + void testInternalBulkExtraction(); + void testBLOB(); void testMultipleResults(); diff --git a/Data/ODBC/testsuite/src/ODBCSybaseTest.cpp b/Data/ODBC/testsuite/src/ODBCSybaseTest.cpp index d75c4e726..145e60386 100644 --- a/Data/ODBC/testsuite/src/ODBCSybaseTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCSybaseTest.cpp @@ -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(); @@ -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; diff --git a/Data/ODBC/testsuite/src/ODBCSybaseTest.h b/Data/ODBC/testsuite/src/ODBCSybaseTest.h index 1d238535a..5128572bc 100644 --- a/Data/ODBC/testsuite/src/ODBCSybaseTest.h +++ b/Data/ODBC/testsuite/src/ODBCSybaseTest.h @@ -56,7 +56,6 @@ private: void recreateNullsTable(const std::string& notNull = ""); void recreateMiscTable(); void recreateLogTable(); - void recreateNumericTable(); void testStoredProcedure(); void testStoredProcedureDynamicAny(); void testStoredProcedureAny(); diff --git a/Data/ODBC/testsuite/src/ODBCTest.cpp b/Data/ODBC/testsuite/src/ODBCTest.cpp index 665e2d0bd..97932ce2c 100644 --- a/Data/ODBC/testsuite/src/ODBCTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCTest.cpp @@ -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; } } @@ -989,9 +989,9 @@ void ODBCTest::testInternalBulkExtraction() _pSession->setFeature("autoBind", true); _pSession->setFeature("autoExtract", true); #ifdef POCO_ODBC_UNICODE - _pExecutor->internalBulkExtractionUTF16(); + _pExecutor->internalBulkExtractionUTF16(0); #else - _pExecutor->internalBulkExtraction(); + _pExecutor->internalBulkExtraction(0); #endif } @@ -1235,33 +1235,6 @@ void ODBCTest::testNullable() } } -void ODBCTest::testNumeric() -{ - if (!_pSession) fail("Test not available."); - - recreateNumericTable(); - std::vector 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) { diff --git a/Data/ODBC/testsuite/src/ODBCTest.h b/Data/ODBC/testsuite/src/ODBCTest.h index d27c4c5fa..b4ddf499f 100644 --- a/Data/ODBC/testsuite/src/ODBCTest.h +++ b/Data/ODBC/testsuite/src/ODBCTest.h @@ -154,7 +154,6 @@ public: virtual void testUnicode(); virtual void testReconnect(); - virtual void testNumeric(); virtual void testSyntaxError(); virtual void testInsertStatReuse(); diff --git a/Data/ODBC/testsuite/src/SQLExecutor.cpp b/Data/ODBC/testsuite/src/SQLExecutor.cpp index fd3a63647..ee8500a30 100644 --- a/Data/ODBC/testsuite/src/SQLExecutor.cpp +++ b/Data/ODBC/testsuite/src/SQLExecutor.cpp @@ -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" @@ -1750,73 +1749,6 @@ void SQLExecutor::prepare() assert (count == 0); } -void SQLExecutor::numericTypes(const std::vector& 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(); - 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(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(); - 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 > v; - v.push_back(Tuple(1, 1.5f, "3")); - v.push_back(Tuple(2, 2.5f, "4")); - v.push_back(Tuple(3, 3.5f, "5")); - v.push_back(Tuple(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(0,0); - assert (1 == i); - - std::string s = rset.value(0,0).convert(); - assert ("1" == s); - - int a = rset.value(0,2); - assert (3 == a); - - try - { - double d = rset.value(1,1); - assert (2.5 == d); - } - catch (BadCastException&) - { - float f = rset.value(1,1); - assert (2.5 == f); - } - - try - { - s = rset.value(2, 2); - } - catch (BadCastException&) - { - UTF16String us = rset.value(2, 2); - Poco::UnicodeConverter::convert(us, s); - } - assert("5" == s); - - i = rset.value("str0", 2); - assert (5 == i); - - const Column >& col = rset.column >(0); - Column >::Iterator it = col.begin(); - Column >::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(0,0); - assert (4 == i); - } - catch(BadCastException&) - { - try - { - //this is for Oracle - double i = rset.value(0,0); - assert (4 == int(i)); - } - catch(BadCastException&) - { - //this is for PostgreSQL - Poco::Int64 big = rset.value(0,0); - assert (4 == big); - } - } - - s = rset.value("cnt", 0).convert(); - assert ("4" == s); - - try { rset.column >(100); fail ("must fail"); } - catch (RangeException&) { } - - try { rset.value(0,0); fail ("must fail"); } - catch (BadCastException&) { } - - stmt = (session() << "DELETE FROM " << ExecUtil::vectors(), now); - rset = stmt; - - try { rset.column >(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()"; @@ -3001,7 +2811,7 @@ void SQLExecutor::filter(const std::string& query, const std::string& intFldName catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } } - +/* void SQLExecutor::internalBulkExtraction() { std::string funct = "internalBulkExtraction()"; @@ -3124,7 +2934,7 @@ void SQLExecutor::internalBulkExtractionUTF16() catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); } catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); } } - +*/ void SQLExecutor::internalStorageType() { diff --git a/Data/ODBC/testsuite/src/SQLExecutor.h b/Data/ODBC/testsuite/src/SQLExecutor.h index 85721163a..01f23ff12 100644 --- a/Data/ODBC/testsuite/src/SQLExecutor.h +++ b/Data/ODBC/testsuite/src/SQLExecutor.h @@ -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,71 @@ 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 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 +218,6 @@ public: void limitPrepare(); void limitZero(); void prepare(); - void numericTypes(const std::vector& vals); void insertStatReuse(); template @@ -562,13 +557,293 @@ public: void tuples(); void tupleVector(); - void internalExtraction(); + template + 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 > v; + v.push_back(Tuple(1, 1.5, "3")); + v.push_back(Tuple(2, 2.5, "4")); + v.push_back(Tuple(3, 3.5, "5")); + v.push_back(Tuple(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(0, 0); + assert(1 == i); + } + catch (Poco::BadCastException& ex) + { + std::cout << ex.displayText() << std::endl; + } + std::string s = rset.value(0,0).convert(); + assert ("1" == s); + + IntType a = rset.value(0,2); + assert (3 == a); + + try + { + double d = rset.value(1,1); + assert (2.5 == d); + } + catch (BadCastException&) + { + float f = rset.value(1,1); + assert (2.5 == f); + } + + try + { + s = rset.value(2, 2); + } + catch (BadCastException&) + { + UTF16String us = rset.value(2, 2); + Poco::UnicodeConverter::convert(us, s); + } + assert("5" == s); + + i = rset.value("str0", 2); + assert (5 == i); + + const Column >& col = rset.column >(0); + Column >::Iterator it = col.begin(); + Column >::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(0,0); + assert (4 == i); + } + catch(BadCastException&) + { + try + { + //this is for Oracle + double i = rset.value(0,0); + assert (4 == int(i)); + } + catch(BadCastException&) + { + //this is for PostgreSQL + Poco::Int64 big = rset.value(0,0); + assert (4 == big); + } + } + + s = rset.value("cnt", 0).convert(); + assert ("4" == s); + + try { rset.column >(100); fail ("must fail"); } + catch (RangeException&) { } + + try { rset.value(0,0); fail ("must fail"); } + catch (BadCastException&) { } + + stmt = (session() << "DELETE FROM " << ExecUtil::vectors(), now); + rset = stmt; + + try { rset.column >(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"); - void internalBulkExtraction(); - void internalBulkExtractionUTF16(); + template + void internalBulkExtraction(IntType) + { + using Poco::Data::RecordSet; + using Poco::NumberFormatter; + + std::string funct = "internalBulkExtraction()"; + int size = 100; + std::vector lastName(size); + std::vector firstName(size); + std::vector address(size); + std::vector age(size); + + for (int i = 0; i < size; ++i) + { + lastName[i] = "LN" + NumberFormatter::format(i); + firstName[i] = "FN" + NumberFormatter::format(i); + address[i] = "Addr" + NumberFormatter::format(i); + age[i] = i; + } + + try + { + session() << "INSERT INTO " << ExecUtil::person() <<" VALUES (?,?,?,?)", + use(lastName, bulk), + use(firstName, bulk), + use(address, bulk), + use(age, bulk), + now; + } + catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } + + try + { + Statement stmt = (session() << "SELECT * FROM " << ExecUtil::person(), bulk(size), now); + RecordSet rset(stmt); + assert (size == rset.rowCount()); + assert("LN0" == rset["LastName"]); + assert (0 == rset["Age"]); + rset.moveNext(); + assert("LN1" == rset["LastName"]); + assert(1 == rset["Age"]); + rset.moveLast(); + assert (std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]); + assert (size - 1 == rset["Age"]); + } + catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } + + try + { + Statement stmt = (session() << "SELECT * FROM " << ExecUtil::person(), limit(size), bulk, now); + RecordSet rset(stmt); + assert (size == rset.rowCount()); + assert ("LN0" == rset["LastName"]); + assert (0 == rset["Age"]); + rset.moveLast(); + assert (std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]); + assert (size - 1 == rset["Age"]); + } + catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } + } + + template + void internalBulkExtractionUTF16(IntType) + { + using Poco::Data::RecordSet; + using Poco::UTF16String; + using Poco::NumberFormatter; + + std::string funct = "internalBulkExtraction()"; + int size = 100; + std::vector lastName(size); + std::vector firstName(size); + std::vector address(size); + std::vector age(size); + + for (int i = 0; i < size; ++i) + { + lastName[i] = Poco::UnicodeConverter::to("LN" + NumberFormatter::format(i)); + firstName[i] = Poco::UnicodeConverter::to("FN" + NumberFormatter::format(i)); + address[i] = Poco::UnicodeConverter::to("Addr" + NumberFormatter::format(i)); + age[i] = i; + } + + try + { + session() << "INSERT INTO " << ExecUtil::person() <<" VALUES (?,?,?,?)", + use(lastName, bulk), + use(firstName, bulk), + use(address, bulk), + use(age, bulk), + now; + } + catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); } + catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); } + + try + { + Statement stmt = (session() << "SELECT * FROM " << ExecUtil::person(), bulk(size), now); + RecordSet rset(stmt); + assert(size == rset.rowCount()); + assert(Poco::UnicodeConverter::to("LN0") == rset["LastName"]); + assert(0 == rset["Age"]); + rset.moveNext(); + assert(Poco::UnicodeConverter::to("LN1") == rset["LastName"]); + assert(1 == rset["Age"]); + rset.moveLast(); + assert(std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]); + assert(size - 1 == rset["Age"]); + } + catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); } + catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); } + + try + { + Statement stmt = (session() << "SELECT * FROM " << ExecUtil::person(), limit(size), bulk, now); + RecordSet rset(stmt); + assert(size == rset.rowCount()); + assert("LN0" == rset["LastName"]); + assert(0 == rset["Age"]); + rset.moveLast(); + assert(std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]); + assert(size - 1 == rset["Age"]); + } + catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); } + catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); } + } + void internalStorageType(); void nulls(bool emptyStrIsSpace = false); void notNulls(const std::string& sqlState = "23502"); diff --git a/Data/include/Poco/Data/AbstractExtraction.h b/Data/include/Poco/Data/AbstractExtraction.h index 8176e5b56..d9644d2e9 100644 --- a/Data/include/Poco/Data/AbstractExtraction.h +++ b/Data/include/Poco/Data/AbstractExtraction.h @@ -49,7 +49,7 @@ public: typedef SharedPtr ExtractorPtr; typedef SharedPtr 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 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 AbstractExtractionVec; typedef std::vector AbstractExtractionVecVec; -typedef std::deque AbstractExtractionDeq; -typedef std::vector AbstractExtractionDeqVec; -typedef std::list AbstractExtractionLst; -typedef std::vector AbstractExtractionLstVec; - // // inlines diff --git a/Data/include/Poco/Data/BulkExtraction.h b/Data/include/Poco/Data/BulkExtraction.h index ea1b2ba5f..94779b6fe 100644 --- a/Data/include/Poco/Data/BulkExtraction.h +++ b/Data/include/Poco/Data/BulkExtraction.h @@ -47,7 +47,7 @@ public: typedef SharedPtr 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) { diff --git a/Data/include/Poco/Data/Extraction.h b/Data/include/Poco/Data/Extraction.h index ddc1f0830..c9b720f01 100644 --- a/Data/include/Poco/Data/Extraction.h +++ b/Data/include/Poco/Data/Extraction.h @@ -87,7 +87,7 @@ public: typedef SharedPtr 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 Ptr; Extraction(std::vector& rResult, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::vector).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default() { @@ -187,7 +187,7 @@ public: } Extraction(std::vector& rResult, const T& def, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::vector).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default(def) { @@ -269,7 +269,7 @@ public: typedef SharedPtr Ptr; Extraction(std::vector& rResult, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::vector).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default() { @@ -277,7 +277,7 @@ public: } Extraction(std::vector& rResult, const bool& def, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::vector).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default(def) { @@ -361,7 +361,7 @@ public: typedef SharedPtr Ptr; Extraction(std::list& rResult, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::list).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default() { @@ -369,7 +369,7 @@ public: } Extraction(std::list& rResult, const T& def, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::list).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default(def) { @@ -451,7 +451,7 @@ public: typedef SharedPtr Ptr; Extraction(std::deque& rResult, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::deque).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default() { @@ -459,7 +459,7 @@ public: } Extraction(std::deque& rResult, const T& def, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::deque).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default(def) { @@ -611,7 +611,7 @@ public: typedef typename ValType::iterator Iterator; Extraction(std::set& rResult, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::set).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default() { @@ -619,7 +619,7 @@ public: } Extraction(std::set& rResult, const T& def, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::set).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default(def) { @@ -675,7 +675,7 @@ public: typedef SharedPtr Ptr; Extraction(std::multiset& rResult, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::multiset).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default() { @@ -683,7 +683,7 @@ public: } Extraction(std::multiset& rResult, const T& def, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::multiset).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default(def) { @@ -739,7 +739,7 @@ public: typedef SharedPtr Ptr; Extraction(std::map& rResult, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::map).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default() { @@ -747,7 +747,7 @@ public: } Extraction(std::map& rResult, const V& def, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::map).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default(def) { @@ -803,7 +803,7 @@ public: typedef SharedPtr Ptr; Extraction(std::multimap& rResult, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::multimap).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default() { @@ -811,7 +811,7 @@ public: } Extraction(std::multimap& rResult, const V& def, const Position& pos = Position(0)): - AbstractExtraction(Limit::LIMIT_UNLIMITED, pos.value()), + AbstractExtraction(typeid(std::multimap).name(), Limit::LIMIT_UNLIMITED, pos.value()), _rResult(rResult), _default(def) { diff --git a/Data/include/Poco/Data/Position.h b/Data/include/Poco/Data/Position.h index 8301301b8..67b79a318 100644 --- a/Data/include/Poco/Data/Position.h +++ b/Data/include/Poco/Data/Position.h @@ -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; } diff --git a/Data/include/Poco/Data/RecordSet.h b/Data/include/Poco/Data/RecordSet.h index c722927b2..b0b7089af 100644 --- a/Data/include/Poco/Data/RecordSet.h +++ b/Data/include/Poco/Data/RecordSet.h @@ -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 @@ -469,11 +470,12 @@ private: } else { - throw Poco::BadCastException(Poco::format("Type cast failed!\nColumn: %z\nTarget type:\t%s" - "\nTarget container type:\t%s\nSource container 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(ExtractionVecPtr).name()), + rExtractions[pos]->type(), std::string(typeid(rExtractions[pos].get()).name()))); } } diff --git a/Data/src/AbstractExtraction.cpp b/Data/src/AbstractExtraction.cpp index a9bf42aff..7c047e570 100644 --- a/Data/src/AbstractExtraction.cpp +++ b/Data/src/AbstractExtraction.cpp @@ -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), diff --git a/Data/src/StatementImpl.cpp b/Data/src/StatementImpl.cpp index a7c0dd02d..a190401e0 100644 --- a/Data/src/StatementImpl.cpp +++ b/Data/src/StatementImpl.cpp @@ -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(currentDataSet())); + // type cast is needed when size_t is 64 bit + makeExtractors(count, static_cast(currentDataSet())); } void StatementImpl::makeExtractors(std::size_t count, const Position& position) diff --git a/Foundation/include/Poco/Types.h b/Foundation/include/Poco/Types.h index 23321d93f..3cdb9c76f 100644 --- a/Foundation/include/Poco/Types.h +++ b/Foundation/include/Poco/Types.h @@ -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 From 96bb22621ecefe1106c1559944801b9f4b12dfde Mon Sep 17 00:00:00 2001 From: Alex Fabijanic Date: Fri, 30 Jun 2017 16:13:56 +0200 Subject: [PATCH 3/4] fix RowFilter refcounting, some cleanup --- Data/ODBC/testsuite/src/ODBCOracleTest.cpp | 15 --- Data/ODBC/testsuite/src/ODBCOracleTest.h | 1 - Data/ODBC/testsuite/src/ODBCTest.cpp | 4 +- Data/ODBC/testsuite/src/SQLExecutor.cpp | 4 +- Data/ODBC/testsuite/src/SQLExecutor.h | 148 +-------------------- Data/include/Poco/Data/RowFilter.h | 13 +- Data/src/RowFilter.cpp | 13 +- 7 files changed, 28 insertions(+), 170 deletions(-) diff --git a/Data/ODBC/testsuite/src/ODBCOracleTest.cpp b/Data/ODBC/testsuite/src/ODBCOracleTest.cpp index 2139f2eac..375f6fd2f 100644 --- a/Data/ODBC/testsuite/src/ODBCOracleTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCOracleTest.cpp @@ -188,21 +188,6 @@ void ODBCOracleTest::testInternalExtraction() } -void ODBCOracleTest::testInternalBulkExtraction() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pSession->setFeature("autoBind", true); - _pSession->setFeature("autoExtract", true); -#ifdef POCO_ODBC_UNICODE - _pExecutor->internalBulkExtractionUTF16(0); -#else - _pExecutor->internalBulkExtraction(0); -#endif -} - - void ODBCOracleTest::testBLOB() { const std::size_t maxFldSize = 1000000; diff --git a/Data/ODBC/testsuite/src/ODBCOracleTest.h b/Data/ODBC/testsuite/src/ODBCOracleTest.h index be44bd45e..5fe2d86a7 100644 --- a/Data/ODBC/testsuite/src/ODBCOracleTest.h +++ b/Data/ODBC/testsuite/src/ODBCOracleTest.h @@ -37,7 +37,6 @@ public: void testBareboneODBC(); void testInternalExtraction(); - void testInternalBulkExtraction(); void testBLOB(); diff --git a/Data/ODBC/testsuite/src/ODBCTest.cpp b/Data/ODBC/testsuite/src/ODBCTest.cpp index 97932ce2c..df9232729 100644 --- a/Data/ODBC/testsuite/src/ODBCTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCTest.cpp @@ -989,9 +989,9 @@ void ODBCTest::testInternalBulkExtraction() _pSession->setFeature("autoBind", true); _pSession->setFeature("autoExtract", true); #ifdef POCO_ODBC_UNICODE - _pExecutor->internalBulkExtractionUTF16(0); + _pExecutor->internalBulkExtractionUTF16(); #else - _pExecutor->internalBulkExtraction(0); + _pExecutor->internalBulkExtraction(); #endif } diff --git a/Data/ODBC/testsuite/src/SQLExecutor.cpp b/Data/ODBC/testsuite/src/SQLExecutor.cpp index ee8500a30..6b20e153b 100644 --- a/Data/ODBC/testsuite/src/SQLExecutor.cpp +++ b/Data/ODBC/testsuite/src/SQLExecutor.cpp @@ -2811,7 +2811,7 @@ void SQLExecutor::filter(const std::string& query, const std::string& intFldName catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } } -/* + void SQLExecutor::internalBulkExtraction() { std::string funct = "internalBulkExtraction()"; @@ -2934,7 +2934,7 @@ void SQLExecutor::internalBulkExtractionUTF16() catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); } catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); } } -*/ + void SQLExecutor::internalStorageType() { diff --git a/Data/ODBC/testsuite/src/SQLExecutor.h b/Data/ODBC/testsuite/src/SQLExecutor.h index 01f23ff12..317ad12e0 100644 --- a/Data/ODBC/testsuite/src/SQLExecutor.h +++ b/Data/ODBC/testsuite/src/SQLExecutor.h @@ -698,151 +698,11 @@ public: } 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"); - template - void internalBulkExtraction(IntType) - { - using Poco::Data::RecordSet; - using Poco::NumberFormatter; - - std::string funct = "internalBulkExtraction()"; - int size = 100; - std::vector lastName(size); - std::vector firstName(size); - std::vector address(size); - std::vector age(size); - - for (int i = 0; i < size; ++i) - { - lastName[i] = "LN" + NumberFormatter::format(i); - firstName[i] = "FN" + NumberFormatter::format(i); - address[i] = "Addr" + NumberFormatter::format(i); - age[i] = i; - } - - try - { - session() << "INSERT INTO " << ExecUtil::person() <<" VALUES (?,?,?,?)", - use(lastName, bulk), - use(firstName, bulk), - use(address, bulk), - use(age, bulk), - now; - } - catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } - - try - { - Statement stmt = (session() << "SELECT * FROM " << ExecUtil::person(), bulk(size), now); - RecordSet rset(stmt); - assert (size == rset.rowCount()); - assert("LN0" == rset["LastName"]); - assert (0 == rset["Age"]); - rset.moveNext(); - assert("LN1" == rset["LastName"]); - assert(1 == rset["Age"]); - rset.moveLast(); - assert (std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]); - assert (size - 1 == rset["Age"]); - } - catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } - - try - { - Statement stmt = (session() << "SELECT * FROM " << ExecUtil::person(), limit(size), bulk, now); - RecordSet rset(stmt); - assert (size == rset.rowCount()); - assert ("LN0" == rset["LastName"]); - assert (0 == rset["Age"]); - rset.moveLast(); - assert (std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]); - assert (size - 1 == rset["Age"]); - } - catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); } - } - - template - void internalBulkExtractionUTF16(IntType) - { - using Poco::Data::RecordSet; - using Poco::UTF16String; - using Poco::NumberFormatter; - - std::string funct = "internalBulkExtraction()"; - int size = 100; - std::vector lastName(size); - std::vector firstName(size); - std::vector address(size); - std::vector age(size); - - for (int i = 0; i < size; ++i) - { - lastName[i] = Poco::UnicodeConverter::to("LN" + NumberFormatter::format(i)); - firstName[i] = Poco::UnicodeConverter::to("FN" + NumberFormatter::format(i)); - address[i] = Poco::UnicodeConverter::to("Addr" + NumberFormatter::format(i)); - age[i] = i; - } - - try - { - session() << "INSERT INTO " << ExecUtil::person() <<" VALUES (?,?,?,?)", - use(lastName, bulk), - use(firstName, bulk), - use(address, bulk), - use(age, bulk), - now; - } - catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); } - catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); } - - try - { - Statement stmt = (session() << "SELECT * FROM " << ExecUtil::person(), bulk(size), now); - RecordSet rset(stmt); - assert(size == rset.rowCount()); - assert(Poco::UnicodeConverter::to("LN0") == rset["LastName"]); - assert(0 == rset["Age"]); - rset.moveNext(); - assert(Poco::UnicodeConverter::to("LN1") == rset["LastName"]); - assert(1 == rset["Age"]); - rset.moveLast(); - assert(std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]); - assert(size - 1 == rset["Age"]); - } - catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); } - catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); } - - try - { - Statement stmt = (session() << "SELECT * FROM " << ExecUtil::person(), limit(size), bulk, now); - RecordSet rset(stmt); - assert(size == rset.rowCount()); - assert("LN0" == rset["LastName"]); - assert(0 == rset["Age"]); - rset.moveLast(); - assert(std::string("LN") + NumberFormatter::format(size - 1) == rset["LastName"]); - assert(size - 1 == rset["Age"]); - } - catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail(funct); } - catch (StatementException& se){ std::cout << se.toString() << std::endl; fail(funct); } - } + void internalBulkExtraction(); + void internalBulkExtractionUTF16(); void internalStorageType(); void nulls(bool emptyStrIsSpace = false); diff --git a/Data/include/Poco/Data/RowFilter.h b/Data/include/Poco/Data/RowFilter.h index be89607b6..f7ee19997 100644 --- a/Data/include/Poco/Data/RowFilter.h +++ b/Data/include/Poco/Data/RowFilter.h @@ -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 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; diff --git a/Data/src/RowFilter.cpp b/Data/src/RowFilter.cpp index 3d3de5f47..4c7db2592 100644 --- a/Data/src/RowFilter.cpp +++ b/Data/src/RowFilter.cpp @@ -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; } From 5cad99a7040fc6610a5ca5ed08cf81915f732faa Mon Sep 17 00:00:00 2001 From: Alex Fabijanic Date: Fri, 30 Jun 2017 16:51:07 +0200 Subject: [PATCH 4/4] fix test table name --- Data/MySQL/testsuite/src/MySQLTest.cpp | 4 +- Data/ODBC/testsuite/src/ODBCDB2Test.cpp | 4 +- Data/ODBC/testsuite/src/ODBCMySQLTest.cpp | 4 +- Data/ODBC/testsuite/src/ODBCOracleTest.cpp | 36 +++++++-------- .../ODBC/testsuite/src/ODBCPostgreSQLTest.cpp | 4 +- Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp | 4 +- Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp | 4 +- Data/ODBC/testsuite/src/ODBCSybaseTest.cpp | 4 +- Data/ODBC/testsuite/src/SQLExecutor.cpp | 44 +++++++++---------- Data/ODBC/testsuite/src/SQLExecutor.h | 5 +++ .../testsuite/src/PostgreSQLTest.cpp | 4 +- 11 files changed, 61 insertions(+), 56 deletions(-) diff --git a/Data/MySQL/testsuite/src/MySQLTest.cpp b/Data/MySQL/testsuite/src/MySQLTest.cpp index f8db41c99..18c932227 100644 --- a/Data/MySQL/testsuite/src/MySQLTest.cpp +++ b/Data/MySQL/testsuite/src/MySQLTest.cpp @@ -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()"); } } diff --git a/Data/ODBC/testsuite/src/ODBCDB2Test.cpp b/Data/ODBC/testsuite/src/ODBCDB2Test.cpp index 9dd16d3d9..cef5e8cb2 100644 --- a/Data/ODBC/testsuite/src/ODBCDB2Test.cpp +++ b/Data/ODBC/testsuite/src/ODBCDB2Test.cpp @@ -626,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()"); } } diff --git a/Data/ODBC/testsuite/src/ODBCMySQLTest.cpp b/Data/ODBC/testsuite/src/ODBCMySQLTest.cpp index 58fe6dc31..b977418e1 100644 --- a/Data/ODBC/testsuite/src/ODBCMySQLTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCMySQLTest.cpp @@ -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()"); } } diff --git a/Data/ODBC/testsuite/src/ODBCOracleTest.cpp b/Data/ODBC/testsuite/src/ODBCOracleTest.cpp index 375f6fd2f..a1913e0eb 100644 --- a/Data/ODBC/testsuite/src/ODBCOracleTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCOracleTest.cpp @@ -617,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); @@ -636,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); @@ -745,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()"); } } diff --git a/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.cpp b/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.cpp index 67ca19b12..e13345376 100644 --- a/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.cpp @@ -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()"); } } diff --git a/Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp b/Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp index 2b95ab449..d08cf03d3 100644 --- a/Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp @@ -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()"); } } diff --git a/Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp b/Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp index 4e7b600c9..91a0f50a5 100644 --- a/Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp @@ -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()"); } } diff --git a/Data/ODBC/testsuite/src/ODBCSybaseTest.cpp b/Data/ODBC/testsuite/src/ODBCSybaseTest.cpp index 145e60386..87debf885 100644 --- a/Data/ODBC/testsuite/src/ODBCSybaseTest.cpp +++ b/Data/ODBC/testsuite/src/ODBCSybaseTest.cpp @@ -205,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()"); } } diff --git a/Data/ODBC/testsuite/src/SQLExecutor.cpp b/Data/ODBC/testsuite/src/SQLExecutor.cpp index 6b20e153b..0791909a4 100644 --- a/Data/ODBC/testsuite/src/SQLExecutor.cpp +++ b/Data/ODBC/testsuite/src/SQLExecutor.cpp @@ -1517,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) { @@ -1525,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)); @@ -1591,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)); @@ -1616,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 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); @@ -1641,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 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); @@ -1662,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 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(); @@ -1695,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 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()); @@ -1738,12 +1738,12 @@ 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); @@ -3265,12 +3265,12 @@ void SQLExecutor::asynchronous(int rowCount) if (!_connInitSql.empty()) tmp << _connInitSql, now; std::vector 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); @@ -3288,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); @@ -3312,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); @@ -3324,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; @@ -3339,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); diff --git a/Data/ODBC/testsuite/src/SQLExecutor.h b/Data/ODBC/testsuite/src/SQLExecutor.h index 317ad12e0..137f3e342 100644 --- a/Data/ODBC/testsuite/src/SQLExecutor.h +++ b/Data/ODBC/testsuite/src/SQLExecutor.h @@ -88,6 +88,11 @@ struct ExecUtil return mangleTable("Strings"); } + static std::string ints() + { + return mangleTable("Ints"); + } + static std::string tuples() { return mangleTable("Tuples"); diff --git a/Data/PostgreSQL/testsuite/src/PostgreSQLTest.cpp b/Data/PostgreSQL/testsuite/src/PostgreSQLTest.cpp index c78b04cc7..deef3f3fa 100644 --- a/Data/PostgreSQL/testsuite/src/PostgreSQLTest.cpp +++ b/Data/PostgreSQL/testsuite/src/PostgreSQLTest.cpp @@ -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()"); } }