merge pg binary extraction support

This commit is contained in:
Günter Obiltschnig
2022-05-17 07:22:04 +02:00
parent 9577af8c6c
commit 562b3b90c0
17 changed files with 1712 additions and 70 deletions

View File

@@ -0,0 +1,346 @@
//
// BinaryExtractor.h
//
// Library: Data/PostgreSQL
// Package: PostgreSQL
// Module: Extractor
//
// Definition of the BinaryExtractor class.
//
// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef SQL_PostgreSQL_BinaryExtractor_INCLUDED
#define SQL_PostgreSQL_BinaryExtractor_INCLUDED
#include "Poco/Data/PostgreSQL/PostgreSQL.h"
#include "Poco/Data/PostgreSQL/PostgreSQLTypes.h"
#include "Poco/Data/PostgreSQL/StatementExecutor.h"
#include "Poco/Data/AbstractExtractor.h"
#include "Poco/Data/LOB.h"
#include "Poco/Types.h"
#include "Poco/Any.h"
#include "Poco/DynamicAny.h"
#include "Poco/Dynamic/Var.h"
namespace Poco {
namespace Data {
namespace PostgreSQL {
class PostgreSQL_API BinaryExtractor: public Poco::Data::AbstractExtractor
/// Extracts and converts data values from the result row returned by PostgreSQL.
/// If NULL is received, the incoming val value is not changed and false is returned
{
public:
using Ptr = SharedPtr<BinaryExtractor>;
BinaryExtractor(StatementExecutor& st);
/// Creates the Extractor.
virtual ~BinaryExtractor();
/// Destroys the Extractor.
virtual bool extract(std::size_t pos, Poco::Int8& val);
/// Extracts an Int8.
virtual bool extract(std::size_t pos, Poco::UInt8& val);
/// Extracts an UInt8.
virtual bool extract(std::size_t pos, Poco::Int16& val);
/// Extracts an Int16.
virtual bool extract(std::size_t pos, Poco::UInt16& val);
/// Extracts an UInt16.
virtual bool extract(std::size_t pos, Poco::Int32& val);
/// Extracts an Int32.
virtual bool extract(std::size_t pos, Poco::UInt32& val);
/// Extracts an UInt32.
virtual bool extract(std::size_t pos, Poco::Int64& val);
/// Extracts an Int64.
virtual bool extract(std::size_t pos, Poco::UInt64& val);
/// Extracts an UInt64.
#ifndef POCO_INT64_IS_LONG
virtual bool extract(std::size_t pos, long& val);
/// Extracts a long. Returns false if null was received.
virtual bool extract(std::size_t pos, unsigned long& val);
/// Extracts an unsigned long. Returns false if null was received.
#endif
virtual bool extract(std::size_t pos, bool& val);
/// Extracts a boolean.
virtual bool extract(std::size_t pos, float& val);
/// Extracts a float.
virtual bool extract(std::size_t pos, double& val);
/// Extracts a double.
virtual bool extract(std::size_t pos, char& val);
/// Extracts a single character.
virtual bool extract(std::size_t pos, std::string& val);
/// Extracts a string.
virtual bool extract(std::size_t pos, Poco::Data::BLOB& val);
/// Extracts a BLOB.
virtual bool extract(std::size_t pos, Poco::Data::CLOB& val);
/// Extracts a CLOB.
virtual bool extract(std::size_t pos, DateTime& val);
/// Extracts a DateTime. Returns false if null was received.
virtual bool extract(std::size_t pos, Date& val);
/// Extracts a Date. Returns false if null was received.
virtual bool extract(std::size_t pos, Time& val);
/// Extracts a Time. Returns false if null was received.
virtual bool extract(std::size_t pos, UUID& val);
/// Extracts a UUID. Returns false if null was received.
virtual bool extract(std::size_t pos, Any& val);
/// Extracts an Any. Returns false if null was received.
virtual bool extract(std::size_t pos, Dynamic::Var& val);
/// Extracts a Dynamic::Var. Returns false if null was received.
virtual bool isNull(std::size_t col, std::size_t row);
/// Returns true if the value at [col,row] position is null.
virtual void reset();
/// Resets any information internally cached by the extractor.
////////////
// Not implemented extract functions
////////////
virtual bool extract(std::size_t pos, std::vector<Poco::Int8>& val);
/// Extracts an Int8 vector.
virtual bool extract(std::size_t pos, std::deque<Poco::Int8>& val);
/// Extracts an Int8 deque.
virtual bool extract(std::size_t pos, std::list<Poco::Int8>& val);
/// Extracts an Int8 list.
virtual bool extract(std::size_t pos, std::vector<Poco::UInt8>& val);
/// Extracts an UInt8 vector.
virtual bool extract(std::size_t pos, std::deque<Poco::UInt8>& val);
/// Extracts an UInt8 deque.
virtual bool extract(std::size_t pos, std::list<Poco::UInt8>& val);
/// Extracts an UInt8 list.
virtual bool extract(std::size_t pos, std::vector<Poco::Int16>& val);
/// Extracts an Int16 vector.
virtual bool extract(std::size_t pos, std::deque<Poco::Int16>& val);
/// Extracts an Int16 deque.
virtual bool extract(std::size_t pos, std::list<Poco::Int16>& val);
/// Extracts an Int16 list.
virtual bool extract(std::size_t pos, std::vector<Poco::UInt16>& val);
/// Extracts an UInt16 vector.
virtual bool extract(std::size_t pos, std::deque<Poco::UInt16>& val);
/// Extracts an UInt16 deque.
virtual bool extract(std::size_t pos, std::list<Poco::UInt16>& val);
/// Extracts an UInt16 list.
virtual bool extract(std::size_t pos, std::vector<Poco::Int32>& val);
/// Extracts an Int32 vector.
virtual bool extract(std::size_t pos, std::deque<Poco::Int32>& val);
/// Extracts an Int32 deque.
virtual bool extract(std::size_t pos, std::list<Poco::Int32>& val);
/// Extracts an Int32 list.
virtual bool extract(std::size_t pos, std::vector<Poco::UInt32>& val);
/// Extracts an UInt32 vector.
virtual bool extract(std::size_t pos, std::deque<Poco::UInt32>& val);
/// Extracts an UInt32 deque.
virtual bool extract(std::size_t pos, std::list<Poco::UInt32>& val);
/// Extracts an UInt32 list.
virtual bool extract(std::size_t pos, std::vector<Poco::Int64>& val);
/// Extracts an Int64 vector.
virtual bool extract(std::size_t pos, std::deque<Poco::Int64>& val);
/// Extracts an Int64 deque.
virtual bool extract(std::size_t pos, std::list<Poco::Int64>& val);
/// Extracts an Int64 list.
virtual bool extract(std::size_t pos, std::vector<Poco::UInt64>& val);
/// Extracts an UInt64 vector.
virtual bool extract(std::size_t pos, std::deque<Poco::UInt64>& val);
/// Extracts an UInt64 deque.
virtual bool extract(std::size_t pos, std::list<Poco::UInt64>& val);
/// Extracts an UInt64 list.
#ifndef POCO_INT64_IS_LONG
virtual bool extract(std::size_t pos, std::vector<long>& val);
/// Extracts a long vector.
virtual bool extract(std::size_t pos, std::deque<long>& val);
/// Extracts a long deque.
virtual bool extract(std::size_t pos, std::list<long>& val);
/// Extracts a long list.
#endif
virtual bool extract(std::size_t pos, std::vector<bool>& val);
/// Extracts a boolean vector.
virtual bool extract(std::size_t pos, std::deque<bool>& val);
/// Extracts a boolean deque.
virtual bool extract(std::size_t pos, std::list<bool>& val);
/// Extracts a boolean list.
virtual bool extract(std::size_t pos, std::vector<float>& val);
/// Extracts a float vector.
virtual bool extract(std::size_t pos, std::deque<float>& val);
/// Extracts a float deque.
virtual bool extract(std::size_t pos, std::list<float>& val);
/// Extracts a float list.
virtual bool extract(std::size_t pos, std::vector<double>& val);
/// Extracts a double vector.
virtual bool extract(std::size_t pos, std::deque<double>& val);
/// Extracts a double deque.
virtual bool extract(std::size_t pos, std::list<double>& val);
/// Extracts a double list.
virtual bool extract(std::size_t pos, std::vector<char>& val);
/// Extracts a character vector.
virtual bool extract(std::size_t pos, std::deque<char>& val);
/// Extracts a character deque.
virtual bool extract(std::size_t pos, std::list<char>& val);
/// Extracts a character list.
virtual bool extract(std::size_t pos, std::vector<std::string>& val);
/// Extracts a string vector.
virtual bool extract(std::size_t pos, std::deque<std::string>& val);
/// Extracts a string deque.
virtual bool extract(std::size_t pos, std::list<std::string>& val);
/// Extracts a string list.
virtual bool extract(std::size_t pos, std::vector<BLOB>& val);
/// Extracts a BLOB vector.
virtual bool extract(std::size_t pos, std::deque<BLOB>& val);
/// Extracts a BLOB deque.
virtual bool extract(std::size_t pos, std::list<BLOB>& val);
/// Extracts a BLOB list.
virtual bool extract(std::size_t pos, std::vector<CLOB>& val);
/// Extracts a CLOB vector.
virtual bool extract(std::size_t pos, std::deque<CLOB>& val);
/// Extracts a CLOB deque.
virtual bool extract(std::size_t pos, std::list<CLOB>& val);
/// Extracts a CLOB list.
virtual bool extract(std::size_t pos, std::vector<DateTime>& val);
/// Extracts a DateTime vector.
virtual bool extract(std::size_t pos, std::deque<DateTime>& val);
/// Extracts a DateTime deque.
virtual bool extract(std::size_t pos, std::list<DateTime>& val);
/// Extracts a DateTime list.
virtual bool extract(std::size_t pos, std::vector<Date>& val);
/// Extracts a Date vector.
virtual bool extract(std::size_t pos, std::deque<Date>& val);
/// Extracts a Date deque.
virtual bool extract(std::size_t pos, std::list<Date>& val);
/// Extracts a Date list.
virtual bool extract(std::size_t pos, std::vector<Time>& val);
/// Extracts a Time vector.
virtual bool extract(std::size_t pos, std::deque<Time>& val);
/// Extracts a Time deque.
virtual bool extract(std::size_t pos, std::list<Time>& val);
/// Extracts a Time list.
virtual bool extract(std::size_t pos, std::vector<Any>& val);
/// Extracts an Any vector.
virtual bool extract(std::size_t pos, std::deque<Any>& val);
/// Extracts an Any deque.
virtual bool extract(std::size_t pos, std::list<Any>& val);
/// Extracts an Any list.
virtual bool extract(std::size_t pos, std::vector<Dynamic::Var>& val);
/// Extracts a Dynamic::Var vector.
virtual bool extract(std::size_t pos, std::deque<Dynamic::Var>& val);
/// Extracts a Dynamic::Var deque.
virtual bool extract(std::size_t pos, std::list<Dynamic::Var>& val);
/// Extracts a Dynamic::Var list.
private:
const OutputParameter& extractPreamble(std::size_t aPosition) const;
bool isColumnNull(const OutputParameter& anOutputParameter) const;
// Prevent VC8 warning "operator= could not be generated"
BinaryExtractor& operator = (const BinaryExtractor&);
private:
StatementExecutor& _statementExecutor;
};
//
// inlines
//
inline bool BinaryExtractor::isColumnNull(const OutputParameter& anOutputParameter) const
{
return anOutputParameter.isNull() || 0 == anOutputParameter.pData();
}
} } } // namespace Poco::Data::PostgreSQL
#endif // SQL_PostgreSQL_BinaryExtractor_INCLUDED

View File

@@ -351,6 +351,15 @@ private:
};
//
// inlines
//
inline bool Extractor::isColumnNull(const OutputParameter& anOutputParameter) const
{
return anOutputParameter.isNull() || 0 == anOutputParameter.pData();
}
} } } // namespace Poco::Data::PostgreSQL

View File

@@ -21,9 +21,9 @@
#include "Poco/Data/PostgreSQL/PostgreSQL.h"
#include "Poco/Data/PostgreSQL/SessionImpl.h"
#include "Poco/Data/PostgreSQL/Binder.h"
#include "Poco/Data/PostgreSQL/Extractor.h"
#include "Poco/Data/PostgreSQL/StatementExecutor.h"
#include "Poco/Data/StatementImpl.h"
#include "Poco/Data/AbstractExtractor.h"
#include "Poco/SharedPtr.h"
#include "Poco/Format.h"
@@ -89,7 +89,7 @@ private:
StatementExecutor _statementExecutor;
Binder::Ptr _pBinder;
Extractor::Ptr _pExtractor;
AbstractExtractor::Ptr _pExtractor;
NextState _hasNext;
};

View File

@@ -31,36 +31,37 @@ namespace PostgreSQL {
/// Oid constants duplicated from PostgreSQL "include/postgresql/server/catalog/pg_type.h"
/// because PostgreSQL compile time definitions are too onerous to reproduce for this module
const Oid INVALIDOID = 0;
const Oid BOOLOID = 16;
const Oid BOOLOID = 16;
const Oid INT2OID = 21;
const Oid INT4OID = 23;
const Oid INT8OID = 20;
const Oid INT2OID = 21;
const Oid INT4OID = 23;
const Oid INT8OID = 20;
const Oid FLOAT8OID = 701; // double
const Oid FLOAT4OID = 700;
const Oid NUMERICOID = 1700;
const Oid FLOAT8OID = 701; // double
const Oid FLOAT4OID = 700;
const Oid NUMERICOID = 1700;
const Oid CHAROID = 18;
const Oid BPCHAROID = 1042; // fixed length char
const Oid VARCHAROID = 1043;
const Oid CHAROID = 18;
const Oid BPCHAROID = 1042; // fixed length char
const Oid VARCHAROID = 1043;
const Oid BYTEAOID = 17; // BLOB
const Oid TEXTOID = 25; // CLOB
const Oid BYTEAOID = 17; // BLOB
const Oid TEXTOID = 25; // CLOB
const Oid DATEOID = 1082;
const Oid TIMEOID = 1083;
const Oid TIMETZOID = 1266;
const Oid TIMESTAMPOID = 1114;
const Oid TIMESTAMPZOID = 1184;
const Oid DATEOID = 1082;
const Oid TIMEOID = 1083;
const Oid TIMETZOID = 1266;
const Oid TIMESTAMPOID = 1114;
const Oid TIMESTAMPTZOID = 1184;
// future use
const Oid BITOID = 1560;
const Oid VARYBITOID = 1562;
const Oid CASHOID = 790;
const Oid MACADDROID = 829;
const Oid UUIDOID = 2950;
const Oid BITOID = 1560;
const Oid VARYBITOID = 1562;
const Oid CASHOID = 790;
const Oid MACADDROID = 829;
const Oid UUIDOID = 2950;
Poco::Data::MetaColumn::ColumnDataType oidToColumnDataType(const Oid anOID);
@@ -132,7 +133,7 @@ private:
};
using OutputParameterVector = std::vector <OutputParameter>;
using OutputParameterVector = std::vector<OutputParameter>;
class PQConnectionInfoOptionsFree

View File

@@ -155,6 +155,9 @@ public:
std::string clientEncoding() const;
/// returns the client encoding
std::string parameterStatus(const std::string& param) const;
/// Returns the value configured on the server for the given parameter.
int libpqVersion() const;
/// returns the version of libpq

View File

@@ -111,6 +111,19 @@ public:
bool isAsynchronousCommit(const std::string& aName = std::string()) const;
/// is the connection in Asynchronous commit mode?
void setBinaryExtraction(const std::string& feature, bool enabled);
/// Sets the "binaryExtraction" feature. If set, column values received from
/// PostgreSQL client will be extracted as binary values. This improves
/// extraction performance, but will not work with all types.
///
/// If not set, all column values will be extracted as strings. This gives
/// lower performance, but allows to extract also types not supported
/// directly by Poco::Data.
bool isBinaryExtraction(const std::string& feature = std::string()) const;
/// Returns true if binary extraction is enabled, otherwise false.
/// See setBinaryExtraction() for more information.
SessionHandle& handle();
/// Get handle
@@ -120,7 +133,8 @@ public:
private:
std::string _connectorName;
mutable SessionHandle _sessionHandle;
std::size_t _timeout;
std::size_t _timeout = 0;
bool _binaryExtraction = false;
};
@@ -159,6 +173,12 @@ inline std::size_t SessionImpl::getConnectionTimeout() const
}
inline bool SessionImpl::isBinaryExtraction(const std::string&) const
{
return _binaryExtraction;
}
} } } // namespace Poco::Data::PostgreSQL

View File

@@ -43,7 +43,7 @@ public:
STMT_EXECUTED
};
explicit StatementExecutor(SessionHandle& aSessionHandle);
explicit StatementExecutor(SessionHandle& aSessionHandle, bool binaryExtraction);
/// Creates the StatementExecutor.
~StatementExecutor();
@@ -90,6 +90,7 @@ private:
typedef std::vector<MetaColumn> ColVec;
SessionHandle& _sessionHandle;
bool _binaryExtraction;
State _state;
PGresult* _pResultHandle;
std::string _SQLStatement;