mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-24 09:12:28 +02:00
improve BLOB handling, clean-up code
This commit is contained in:
@@ -329,15 +329,10 @@ private:
|
|||||||
{
|
{
|
||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
if (isColumnNull(outputParameter))
|
if (isColumnNull(outputParameter)) return false;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string tempString; // since the postgreSQL API in use is all about strings...
|
std::string tempString; // since the postgreSQL API in use is all about strings...
|
||||||
|
|
||||||
bool returnValue = extract(pos, tempString);
|
bool returnValue = extract(pos, tempString);
|
||||||
|
|
||||||
if (returnValue)
|
if (returnValue)
|
||||||
{
|
{
|
||||||
val = tempString;
|
val = tempString;
|
||||||
@@ -349,7 +344,7 @@ private:
|
|||||||
bool extractToDynamic(std::size_t pos, Dynamic::Var& val);
|
bool extractToDynamic(std::size_t pos, Dynamic::Var& val);
|
||||||
|
|
||||||
// Prevent VC8 warning "operator= could not be generated"
|
// Prevent VC8 warning "operator= could not be generated"
|
||||||
Extractor& operator=(const Extractor&);
|
Extractor& operator = (const Extractor&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StatementExecutor& _statementExecutor;
|
StatementExecutor& _statementExecutor;
|
||||||
|
|||||||
@@ -279,7 +279,8 @@ inline const void* InputParameter::pInternalRepresentation() const
|
|||||||
return _pNonStringVersionRepresentation;
|
return _pNonStringVersionRepresentation;
|
||||||
|
|
||||||
case Poco::Data::MetaColumn::FDT_UNKNOWN:
|
case Poco::Data::MetaColumn::FDT_UNKNOWN:
|
||||||
default: return 0;
|
default:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,8 +89,7 @@ public:
|
|||||||
|
|
||||||
void connect(const char* aConnectionString);
|
void connect(const char* aConnectionString);
|
||||||
|
|
||||||
void connect(const char* aHost, const char* aUser, const char* aPassword,
|
void connect(const char* aHost, const char* aUser, const char* aPassword, const char* aDatabase, unsigned short aPort, unsigned int aConnectionTimeout);
|
||||||
const char* aDatabase, unsigned short aPort, unsigned int aConnectionTimeout);
|
|
||||||
|
|
||||||
bool isConnected() const;
|
bool isConnected() const;
|
||||||
/// is a connection established?
|
/// is a connection established?
|
||||||
|
|||||||
@@ -205,8 +205,8 @@ Binder::bindVector() const
|
|||||||
|
|
||||||
void Binder::updateBindVectorToCurrentValues()
|
void Binder::updateBindVectorToCurrentValues()
|
||||||
{
|
{
|
||||||
InputParameterVector::iterator itr = _bindVector.begin();
|
InputParameterVector::iterator itr = _bindVector.begin();
|
||||||
InputParameterVector::iterator itrEnd = _bindVector.end();
|
InputParameterVector::iterator itrEnd = _bindVector.end();
|
||||||
|
|
||||||
for (; itr != itrEnd; ++itr)
|
for (; itr != itrEnd; ++itr)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
#include "Poco/Data/Time.h"
|
#include "Poco/Data/Time.h"
|
||||||
#include "Poco/NumberParser.h"
|
#include "Poco/NumberParser.h"
|
||||||
#include "Poco/DateTimeParser.h"
|
#include "Poco/DateTimeParser.h"
|
||||||
|
#include "Poco/MemoryStream.h"
|
||||||
|
#include "Poco/HexBinaryDecoder.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
|
||||||
@@ -42,14 +44,10 @@ bool Extractor::extract(std::size_t pos, Poco::Int8& val)
|
|||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
int tempVal = 0;
|
int tempVal = 0;
|
||||||
|
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParse(outputParameter.pData(), tempVal))
|
||||||
if ( isColumnNull(outputParameter)
|
|
||||||
|| ! Poco::NumberParser::tryParse(outputParameter.pData(), tempVal)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = static_cast<Int8>(tempVal);
|
val = static_cast<Int8>(tempVal);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -61,14 +59,10 @@ bool Extractor::extract(std::size_t pos, Poco::UInt8& val)
|
|||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
unsigned int tempVal = 0;
|
unsigned int tempVal = 0;
|
||||||
|
if (isColumnNull(outputParameter)|| !Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), tempVal))
|
||||||
if ( isColumnNull(outputParameter)
|
|
||||||
|| ! Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), tempVal)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = static_cast<UInt8>(tempVal);
|
val = static_cast<UInt8>(tempVal);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -80,14 +74,10 @@ bool Extractor::extract(std::size_t pos, Poco::Int16& val)
|
|||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
int tempVal = 0;
|
int tempVal = 0;
|
||||||
|
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParse(outputParameter.pData(), tempVal))
|
||||||
if ( isColumnNull(outputParameter)
|
|
||||||
|| ! Poco::NumberParser::tryParse(outputParameter.pData(), tempVal)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = static_cast<Int16>(tempVal);
|
val = static_cast<Int16>(tempVal);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -99,14 +89,10 @@ bool Extractor::extract(std::size_t pos, Poco::UInt16& val)
|
|||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
unsigned int tempVal = 0;
|
unsigned int tempVal = 0;
|
||||||
|
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), tempVal))
|
||||||
if ( isColumnNull(outputParameter)
|
|
||||||
|| ! Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), tempVal)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = static_cast<UInt16>(tempVal);
|
val = static_cast<UInt16>(tempVal);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -117,9 +103,7 @@ bool Extractor::extract(std::size_t pos, Poco::Int32& val)
|
|||||||
{
|
{
|
||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
if ( isColumnNull(outputParameter)
|
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParse(outputParameter.pData(), val))
|
||||||
|| ! Poco::NumberParser::tryParse(outputParameter.pData(), val)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -132,9 +116,7 @@ bool Extractor::extract(std::size_t pos, Poco::UInt32& val)
|
|||||||
{
|
{
|
||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
if ( isColumnNull(outputParameter)
|
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), val))
|
||||||
|| ! Poco::NumberParser::tryParseUnsigned(outputParameter.pData(), val)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -147,9 +129,7 @@ bool Extractor::extract(std::size_t pos, Poco::Int64& val)
|
|||||||
{
|
{
|
||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
if ( isColumnNull(outputParameter)
|
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParse64(outputParameter.pData(), val))
|
||||||
|| ! Poco::NumberParser::tryParse64(outputParameter.pData(), val)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -162,9 +142,7 @@ bool Extractor::extract(std::size_t pos, Poco::UInt64& val)
|
|||||||
{
|
{
|
||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
if ( isColumnNull(outputParameter)
|
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParseUnsigned64(outputParameter.pData(), val))
|
||||||
|| ! Poco::NumberParser::tryParseUnsigned64(outputParameter.pData(), val)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -179,13 +157,10 @@ bool Extractor::extract(std::size_t pos, long& val)
|
|||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
Poco::Int64 tempVal = 0;
|
Poco::Int64 tempVal = 0;
|
||||||
|
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParse64(outputParameter.pData(), tempVal))
|
||||||
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParse64(outputParameter.pData(), tempVal)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = (long)tempVal;
|
val = (long)tempVal;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -197,14 +172,10 @@ bool Extractor::extract(std::size_t pos, unsigned long& val)
|
|||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
Poco::UInt64 tempVal = 0;
|
Poco::UInt64 tempVal = 0;
|
||||||
|
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParseUnsigned64(outputParameter.pData(), tempVal))
|
||||||
if ( isColumnNull(outputParameter)
|
|
||||||
|| ! Poco::NumberParser::tryParseUnsigned64(outputParameter.pData(), tempVal)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = (unsigned long)tempVal;
|
val = (unsigned long)tempVal;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -216,19 +187,12 @@ bool Extractor::extract(std::size_t pos, bool& val)
|
|||||||
{
|
{
|
||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
if ( isColumnNull(outputParameter))
|
if (isColumnNull(outputParameter))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('t' == *outputParameter.pData())
|
val = 't' == *outputParameter.pData();
|
||||||
{
|
|
||||||
val = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
val = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -239,15 +203,11 @@ bool Extractor::extract(std::size_t pos, float& val)
|
|||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
double tempVal = 0.0;
|
double tempVal = 0.0;
|
||||||
|
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParseFloat(outputParameter.pData(), tempVal))
|
||||||
if ( isColumnNull(outputParameter)
|
|
||||||
|| ! Poco::NumberParser::tryParseFloat(outputParameter.pData(), tempVal)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
val = static_cast<float>(tempVal);
|
||||||
val = (float)tempVal;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -257,9 +217,7 @@ bool Extractor::extract(std::size_t pos, double& val)
|
|||||||
{
|
{
|
||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
if ( isColumnNull(outputParameter)
|
if (isColumnNull(outputParameter) || !Poco::NumberParser::tryParseFloat(outputParameter.pData(), val))
|
||||||
|| ! Poco::NumberParser::tryParseFloat(outputParameter.pData(), val)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -272,11 +230,10 @@ bool Extractor::extract(std::size_t pos, char& val)
|
|||||||
{
|
{
|
||||||
OutputParameter outputParameter = extractPreamble(pos);
|
OutputParameter outputParameter = extractPreamble(pos);
|
||||||
|
|
||||||
if (isColumnNull(outputParameter))
|
if (isColumnNull(outputParameter))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = *outputParameter.pData();
|
val = *outputParameter.pData();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -291,7 +248,6 @@ bool Extractor::extract(std::size_t pos, std::string& val)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
val.assign(outputParameter.pData(), outputParameter.size());
|
val.assign(outputParameter.pData(), outputParameter.size());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -309,32 +265,24 @@ bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
|
|||||||
|
|
||||||
// convert the PostgreSQL text format to binary and append to the BLOB
|
// convert the PostgreSQL text format to binary and append to the BLOB
|
||||||
// Format: \x10843029479abcf ... two characters for every byte
|
// 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());
|
const char * pBLOB = reinterpret_cast<const char*>(outputParameter.pData());
|
||||||
std::size_t blobSize = outputParameter.size();
|
std::size_t blobSize = outputParameter.size();
|
||||||
val = Poco::Data::BLOB(); // don't share contents with _default
|
val = Poco::Data::BLOB(); // don't share contents with _default
|
||||||
|
|
||||||
if ( '\\' == pBLOB[0]
|
if (blobSize > 2 && '\\' == pBLOB[0] && 'x' == pBLOB[1]) // preamble to BYTEA data format in text form is \x
|
||||||
&& 'x' == pBLOB[1] // preamble to BYTEA data format in text form is \x
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
blobSize -= 2; // lose the preamble
|
blobSize -= 2; // lose the preamble
|
||||||
blobSize /= 2; // each byte is encoded as two text characters
|
|
||||||
|
|
||||||
for (int i = 0; i < blobSize * 2; i += 2)
|
Poco::MemoryInputStream mistr(pBLOB + 2, blobSize);
|
||||||
|
Poco::HexBinaryDecoder decoder(mistr);
|
||||||
|
auto* pDecoderBuf = decoder.rdbuf();
|
||||||
|
blobSize /= 2;
|
||||||
|
val.resize(blobSize);
|
||||||
|
char* pData = reinterpret_cast<char*>(val.rawContent());
|
||||||
|
while (blobSize-- > 0)
|
||||||
{
|
{
|
||||||
std::string buffer(&pBLOB[i + 2], 2);
|
*pData++ = pDecoderBuf->sbumpc();
|
||||||
unsigned int binaryBuffer = 0;
|
|
||||||
if (Poco::NumberParser::tryParseHex(buffer, binaryBuffer))
|
|
||||||
{
|
|
||||||
UInt8 finalBinaryBuffer = static_cast<UInt8>(binaryBuffer); // downsize
|
|
||||||
val.appendRaw(&finalBinaryBuffer, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -349,7 +297,6 @@ bool Extractor::extract(std::size_t pos, Poco::Data::CLOB& val)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
val.assignRaw(outputParameter.pData(), outputParameter.size());
|
val.assignRaw(outputParameter.pData(), outputParameter.size());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -367,14 +314,11 @@ bool Extractor::extract(std::size_t pos, DateTime& val)
|
|||||||
|
|
||||||
int tzd = -1;
|
int tzd = -1;
|
||||||
DateTime dateTime;
|
DateTime dateTime;
|
||||||
|
if (!DateTimeParser::tryParse(outputParameter.pData(), dateTime, tzd))
|
||||||
if (! DateTimeParser::tryParse(outputParameter.pData(), dateTime, tzd))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dateTime.makeUTC(tzd);
|
dateTime.makeUTC(tzd);
|
||||||
|
|
||||||
val = dateTime;
|
val = dateTime;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -389,17 +333,13 @@ bool Extractor::extract(std::size_t pos, Date& val)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tzd = -1;
|
int tzd = -1;
|
||||||
DateTime dateTime;
|
DateTime dateTime;
|
||||||
|
if (!DateTimeParser::tryParse(outputParameter.pData(), dateTime, tzd))
|
||||||
if (! DateTimeParser::tryParse(outputParameter.pData(), dateTime, tzd))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dateTime.makeUTC(tzd);
|
dateTime.makeUTC(tzd);
|
||||||
|
|
||||||
val.assign(dateTime.year(), dateTime.month(), dateTime.day());
|
val.assign(dateTime.year(), dateTime.month(), dateTime.day());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -414,10 +354,8 @@ bool Extractor::extract(std::size_t pos, Time& val)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tzd = -1;
|
int tzd = -1;
|
||||||
DateTime dateTime;
|
DateTime dateTime;
|
||||||
|
|
||||||
if (! DateTimeParser::tryParse("%H:%M:%s%z", outputParameter.pData(), dateTime, tzd))
|
if (! DateTimeParser::tryParse("%H:%M:%s%z", outputParameter.pData(), dateTime, tzd))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -108,8 +108,7 @@ bool PostgreSQLStatementImpl::canBind() const
|
|||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if ((_statementExecutor.state() >= StatementExecutor::STMT_COMPILED)
|
if ((_statementExecutor.state() >= StatementExecutor::STMT_COMPILED) && !bindings().empty())
|
||||||
&& !bindings().empty())
|
|
||||||
{
|
{
|
||||||
ret = (*bindings().begin())->canBind();
|
ret = (*bindings().begin())->canBind();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ void SessionHandle::connect(const std::string& aConnectionString)
|
|||||||
|
|
||||||
_pConnection = PQconnectdb(aConnectionString.c_str());
|
_pConnection = PQconnectdb(aConnectionString.c_str());
|
||||||
|
|
||||||
if (! isConnectedNoLock())
|
if (!isConnectedNoLock())
|
||||||
{
|
{
|
||||||
throw ConnectionFailedException(std::string("Connection Error: ") + lastErrorNoLock());
|
throw ConnectionFailedException(std::string("Connection Error: ") + lastErrorNoLock());
|
||||||
}
|
}
|
||||||
@@ -151,6 +151,7 @@ void SessionHandle::disconnect()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: Figure out what happens if a connection is reset with a pending transaction
|
// TODO: Figure out what happens if a connection is reset with a pending transaction
|
||||||
bool SessionHandle::reset()
|
bool SessionHandle::reset()
|
||||||
{
|
{
|
||||||
@@ -174,7 +175,7 @@ std::string SessionHandle::lastError() const
|
|||||||
{
|
{
|
||||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||||
|
|
||||||
if (! isConnectedNoLock())
|
if (!isConnectedNoLock())
|
||||||
{
|
{
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
@@ -196,7 +197,7 @@ void SessionHandle::startTransaction()
|
|||||||
{
|
{
|
||||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||||
|
|
||||||
if (! isConnectedNoLock())
|
if (!isConnectedNoLock())
|
||||||
{
|
{
|
||||||
throw NotConnectedException();
|
throw NotConnectedException();
|
||||||
}
|
}
|
||||||
@@ -223,7 +224,7 @@ void SessionHandle::commit()
|
|||||||
{
|
{
|
||||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||||
|
|
||||||
if (! isConnectedNoLock())
|
if (!isConnectedNoLock())
|
||||||
{
|
{
|
||||||
throw NotConnectedException();
|
throw NotConnectedException();
|
||||||
}
|
}
|
||||||
@@ -247,7 +248,7 @@ void SessionHandle::rollback()
|
|||||||
{
|
{
|
||||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||||
|
|
||||||
if (! isConnectedNoLock())
|
if (!isConnectedNoLock())
|
||||||
{
|
{
|
||||||
throw NotConnectedException();
|
throw NotConnectedException();
|
||||||
}
|
}
|
||||||
@@ -291,7 +292,7 @@ void SessionHandle::setAsynchronousCommit(bool aShouldAsynchronousCommit)
|
|||||||
{
|
{
|
||||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||||
|
|
||||||
if (! isConnectedNoLock())
|
if (!isConnectedNoLock())
|
||||||
{
|
{
|
||||||
throw NotConnectedException();
|
throw NotConnectedException();
|
||||||
}
|
}
|
||||||
@@ -318,7 +319,7 @@ void SessionHandle::cancel()
|
|||||||
{
|
{
|
||||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||||
|
|
||||||
if (! isConnectedNoLock())
|
if (!isConnectedNoLock())
|
||||||
{
|
{
|
||||||
throw NotConnectedException();
|
throw NotConnectedException();
|
||||||
}
|
}
|
||||||
@@ -335,7 +336,7 @@ void SessionHandle::setTransactionIsolation(Poco::UInt32 aTI)
|
|||||||
{
|
{
|
||||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||||
|
|
||||||
if (! isConnectedNoLock())
|
if (!isConnectedNoLock())
|
||||||
{
|
{
|
||||||
throw NotConnectedException();
|
throw NotConnectedException();
|
||||||
}
|
}
|
||||||
@@ -345,7 +346,7 @@ void SessionHandle::setTransactionIsolation(Poco::UInt32 aTI)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! hasTransactionIsolation(aTI))
|
if (!hasTransactionIsolation(aTI))
|
||||||
{
|
{
|
||||||
throw Poco::InvalidArgumentException("setTransactionIsolation()");
|
throw Poco::InvalidArgumentException("setTransactionIsolation()");
|
||||||
}
|
}
|
||||||
@@ -354,12 +355,12 @@ void SessionHandle::setTransactionIsolation(Poco::UInt32 aTI)
|
|||||||
|
|
||||||
switch (aTI)
|
switch (aTI)
|
||||||
{
|
{
|
||||||
case Session::TRANSACTION_READ_COMMITTED:
|
case Session::TRANSACTION_READ_COMMITTED:
|
||||||
isolationLevel = POSTGRESQL_READ_COMMITTED; break;
|
isolationLevel = POSTGRESQL_READ_COMMITTED; break;
|
||||||
case Session::TRANSACTION_REPEATABLE_READ:
|
case Session::TRANSACTION_REPEATABLE_READ:
|
||||||
isolationLevel = POSTGRESQL_REPEATABLE_READ; break;
|
isolationLevel = POSTGRESQL_REPEATABLE_READ; break;
|
||||||
case Session::TRANSACTION_SERIALIZABLE:
|
case Session::TRANSACTION_SERIALIZABLE:
|
||||||
isolationLevel = POSTGRESQL_SERIALIZABLE; break;
|
isolationLevel = POSTGRESQL_SERIALIZABLE; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PGresult* pPQResult = PQexec(_pConnection, Poco::format("SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL %s", isolationLevel).c_str());
|
PGresult* pPQResult = PQexec(_pConnection, Poco::format("SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL %s", isolationLevel).c_str());
|
||||||
@@ -393,12 +394,12 @@ void SessionHandle::deallocatePreparedStatement(const std::string& aPreparedStat
|
|||||||
{
|
{
|
||||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||||
|
|
||||||
if (! isConnectedNoLock())
|
if (!isConnectedNoLock())
|
||||||
{
|
{
|
||||||
throw NotConnectedException();
|
throw NotConnectedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! _inTransaction)
|
if (!_inTransaction)
|
||||||
{
|
{
|
||||||
deallocatePreparedStatementNoLock(aPreparedStatementToDeAllocate);
|
deallocatePreparedStatementNoLock(aPreparedStatementToDeAllocate);
|
||||||
}
|
}
|
||||||
@@ -431,7 +432,7 @@ void SessionHandle::deallocatePreparedStatementNoLock(const std::string& aPrepar
|
|||||||
void SessionHandle::deallocateStoredPreparedStatements()
|
void SessionHandle::deallocateStoredPreparedStatements()
|
||||||
{
|
{
|
||||||
// DO NOT ACQUIRE THE MUTEX IN PRIVATE METHODS
|
// DO NOT ACQUIRE THE MUTEX IN PRIVATE METHODS
|
||||||
while (! _preparedStatementsToBeDeallocated.empty())
|
while (!_preparedStatementsToBeDeallocated.empty())
|
||||||
{
|
{
|
||||||
deallocatePreparedStatementNoLock(_preparedStatementsToBeDeallocated.back());
|
deallocatePreparedStatementNoLock(_preparedStatementsToBeDeallocated.back());
|
||||||
|
|
||||||
@@ -444,7 +445,7 @@ int SessionHandle::serverVersion() const
|
|||||||
{
|
{
|
||||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||||
|
|
||||||
if (! isConnectedNoLock())
|
if (!isConnectedNoLock())
|
||||||
{
|
{
|
||||||
throw NotConnectedException();
|
throw NotConnectedException();
|
||||||
}
|
}
|
||||||
@@ -457,7 +458,7 @@ int SessionHandle::serverProcessID() const
|
|||||||
{
|
{
|
||||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||||
|
|
||||||
if (! isConnectedNoLock())
|
if (!isConnectedNoLock())
|
||||||
{
|
{
|
||||||
throw NotConnectedException();
|
throw NotConnectedException();
|
||||||
}
|
}
|
||||||
@@ -470,7 +471,7 @@ int SessionHandle::protocoVersion() const
|
|||||||
{
|
{
|
||||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||||
|
|
||||||
if (! isConnectedNoLock())
|
if (!isConnectedNoLock())
|
||||||
{
|
{
|
||||||
throw NotConnectedException();
|
throw NotConnectedException();
|
||||||
}
|
}
|
||||||
@@ -483,7 +484,7 @@ std::string SessionHandle::clientEncoding() const
|
|||||||
{
|
{
|
||||||
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
Poco::FastMutex::ScopedLock mutexLocker(_sessionMutex);
|
||||||
|
|
||||||
if (! isConnectedNoLock())
|
if (!isConnectedNoLock())
|
||||||
{
|
{
|
||||||
throw NotConnectedException();
|
throw NotConnectedException();
|
||||||
}
|
}
|
||||||
@@ -502,7 +503,7 @@ SessionParametersMap SessionHandle::setConnectionInfoParameters(PQconninfoOption
|
|||||||
{
|
{
|
||||||
SessionParametersMap sessionParametersMap;
|
SessionParametersMap sessionParametersMap;
|
||||||
|
|
||||||
while (0 != pConnInfOpt->keyword)
|
while (pConnInfOpt->keyword)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -542,7 +543,7 @@ SessionParametersMap SessionHandle::connectionDefaultParameters()
|
|||||||
|
|
||||||
SessionParametersMap SessionHandle::connectionParameters() const
|
SessionParametersMap SessionHandle::connectionParameters() const
|
||||||
{
|
{
|
||||||
if (! isConnected())
|
if (!isConnected())
|
||||||
{
|
{
|
||||||
throw NotConnectedException();
|
throw NotConnectedException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace
|
|||||||
{
|
{
|
||||||
std::string connectionString;
|
std::string connectionString;
|
||||||
|
|
||||||
for (std::map<std::string, std::string>::const_iterator citr = anOptionsMap.begin(); citr != anOptionsMap.end(); ++citr)
|
for (auto citr = anOptionsMap.begin(); citr != anOptionsMap.end(); ++citr)
|
||||||
{
|
{
|
||||||
connectionString.append(citr->first);
|
connectionString.append(citr->first);
|
||||||
connectionString.append("=");
|
connectionString.append("=");
|
||||||
@@ -93,7 +93,7 @@ void SessionImpl::open(const std::string& aConnectionString)
|
|||||||
throw ConnectionException("Session already connected");
|
throw ConnectionException("Session already connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! aConnectionString.empty())
|
if (!aConnectionString.empty())
|
||||||
{
|
{
|
||||||
setConnectionString(aConnectionString);
|
setConnectionString(aConnectionString);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ namespace
|
|||||||
Poco::RegularExpression::Match match = { 0 , 0 }; // Match is a struct, not a class :-(
|
Poco::RegularExpression::Match match = { 0 , 0 }; // Match is a struct, not a class :-(
|
||||||
|
|
||||||
std::size_t startingPosition = 0;
|
std::size_t startingPosition = 0;
|
||||||
|
|
||||||
while (match.offset != std::string::npos)
|
while (match.offset != std::string::npos)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -110,7 +109,7 @@ StatementExecutor::State StatementExecutor::state() const
|
|||||||
|
|
||||||
void StatementExecutor::prepare(const std::string& aSQLStatement)
|
void StatementExecutor::prepare(const std::string& aSQLStatement)
|
||||||
{
|
{
|
||||||
if (! _sessionHandle.isConnected()) throw NotConnectedException();
|
if (!_sessionHandle.isConnected()) throw NotConnectedException();
|
||||||
if (_state >= STMT_COMPILED) return;
|
if (_state >= STMT_COMPILED) return;
|
||||||
|
|
||||||
// clear out the metadata. One way or another it is now obsolete.
|
// clear out the metadata. One way or another it is now obsolete.
|
||||||
@@ -160,7 +159,7 @@ void StatementExecutor::prepare(const std::string& aSQLStatement)
|
|||||||
|
|
||||||
{
|
{
|
||||||
PQResultClear resultClearer(ptrPGResult);
|
PQResultClear resultClearer(ptrPGResult);
|
||||||
if (! ptrPGResult || PQresultStatus(ptrPGResult) != PGRES_COMMAND_OK)
|
if (!ptrPGResult || PQresultStatus(ptrPGResult) != PGRES_COMMAND_OK)
|
||||||
{
|
{
|
||||||
throw StatementException(std::string("postgresql_stmt_describe error: ") +
|
throw StatementException(std::string("postgresql_stmt_describe error: ") +
|
||||||
PQresultErrorMessage (ptrPGResult) + " " + aSQLStatement);
|
PQresultErrorMessage (ptrPGResult) + " " + aSQLStatement);
|
||||||
@@ -186,7 +185,7 @@ void StatementExecutor::prepare(const std::string& aSQLStatement)
|
|||||||
|
|
||||||
void StatementExecutor::bindParams(const InputParameterVector& anInputParameterVector)
|
void StatementExecutor::bindParams(const InputParameterVector& anInputParameterVector)
|
||||||
{
|
{
|
||||||
if (! _sessionHandle.isConnected()) throw NotConnectedException();
|
if (!_sessionHandle.isConnected()) throw NotConnectedException();
|
||||||
|
|
||||||
if (_state < STMT_COMPILED) throw StatementException("Statement is not compiled yet");
|
if (_state < STMT_COMPILED) throw StatementException("Statement is not compiled yet");
|
||||||
|
|
||||||
@@ -203,7 +202,7 @@ void StatementExecutor::bindParams(const InputParameterVector& anInputParameterV
|
|||||||
|
|
||||||
void StatementExecutor::execute()
|
void StatementExecutor::execute()
|
||||||
{
|
{
|
||||||
if (! _sessionHandle.isConnected()) throw NotConnectedException();
|
if (!_sessionHandle.isConnected()) throw NotConnectedException();
|
||||||
|
|
||||||
if (_state < STMT_COMPILED) throw StatementException("Statement is not compiled yet");
|
if (_state < STMT_COMPILED) throw StatementException("Statement is not compiled yet");
|
||||||
|
|
||||||
@@ -225,8 +224,8 @@ void StatementExecutor::execute()
|
|||||||
std::vector<int> parameterLengthVector;
|
std::vector<int> parameterLengthVector;
|
||||||
std::vector<int> parameterFormatVector;
|
std::vector<int> parameterFormatVector;
|
||||||
|
|
||||||
InputParameterVector::const_iterator cItr = _inputParameterVector.begin();
|
InputParameterVector::const_iterator cItr = _inputParameterVector.begin();
|
||||||
InputParameterVector::const_iterator cItrEnd = _inputParameterVector.end();
|
InputParameterVector::const_iterator cItrEnd = _inputParameterVector.end();
|
||||||
|
|
||||||
for (; cItr != cItrEnd; ++cItr)
|
for (; cItr != cItrEnd; ++cItr)
|
||||||
{
|
{
|
||||||
@@ -315,7 +314,7 @@ void StatementExecutor::execute()
|
|||||||
|
|
||||||
bool StatementExecutor::fetch()
|
bool StatementExecutor::fetch()
|
||||||
{
|
{
|
||||||
if (! _sessionHandle.isConnected())
|
if (!_sessionHandle.isConnected())
|
||||||
{
|
{
|
||||||
throw NotConnectedException();
|
throw NotConnectedException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,13 +27,9 @@ namespace PostgreSQL {
|
|||||||
std::string Utility::serverInfo(SessionHandle* aHandlePtr)
|
std::string Utility::serverInfo(SessionHandle* aHandlePtr)
|
||||||
{
|
{
|
||||||
std::string srvrInfo = "Process ID: ";
|
std::string srvrInfo = "Process ID: ";
|
||||||
|
|
||||||
srvrInfo.append(Poco::NumberFormatter::format(aHandlePtr->serverProcessID()));
|
srvrInfo.append(Poco::NumberFormatter::format(aHandlePtr->serverProcessID()));
|
||||||
|
|
||||||
srvrInfo.append(" Protocol Version: ");
|
srvrInfo.append(" Protocol Version: ");
|
||||||
|
|
||||||
srvrInfo.append(Poco::NumberFormatter::format(aHandlePtr->protocoVersion()));
|
srvrInfo.append(Poco::NumberFormatter::format(aHandlePtr->protocoVersion()));
|
||||||
|
|
||||||
return srvrInfo;
|
return srvrInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +57,6 @@ std::string Utility::hostInfo(SessionHandle* aHandlePtr)
|
|||||||
SessionParametersMap parametersMap = aHandlePtr->connectionParameters();
|
SessionParametersMap parametersMap = aHandlePtr->connectionParameters();
|
||||||
|
|
||||||
SessionParametersMap::const_iterator cItr = parametersMap.find("host");
|
SessionParametersMap::const_iterator cItr = parametersMap.find("host");
|
||||||
|
|
||||||
if (parametersMap.end() == cItr)
|
if (parametersMap.end() == cItr)
|
||||||
{
|
{
|
||||||
return std::string();
|
return std::string();
|
||||||
|
|||||||
@@ -130,7 +130,18 @@ public:
|
|||||||
if (_pContent->empty())
|
if (_pContent->empty())
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return &(*_pContent)[0];
|
return _pContent->data();
|
||||||
|
}
|
||||||
|
|
||||||
|
T* rawContent()
|
||||||
|
/// Returns the raw content.
|
||||||
|
///
|
||||||
|
/// If the LOB is empty, returns NULL.
|
||||||
|
{
|
||||||
|
if (_pContent->empty())
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return _pContent->data();
|
||||||
}
|
}
|
||||||
|
|
||||||
void assignVal(std::size_t count, const T& val)
|
void assignVal(std::size_t count, const T& val)
|
||||||
@@ -155,6 +166,18 @@ public:
|
|||||||
_pContent->insert(_pContent->end(), pChar, pChar+count);
|
_pContent->insert(_pContent->end(), pChar, pChar+count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reserve(std::size_t size)
|
||||||
|
/// Sets the capacity of the internal buffer.
|
||||||
|
{
|
||||||
|
_pContent->reserve(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resize(std::size_t size)
|
||||||
|
/// Resizes the internal buffer.
|
||||||
|
{
|
||||||
|
_pContent->resize(size);
|
||||||
|
}
|
||||||
|
|
||||||
void clear(bool doCompact = false)
|
void clear(bool doCompact = false)
|
||||||
/// Clears the content of the blob.
|
/// Clears the content of the blob.
|
||||||
/// If doCompact is true, trims the excess capacity.
|
/// If doCompact is true, trims the excess capacity.
|
||||||
@@ -185,6 +208,12 @@ public:
|
|||||||
return static_cast<std::size_t>(_pContent->size());
|
return static_cast<std::size_t>(_pContent->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t capacity() const
|
||||||
|
/// Returns the capacity of the underlying buffer.
|
||||||
|
{
|
||||||
|
return static_cast<std::size_t>(_pContent->capacity());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ContentPtr _pContent;
|
ContentPtr _pContent;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user