data housekeeping

- removed naked pointers from Data interfaces
- fixed GH #82: name conflict in Data::Keywords::bind
- fixed GH #157: MySQL: cannot bind to 'long' data type on
Windows/Visual C++
- fixed GH #158: MySQL: MYSQL_BIND 'is_unsigned' member is not set
This commit is contained in:
Aleksandar Fabijanic
2013-04-28 12:34:07 -05:00
parent c6207985d8
commit a50823c5a8
34 changed files with 669 additions and 597 deletions

View File

@@ -71,8 +71,10 @@ class ODBC_API Extractor: public Poco::Data::AbstractExtractor
/// If NULL is received, the incoming val value is not changed and false is returned
{
public:
typedef Preparator::Ptr PreparatorPtr;
Extractor(const StatementHandle& rStmt,
Preparator& rPreparator);
Preparator::Ptr pPreparator);
/// Creates the Extractor.
~Extractor();
@@ -370,8 +372,8 @@ private:
bool extractBoundImpl(std::size_t pos, T& val)
{
if (isNull(pos)) return false;
poco_assert_dbg (typeid(T) == _rPreparator[pos].type());
val = *AnyCast<T>(&_rPreparator[pos]);
poco_assert_dbg (typeid(T) == _pPreparator->at(pos).type());
val = *AnyCast<T>(&_pPreparator->at(pos));
return true;
}
@@ -382,8 +384,8 @@ private:
bool extractBoundImplContainer(std::size_t pos, C& val)
{
typedef typename C::value_type Type;
poco_assert_dbg (typeid(std::vector<Type>) == _rPreparator[pos].type());
std::vector<Type>& v = RefAnyCast<std::vector<Type> >(_rPreparator[pos]);
poco_assert_dbg (typeid(std::vector<Type>) == _pPreparator->at(pos).type());
std::vector<Type>& v = RefAnyCast<std::vector<Type> >(_pPreparator->at(pos));
val.assign(v.begin(), v.end());
return true;
}
@@ -405,14 +407,14 @@ private:
typedef typename C::iterator ItType;
typedef typename StringType::value_type CharType;
CharType** pc = AnyCast<CharType*>(&_rPreparator[pos]);
CharType** pc = AnyCast<CharType*>(&(_pPreparator->at(pos)));
poco_assert_dbg (pc);
poco_assert_dbg (_rPreparator.bulkSize() == values.size());
poco_assert_dbg (_pPreparator->bulkSize() == values.size());
std::size_t colWidth = columnSize(pos);
ItType it = values.begin();
ItType end = values.end();
for (int row = 0; it != end; ++it, ++row)
it->assign(*pc + row * colWidth, _rPreparator.actualDataSize(pos, row));
it->assign(*pc + row * colWidth, _pPreparator->actualDataSize(pos, row));
return true;
}
@@ -424,14 +426,14 @@ private:
typedef typename LOBType::ValueType CharType;
typedef typename C::iterator ItType;
CharType** pc = AnyCast<CharType*>(&_rPreparator[pos]);
CharType** pc = AnyCast<CharType*>(&(_pPreparator->at(pos)));
poco_assert_dbg (pc);
poco_assert_dbg (_rPreparator.bulkSize() == values.size());
std::size_t colWidth = _rPreparator.maxDataSize(pos);
poco_assert_dbg (_pPreparator->bulkSize() == values.size());
std::size_t colWidth = _pPreparator->maxDataSize(pos);
ItType it = values.begin();
ItType end = values.end();
for (int row = 0; it != end; ++it, ++row)
it->assignRaw(*pc + row * colWidth, _rPreparator.actualDataSize(pos, row));
it->assignRaw(*pc + row * colWidth, _pPreparator->actualDataSize(pos, row));
return true;
}
@@ -441,9 +443,9 @@ private:
{
if (isNull(pos)) return false;
std::size_t dataSize = _rPreparator.actualDataSize(pos);
std::size_t dataSize = _pPreparator->actualDataSize(pos);
checkDataSize(dataSize);
T* sp = AnyCast<T*>(_rPreparator[pos]);
T* sp = AnyCast<T*>(_pPreparator->at(pos));
val.assignRaw(sp, dataSize);
return true;
@@ -569,10 +571,10 @@ private:
SQLINTEGER columnSize(std::size_t pos) const;
const StatementHandle& _rStmt;
Preparator& _rPreparator;
const StatementHandle& _rStmt;
PreparatorPtr _pPreparator;
Preparator::DataExtraction _dataExtraction;
std::vector<SQLLEN> _lengths;
std::vector<SQLLEN> _lengths;
};
@@ -654,7 +656,7 @@ inline bool Extractor::extractBoundImplContainer(std::size_t pos,
inline void Extractor::setDataExtraction(Preparator::DataExtraction ext)
{
_rPreparator.setDataExtraction(_dataExtraction = ext);
_pPreparator->setDataExtraction(_dataExtraction = ext);
}
@@ -686,7 +688,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 maxSize = _rPreparator.maxDataSize(pos);
std::size_t maxSize = _pPreparator->maxDataSize(pos);
if (size > maxSize) size = maxSize;
return (SQLINTEGER) size;
}

View File

@@ -104,10 +104,10 @@ protected:
void bindImpl();
/// Binds all parameters and executes the statement.
AbstractExtractor& extractor();
AbstractExtraction::ExtractorPtr extractor();
/// Returns the concrete extractor used by the statement.
AbstractBinder& binder();
AbstractBinding::BinderPtr binder();
/// Returns the concrete binder used by the statement.
std::string nativeSQL();
@@ -181,18 +181,18 @@ private:
//
// inlines
//
inline AbstractExtractor& ODBCStatementImpl::extractor()
inline AbstractExtraction::ExtractorPtr ODBCStatementImpl::extractor()
{
poco_assert_dbg (currentDataSet() < _extractors.size());
poco_assert_dbg (_extractors[currentDataSet()]);
return *_extractors[currentDataSet()];
return _extractors[currentDataSet()];
}
inline AbstractBinder& ODBCStatementImpl::binder()
inline AbstractBinding::BinderPtr ODBCStatementImpl::binder()
{
poco_assert_dbg (_pBinder);
return *_pBinder;
poco_assert_dbg (!_pBinder.isNull());
return _pBinder;
}

View File

@@ -81,9 +81,9 @@ class ODBC_API Preparator : public AbstractPreparator
///
/// Preparator object is used to :
///
/// 1) Prepare SQL statement.
/// 2) Provide and contain the memory locations where retrieved values are placed during recordset iteration.
/// 3) Keep count of returned number of columns with their respective datatypes and sizes.
/// 1) Prepare SQL statement.
/// 2) Provide and contain the memory locations where retrieved values are placed during recordset iteration.
/// 3) Keep count of returned number of columns with their respective datatypes and sizes.
///
/// Notes:
///
@@ -94,6 +94,7 @@ class ODBC_API Preparator : public AbstractPreparator
{
public:
typedef std::vector<char*> CharArray;
typedef SharedPtr<Preparator> Ptr;
enum DataExtraction
{
@@ -390,6 +391,9 @@ public:
Poco::Any& operator [] (std::size_t pos);
/// Returns reference to column data.
Poco::Any& at(std::size_t pos);
/// Returns reference to column data.
void setMaxFieldSize(std::size_t size);
/// Sets maximum supported field size.
@@ -1224,6 +1228,12 @@ inline Preparator::DataExtraction Preparator::getDataExtraction() const
inline Poco::Any& Preparator::operator [] (std::size_t pos)
{
return at(pos);
}
inline Poco::Any& Preparator::at(std::size_t pos)
{
return _values.at(pos);
}

View File

@@ -55,10 +55,10 @@ const std::string Extractor::FLD_SIZE_EXCEEDED_FMT = "Specified data size (%z by
Extractor::Extractor(const StatementHandle& rStmt,
Preparator& rPreparator):
Preparator::Ptr pPreparator):
_rStmt(rStmt),
_rPreparator(rPreparator),
_dataExtraction(rPreparator.getDataExtraction())
_pPreparator(pPreparator),
_dataExtraction(pPreparator->getDataExtraction())
{
}
@@ -73,8 +73,8 @@ bool Extractor::extractBoundImpl<std::string>(std::size_t pos, std::string& val)
{
if (isNull(pos)) return false;
std::size_t dataSize = _rPreparator.actualDataSize(pos);
char* sp = AnyCast<char*>(_rPreparator[pos]);
std::size_t dataSize = _pPreparator->actualDataSize(pos);
char* sp = AnyCast<char*>(_pPreparator->at(pos));
std::size_t len = std::strlen(sp);
if (len < dataSize) dataSize = len;
checkDataSize(dataSize);
@@ -88,7 +88,7 @@ template<>
bool Extractor::extractBoundImpl<Poco::Data::Date>(std::size_t pos, Poco::Data::Date& val)
{
if (isNull(pos)) return false;
SQL_DATE_STRUCT& ds = *AnyCast<SQL_DATE_STRUCT>(&_rPreparator[pos]);
SQL_DATE_STRUCT& ds = *AnyCast<SQL_DATE_STRUCT>(&(_pPreparator->at(pos)));
Utility::dateSync(val, ds);
return true;
}
@@ -98,7 +98,7 @@ template<>
bool Extractor::extractBoundImplContainer<std::vector<Poco::Data::Date> >(std::size_t pos,
std::vector<Poco::Data::Date>& val)
{
std::vector<SQL_DATE_STRUCT>& ds = RefAnyCast<std::vector<SQL_DATE_STRUCT> >(_rPreparator[pos]);
std::vector<SQL_DATE_STRUCT>& ds = RefAnyCast<std::vector<SQL_DATE_STRUCT> >(_pPreparator->at(pos));
Utility::dateSync(val, ds);
return true;
}
@@ -108,7 +108,7 @@ template<>
bool Extractor::extractBoundImplContainer<std::deque<Poco::Data::Date> >(std::size_t pos,
std::deque<Poco::Data::Date>& val)
{
std::vector<SQL_DATE_STRUCT>& ds = RefAnyCast<std::vector<SQL_DATE_STRUCT> >(_rPreparator[pos]);
std::vector<SQL_DATE_STRUCT>& ds = RefAnyCast<std::vector<SQL_DATE_STRUCT> >(_pPreparator->at(pos));
Utility::dateSync(val, ds);
return true;
}
@@ -118,7 +118,7 @@ template<>
bool Extractor::extractBoundImplContainer<std::list<Poco::Data::Date> >(std::size_t pos,
std::list<Poco::Data::Date>& val)
{
std::vector<SQL_DATE_STRUCT>& ds = RefAnyCast<std::vector<SQL_DATE_STRUCT> >(_rPreparator[pos]);
std::vector<SQL_DATE_STRUCT>& ds = RefAnyCast<std::vector<SQL_DATE_STRUCT> >(_pPreparator->at(pos));
Utility::dateSync(val, ds);
return true;
}
@@ -129,9 +129,9 @@ bool Extractor::extractBoundImpl<Poco::Data::Time>(std::size_t pos, Poco::Data::
{
if (isNull(pos)) return false;
std::size_t dataSize = _rPreparator.actualDataSize(pos);
std::size_t dataSize = _pPreparator->actualDataSize(pos);
checkDataSize(dataSize);
SQL_TIME_STRUCT& ts = *AnyCast<SQL_TIME_STRUCT>(&_rPreparator[pos]);
SQL_TIME_STRUCT& ts = *AnyCast<SQL_TIME_STRUCT>(&_pPreparator->at(pos));
Utility::timeSync(val, ts);
return true;
@@ -142,7 +142,7 @@ template<>
bool Extractor::extractBoundImplContainer<std::vector<Poco::Data::Time> >(std::size_t pos,
std::vector<Poco::Data::Time>& val)
{
std::vector<SQL_TIME_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIME_STRUCT> >(_rPreparator[pos]);
std::vector<SQL_TIME_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIME_STRUCT> >(_pPreparator->at(pos));
Utility::timeSync(val, ds);
return true;
}
@@ -152,7 +152,7 @@ template<>
bool Extractor::extractBoundImplContainer<std::deque<Poco::Data::Time> >(std::size_t pos,
std::deque<Poco::Data::Time>& val)
{
std::vector<SQL_TIME_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIME_STRUCT> >(_rPreparator[pos]);
std::vector<SQL_TIME_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIME_STRUCT> >(_pPreparator->at(pos));
Utility::timeSync(val, ds);
return true;
}
@@ -162,7 +162,7 @@ template<>
bool Extractor::extractBoundImplContainer<std::list<Poco::Data::Time> >(std::size_t pos,
std::list<Poco::Data::Time>& val)
{
std::vector<SQL_TIME_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIME_STRUCT> >(_rPreparator[pos]);
std::vector<SQL_TIME_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIME_STRUCT> >(_pPreparator->at(pos));
Utility::timeSync(val, ds);
return true;
}
@@ -173,9 +173,9 @@ bool Extractor::extractBoundImpl<Poco::DateTime>(std::size_t pos, Poco::DateTime
{
if (isNull(pos)) return false;
std::size_t dataSize = _rPreparator.actualDataSize(pos);
std::size_t dataSize = _pPreparator->actualDataSize(pos);
checkDataSize(dataSize);
SQL_TIMESTAMP_STRUCT& tss = *AnyCast<SQL_TIMESTAMP_STRUCT>(&_rPreparator[pos]);
SQL_TIMESTAMP_STRUCT& tss = *AnyCast<SQL_TIMESTAMP_STRUCT>(&_pPreparator->at(pos));
Utility::dateTimeSync(val, tss);
return true;
@@ -186,7 +186,7 @@ template<>
bool Extractor::extractBoundImplContainer<std::vector<Poco::DateTime> >(std::size_t pos,
std::vector<Poco::DateTime>& val)
{
std::vector<SQL_TIMESTAMP_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIMESTAMP_STRUCT> >(_rPreparator[pos]);
std::vector<SQL_TIMESTAMP_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIMESTAMP_STRUCT> >(_pPreparator->at(pos));
Utility::dateTimeSync(val, ds);
return true;
}
@@ -196,7 +196,7 @@ template<>
bool Extractor::extractBoundImplContainer<std::deque<Poco::DateTime> >(std::size_t pos,
std::deque<Poco::DateTime>& val)
{
std::vector<SQL_TIMESTAMP_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIMESTAMP_STRUCT> >(_rPreparator[pos]);
std::vector<SQL_TIMESTAMP_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIMESTAMP_STRUCT> >(_pPreparator->at(pos));
Utility::dateTimeSync(val, ds);
return true;
}
@@ -206,7 +206,7 @@ template<>
bool Extractor::extractBoundImplContainer<std::list<Poco::DateTime> >(std::size_t pos,
std::list<Poco::DateTime>& val)
{
std::vector<SQL_TIMESTAMP_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIMESTAMP_STRUCT> >(_rPreparator[pos]);
std::vector<SQL_TIMESTAMP_STRUCT>& ds = RefAnyCast<std::vector<SQL_TIMESTAMP_STRUCT> >(_pPreparator->at(pos));
Utility::dateTimeSync(val, ds);
return true;
}
@@ -216,8 +216,8 @@ template<>
bool Extractor::extractBoundImplContainer<std::vector<bool> >(std::size_t pos,
std::vector<bool>& val)
{
std::size_t length = _rPreparator.getLength();
bool** p = AnyCast<bool*>(&_rPreparator[pos]);
std::size_t length = _pPreparator->getLength();
bool** p = AnyCast<bool*>(&_pPreparator->at(pos));
val.assign(*p, *p + length);
return true;
}
@@ -227,8 +227,8 @@ template<>
bool Extractor::extractBoundImplContainer<std::deque<bool> >(std::size_t pos,
std::deque<bool>& val)
{
std::size_t length = _rPreparator.getLength();
bool** p = AnyCast<bool*>(&_rPreparator[pos]);
std::size_t length = _pPreparator->getLength();
bool** p = AnyCast<bool*>(&_pPreparator->at(pos));
val.assign(*p, *p + length);
return true;
}
@@ -238,8 +238,8 @@ template<>
bool Extractor::extractBoundImplContainer<std::list<bool> >(std::size_t pos,
std::list<bool>& val)
{
std::size_t length = _rPreparator.getLength();
bool** p = AnyCast<bool*>(&_rPreparator[pos]);
std::size_t length = _pPreparator->getLength();
bool** p = AnyCast<bool*>(&_pPreparator->at(pos));
val.assign(*p, *p + length);
return true;
}
@@ -248,7 +248,7 @@ bool Extractor::extractBoundImplContainer<std::list<bool> >(std::size_t pos,
template<>
bool Extractor::extractManualImpl<std::string>(std::size_t pos, std::string& val, SQLSMALLINT cType)
{
std::size_t maxSize = _rPreparator.getMaxFieldSize();
std::size_t maxSize = _pPreparator->getMaxFieldSize();
std::size_t fetchedSize = 0;
std::size_t totalSize = 0;
@@ -304,7 +304,7 @@ bool Extractor::extractManualImpl<Poco::Data::CLOB>(std::size_t pos,
Poco::Data::CLOB& val,
SQLSMALLINT cType)
{
std::size_t maxSize = _rPreparator.getMaxFieldSize();
std::size_t maxSize = _pPreparator->getMaxFieldSize();
std::size_t fetchedSize = 0;
std::size_t totalSize = 0;
@@ -1209,13 +1209,13 @@ bool Extractor::isNull(std::size_t col, std::size_t row)
}
}
else
return SQL_NULL_DATA == _rPreparator.actualDataSize(col, row);
return SQL_NULL_DATA == _pPreparator->actualDataSize(col, row);
}
void Extractor::checkDataSize(std::size_t size)
{
std::size_t maxSize = _rPreparator.getMaxFieldSize();
std::size_t maxSize = _pPreparator->getMaxFieldSize();
if (size > maxSize)
throw DataException(format(FLD_SIZE_EXCEEDED_FMT, size, maxSize));
}

View File

@@ -163,7 +163,7 @@ void ODBCStatementImpl::addPreparator()
else
_preparations.push_back(new Preparator(*_preparations[0]));
_extractors.push_back(new Extractor(_stmt, *_preparations.back()));
_extractors.push_back(new Extractor(_stmt, _preparations.back()));
}
@@ -189,10 +189,10 @@ void ODBCStatementImpl::doPrepare()
for (std::size_t pos = 0; it != itEnd; ++it)
{
AbstractPreparation* pAP = (*it)->createPreparation(_preparations[curDataSet], pos);
Poco::Data::AbstractPreparator::Ptr pP = _preparations[curDataSet];
std::auto_ptr<AbstractPreparation> pAP((*it)->createPreparation(pP, pos));
pAP->prepare();
pos += (*it)->numOfColumnsHandled();
delete pAP;
}
_prepared = true;