1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-01-31 18:07:14 +01:00
Sandu Liviu Catalin 4a6bfc086c 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.
2021-01-30 08:51:39 +02:00

871 lines
18 KiB
C++

//
// 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