improve BLOB handling, clean-up code

This commit is contained in:
Günter Obiltschnig
2021-06-25 09:22:58 +02:00
parent 52e0581edc
commit ca3d168153
11 changed files with 101 additions and 145 deletions

View File

@@ -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;

View File

@@ -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;
} }
} }

View File

@@ -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?

View File

@@ -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)
{ {

View File

@@ -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;

View File

@@ -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();
} }

View File

@@ -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();
} }

View File

@@ -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);
} }

View File

@@ -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();
} }

View File

@@ -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();

View File

@@ -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;
}; };