mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-09-14 12:07:09 +02:00
Major plugin refactor and cleanup.
Switched to POCO library for unified platform/library interface. Deprecated the external module API. It was creating more problems than solving. Removed most built-in libraries in favor of system libraries for easier maintenance. Cleaned and secured code with help from static analyzers.
This commit is contained in:
667
vendor/POCO/Data/PostgreSQL/src/Binder.cpp
vendored
Normal file
667
vendor/POCO/Data/PostgreSQL/src/Binder.cpp
vendored
Normal file
@@ -0,0 +1,667 @@
|
||||
//
|
||||
// Binder.cpp
|
||||
//
|
||||
// Library: Data/PostgreSQL
|
||||
// Package: PostgreSQL
|
||||
// Module: Binder
|
||||
//
|
||||
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/PostgreSQL/Binder.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include "Poco/DateTimeFormat.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace PostgreSQL {
|
||||
|
||||
|
||||
Binder::Binder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Binder::~Binder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Poco::Int8& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_INT8, &val, sizeof(Poco::Int8));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Poco::UInt8& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_UINT8, &val, sizeof(Poco::UInt8));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Poco::Int16& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_INT16, &val, sizeof(Poco::Int16));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Poco::UInt16& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_UINT16, &val, sizeof(Poco::UInt16));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Poco::Int32& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_INT32, &val, sizeof(Poco::Int32));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Poco::UInt32& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_UINT32, &val, sizeof(Poco::UInt32));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Poco::Int64& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_INT64, &val, sizeof(Poco::Int64));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Poco::UInt64& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_UINT64, &val, sizeof(Poco::UInt64));
|
||||
}
|
||||
|
||||
|
||||
#ifndef POCO_INT64_IS_LONG
|
||||
void Binder::bind(std::size_t pos, const long& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_INT64, &val, sizeof(Poco::Int64));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const unsigned long& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_UINT64, &val, sizeof(Poco::UInt64));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const bool& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_BOOL, &val, sizeof(bool));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const float& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_FLOAT, &val, sizeof(float));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const double& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_DOUBLE, &val, sizeof(double));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const char& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
// USING UINT8 because Poco::Data::MetaColumn does not have a single character type, just std::string
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_UINT8, &val, sizeof(char));
|
||||
}
|
||||
|
||||
// complex types
|
||||
|
||||
void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_STRING, &val, static_cast<int>(val.size()));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_BLOB, &val, static_cast<int>(val.size()));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Poco::Data::CLOB& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_CLOB, &val, static_cast<int>(val.size()));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Poco::DateTime& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_TIMESTAMP, &val, sizeof(Poco::DateTime));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Date& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_DATE, &val, sizeof(Date));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const Time& val, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_TIME, &val, sizeof(Time));
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t pos, const NullData&, Direction dir)
|
||||
{
|
||||
poco_assert(dir == PD_IN);
|
||||
realBind(pos, Poco::Data::MetaColumn::FDT_UNKNOWN, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
std::size_t Binder::size() const
|
||||
{
|
||||
return static_cast<std::size_t>(_bindVector.size());
|
||||
}
|
||||
|
||||
|
||||
InputParameterVector
|
||||
Binder::bindVector() const
|
||||
{
|
||||
return _bindVector;
|
||||
}
|
||||
|
||||
|
||||
void Binder::updateBindVectorToCurrentValues()
|
||||
{
|
||||
InputParameterVector::iterator itr = _bindVector.begin();
|
||||
InputParameterVector::iterator itrEnd = _bindVector.end();
|
||||
|
||||
for (; itr != itrEnd; ++itr)
|
||||
{
|
||||
switch (itr->fieldType())
|
||||
{
|
||||
case Poco::Data::MetaColumn::FDT_INT8:
|
||||
itr->setStringVersionRepresentation(Poco::NumberFormatter::format(* static_cast<const Poco::Int8*>(itr->pData())));
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_UINT8:
|
||||
itr->setStringVersionRepresentation(Poco::NumberFormatter::format(* static_cast<const Poco::UInt8*>(itr->pData())));
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_INT16:
|
||||
itr->setStringVersionRepresentation(Poco::NumberFormatter::format(* static_cast<const Poco::Int16*>(itr->pData())));
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_UINT16:
|
||||
itr->setStringVersionRepresentation(Poco::NumberFormatter::format(* static_cast<const Poco::UInt16*>(itr->pData())));
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_INT32:
|
||||
itr->setStringVersionRepresentation(Poco::NumberFormatter::format(* static_cast<const Poco::Int32*>(itr->pData())));
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_UINT32:
|
||||
itr->setStringVersionRepresentation(Poco::NumberFormatter::format(* static_cast<const Poco::UInt32*>(itr->pData())));
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_INT64:
|
||||
itr->setStringVersionRepresentation(Poco::NumberFormatter::format(* static_cast<const Poco::Int64*>(itr->pData())));
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_UINT64:
|
||||
itr->setStringVersionRepresentation(Poco::NumberFormatter::format(* static_cast<const Poco::UInt64*>(itr->pData())));
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_BOOL:
|
||||
{
|
||||
const bool currentBoolValue = * static_cast<const bool*>(itr->pData());
|
||||
itr->setStringVersionRepresentation(currentBoolValue ? "TRUE" : "FALSE");
|
||||
}
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_FLOAT:
|
||||
itr->setStringVersionRepresentation(Poco::NumberFormatter::format(* static_cast<const float*>(itr->pData())));
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_DOUBLE:
|
||||
itr->setStringVersionRepresentation(Poco::NumberFormatter::format(* static_cast<const double*>(itr->pData())));
|
||||
break;
|
||||
|
||||
// case Poco::Data::MetaColumn::FDT_CHAR:
|
||||
// itr->setStringVersionRepresentation(std::string(static_cast<const char*>(itr->pData()), 1)); // single character string
|
||||
// break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_STRING:
|
||||
itr->setStringVersionRepresentation(* static_cast<const std::string*>(itr->pData()));
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_TIMESTAMP:
|
||||
{
|
||||
const Poco::DateTime& dateTime = * static_cast<const Poco::DateTime*>(itr->pData());
|
||||
itr->setStringVersionRepresentation(DateTimeFormatter::format(dateTime, Poco::DateTimeFormat::ISO8601_FRAC_FORMAT));
|
||||
}
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_DATE:
|
||||
{
|
||||
const Poco::Data::Date& date = * static_cast<const Poco::Data::Date*>(itr->pData());
|
||||
itr->setStringVersionRepresentation(DateTimeFormatter::format(Poco::DateTime(date.year(), date.month(), date.day()), "%Y-%m-%d"));
|
||||
}
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_TIME:
|
||||
{
|
||||
const Poco::Data::Time& time = * static_cast<const Poco::Data::Time*>(itr->pData());
|
||||
itr->setStringVersionRepresentation(DateTimeFormatter::format(Poco::DateTime(0, 1, 1, time.hour(), time.minute(), time.second()), "%H:%M:%s%z"));
|
||||
}
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_BLOB:
|
||||
{
|
||||
const Poco::Data::BLOB& blob = * static_cast<const Poco::Data::BLOB*>(itr->pData());
|
||||
itr->setNonStringVersionRepresentation(static_cast<const void*> (blob.rawContent()), blob.size());
|
||||
}
|
||||
break;
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_CLOB:
|
||||
{
|
||||
const Poco::Data::CLOB& clob = * static_cast<const Poco::Data::CLOB*>(itr->pData());
|
||||
itr->setNonStringVersionRepresentation(static_cast<const void*> (clob.rawContent()), clob.size());
|
||||
}
|
||||
|
||||
case Poco::Data::MetaColumn::FDT_UNKNOWN:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Binder::realBind(std::size_t aPosition, Poco::Data::MetaColumn::ColumnDataType aFieldType, const void* aBufferPtr, std::size_t aLength)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (aPosition >= _bindVector.size())
|
||||
{
|
||||
_bindVector.resize(aPosition + 1);
|
||||
}
|
||||
|
||||
InputParameter inputParameter(aFieldType, aBufferPtr, aLength);
|
||||
|
||||
_bindVector[aPosition] = inputParameter;
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
PostgreSQLException("Memory allocation error while binding");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::Int8>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::Int8>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::Int8>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::UInt8>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::UInt8>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::UInt8>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::Int16>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::Int16>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::Int16>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::UInt16>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::UInt16>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::UInt16>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::Int32>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::Int32>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::Int32>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::UInt32>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::UInt32>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::UInt32>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::Int64>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::Int64>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::Int64>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::UInt64>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::UInt64>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::UInt64>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<bool>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<bool>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<bool>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<float>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<float>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<float>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<double>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<double>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<double>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<char>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<char>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<char>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::Data::BLOB>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::Data::BLOB>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::Data::BLOB>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::Data::CLOB>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::Data::CLOB>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::Data::CLOB>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::DateTime>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::DateTime>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::DateTime>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::Data::Date>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::Data::Date>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::Data::Date>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::Data::Time>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::Data::Time>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::Data::Time>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<Poco::Data::NullData>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<Poco::Data::NullData>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<Poco::Data::NullData>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::vector<std::string>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::deque<std::string>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
void Binder::bind(std::size_t /*pos*/, const std::list<std::string>& /*val*/, Direction /*dir*/)
|
||||
{
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::PostgreSQL
|
62
vendor/POCO/Data/PostgreSQL/src/Connector.cpp
vendored
Normal file
62
vendor/POCO/Data/PostgreSQL/src/Connector.cpp
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// Connector.cpp
|
||||
//
|
||||
// Library: Data/PostgreSQL
|
||||
// Package: PostgreSQL
|
||||
// Module: Connector
|
||||
//
|
||||
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/PostgreSQL/Connector.h"
|
||||
#include "Poco/Data/PostgreSQL/SessionImpl.h"
|
||||
#include "Poco/Data/SessionFactory.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace PostgreSQL {
|
||||
|
||||
|
||||
const std::string Connector::KEY("postgresql");
|
||||
|
||||
|
||||
Connector::Connector()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Connector::~Connector()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const std::string& Connector::name() const
|
||||
{
|
||||
return KEY;
|
||||
}
|
||||
|
||||
|
||||
SessionImpl::Ptr Connector::createSession(const std::string& aConnectionString, std::size_t aTimeout)
|
||||
{
|
||||
return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(aConnectionString, aTimeout));
|
||||
}
|
||||
|
||||
|
||||
void Connector::registerConnector()
|
||||
{
|
||||
Poco::Data::SessionFactory::instance().add(new Connector());
|
||||
}
|
||||
|
||||
|
||||
void Connector::unregisterConnector()
|
||||
{
|
||||
Poco::Data::SessionFactory::instance().remove(KEY);
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::PostgreSQL
|
870
vendor/POCO/Data/PostgreSQL/src/Extractor.cpp
vendored
Normal file
870
vendor/POCO/Data/PostgreSQL/src/Extractor.cpp
vendored
Normal file
@@ -0,0 +1,870 @@
|
||||
//
|
||||
// Extractor.cpp
|
||||
//
|
||||
// Library: Data/PostgreSQL
|
||||
// Package: PostgreSQL
|
||||
// Module: Extractor
|
||||
//
|
||||
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/PostgreSQL/Extractor.h"
|
||||
#include "Poco/Data/Date.h"
|
||||
#include "Poco/Data/Time.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/DateTimeParser.h"
|
||||
#include <limits>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace PostgreSQL {
|
||||
|
||||
|
||||
Extractor::Extractor(StatementExecutor& st /*, ResultMetadata& md */):
|
||||
_statementExecutor (st)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Extractor::~Extractor()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Int8& val)
|
||||
{
|
||||
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
int tempVal = 0;
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParse(outputParameter.pData(), tempVal)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = static_cast<Int8>(tempVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::UInt8& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
unsigned int tempVal = 0;
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), tempVal)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = static_cast<Int8>(tempVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Int16& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
int tempVal = 0;
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParse(outputParameter.pData(), tempVal)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = static_cast<Int8>(tempVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::UInt16& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
unsigned int tempVal = 0;
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), tempVal)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = static_cast<Int8>(tempVal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Int32& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParse(outputParameter.pData(), val)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::UInt32& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), val)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Int64& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParse64(outputParameter.pData(), val)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::UInt64& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseUnsigned64(outputParameter.pData(), val)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#ifndef POCO_INT64_IS_LONG
|
||||
bool Extractor::extract(std::size_t pos, long& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
Poco::Int64 tempVal = 0;
|
||||
|
||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParse64(outputParameter.pData(), tempVal)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = (long)tempVal;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, unsigned long& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
Poco::UInt64 tempVal = 0;
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseUnsigned64(outputParameter.pData(), tempVal)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = (unsigned long)tempVal;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, bool& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if ( isColumnNull(outputParameter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ('t' == *outputParameter.pData())
|
||||
{
|
||||
val = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, float& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
double tempVal = 0.0;
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseFloat(outputParameter.pData(), tempVal)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = (float)tempVal;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, double& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if ( isColumnNull(outputParameter)
|
||||
|| ! Poco::NumberParser::tryParseFloat(outputParameter.pData(), val)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, char& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if (isColumnNull(outputParameter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = *outputParameter.pData();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, std::string& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if (isColumnNull(outputParameter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val.assign(outputParameter.pData(), outputParameter.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if (isColumnNull(outputParameter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// convert the PostgreSQL text format to binary and append to the BLOB
|
||||
// Format: \x10843029479abcf ... two characters for every byte
|
||||
//
|
||||
// The code below can be made more efficient by converting more than one byte at a time
|
||||
// also if BLOB had a resize method it would be useful to allocate memory in one
|
||||
// attempt.
|
||||
//
|
||||
|
||||
const char * pBLOB = reinterpret_cast<const char*>(outputParameter.pData());
|
||||
std::size_t BLOBSize = outputParameter.size();
|
||||
|
||||
if ( '\\' == pBLOB[0]
|
||||
&& 'x' == pBLOB[1] // preamble to BYTEA data format in text form is \x
|
||||
)
|
||||
{
|
||||
BLOBSize -= 2; // lose the preamble
|
||||
BLOBSize /= 2; // each byte is encoded as two text characters
|
||||
|
||||
for (int i = 0; i < BLOBSize * 2; i += 2)
|
||||
{
|
||||
std::string buffer(&pBLOB[i + 2], 2);
|
||||
unsigned int binaryBuffer = 0;
|
||||
if (Poco::NumberParser::tryParseHex(buffer, binaryBuffer))
|
||||
{
|
||||
UInt8 finalBinaryBuffer = static_cast<UInt8>(binaryBuffer); // downsize
|
||||
val.appendRaw(&finalBinaryBuffer, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Poco::Data::CLOB& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if (isColumnNull(outputParameter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val.assignRaw(outputParameter.pData(), outputParameter.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, DateTime& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if (isColumnNull(outputParameter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int tzd = -1;
|
||||
DateTime dateTime;
|
||||
|
||||
if (! DateTimeParser::tryParse(outputParameter.pData(), dateTime, tzd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
dateTime.makeUTC(tzd);
|
||||
|
||||
val = dateTime;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Date& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if (isColumnNull(outputParameter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int tzd = -1;
|
||||
DateTime dateTime;
|
||||
|
||||
if (! DateTimeParser::tryParse(outputParameter.pData(), dateTime, tzd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
dateTime.makeUTC(tzd);
|
||||
|
||||
val.assign(dateTime.year(), dateTime.month(), dateTime.day());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Time& val)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(pos);
|
||||
|
||||
if (isColumnNull(outputParameter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int tzd = -1;
|
||||
DateTime dateTime;
|
||||
|
||||
if (! DateTimeParser::tryParse("%H:%M:%s%z", outputParameter.pData(), dateTime, tzd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// dateTime.makeUTC(tzd); // TODO
|
||||
// Note: Poco::Data::Time should be extended to support the fractional components of Poco::DateTime
|
||||
|
||||
val.assign(dateTime.hour(), dateTime.minute(), dateTime.second());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Any& val)
|
||||
{
|
||||
return extractStringImpl (pos, val);
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t pos, Dynamic::Var& val)
|
||||
{
|
||||
return extractStringImpl (pos, val);
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::isNull(std::size_t col, std::size_t /*row*/)
|
||||
{
|
||||
OutputParameter outputParameter = extractPreamble(col);
|
||||
|
||||
if (isColumnNull(outputParameter))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Extractor::reset()
|
||||
{
|
||||
AbstractExtractor::reset();
|
||||
}
|
||||
|
||||
|
||||
const OutputParameter&
|
||||
Extractor::extractPreamble(std::size_t aPosition) const
|
||||
{
|
||||
if (_statementExecutor.columnsReturned() <= aPosition)
|
||||
{
|
||||
throw PostgreSQLException("Extractor: attempt to extract more parameters than query result contains");
|
||||
}
|
||||
|
||||
return _statementExecutor.resultColumn(aPosition);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Extractor::isColumnNull (const OutputParameter& anOutputParameter) const
|
||||
{
|
||||
return anOutputParameter.isNull()
|
||||
|| 0 == anOutputParameter.pData();
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
// Not implemented
|
||||
//////////////
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::Int8>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::Int8>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::Int8>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::UInt8>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::UInt8>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::UInt8>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::Int16>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::Int16>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::Int16>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::UInt16>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::UInt16>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::UInt16>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::Int32>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::Int32>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::Int32>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::UInt32>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::UInt32>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::UInt32>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::Int64>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::Int64>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::Int64>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Poco::UInt64>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Poco::UInt64>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Poco::UInt64>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
#ifndef POCO_INT64_IS_LONG
|
||||
bool Extractor::extract(std::size_t , std::vector<long>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<long>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<long>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<bool>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<bool>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<bool>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<float>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<float>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<float>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<double>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<double>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<double>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<char>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<char>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<char>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<std::string>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<std::string>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<std::string>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<BLOB>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<BLOB>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<BLOB>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<CLOB>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<CLOB>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<CLOB>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<DateTime>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<DateTime>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<DateTime>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Date>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Date>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Date>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Time>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Time>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Time>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Any>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Any>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Any>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::vector<Dynamic::Var>&)
|
||||
{
|
||||
throw NotImplementedException("std::vector extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::deque<Dynamic::Var>&)
|
||||
{
|
||||
throw NotImplementedException("std::deque extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
bool Extractor::extract(std::size_t , std::list<Dynamic::Var>&)
|
||||
{
|
||||
throw NotImplementedException("std::list extractor must be implemented.");
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::PostgreSQL
|
72
vendor/POCO/Data/PostgreSQL/src/PostgreSQLException.cpp
vendored
Normal file
72
vendor/POCO/Data/PostgreSQL/src/PostgreSQLException.cpp
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// PostgreSQLException.cpp
|
||||
//
|
||||
// Library: Data/PostgreSQL
|
||||
// Package: PostgreSQL
|
||||
// Module: PostgreSQLException
|
||||
//
|
||||
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/PostgreSQL/PostgreSQLException.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace PostgreSQL {
|
||||
|
||||
|
||||
PostgreSQLException::PostgreSQLException(const std::string& aMessage):
|
||||
Poco::Data::DataException(std::string("[PostgreSQL]: ") + aMessage)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PostgreSQLException::PostgreSQLException(const PostgreSQLException& anException):
|
||||
Poco::Data::DataException(anException)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PostgreSQLException::~PostgreSQLException() throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ConnectionException
|
||||
//
|
||||
|
||||
|
||||
ConnectionException::ConnectionException(const std::string& aMessage):
|
||||
PostgreSQLException(aMessage)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// TransactionException
|
||||
//
|
||||
|
||||
TransactionException::TransactionException(const std::string& aMessage):
|
||||
ConnectionException(aMessage)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// StatementException
|
||||
//
|
||||
|
||||
|
||||
StatementException::StatementException(const std::string& aMessage):
|
||||
PostgreSQLException(aMessage)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::PostgreSQL
|
169
vendor/POCO/Data/PostgreSQL/src/PostgreSQLStatementImpl.cpp
vendored
Normal file
169
vendor/POCO/Data/PostgreSQL/src/PostgreSQLStatementImpl.cpp
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
//
|
||||
// PostgreSQLStatementImpl.cpp
|
||||
//
|
||||
// Library: Data/PostgreSQL
|
||||
// Package: PostgreSQL
|
||||
// Module: PostgreSQLStatementImpl
|
||||
//
|
||||
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/PostgreSQL/PostgreSQLStatementImpl.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace PostgreSQL {
|
||||
|
||||
|
||||
PostgreSQLStatementImpl::PostgreSQLStatementImpl(SessionImpl& aSessionImpl):
|
||||
Poco::Data::StatementImpl(aSessionImpl),
|
||||
_statementExecutor(aSessionImpl.handle()),
|
||||
_pBinder(new Binder),
|
||||
_pExtractor(new Extractor (_statementExecutor)),
|
||||
_hasNext(NEXT_DONTKNOW)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PostgreSQLStatementImpl::~PostgreSQLStatementImpl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::size_t PostgreSQLStatementImpl::columnsReturned() const
|
||||
{
|
||||
return _statementExecutor.columnsReturned();
|
||||
}
|
||||
|
||||
|
||||
int PostgreSQLStatementImpl::affectedRowCount() const
|
||||
{
|
||||
return (int)_statementExecutor.getAffectedRowCount();
|
||||
}
|
||||
|
||||
|
||||
const MetaColumn& PostgreSQLStatementImpl::metaColumn(std::size_t aPosition) const
|
||||
{
|
||||
return _statementExecutor.metaColumn(aPosition);
|
||||
}
|
||||
|
||||
|
||||
bool PostgreSQLStatementImpl::hasNext()
|
||||
{
|
||||
if (NEXT_DONTKNOW == _hasNext)
|
||||
{
|
||||
if (columnsReturned() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_statementExecutor.fetch())
|
||||
{
|
||||
_hasNext = NEXT_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
_hasNext = NEXT_FALSE;
|
||||
return false;
|
||||
}
|
||||
else if (NEXT_TRUE == _hasNext)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::size_t PostgreSQLStatementImpl::next()
|
||||
{
|
||||
if (! hasNext())
|
||||
{
|
||||
throw StatementException("No data received");
|
||||
}
|
||||
|
||||
Poco::Data::AbstractExtractionVec::iterator it= extractions().begin();
|
||||
Poco::Data::AbstractExtractionVec::iterator itEnd = extractions().end();
|
||||
|
||||
std::size_t position = 0;
|
||||
|
||||
for (; it != itEnd; ++it)
|
||||
{
|
||||
(*it)->extract(position);
|
||||
position += (*it)->numOfColumnsHandled();
|
||||
}
|
||||
|
||||
_hasNext = NEXT_DONTKNOW;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bool PostgreSQLStatementImpl::canBind() const
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if ((_statementExecutor.state() >= StatementExecutor::STMT_COMPILED)
|
||||
&& !bindings().empty())
|
||||
{
|
||||
ret = (*bindings().begin())->canBind();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool PostgreSQLStatementImpl::canCompile() const
|
||||
{
|
||||
return (_statementExecutor.state() < StatementExecutor::STMT_COMPILED);
|
||||
}
|
||||
|
||||
|
||||
void PostgreSQLStatementImpl::compileImpl()
|
||||
{
|
||||
_statementExecutor.prepare(toString());
|
||||
}
|
||||
|
||||
|
||||
void PostgreSQLStatementImpl::bindImpl()
|
||||
{
|
||||
Poco::Data::AbstractBindingVec& binds = bindings();
|
||||
|
||||
std::size_t position = 0;
|
||||
Poco::Data::AbstractBindingVec::iterator it= binds.begin();
|
||||
Poco::Data::AbstractBindingVec::iterator itEnd = binds.end();
|
||||
|
||||
for (; it != itEnd && (*it)->canBind(); ++it)
|
||||
{
|
||||
(*it)->bind(position);
|
||||
position += (*it)->numOfColumnsHandled();
|
||||
}
|
||||
|
||||
_pBinder->updateBindVectorToCurrentValues();
|
||||
|
||||
_statementExecutor.bindParams(_pBinder->bindVector());
|
||||
|
||||
_statementExecutor.execute();
|
||||
|
||||
_hasNext = NEXT_DONTKNOW;
|
||||
}
|
||||
|
||||
|
||||
Poco::Data::AbstractExtractor::Ptr PostgreSQLStatementImpl::extractor()
|
||||
{
|
||||
return _pExtractor;
|
||||
}
|
||||
|
||||
|
||||
Poco::Data::AbstractBinder::Ptr PostgreSQLStatementImpl::binder()
|
||||
{
|
||||
return _pBinder;
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::PostgreSQL
|
107
vendor/POCO/Data/PostgreSQL/src/PostgreSQLTypes.cpp
vendored
Normal file
107
vendor/POCO/Data/PostgreSQL/src/PostgreSQLTypes.cpp
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
//
|
||||
// PostgreSQLTypes.cpp
|
||||
//
|
||||
// Library: Data/PostgreSQL
|
||||
// Package: PostgreSQL
|
||||
// Module: PostgreSQLTypes
|
||||
//
|
||||
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/PostgreSQL/PostgreSQLTypes.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace PostgreSQL {
|
||||
|
||||
|
||||
Poco::Data::MetaColumn::ColumnDataType oidToColumnDataType(const Oid anOID)
|
||||
{
|
||||
Poco::Data::MetaColumn::ColumnDataType cdt = Poco::Data::MetaColumn::FDT_UNKNOWN;
|
||||
|
||||
switch (anOID)
|
||||
{
|
||||
// bool
|
||||
case BOOLOID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_BOOL;
|
||||
break;
|
||||
|
||||
// integers
|
||||
case INT2OID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_INT16;
|
||||
break;
|
||||
case INT4OID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_INT32;
|
||||
break;
|
||||
case INT8OID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_INT64;
|
||||
break;
|
||||
|
||||
// floating point
|
||||
case FLOAT8OID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_DOUBLE;
|
||||
break;
|
||||
case FLOAT4OID:
|
||||
// cdt = Poco::Data::MetaColumn::FDT_FLOAT; This a bug in Poco::Data:: as a 4 byte "float" can't be cast/ugraded to an 8 byte "double"
|
||||
cdt = Poco::Data::MetaColumn::FDT_DOUBLE;
|
||||
break;
|
||||
case NUMERICOID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_DOUBLE;
|
||||
break;
|
||||
|
||||
// character strings
|
||||
case CHAROID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_STRING;
|
||||
break;
|
||||
case BPCHAROID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_STRING;
|
||||
break;
|
||||
case VARCHAROID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_STRING;
|
||||
break;
|
||||
|
||||
// BLOB, CLOB
|
||||
case BYTEAOID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_BLOB;
|
||||
break;
|
||||
case TEXTOID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_CLOB;
|
||||
break;
|
||||
|
||||
// date
|
||||
case DATEOID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_DATE;
|
||||
break;
|
||||
|
||||
// time
|
||||
case TIMEOID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_TIME;
|
||||
break;
|
||||
case TIMETZOID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_TIME;
|
||||
break;
|
||||
|
||||
//timestamp
|
||||
case TIMESTAMPOID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_TIMESTAMP;
|
||||
break;
|
||||
case TIMESTAMPZOID:
|
||||
cdt = Poco::Data::MetaColumn::FDT_TIMESTAMP;
|
||||
break;
|
||||
|
||||
// everything else is a string
|
||||
default:
|
||||
cdt = Poco::Data::MetaColumn::FDT_STRING;
|
||||
break;
|
||||
}
|
||||
|
||||
return cdt;
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::PostgreSQL
|
563
vendor/POCO/Data/PostgreSQL/src/SessionHandle.cpp
vendored
Normal file
563
vendor/POCO/Data/PostgreSQL/src/SessionHandle.cpp
vendored
Normal file
@@ -0,0 +1,563 @@
|
||||
//
|
||||
// SessionHandle.cpp
|
||||
//
|
||||
// Library: Data/PostgreSQL
|
||||
// Package: PostgreSQL
|
||||
// Module: SessionHandle
|
||||
//
|
||||
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/PostgreSQL/SessionHandle.h"
|
||||
#include "Poco/Data/PostgreSQL/PostgreSQLException.h"
|
||||
#include "Poco/Data/PostgreSQL/PostgreSQLTypes.h"
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
|
||||
|
||||
#define POCO_POSTGRESQL_VERSION_NUMBER ((NDB_VERSION_MAJOR<<16) | (NDB_VERSION_MINOR<<8) | (NDB_VERSION_BUILD&0xFF))
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace PostgreSQL {
|
||||
|
||||
|
||||
//const std::string SessionHandle::POSTGRESQL_READ_UNCOMMITTED = "READ UNCOMMITTED";
|
||||
const std::string SessionHandle::POSTGRESQL_READ_COMMITTED = "READ COMMITTED";
|
||||
const std::string SessionHandle::POSTGRESQL_REPEATABLE_READ = "REPEATABLE READ";
|
||||
const std::string SessionHandle::POSTGRESQL_SERIALIZABLE = "SERIALIZABLE";
|
||||
|
||||
|
||||
SessionHandle::SessionHandle():
|
||||
_pConnection(0),
|
||||
_inTransaction(false),
|
||||
_isAutoCommit(true),
|
||||
_isAsynchronousCommit(false),
|
||||
_tranactionIsolationLevel(Session::TRANSACTION_READ_COMMITTED)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SessionHandle::~SessionHandle()
|
||||
{
|
||||
try
|
||||
{
|
||||
disconnect();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SessionHandle::isConnected() const
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
return isConnectedNoLock();
|
||||
}
|
||||
|
||||
|
||||
bool SessionHandle::isConnectedNoLock() const
|
||||
{
|
||||
// DO NOT ACQUIRE THE MUTEX IN PRIVATE METHODS
|
||||
|
||||
if (_pConnection && PQstatus(_pConnection) == CONNECTION_OK)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::connect(const std::string& aConnectionString)
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (isConnectedNoLock())
|
||||
{
|
||||
throw ConnectionFailedException("Already Connected");
|
||||
}
|
||||
|
||||
_pConnection = PQconnectdb(aConnectionString.c_str());
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
{
|
||||
throw ConnectionFailedException(std::string("Connection Error: ") + lastErrorNoLock());
|
||||
}
|
||||
|
||||
_connectionString = aConnectionString;
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::connect(const char* aConnectionString)
|
||||
{
|
||||
connect(std::string(aConnectionString));
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::connect(const char* aHost, const char* aUser, const char* aPassword,
|
||||
const char* aDatabase, unsigned short aPort, unsigned int aConnectionTimeout)
|
||||
{
|
||||
std::string connectionString;
|
||||
|
||||
connectionString.append("host=");
|
||||
connectionString.append(aHost);
|
||||
connectionString.append(" ");
|
||||
|
||||
connectionString.append("user=");
|
||||
connectionString.append(aUser);
|
||||
connectionString.append(" ");
|
||||
|
||||
connectionString.append("password=");
|
||||
connectionString.append(aPassword);
|
||||
connectionString.append(" ");
|
||||
|
||||
connectionString.append("dbname=");
|
||||
connectionString.append(aDatabase);
|
||||
connectionString.append(" ");
|
||||
|
||||
connectionString.append("port=");
|
||||
Poco::NumberFormatter::append(connectionString, aPort);
|
||||
connectionString.append(" ");
|
||||
|
||||
connectionString.append("connect_timeout=");
|
||||
Poco::NumberFormatter::append(connectionString, aConnectionTimeout);
|
||||
|
||||
connect(connectionString);
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::disconnect()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (isConnectedNoLock())
|
||||
{
|
||||
PQfinish(_pConnection);
|
||||
|
||||
_pConnection = 0;
|
||||
|
||||
_connectionString = std::string();
|
||||
_inTransaction= false;
|
||||
_isAutoCommit = true;
|
||||
_isAsynchronousCommit = false;
|
||||
_tranactionIsolationLevel = Session::TRANSACTION_READ_COMMITTED;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Figure out what happens if a connection is reset with a pending transaction
|
||||
bool SessionHandle::reset()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (_pConnection)
|
||||
{
|
||||
PQreset(_pConnection);
|
||||
}
|
||||
|
||||
if (isConnectedNoLock())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::string SessionHandle::lastError() const
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return lastErrorNoLock();
|
||||
}
|
||||
|
||||
|
||||
std::string SessionHandle::lastErrorNoLock() const
|
||||
{
|
||||
// DO NOT ACQUIRE THE MUTEX IN PRIVATE METHODS
|
||||
std::string lastErrorString (0 != _pConnection ? PQerrorMessage(_pConnection) : "not connected");
|
||||
|
||||
return lastErrorString;
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::startTransaction()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
if (_inTransaction)
|
||||
{
|
||||
return; // NO-OP
|
||||
}
|
||||
|
||||
PGresult* pPQResult = PQexec(_pConnection, "BEGIN");
|
||||
|
||||
PQResultClear resultClearer(pPQResult);
|
||||
|
||||
if (PQresultStatus(pPQResult) != PGRES_COMMAND_OK)
|
||||
{
|
||||
throw StatementException(std::string("BEGIN statement failed:: ") + lastErrorNoLock());
|
||||
}
|
||||
|
||||
_inTransaction = true;
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::commit()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
PGresult* pPQResult = PQexec(_pConnection, "COMMIT");
|
||||
|
||||
PQResultClear resultClearer(pPQResult);
|
||||
|
||||
if (PQresultStatus(pPQResult) != PGRES_COMMAND_OK)
|
||||
{
|
||||
throw StatementException(std::string("COMMIT statement failed:: ") + lastErrorNoLock());
|
||||
}
|
||||
|
||||
_inTransaction = false;
|
||||
|
||||
deallocateStoredPreparedStatements();
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::rollback()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
PGresult* pPQResult = PQexec(_pConnection, "ROLLBACK");
|
||||
|
||||
PQResultClear resultClearer(pPQResult);
|
||||
|
||||
if (PQresultStatus(pPQResult) != PGRES_COMMAND_OK)
|
||||
{
|
||||
throw StatementException(std::string("ROLLBACK statement failed:: ") + lastErrorNoLock());
|
||||
}
|
||||
|
||||
_inTransaction = false;
|
||||
|
||||
deallocateStoredPreparedStatements();
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::setAutoCommit(bool aShouldAutoCommit)
|
||||
{
|
||||
if (aShouldAutoCommit == _isAutoCommit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (aShouldAutoCommit)
|
||||
{
|
||||
commit(); // end any in process transaction
|
||||
}
|
||||
else
|
||||
{
|
||||
startTransaction(); // start a new transaction
|
||||
}
|
||||
|
||||
_isAutoCommit = aShouldAutoCommit;
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::setAsynchronousCommit(bool aShouldAsynchronousCommit)
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
if (aShouldAsynchronousCommit == _isAsynchronousCommit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PGresult* pPQResult = PQexec(_pConnection, aShouldAsynchronousCommit ? "SET SYNCHRONOUS COMMIT TO OFF" : "SET SYNCHRONOUS COMMIT TO ON");
|
||||
|
||||
PQResultClear resultClearer(pPQResult);
|
||||
|
||||
if (PQresultStatus(pPQResult) != PGRES_COMMAND_OK)
|
||||
{
|
||||
throw StatementException(std::string("SET SYNCHRONUS COMMIT statement failed:: ") + lastErrorNoLock());
|
||||
}
|
||||
|
||||
_isAsynchronousCommit = aShouldAsynchronousCommit;
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::cancel()
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
PGcancel* ptrPGCancel = PQgetCancel(_pConnection);
|
||||
|
||||
PGCancelFree cancelFreer(ptrPGCancel);
|
||||
|
||||
PQcancel(ptrPGCancel, 0, 0); // no error buffer
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::setTransactionIsolation(Poco::UInt32 aTI)
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
if (aTI == _tranactionIsolationLevel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (! hasTransactionIsolation(aTI))
|
||||
{
|
||||
throw Poco::InvalidArgumentException("setTransactionIsolation()");
|
||||
}
|
||||
|
||||
std::string isolationLevel;
|
||||
|
||||
switch (aTI)
|
||||
{
|
||||
case Session::TRANSACTION_READ_COMMITTED:
|
||||
isolationLevel = POSTGRESQL_READ_COMMITTED; break;
|
||||
case Session::TRANSACTION_REPEATABLE_READ:
|
||||
isolationLevel = POSTGRESQL_REPEATABLE_READ; break;
|
||||
case Session::TRANSACTION_SERIALIZABLE:
|
||||
isolationLevel = POSTGRESQL_SERIALIZABLE; break;
|
||||
}
|
||||
|
||||
PGresult* pPQResult = PQexec(_pConnection, Poco::format("SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL %s", isolationLevel).c_str());
|
||||
|
||||
PQResultClear resultClearer(pPQResult);
|
||||
|
||||
if (PQresultStatus(pPQResult) != PGRES_COMMAND_OK)
|
||||
{
|
||||
throw StatementException(std::string("set transaction isolation statement failed: ") + lastErrorNoLock());
|
||||
}
|
||||
|
||||
_tranactionIsolationLevel = aTI;
|
||||
}
|
||||
|
||||
|
||||
Poco::UInt32 SessionHandle::transactionIsolation()
|
||||
{
|
||||
return _tranactionIsolationLevel;
|
||||
}
|
||||
|
||||
|
||||
bool SessionHandle::hasTransactionIsolation(Poco::UInt32 aTI)
|
||||
{
|
||||
return Session::TRANSACTION_READ_COMMITTED == aTI
|
||||
|| Session::TRANSACTION_REPEATABLE_READ == aTI
|
||||
|| Session::TRANSACTION_SERIALIZABLE == aTI;
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::deallocatePreparedStatement(const std::string& aPreparedStatementToDeAllocate)
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
if (! _inTransaction)
|
||||
{
|
||||
deallocatePreparedStatementNoLock(aPreparedStatementToDeAllocate);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
_preparedStatementsToBeDeallocated.push_back(aPreparedStatementToDeAllocate);
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::deallocatePreparedStatementNoLock(const std::string& aPreparedStatementToDeAllocate)
|
||||
{
|
||||
PGresult* pPQResult = PQexec(_pConnection, (std::string("DEALLOCATE ") + aPreparedStatementToDeAllocate).c_str());
|
||||
|
||||
PQResultClear resultClearer(pPQResult);
|
||||
|
||||
if (PQresultStatus(pPQResult) != PGRES_COMMAND_OK)
|
||||
{
|
||||
throw StatementException(std::string("DEALLOCATE statement failed: ") + lastErrorNoLock());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SessionHandle::deallocateStoredPreparedStatements()
|
||||
{
|
||||
// DO NOT ACQUIRE THE MUTEX IN PRIVATE METHODS
|
||||
while (! _preparedStatementsToBeDeallocated.empty())
|
||||
{
|
||||
deallocatePreparedStatementNoLock(_preparedStatementsToBeDeallocated.back());
|
||||
|
||||
_preparedStatementsToBeDeallocated.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SessionHandle::serverVersion() const
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
return PQserverVersion(_pConnection);
|
||||
}
|
||||
|
||||
|
||||
int SessionHandle::serverProcessID() const
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
return PQbackendPID(_pConnection);
|
||||
}
|
||||
|
||||
|
||||
int SessionHandle::protocoVersion() const
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
return PQprotocolVersion(_pConnection);
|
||||
}
|
||||
|
||||
|
||||
std::string SessionHandle::clientEncoding() const
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
if (! isConnectedNoLock())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
return pg_encoding_to_char(PQclientEncoding(_pConnection));
|
||||
}
|
||||
|
||||
|
||||
int SessionHandle::libpqVersion() const
|
||||
{
|
||||
return PQlibVersion();
|
||||
}
|
||||
|
||||
|
||||
SessionParametersMap SessionHandle::setConnectionInfoParameters(PQconninfoOption* pConnInfOpt)
|
||||
{
|
||||
SessionParametersMap sessionParametersMap;
|
||||
|
||||
while (0 != pConnInfOpt->keyword)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string keyword = pConnInfOpt->keyword ? pConnInfOpt->keyword : std::string();
|
||||
std::string environmentVariableVersion = pConnInfOpt->envvar ? pConnInfOpt->envvar : std::string();
|
||||
std::string compiledVersion = pConnInfOpt->compiled ? pConnInfOpt->compiled : std::string();
|
||||
std::string currentValue = pConnInfOpt->val ? pConnInfOpt->val : std::string();
|
||||
std::string dialogLabel = pConnInfOpt->label? pConnInfOpt->label: std::string();
|
||||
std::string dialogDisplayCharacter = pConnInfOpt->dispchar ? pConnInfOpt->dispchar : std::string();
|
||||
int dialogDisplaysize = pConnInfOpt->dispsize;
|
||||
|
||||
SessionParameters connParams(keyword, environmentVariableVersion, compiledVersion,
|
||||
currentValue, dialogLabel, dialogDisplayCharacter, dialogDisplaysize);
|
||||
|
||||
sessionParametersMap.insert(SessionParametersMap::value_type(connParams.keyword(), connParams));
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
}
|
||||
|
||||
++pConnInfOpt;
|
||||
}
|
||||
|
||||
return sessionParametersMap;
|
||||
}
|
||||
|
||||
|
||||
SessionParametersMap SessionHandle::connectionDefaultParameters()
|
||||
{
|
||||
PQconninfoOption* ptrConnInfoOptions = PQconndefaults();
|
||||
|
||||
PQConnectionInfoOptionsFree connectionOptionsFreeer(ptrConnInfoOptions);
|
||||
|
||||
return setConnectionInfoParameters(ptrConnInfoOptions);
|
||||
}
|
||||
|
||||
|
||||
SessionParametersMap SessionHandle::connectionParameters() const
|
||||
{
|
||||
if (! isConnected())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
PQconninfoOption* ptrConnInfoOptions = 0;
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||
|
||||
ptrConnInfoOptions = PQconninfo(_pConnection);
|
||||
}
|
||||
|
||||
PQConnectionInfoOptionsFree connectionOptionsFreeer(ptrConnInfoOptions);
|
||||
|
||||
return setConnectionInfoParameters(ptrConnInfoOptions);
|
||||
}
|
||||
|
||||
|
||||
} } } // Poco::Data::PostgreSQL
|
246
vendor/POCO/Data/PostgreSQL/src/SessionImpl.cpp
vendored
Normal file
246
vendor/POCO/Data/PostgreSQL/src/SessionImpl.cpp
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
//
|
||||
// SessionImpl.cpp
|
||||
//
|
||||
// Library: Data/PostgreSQL
|
||||
// Package: PostgreSQL
|
||||
// Module: SessionImpl
|
||||
//
|
||||
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/PostgreSQL/SessionImpl.h"
|
||||
#include "Poco/Data/PostgreSQL/PostgreSQLException.h"
|
||||
#include "Poco/Data/PostgreSQL/PostgreSQLStatementImpl.h"
|
||||
#include "Poco/Data/PostgreSQL/PostgreSQLTypes.h"
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/String.h"
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string copyStripped(std::string::const_iterator aFromStringCItr, std::string::const_iterator aToStringCItr)
|
||||
{
|
||||
// skip leading spaces
|
||||
while ((aFromStringCItr != aToStringCItr) && isspace(*aFromStringCItr)) aFromStringCItr++;
|
||||
// skip trailing spaces
|
||||
while ((aFromStringCItr != aToStringCItr) && isspace(*(aToStringCItr - 1))) aToStringCItr--;
|
||||
|
||||
return std::string(aFromStringCItr, aToStringCItr);
|
||||
}
|
||||
|
||||
std::string createConnectionStringFromOptionsMap(const std::map <std::string, std::string> anOptionsMap)
|
||||
{
|
||||
std::string connectionString;
|
||||
|
||||
for (std::map<std::string, std::string>::const_iterator citr = anOptionsMap.begin(); citr != anOptionsMap.end(); ++citr)
|
||||
{
|
||||
connectionString.append(citr->first);
|
||||
connectionString.append("=");
|
||||
connectionString.append(citr->second);
|
||||
connectionString.append(" ");
|
||||
}
|
||||
|
||||
return connectionString;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace PostgreSQL {
|
||||
|
||||
|
||||
SessionImpl::SessionImpl(const std::string& aConnectionString, std::size_t aLoginTimeout):
|
||||
Poco::Data::AbstractSessionImpl<SessionImpl>(aConnectionString, aLoginTimeout)
|
||||
{
|
||||
setProperty("handle", static_cast<SessionHandle*>(&_sessionHandle));
|
||||
setConnectionTimeout(CONNECTION_TIMEOUT_DEFAULT);
|
||||
open();
|
||||
}
|
||||
|
||||
|
||||
SessionImpl::~SessionImpl()
|
||||
{
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::setConnectionTimeout(std::size_t aTimeout)
|
||||
{
|
||||
_timeout = aTimeout;
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::open(const std::string& aConnectionString)
|
||||
{
|
||||
if (connectionString() != aConnectionString)
|
||||
{
|
||||
if (isConnected())
|
||||
{
|
||||
throw ConnectionException("Session already connected");
|
||||
}
|
||||
|
||||
if (! aConnectionString.empty())
|
||||
{
|
||||
setConnectionString(aConnectionString);
|
||||
}
|
||||
}
|
||||
|
||||
poco_assert_dbg (! connectionString().empty());
|
||||
|
||||
unsigned int timeout = static_cast<unsigned int>(getLoginTimeout());
|
||||
|
||||
// PostgreSQL connections can use environment variables for connection parameters.
|
||||
// As such it is not an error if they are not part of the connection string
|
||||
|
||||
std::map <std::string, std::string> optionsMap;
|
||||
|
||||
// Default values
|
||||
optionsMap["connect_timeout"] = Poco::NumberFormatter::format(timeout);
|
||||
|
||||
const std::string& connString = connectionString();
|
||||
|
||||
for (std::string::const_iterator start = connString.begin();;)
|
||||
{
|
||||
std::string::const_iterator finish = std::find(start, connString.end(), ' '); // space is the separator between keyword=value pairs
|
||||
std::string::const_iterator middle = std::find(start, finish, '=');
|
||||
|
||||
if (middle == finish)
|
||||
{
|
||||
throw PostgreSQLException("create session: bad connection string format, cannot find '='");
|
||||
}
|
||||
|
||||
optionsMap[ copyStripped(start, middle) ] = copyStripped(middle + 1, finish);
|
||||
|
||||
if ((finish == connString.end()) || (finish + 1 == connString.end())) break;
|
||||
|
||||
start = finish + 1;
|
||||
}
|
||||
|
||||
// Real connect
|
||||
_sessionHandle.connect(createConnectionStringFromOptionsMap(optionsMap));
|
||||
|
||||
addFeature("autoCommit",
|
||||
&SessionImpl::setAutoCommit,
|
||||
&SessionImpl::isAutoCommit);
|
||||
|
||||
addFeature("asynchronousCommit",
|
||||
&SessionImpl::setAutoCommit,
|
||||
&SessionImpl::isAutoCommit);
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::close()
|
||||
{
|
||||
if (isConnected())
|
||||
{
|
||||
_sessionHandle.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::reset()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::isConnected() const
|
||||
{
|
||||
return _sessionHandle.isConnected();
|
||||
}
|
||||
|
||||
|
||||
StatementImpl::Ptr SessionImpl::createStatementImpl()
|
||||
{
|
||||
return new PostgreSQLStatementImpl (*this);
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::isTransaction() const
|
||||
{
|
||||
return _sessionHandle.isTransaction();
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::begin()
|
||||
{
|
||||
if (isTransaction())
|
||||
{
|
||||
throw Poco::InvalidAccessException("Already in transaction.");
|
||||
}
|
||||
|
||||
_sessionHandle.startTransaction();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::commit()
|
||||
{
|
||||
// Not an error to issue a COMMIT without a preceding BEGIN
|
||||
_sessionHandle.commit();
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::rollback()
|
||||
{
|
||||
// Not an error to issue a ROLLBACK without a preceding BEGIN
|
||||
_sessionHandle.rollback();
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::setAutoCommit(const std::string&, bool aValue)
|
||||
{
|
||||
_sessionHandle.setAutoCommit(aValue);
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::isAutoCommit(const std::string&) const
|
||||
{
|
||||
return _sessionHandle.isAutoCommit();
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::setAsynchronousCommit(const std::string&, bool aValue)
|
||||
{
|
||||
_sessionHandle.setAsynchronousCommit(aValue);
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::isAsynchronousCommit(const std::string&) const
|
||||
{
|
||||
return _sessionHandle.isAsynchronousCommit();
|
||||
}
|
||||
|
||||
|
||||
void SessionImpl::setTransactionIsolation(Poco::UInt32 aTI)
|
||||
{
|
||||
return _sessionHandle.setTransactionIsolation(aTI);
|
||||
}
|
||||
|
||||
|
||||
Poco::UInt32 SessionImpl::getTransactionIsolation() const
|
||||
{
|
||||
return _sessionHandle.transactionIsolation();
|
||||
}
|
||||
|
||||
|
||||
bool SessionImpl::hasTransactionIsolation(Poco::UInt32 aTI) const
|
||||
{
|
||||
return _sessionHandle.hasTransactionIsolation(aTI);
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::PostgreSQL
|
414
vendor/POCO/Data/PostgreSQL/src/StatementExecutor.cpp
vendored
Normal file
414
vendor/POCO/Data/PostgreSQL/src/StatementExecutor.cpp
vendored
Normal file
@@ -0,0 +1,414 @@
|
||||
//
|
||||
// StatementExecutor.cpp
|
||||
//
|
||||
// Library: Data/PostgreSQL
|
||||
// Package: PostgreSQL
|
||||
// Module: StatementExecutor
|
||||
//
|
||||
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/PostgreSQL/StatementExecutor.h"
|
||||
#include "Poco/Data/PostgreSQL/PostgreSQLTypes.h"
|
||||
#include "Poco/Format.h"
|
||||
#include "Poco/UUID.h"
|
||||
#include "Poco/UUIDGenerator.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/RegularExpression.h"
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
std::size_t countOfPlaceHoldersInSQLStatement(const std::string& aSQLStatement)
|
||||
{
|
||||
// Find unique placeholders.
|
||||
// Unique placeholders allow the same placeholder to be used multiple times in the same statement.
|
||||
|
||||
// NON C++11 implementation
|
||||
|
||||
//if (aSQLStatement.empty())
|
||||
//{
|
||||
//return 0;
|
||||
//}
|
||||
|
||||
// set to hold the unique placeholders ($1, $2, $3, etc.).
|
||||
// A set is used because the same placeholder can be used muliple times
|
||||
std::set<std::string> placeholderSet;
|
||||
|
||||
Poco::RegularExpression placeholderRE("[$][0-9]+");
|
||||
Poco::RegularExpression::Match match = { 0 , 0 }; // Match is a struct, not a class :-(
|
||||
|
||||
std::size_t startingPosition = 0;
|
||||
|
||||
while (match.offset != std::string::npos)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (placeholderRE.match(aSQLStatement, startingPosition, match))
|
||||
{
|
||||
placeholderSet.insert(aSQLStatement.substr(match.offset, match.length));
|
||||
startingPosition = match.offset + match.length;
|
||||
}
|
||||
}
|
||||
catch (Poco::RegularExpressionException &)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return placeholderSet.size();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace PostgreSQL {
|
||||
|
||||
|
||||
StatementExecutor::StatementExecutor(SessionHandle& sessionHandle):
|
||||
_sessionHandle(sessionHandle),
|
||||
_state(STMT_INITED),
|
||||
_pResultHandle(0),
|
||||
_countPlaceholdersInSQLStatement(0),
|
||||
_currentRow(0),
|
||||
_affectedRowCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
StatementExecutor::~StatementExecutor()
|
||||
{
|
||||
try
|
||||
{
|
||||
// remove the prepared statement from the session
|
||||
if(_sessionHandle.isConnected() && _state >= STMT_COMPILED)
|
||||
{
|
||||
_sessionHandle.deallocatePreparedStatement(_preparedStatementName);
|
||||
}
|
||||
|
||||
PQResultClear resultClearer(_pResultHandle);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StatementExecutor::State StatementExecutor::state() const
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
|
||||
|
||||
void StatementExecutor::prepare(const std::string& aSQLStatement)
|
||||
{
|
||||
if (! _sessionHandle.isConnected()) throw NotConnectedException();
|
||||
if (_state >= STMT_COMPILED) return;
|
||||
|
||||
// clear out the metadata. One way or another it is now obsolete.
|
||||
_countPlaceholdersInSQLStatement = 0;
|
||||
_SQLStatement= std::string();
|
||||
_preparedStatementName = std::string();
|
||||
_resultColumns.clear();
|
||||
|
||||
// clear out any result data. One way or another it is now obsolete.
|
||||
clearResults();
|
||||
|
||||
// prepare parameters for the call to PQprepare
|
||||
const char* ptrCSQLStatement = aSQLStatement.c_str();
|
||||
std::size_t countPlaceholdersInSQLStatement = countOfPlaceHoldersInSQLStatement(aSQLStatement);
|
||||
|
||||
Poco::UUIDGenerator& generator = Poco::UUIDGenerator::defaultGenerator();
|
||||
Poco::UUID uuid(generator.create()); // time based
|
||||
std::string statementName = uuid.toString();
|
||||
statementName.insert(0, 1, 'p'); // prepared statement names can't start with a number
|
||||
std::replace(statementName.begin(), statementName.end(), '-', 'p'); // PostgreSQL doesn't like dashes in prepared statement names
|
||||
const char* pStatementName = statementName.c_str();
|
||||
|
||||
PGresult* ptrPGResult = 0;
|
||||
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionHandle.mutex());
|
||||
|
||||
// prepare the statement - temporary PGresult returned
|
||||
ptrPGResult = PQprepare(_sessionHandle, pStatementName, ptrCSQLStatement, (int)countPlaceholdersInSQLStatement, 0);
|
||||
}
|
||||
|
||||
{
|
||||
// setup to clear the result from PQprepare
|
||||
PQResultClear resultClearer(ptrPGResult);
|
||||
|
||||
if (!ptrPGResult || PQresultStatus(ptrPGResult) != PGRES_COMMAND_OK)
|
||||
{
|
||||
throw StatementException(std::string("postgresql_stmt_prepare error: ") + PQresultErrorMessage (ptrPGResult) + " " + aSQLStatement);
|
||||
}
|
||||
}
|
||||
|
||||
// Determine what the structure of a statement result will look like
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionHandle.mutex());
|
||||
ptrPGResult = PQdescribePrepared(_sessionHandle, pStatementName);
|
||||
}
|
||||
|
||||
{
|
||||
PQResultClear resultClearer(ptrPGResult);
|
||||
if (! ptrPGResult || PQresultStatus(ptrPGResult) != PGRES_COMMAND_OK)
|
||||
{
|
||||
throw StatementException(std::string("postgresql_stmt_describe error: ") +
|
||||
PQresultErrorMessage (ptrPGResult) + " " + aSQLStatement);
|
||||
}
|
||||
|
||||
// remember the structure of the statement result
|
||||
int fieldCount = PQnfields(ptrPGResult);
|
||||
if (fieldCount < 0) fieldCount = 0;
|
||||
|
||||
for (int i = 0; i < fieldCount; ++i)
|
||||
{
|
||||
_resultColumns.push_back(MetaColumn(i, PQfname(ptrPGResult, i),
|
||||
oidToColumnDataType(PQftype(ptrPGResult, i)), 0, 0, true));
|
||||
}
|
||||
}
|
||||
|
||||
_SQLStatement = aSQLStatement;
|
||||
_preparedStatementName = statementName;
|
||||
_countPlaceholdersInSQLStatement = countPlaceholdersInSQLStatement;
|
||||
_state = STMT_COMPILED; // must be last
|
||||
}
|
||||
|
||||
|
||||
void StatementExecutor::bindParams(const InputParameterVector& anInputParameterVector)
|
||||
{
|
||||
if (! _sessionHandle.isConnected()) throw NotConnectedException();
|
||||
|
||||
if (_state < STMT_COMPILED) throw StatementException("Statement is not compiled yet");
|
||||
|
||||
if (anInputParameterVector.size() != _countPlaceholdersInSQLStatement)
|
||||
{
|
||||
throw StatementException(std::string("incorrect bind parameters count for SQL Statement: ") +
|
||||
_SQLStatement);
|
||||
}
|
||||
|
||||
// Just record the input vector for later execution
|
||||
_inputParameterVector = anInputParameterVector;
|
||||
}
|
||||
|
||||
|
||||
void StatementExecutor::execute()
|
||||
{
|
||||
if (! _sessionHandle.isConnected()) throw NotConnectedException();
|
||||
|
||||
if (_state < STMT_COMPILED) throw StatementException("Statement is not compiled yet");
|
||||
|
||||
if (_countPlaceholdersInSQLStatement != 0 &&
|
||||
_inputParameterVector.size() != _countPlaceholdersInSQLStatement)
|
||||
{
|
||||
throw StatementException("Count of Parameters in Statement different than supplied parameters");
|
||||
}
|
||||
|
||||
// "transmogrify" the _inputParameterVector to the C format required by PQexecPrepared
|
||||
|
||||
/* - from example
|
||||
const char *paramValues[1];
|
||||
int paramLengths[1];
|
||||
int paramFormats[1];
|
||||
*/
|
||||
|
||||
std::vector<const char *> pParameterVector;
|
||||
std::vector<int> parameterLengthVector;
|
||||
std::vector<int> parameterFormatVector;
|
||||
|
||||
InputParameterVector::const_iterator cItr = _inputParameterVector.begin();
|
||||
InputParameterVector::const_iterator cItrEnd = _inputParameterVector.end();
|
||||
|
||||
for (; cItr != cItrEnd; ++cItr)
|
||||
{
|
||||
try
|
||||
{
|
||||
pParameterVector.push_back (static_cast<const char*>(cItr->pInternalRepresentation()));
|
||||
parameterLengthVector.push_back((int)cItr->size());
|
||||
parameterFormatVector.push_back((int)cItr->isBinary() ? 1 : 0);
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
throw StatementException("Memory Allocation Error");
|
||||
}
|
||||
}
|
||||
|
||||
// clear out any result data. One way or another it is now obsolete.
|
||||
clearResults();
|
||||
|
||||
PGresult* ptrPGResult = 0;
|
||||
{
|
||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionHandle.mutex());
|
||||
|
||||
ptrPGResult = PQexecPrepared (_sessionHandle,
|
||||
_preparedStatementName.c_str(), (int)_countPlaceholdersInSQLStatement,
|
||||
_inputParameterVector.size() != 0 ? &pParameterVector[ 0 ] : 0,
|
||||
_inputParameterVector.size() != 0 ? ¶meterLengthVector[ 0 ] : 0,
|
||||
_inputParameterVector.size() != 0 ? ¶meterFormatVector[ 0 ] : 0, 0);
|
||||
}
|
||||
|
||||
// Don't setup to auto clear the result (ptrPGResult). It is required to retrieve the results later.
|
||||
|
||||
if (!ptrPGResult || (PQresultStatus(ptrPGResult) != PGRES_COMMAND_OK &&
|
||||
PQresultStatus(ptrPGResult) != PGRES_TUPLES_OK))
|
||||
{
|
||||
PQResultClear resultClearer(ptrPGResult);
|
||||
|
||||
const char* pSeverity = PQresultErrorField(ptrPGResult, PG_DIAG_SEVERITY);
|
||||
const char* pSQLState = PQresultErrorField(ptrPGResult, PG_DIAG_SQLSTATE);
|
||||
const char* pDetail = PQresultErrorField(ptrPGResult, PG_DIAG_MESSAGE_DETAIL);
|
||||
const char* pHint = PQresultErrorField(ptrPGResult, PG_DIAG_MESSAGE_HINT);
|
||||
const char* pConstraint = PQresultErrorField(ptrPGResult, PG_DIAG_CONSTRAINT_NAME);
|
||||
|
||||
throw StatementException(std::string("postgresql_stmt_execute error: ")
|
||||
+ PQresultErrorMessage (ptrPGResult)
|
||||
+ " Severity: " + (pSeverity ? pSeverity : "N/A")
|
||||
+ " State: " + (pSQLState ? pSQLState : "N/A")
|
||||
+ " Detail: " + (pDetail ? pDetail : "N/A")
|
||||
+ " Hint: " + (pHint ? pHint : "N/A")
|
||||
+ " Constraint: " + (pConstraint ? pConstraint : "N/A"));
|
||||
}
|
||||
|
||||
_pResultHandle = ptrPGResult;
|
||||
|
||||
// are there any results?
|
||||
|
||||
int affectedRowCount = 0;
|
||||
|
||||
if (PGRES_TUPLES_OK == PQresultStatus(_pResultHandle))
|
||||
{
|
||||
affectedRowCount = PQntuples(_pResultHandle);
|
||||
|
||||
if (affectedRowCount >= 0)
|
||||
{
|
||||
_affectedRowCount = static_cast<std::size_t>(affectedRowCount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // non Select DML statments also have an affected row count.
|
||||
// unfortunately PostgreSQL offers up this count as a char * - go figure!
|
||||
const char * pNonSelectAffectedRowCountString = PQcmdTuples(_pResultHandle);
|
||||
if (0 != pNonSelectAffectedRowCountString)
|
||||
{
|
||||
if ( Poco::NumberParser::tryParse(pNonSelectAffectedRowCountString, affectedRowCount)
|
||||
&& affectedRowCount >= 0
|
||||
)
|
||||
{
|
||||
_affectedRowCount = static_cast<std::size_t>(affectedRowCount);
|
||||
_currentRow = _affectedRowCount; // no fetching on these statements!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_state = STMT_EXECUTED;
|
||||
}
|
||||
|
||||
|
||||
bool StatementExecutor::fetch()
|
||||
{
|
||||
if (! _sessionHandle.isConnected())
|
||||
{
|
||||
throw NotConnectedException();
|
||||
}
|
||||
|
||||
if (_state < STMT_EXECUTED)
|
||||
{
|
||||
throw StatementException("Statement is not yet executed");
|
||||
}
|
||||
|
||||
std::size_t countColumns = columnsReturned();
|
||||
|
||||
// first time to fetch?
|
||||
if (0 == _outputParameterVector.size())
|
||||
{
|
||||
// setup a output vector for the results
|
||||
_outputParameterVector.resize(countColumns);
|
||||
}
|
||||
|
||||
// already retrieved last row?
|
||||
if (_currentRow == getAffectedRowCount())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 == countColumns || PGRES_TUPLES_OK != PQresultStatus(_pResultHandle))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < countColumns; ++i)
|
||||
{
|
||||
int fieldLength = PQgetlength(_pResultHandle, static_cast<int> (_currentRow), static_cast<int> (i));
|
||||
|
||||
Oid columnInternalDataType = PQftype(_pResultHandle, i); // Oid of column
|
||||
|
||||
_outputParameterVector.at(i).setValues(oidToColumnDataType(columnInternalDataType), // Poco::Data::MetaData version of the Column Data Type
|
||||
columnInternalDataType, // Postgres Version
|
||||
_currentRow, // the row number of the result
|
||||
PQgetvalue(_pResultHandle, (int)_currentRow, i), // a pointer to the data
|
||||
(-1 == fieldLength ? 0 : fieldLength), // the length of the data returned
|
||||
PQgetisnull(_pResultHandle, (int)_currentRow, i) == 1 ? true : false); // is the column value null?
|
||||
}
|
||||
|
||||
++_currentRow;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::size_t StatementExecutor::getAffectedRowCount() const
|
||||
{
|
||||
return _affectedRowCount;
|
||||
}
|
||||
|
||||
|
||||
std::size_t StatementExecutor::columnsReturned() const
|
||||
{
|
||||
return static_cast<std::size_t> (_resultColumns.size());
|
||||
}
|
||||
|
||||
|
||||
const MetaColumn& StatementExecutor::metaColumn(std::size_t aPosition) const
|
||||
{
|
||||
if (aPosition >= columnsReturned())
|
||||
{
|
||||
throw StatementException("Invalid column number for metaColumn");
|
||||
}
|
||||
|
||||
return _resultColumns.at(aPosition);
|
||||
}
|
||||
|
||||
|
||||
const OutputParameter& StatementExecutor::resultColumn(std::size_t aPosition) const
|
||||
{
|
||||
if (aPosition >= columnsReturned())
|
||||
{
|
||||
throw StatementException("Invalid column number for resultColumn");
|
||||
}
|
||||
|
||||
return _outputParameterVector.at(aPosition);
|
||||
}
|
||||
|
||||
|
||||
void StatementExecutor::clearResults()
|
||||
{
|
||||
// clear out any old result first
|
||||
{
|
||||
PQResultClear resultClearer(_pResultHandle);
|
||||
}
|
||||
|
||||
_outputParameterVector.clear();
|
||||
_affectedRowCount = 0;
|
||||
_currentRow = 0;
|
||||
}
|
||||
|
||||
|
||||
} } } // Poco::Data::PostgreSQL
|
92
vendor/POCO/Data/PostgreSQL/src/Utility.cpp
vendored
Normal file
92
vendor/POCO/Data/PostgreSQL/src/Utility.cpp
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// Utility.cpp
|
||||
//
|
||||
// Library: Data/PostgreSQL
|
||||
// Package: PostgreSQL
|
||||
// Module: Utility
|
||||
//
|
||||
// Implementation of Utility
|
||||
//
|
||||
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Data/PostgreSQL/Utility.h"
|
||||
#include "Poco/Data/PostgreSQL/SessionImpl.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Data {
|
||||
namespace PostgreSQL {
|
||||
|
||||
|
||||
std::string Utility::serverInfo(SessionHandle* aHandlePtr)
|
||||
{
|
||||
std::string srvrInfo = "Process ID: ";
|
||||
|
||||
srvrInfo.append(Poco::NumberFormatter::format(aHandlePtr->serverProcessID()));
|
||||
|
||||
srvrInfo.append(" Protocol Version: ");
|
||||
|
||||
srvrInfo.append(Poco::NumberFormatter::format(aHandlePtr->protocoVersion()));
|
||||
|
||||
return srvrInfo;
|
||||
}
|
||||
|
||||
|
||||
std::string Utility::serverInfo(Session& aSession)
|
||||
{
|
||||
return serverInfo(handle(aSession));
|
||||
}
|
||||
|
||||
|
||||
int Utility::serverVersion(SessionHandle* aHandlePtr)
|
||||
{
|
||||
return aHandlePtr->serverVersion();
|
||||
}
|
||||
|
||||
|
||||
int Utility::serverVersion(Session& aSession)
|
||||
{
|
||||
return serverVersion(handle(aSession));
|
||||
}
|
||||
|
||||
|
||||
std::string Utility::hostInfo(SessionHandle* aHandlePtr)
|
||||
{
|
||||
SessionParametersMap parametersMap = aHandlePtr->connectionParameters();
|
||||
|
||||
SessionParametersMap::const_iterator cItr = parametersMap.find("host");
|
||||
|
||||
if (parametersMap.end() == cItr)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return cItr->second.currentValue();
|
||||
}
|
||||
|
||||
|
||||
std::string Utility::hostInfo(Session& aSession)
|
||||
{
|
||||
return hostInfo(handle(aSession));
|
||||
}
|
||||
|
||||
|
||||
std::string Utility::sessionEncoding(SessionHandle* aHandlePtr)
|
||||
{
|
||||
return aHandlePtr->clientEncoding();
|
||||
}
|
||||
|
||||
|
||||
std::string Utility::sessionEncoding(Poco::Data::Session& aSession)
|
||||
{
|
||||
return sessionEncoding(handle(aSession));
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::Data::PostgreSQL
|
Reference in New Issue
Block a user