Skip to content

Commit

Permalink
MSTKPROJ-1416 fixed numeric fetching issues and sproc returning 0 emp…
Browse files Browse the repository at this point in the history
…ty result
  • Loading branch information
Kostya Lutsenko committed Apr 16, 2015
1 parent ea9e5e7 commit 6b2996d
Show file tree
Hide file tree
Showing 22 changed files with 557 additions and 297 deletions.
6 changes: 4 additions & 2 deletions Data/ODBC/include/Poco/Data/ODBC/Binder.h
Expand Up @@ -72,8 +72,9 @@ class ODBC_API Binder: public Poco::Data::AbstractBinder

Binder(const StatementHandle& rStmt,
std::size_t maxFieldSize,
ParameterBinding dataBinding = PB_IMMEDIATE,
TypeInfo* pDataTypes = 0);
ParameterBinding dataBinding,
TypeInfo* pDataTypes,
bool numericToString);
/// Creates the Binder.

~Binder();
Expand Down Expand Up @@ -1010,6 +1011,7 @@ class ODBC_API Binder: public Poco::Data::AbstractBinder
std::size_t _maxCharColLength;
std::size_t _maxWCharColLength;
std::size_t _maxVarBinColSize;
bool _numericToString;
};


Expand Down
4 changes: 2 additions & 2 deletions Data/ODBC/include/Poco/Data/ODBC/Extractor.h
Expand Up @@ -511,7 +511,7 @@ class ODBC_API Extractor: public Poco::Data::AbstractExtractor
bool extractImpl(std::size_t pos, T& val)
/// Utility function for extraction of Any and DynamicAny.
{
ODBCMetaColumn column(_rStmt, pos);
ODBCMetaColumn column(_rStmt, pos, _pPreparator->numericToString());

switch (column.type())
{
Expand Down Expand Up @@ -717,7 +717,7 @@ inline bool Extractor::isNullLengthIndicator(SQLLEN val) const

inline SQLINTEGER Extractor::columnSize(std::size_t pos) const
{
std::size_t size = ODBCMetaColumn(_rStmt, pos).length();
std::size_t size = ODBCMetaColumn(_rStmt, pos, _pPreparator->numericToString()).length();
std::size_t maxSize = _pPreparator->maxDataSize(pos);
if (size > maxSize) size = maxSize;
return (SQLINTEGER) size;
Expand Down
3 changes: 2 additions & 1 deletion Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h
Expand Up @@ -39,7 +39,7 @@ namespace ODBC {
class ODBC_API ODBCMetaColumn: public MetaColumn
{
public:
explicit ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position);
ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position, bool numericToString);
/// Creates the ODBCMetaColumn.

~ODBCMetaColumn();
Expand Down Expand Up @@ -73,6 +73,7 @@ class ODBC_API ODBCMetaColumn: public MetaColumn
SQLLEN _dataLength;
const StatementHandle& _rStmt;
ColumnDescription _columnDesc;
bool _numericToString;
};


Expand Down
1 change: 1 addition & 0 deletions Data/ODBC/include/Poco/Data/ODBC/ODBCStatementImpl.h
Expand Up @@ -156,6 +156,7 @@ class ODBC_API ODBCStatementImpl: public Poco::Data::StatementImpl
bool _prepared;
mutable std::size_t _affectedRowCount;
bool _canCompile;
bool _numericToString;
};


Expand Down
16 changes: 14 additions & 2 deletions Data/ODBC/include/Poco/Data/ODBC/Preparator.h
Expand Up @@ -101,7 +101,9 @@ class ODBC_API Preparator : public AbstractPreparator
Preparator(const StatementHandle& rStmt,
const std::string& statement,
std::size_t maxFieldSize,
DataExtraction dataExtraction = DE_BOUND);
DataExtraction dataExtraction,
bool numericToString
);
/// Creates the Preparator.

Preparator(const Preparator& other);
Expand Down Expand Up @@ -416,6 +418,9 @@ class ODBC_API Preparator : public AbstractPreparator
DataExtraction getDataExtraction() const;
/// Returns data extraction mode.

bool numericToString() const;
/// Tells if numeric values are always converted to string

private:
typedef std::vector<Poco::Any> ValueVec;
typedef std::vector<SQLLEN> LengthVec;
Expand All @@ -429,7 +434,7 @@ class ODBC_API Preparator : public AbstractPreparator
void prepareImpl(std::size_t pos, const C* pVal = 0)
/// Utility function to prepare Any and DynamicAny.
{
ODBCMetaColumn col(_rStmt, pos);
ODBCMetaColumn col(_rStmt, pos, _numericToString);

switch (col.type())
{
Expand Down Expand Up @@ -681,6 +686,7 @@ class ODBC_API Preparator : public AbstractPreparator
mutable IndexMap _varLengthArrays;
std::size_t _maxFieldSize;
DataExtraction _dataExtraction;
bool _numericToString;
};


Expand Down Expand Up @@ -1267,6 +1273,12 @@ inline Poco::Any& Preparator::at(std::size_t pos)
}


inline bool Preparator::numericToString() const
{
return _numericToString;
}


} } } // namespace Poco::Data::ODBC


Expand Down
40 changes: 40 additions & 0 deletions Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h
Expand Up @@ -45,6 +45,7 @@ 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_TO_STRING_FEATURE;

enum TransactionCapability
{
Expand Down Expand Up @@ -167,10 +168,24 @@ class ODBC_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
Poco::Any dataTypeInfo(const std::string& rName="");
/// Returns the data types information.

bool numericToString() const;
/// Tells if NUMERIC values to be always
/// converted to string

void setNumericToString(bool 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 setNumericToString(const std::string&, bool rValue);

bool numericToString(const std::string& nm);

void init();

static const int FUNCTIONS = SQL_API_ODBC3_ALL_FUNCTIONS_SIZE;

void checkError(SQLRETURN rc, const std::string& msg="");
Expand All @@ -184,6 +199,7 @@ class ODBC_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
Poco::Any _maxFieldSize;
bool _autoBind;
bool _autoExtract;
bool _numericToString;
TypeInfo _dataTypes;
char _canTransact;
bool _inTransaction;
Expand Down Expand Up @@ -286,6 +302,30 @@ inline int SessionImpl::queryTimeout() const
}


inline bool SessionImpl::numericToString() const
{
return _numericToString;
}


inline bool SessionImpl::numericToString(const std::string&)
{
return numericToString();
}


inline void SessionImpl::setNumericToString(bool value)
{
_numericToString = value;
}


inline void SessionImpl::setNumericToString(const std::string&, bool rValue)
{
setNumericToString(rValue);
}


} } } // namespace Poco::Data::ODBC


Expand Down
10 changes: 6 additions & 4 deletions Data/ODBC/src/Binder.cpp
Expand Up @@ -31,15 +31,17 @@ namespace ODBC {
Binder::Binder(const StatementHandle& rStmt,
std::size_t maxFieldSize,
Binder::ParameterBinding dataBinding,
TypeInfo* pDataTypes):
TypeInfo* pDataTypes,
bool numericToString) :
_rStmt(rStmt),
_paramBinding(dataBinding),
_pTypeInfo(pDataTypes),
_paramSetSize(0),
_maxFieldSize(maxFieldSize),
_maxCharColLength(1024),
_maxWCharColLength(1024),
_maxVarBinColSize(1024)
_maxVarBinColSize(1024),
_numericToString(numericToString)
{
const std::string NM("COLUMN_SIZE");
Poco::DynamicAny r;
Expand Down Expand Up @@ -474,7 +476,7 @@ void Binder::getColSizeAndPrecision(std::size_t pos,

try
{
ODBCMetaColumn c(_rStmt, pos);
ODBCMetaColumn c(_rStmt, pos, _numericToString);
colSize = (SQLINTEGER) c.length();
decDigits = (SQLSMALLINT) c.precision();
return;
Expand All @@ -495,7 +497,7 @@ void Binder::getColumnOrParameterSize(std::size_t pos, SQLINTEGER& size)

try
{
ODBCMetaColumn col(_rStmt, pos);
ODBCMetaColumn col(_rStmt, pos, _numericToString);
colSize = col.length();
}
catch (StatementException&) { }
Expand Down
40 changes: 32 additions & 8 deletions Data/ODBC/src/ODBCMetaColumn.cpp
Expand Up @@ -23,9 +23,10 @@ namespace Data {
namespace ODBC {


ODBCMetaColumn::ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position) :
ODBCMetaColumn::ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position, bool numericToString) :
MetaColumn(position),
_rStmt(rStmt)
_rStmt(rStmt),
_numericToString(numericToString)
{
init();
}
Expand Down Expand Up @@ -112,12 +113,35 @@ void ODBCMetaColumn::init()

case SQL_NUMERIC:
case SQL_DECIMAL:
if (0 == _columnDesc.decimalDigits)
setType(MetaColumn::FDT_INT32);
else
setType(MetaColumn::FDT_DOUBLE);

break;
{
bool toString = _numericToString;
if (!toString && 0 == _columnDesc.decimalDigits)
{
if (_columnDesc.size <= 9)
setType(MetaColumn::FDT_INT32);
else if (_columnDesc.size <= 18)
setType(MetaColumn::FDT_INT64);
else
toString = true;
}
else if (!toString)
{
if (_columnDesc.size > 16) // we can't have more than 16 digits in double
toString = true;
else
setType(MetaColumn::FDT_DOUBLE);
}
if (toString)
{
setLength(_columnDesc.size + 4);
#if defined(UNICODE)
setType(MetaColumn::FDT_WSTRING);
#else
setType(MetaColumn::FDT_STRING);
#endif
}
}
break;

case SQL_REAL:
setType(MetaColumn::FDT_FLOAT); break;
Expand Down
16 changes: 9 additions & 7 deletions Data/ODBC/src/ODBCStatementImpl.cpp
Expand Up @@ -46,7 +46,8 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
_nextResponse(0),
_prepared(false),
_affectedRowCount(0),
_canCompile(true)
_canCompile(true),
_numericToString(rSession.numericToString())
{
int queryTimeout = rSession.queryTimeout();
if (queryTimeout >= 0)
Expand Down Expand Up @@ -93,11 +94,12 @@ void ODBCStatementImpl::compileImpl()
{
Poco::Any dti = session().getProperty("dataTypeInfo");
pDT = AnyCast<TypeInfo*>(dti);
}catch (NotSupportedException&) { }
} catch (NotSupportedException&) { }

std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
const std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
const bool numericToString = dynamic_cast<SessionImpl&>(session()).numericToString();

_pBinder = new Binder(_stmt, maxFieldSize, bind, pDT);
_pBinder = new Binder(_stmt, maxFieldSize, bind, pDT, numericToString);

makeInternalExtractors();
doPrepare();
Expand Down Expand Up @@ -138,7 +140,7 @@ void ODBCStatementImpl::addPreparator()

std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));

_preparations.push_back(new Preparator(_stmt, statement, maxFieldSize, ext));
_preparations.push_back(new Preparator(_stmt, statement, maxFieldSize, ext, _numericToString));
}
else
_preparations.push_back(new Preparator(*_preparations[0]));
Expand Down Expand Up @@ -326,7 +328,7 @@ bool ODBCStatementImpl::hasNext()
if (nextResultSet()) {
addPreparator();
fillColumns(currentDataSet() + 1);
makeExtractors(_preparations.back()->columns(), currentDataSet() + 1);
makeExtractors(_preparations.back()->columns(), static_cast<Position::Position_Type>(currentDataSet() + 1));
activateNextDataSet();
}
else return false;
Expand Down Expand Up @@ -443,7 +445,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));
_columnPtrs[dataSetPos].push_back(new ODBCMetaColumn(_stmt, i, _numericToString));
}


Expand Down
11 changes: 7 additions & 4 deletions Data/ODBC/src/Preparator.cpp
Expand Up @@ -30,10 +30,12 @@ namespace ODBC {
Preparator::Preparator(const StatementHandle& rStmt,
const std::string& statement,
std::size_t maxFieldSize,
DataExtraction dataExtraction):
DataExtraction dataExtraction,
bool numericToString) :
_rStmt(rStmt),
_maxFieldSize(maxFieldSize),
_dataExtraction(dataExtraction)
_dataExtraction(dataExtraction),
_numericToString(numericToString)
{
SQLCHAR* pStr = (SQLCHAR*) statement.c_str();
if (Utility::isError(Poco::Data::ODBC::SQLPrepare(_rStmt, pStr, (SQLINTEGER) statement.length())))
Expand All @@ -44,7 +46,8 @@ Preparator::Preparator(const StatementHandle& rStmt,
Preparator::Preparator(const Preparator& other):
_rStmt(other._rStmt),
_maxFieldSize(other._maxFieldSize),
_dataExtraction(other._dataExtraction)
_dataExtraction(other._dataExtraction),
_numericToString(other._numericToString)
{
resize();
}
Expand Down Expand Up @@ -155,7 +158,7 @@ std::size_t Preparator::maxDataSize(std::size_t pos) const

try
{
ODBCMetaColumn mc(_rStmt, pos);
ODBCMetaColumn mc(_rStmt, pos, _numericToString);
sz = mc.length();

// accomodate for terminating zero (non-bulk only!)
Expand Down

0 comments on commit 6b2996d

Please sign in to comment.