Major plugin refactor and cleanup.

Switched to POCO library for unified platform/library interface.
Deprecated the external module API. It was creating more problems than solving.
Removed most built-in libraries in favor of system libraries for easier maintenance.
Cleaned and secured code with help from static analyzers.
This commit is contained in:
Sandu Liviu Catalin committed 2021-01-30 08:51:39 +02:00
1 parent e0e34b4030
commit 4a6bfc086c
6219 files changed
+1209835 -454916

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,99 @@
//
// ConnectionHandle.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: ConnectionHandle
//
// Definition of ConnectionHandle.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_ConnectionHandle_INCLUDED
#define Data_ODBC_ConnectionHandle_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/ODBC/EnvironmentHandle.h"
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
#include <sqltypes.h>
namespace Poco {
namespace Data {
namespace ODBC {
class SessionImpl;
class ODBC_API ConnectionHandle
/// ODBC connection handle class
{
public:
ConnectionHandle(EnvironmentHandle* pEnvironment = 0);
/// Creates the ConnectionHandle.
~ConnectionHandle();
/// Creates the ConnectionHandle.
operator const SQLHDBC& () const;
/// Const conversion operator into reference to native type.
const SQLHDBC& handle() const;
/// Returns const reference to handle;
private:
operator SQLHDBC& ();
/// Conversion operator into reference to native type.
SQLHDBC& handle();
/// Returns reference to handle;
ConnectionHandle(const ConnectionHandle&);
const ConnectionHandle& operator=(const ConnectionHandle&);
const EnvironmentHandle* _pEnvironment;
SQLHDBC _hdbc;
bool _ownsEnvironment;
friend class Poco::Data::ODBC::SessionImpl;
};
//
// inlines
//
inline ConnectionHandle::operator const SQLHDBC& () const
{
return handle();
}
inline const SQLHDBC& ConnectionHandle::handle() const
{
return _hdbc;
}
inline ConnectionHandle::operator SQLHDBC& ()
{
return handle();
}
inline SQLHDBC& ConnectionHandle::handle()
{
return _hdbc;
}
} } } // namespace Poco::Data::ODBC
#endif
@@ -0,0 +1,96 @@
//
// Connector.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: Connector
//
// Definition of the Connector class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_Connector_INCLUDED
#define Data_ODBC_Connector_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/Connector.h"
namespace Poco {
namespace Data {
namespace ODBC {
class ODBC_API Connector: public Poco::Data::Connector
/// Connector instantiates SqLite SessionImpl objects.
{
public:
static const std::string KEY;
/// Keyword for creating ODBC sessions.
Connector();
/// Creates the Connector.
~Connector();
/// Destroys the Connector.
const std::string& name() const;
/// Returns the name associated with this connector.
Poco::AutoPtr<Poco::Data::SessionImpl> createSession(const std::string& connectionString,
std::size_t timeout = Poco::Data::SessionImpl::LOGIN_TIMEOUT_DEFAULT);
/// Creates a ODBC SessionImpl object and initializes it with the given connectionString.
static void registerConnector();
/// Registers the Connector under the Keyword Connector::KEY at the Poco::Data::SessionFactory
static void unregisterConnector();
/// Unregisters the Connector under the Keyword Connector::KEY at the Poco::Data::SessionFactory
static void bindStringToLongVarChar(bool flag = true);
/// If set to true (default), std::string is bound to SQL_LONGVARCHAR.
///
/// This can cause issues with SQL Server, resulting in an error
/// ("The data types varchar and text are incompatible in the equal to operator")
/// when comparing against a VARCHAR.
///
/// Set this to false to bind std::string to SQL_VARCHAR.
///
/// NOTE: This is a global setting, affecting all sessions.
/// This setting should not be changed after the first Session has
/// been created.
static bool stringBoundToLongVarChar();
/// Returns true if std::string is bound to SQL_LONGVARCHAR,
/// otherwise false (bound to SQL_VARCHAR).
private:
static bool _bindStringToLongVarChar;
};
///
/// inlines
///
inline const std::string& Connector::name() const
{
return KEY;
}
inline bool Connector::stringBoundToLongVarChar()
{
return _bindStringToLongVarChar;
}
} } } // namespace Poco::Data::ODBC
#endif // Data_ODBC_Connector_INCLUDED
@@ -0,0 +1,239 @@
//
// Diagnostics.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: Diagnostics
//
// Definition of Diagnostics.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_Diagnostics_INCLUDED
#define Data_ODBC_Diagnostics_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#include <vector>
#include <cstring>
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
#include <sqlext.h>
namespace Poco {
namespace Data {
namespace ODBC {
template <typename H, SQLSMALLINT handleType>
class Diagnostics
/// Utility class providing functionality for retrieving ODBC diagnostic
/// records. Diagnostics object must be created with corresponding handle
/// as constructor argument. During construction, diagnostic records fields
/// are populated and the object is ready for querying.
{
public:
static const unsigned int SQL_STATE_SIZE = SQL_SQLSTATE_SIZE + 1;
static const unsigned int SQL_MESSAGE_LENGTH = SQL_MAX_MESSAGE_LENGTH + 1;
static const unsigned int SQL_NAME_LENGTH = 128;
static const std::string DATA_TRUNCATED;
struct DiagnosticFields
{
/// SQLGetDiagRec fields
SQLCHAR _sqlState[SQL_STATE_SIZE];
SQLCHAR _message[SQL_MESSAGE_LENGTH];
SQLINTEGER _nativeError;
};
typedef std::vector<DiagnosticFields> FieldVec;
typedef typename FieldVec::const_iterator Iterator;
explicit Diagnostics(const H& handle): _handle(handle)
/// Creates and initializes the Diagnostics.
{
std::memset(_connectionName, 0, sizeof(_connectionName));
std::memset(_serverName, 0, sizeof(_serverName));
diagnostics();
}
~Diagnostics()
/// Destroys the Diagnostics.
{
}
std::string sqlState(int index) const
/// Returns SQL state.
{
poco_assert (index < count());
return std::string((char*) _fields[index]._sqlState);
}
std::string message(int index) const
/// Returns error message.
{
poco_assert (index < count());
return std::string((char*) _fields[index]._message);
}
long nativeError(int index) const
/// Returns native error code.
{
poco_assert (index < count());
return _fields[index]._nativeError;
}
std::string connectionName() const
/// Returns the connection name.
/// If there is no active connection, connection name defaults to NONE.
/// If connection name is not applicable for query context (such as when querying environment handle),
/// connection name defaults to NOT_APPLICABLE.
{
return std::string((char*) _connectionName);
}
std::string serverName() const
/// Returns the server name.
/// If the connection has not been established, server name defaults to NONE.
/// If server name is not applicable for query context (such as when querying environment handle),
/// connection name defaults to NOT_APPLICABLE.
{
return std::string((char*) _serverName);
}
int count() const
/// Returns the number of contained diagnostic records.
{
return (int) _fields.size();
}
void reset()
/// Resets the diagnostic fields container.
{
_fields.clear();
}
const FieldVec& fields() const
{
return _fields;
}
Iterator begin() const
{
return _fields.begin();
}
Iterator end() const
{
return _fields.end();
}
const Diagnostics& diagnostics()
{
DiagnosticFields df;
SQLSMALLINT count = 1;
SQLSMALLINT messageLength = 0;
static const std::string none = "None";
static const std::string na = "Not applicable";
reset();
while (!Utility::isError(SQLGetDiagRec(handleType,
_handle,
count,
df._sqlState,
&df._nativeError,
df._message,
SQL_MESSAGE_LENGTH,
&messageLength)))
{
if (1 == count)
{
// success of the following two calls is optional
// (they fail if connection has not been established yet
// or return empty string if not applicable for the context)
if (Utility::isError(SQLGetDiagField(handleType,
_handle,
count,
SQL_DIAG_CONNECTION_NAME,
_connectionName,
sizeof(_connectionName),
&messageLength)))
{
std::size_t len = sizeof(_connectionName) > none.length() ?
none.length() : sizeof(_connectionName) - 1;
std::memcpy(_connectionName, none.c_str(), len);
}
else if (0 == _connectionName[0])
{
std::size_t len = sizeof(_connectionName) > na.length() ?
na.length() : sizeof(_connectionName) - 1;
std::memcpy(_connectionName, na.c_str(), len);
}
if (Utility::isError(SQLGetDiagField(handleType,
_handle,
count,
SQL_DIAG_SERVER_NAME,
_serverName,
sizeof(_serverName),
&messageLength)))
{
std::size_t len = sizeof(_serverName) > none.length() ?
none.length() : sizeof(_serverName) - 1;
std::memcpy(_serverName, none.c_str(), len);
}
else if (0 == _serverName[0])
{
std::size_t len = sizeof(_serverName) > na.length() ?
na.length() : sizeof(_serverName) - 1;
std::memcpy(_serverName, na.c_str(), len);
}
}
_fields.push_back(df);
std::memset(df._sqlState, 0, SQL_STATE_SIZE);
std::memset(df._message, 0, SQL_MESSAGE_LENGTH);
df._nativeError = 0;
++count;
}
return *this;
}
private:
Diagnostics();
/// SQLGetDiagField fields
SQLCHAR _connectionName[SQL_NAME_LENGTH];
SQLCHAR _serverName[SQL_NAME_LENGTH];
/// Diagnostics container
FieldVec _fields;
/// Context handle
const H& _handle;
};
typedef Diagnostics<SQLHENV, SQL_HANDLE_ENV> EnvironmentDiagnostics;
typedef Diagnostics<SQLHDBC, SQL_HANDLE_DBC> ConnectionDiagnostics;
typedef Diagnostics<SQLHSTMT, SQL_HANDLE_STMT> StatementDiagnostics;
typedef Diagnostics<SQLHDESC, SQL_HANDLE_DESC> DescriptorDiagnostics;
} } } // namespace Poco::Data::ODBC
#endif
@@ -0,0 +1,94 @@
//
// EnvironmentHandle.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: EnvironmentHandle
//
// Definition of EnvironmentHandle.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_EnvironmentHandle_INCLUDED
#define Data_ODBC_EnvironmentHandle_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
#include <sqltypes.h>
namespace Poco {
namespace Data {
namespace ODBC {
class ODBC_API EnvironmentHandle
/// ODBC environment handle class
{
public:
EnvironmentHandle();
/// Creates the EnvironmentHandle.
~EnvironmentHandle();
/// Destroys the EnvironmentHandle.
operator const SQLHENV& () const;
/// Const conversion operator into reference to native type.
const SQLHENV& handle() const;
/// Returns const reference to handle.
private:
operator SQLHENV& ();
/// Conversion operator into reference to native type.
SQLHENV& handle();
/// Returns reference to handle.
EnvironmentHandle(const EnvironmentHandle&);
const EnvironmentHandle& operator=(const EnvironmentHandle&);
SQLHENV _henv;
bool _isOwner;
};
///
/// inlines
///
inline EnvironmentHandle::operator const SQLHENV& () const
{
return handle();
}
inline const SQLHENV& EnvironmentHandle::handle() const
{
return _henv;
}
inline EnvironmentHandle::operator SQLHENV& ()
{
return handle();
}
inline SQLHENV& EnvironmentHandle::handle()
{
return _henv;
}
} } } // namespace Poco::Data::ODBC
#endif
+124
View File
@@ -0,0 +1,124 @@
//
// Error.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: Error
//
// Definition of Error.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_Error_INCLUDED
#define Data_ODBC_Error_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/ODBC/Utility.h"
#include "Poco/Data/ODBC/Diagnostics.h"
#include "Poco/Format.h"
#include <vector>
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
#include <sqlext.h>
namespace Poco {
namespace Data {
namespace ODBC {
template <typename H, SQLSMALLINT handleType>
class Error
/// Class encapsulating ODBC diagnostic record collection. Collection is generated
/// during construction. Class provides access and string generation for the collection
/// as well as individual diagnostic records.
{
public:
explicit Error(const H& handle) : _diagnostics(handle)
/// Creates the Error.
{
}
~Error()
/// Destroys the Error.
{
}
const Diagnostics<H, handleType>& diagnostics() const
/// Returns the associated diagnostics.
{
return _diagnostics;
}
int count() const
/// Returns the count of diagnostic records.
{
return (int) _diagnostics.count();
}
std::string& toString(int index, std::string& str) const
/// Generates the string for the diagnostic record.
{
if ((index < 0) || (index > (count() - 1)))
return str;
std::string s;
Poco::format(s,
"===========================\n"
"ODBC Diagnostic record #%d:\n"
"===========================\n"
"SQLSTATE = %s\nNative Error Code = %ld\n%s\n\n",
index + 1,
_diagnostics.sqlState(index),
_diagnostics.nativeError(index),
_diagnostics.message(index));
str.append(s);
return str;
}
std::string toString() const
/// Generates the string for the diagnostic record collection.
{
std::string str;
Poco::format(str,
"Connection:%s\nServer:%s\n",
_diagnostics.connectionName(),
_diagnostics.serverName());
std::string s;
for (int i = 0; i < count(); ++i)
{
s.clear();
str.append(toString(i, s));
}
return str;
}
private:
Error();
Diagnostics<H, handleType> _diagnostics;
};
typedef Error<SQLHENV, SQL_HANDLE_ENV> EnvironmentError;
typedef Error<SQLHDBC, SQL_HANDLE_DBC> ConnectionError;
typedef Error<SQLHSTMT, SQL_HANDLE_STMT> StatementError;
typedef Error<SQLHSTMT, SQL_HANDLE_DESC> DescriptorError;
} } } // namespace Poco::Data::ODBC
#endif
+728
View File
@@ -0,0 +1,728 @@
//
// Extractor.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: Extractor
//
// Definition of the Extractor class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_Extractor_INCLUDED
#define Data_ODBC_Extractor_INCLUDED
#include "Poco/Data/Constants.h"
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/AbstractExtractor.h"
#include "Poco/Data/ODBC/Preparator.h"
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
#include "Poco/Data/ODBC/Error.h"
#include "Poco/Data/ODBC/Utility.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/DateTime.h"
#include "Poco/Any.h"
#include "Poco/Dynamic/Var.h"
#include "Poco/Nullable.h"
#include "Poco/UTFString.h"
#include "Poco/Exception.h"
#include <map>
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
#include <sqltypes.h>
namespace Poco {
namespace Data {
namespace ODBC {
class ODBC_API Extractor: public Poco::Data::AbstractExtractor
/// Extracts and converts data values from the result row returned by ODBC.
/// If NULL is received, the incoming val value is not changed and false is returned
{
public:
typedef Preparator::Ptr PreparatorPtr;
Extractor(const StatementHandle& rStmt,
Preparator::Ptr pPreparator);
/// Creates the Extractor.
~Extractor();
/// Destroys the Extractor.
bool extract(std::size_t pos, Poco::Int8& val);
/// Extracts an Int8.
bool extract(std::size_t pos, std::vector<Poco::Int8>& val);
/// Extracts an Int8 vector.
bool extract(std::size_t pos, std::deque<Poco::Int8>& val);
/// Extracts an Int8 deque.
bool extract(std::size_t pos, std::list<Poco::Int8>& val);
/// Extracts an Int8 list.
bool extract(std::size_t pos, Poco::UInt8& val);
/// Extracts an UInt8.
bool extract(std::size_t pos, std::vector<Poco::UInt8>& val);
/// Extracts an UInt8 vector.
bool extract(std::size_t pos, std::deque<Poco::UInt8>& val);
/// Extracts an UInt8 deque.
bool extract(std::size_t pos, std::list<Poco::UInt8>& val);
/// Extracts an UInt8 list.
bool extract(std::size_t pos, Poco::Int16& val);
/// Extracts an Int16.
bool extract(std::size_t pos, std::vector<Poco::Int16>& val);
/// Extracts an Int16 vector.
bool extract(std::size_t pos, std::deque<Poco::Int16>& val);
/// Extracts an Int16 deque.
bool extract(std::size_t pos, std::list<Poco::Int16>& val);
/// Extracts an Int16 list.
bool extract(std::size_t pos, Poco::UInt16& val);
/// Extracts an UInt16.
bool extract(std::size_t pos, std::vector<Poco::UInt16>& val);
/// Extracts an UInt16 vector.
bool extract(std::size_t pos, std::deque<Poco::UInt16>& val);
/// Extracts an UInt16 deque.
bool extract(std::size_t pos, std::list<Poco::UInt16>& val);
/// Extracts an UInt16 list.
bool extract(std::size_t pos, Poco::Int32& val);
/// Extracts an Int32.
bool extract(std::size_t pos, std::vector<Poco::Int32>& val);
/// Extracts an Int32 vector.
bool extract(std::size_t pos, std::deque<Poco::Int32>& val);
/// Extracts an Int32 deque.
bool extract(std::size_t pos, std::list<Poco::Int32>& val);
/// Extracts an Int32 list.
bool extract(std::size_t pos, Poco::UInt32& val);
/// Extracts an UInt32.
bool extract(std::size_t pos, std::vector<Poco::UInt32>& val);
/// Extracts an UInt32 vector.
bool extract(std::size_t pos, std::deque<Poco::UInt32>& val);
/// Extracts an UInt32 deque.
bool extract(std::size_t pos, std::list<Poco::UInt32>& val);
/// Extracts an UInt32 list.
bool extract(std::size_t pos, Poco::Int64& val);
/// Extracts an Int64.
bool extract(std::size_t pos, std::vector<Poco::Int64>& val);
/// Extracts an Int64 vector.
bool extract(std::size_t pos, std::deque<Poco::Int64>& val);
/// Extracts an Int64 deque.
bool extract(std::size_t pos, std::list<Poco::Int64>& val);
/// Extracts an Int64 list.
bool extract(std::size_t pos, Poco::UInt64& val);
/// Extracts an UInt64.
bool extract(std::size_t pos, std::vector<Poco::UInt64>& val);
/// Extracts an UInt64 vector.
bool extract(std::size_t pos, std::deque<Poco::UInt64>& val);
/// Extracts an UInt64 deque.
bool extract(std::size_t pos, std::list<Poco::UInt64>& val);
/// Extracts an UInt64 list.
#ifndef POCO_INT64_IS_LONG
bool extract(std::size_t pos, long& val);
/// Extracts a long.
bool extract(std::size_t pos, unsigned long& val);
/// Extracts an unsigned long.
bool extract(std::size_t pos, std::vector<long>& val);
/// Extracts a long vector.
bool extract(std::size_t pos, std::deque<long>& val);
/// Extracts a long deque.
bool extract(std::size_t pos, std::list<long>& val);
/// Extracts a long list.
#endif
bool extract(std::size_t pos, bool& val);
/// Extracts a boolean.
bool extract(std::size_t pos, std::vector<bool>& val);
/// Extracts a boolean vector.
bool extract(std::size_t pos, std::deque<bool>& val);
/// Extracts a boolean deque.
bool extract(std::size_t pos, std::list<bool>& val);
/// Extracts a boolean list.
bool extract(std::size_t pos, float& val);
/// Extracts a float.
bool extract(std::size_t pos, std::vector<float>& val);
/// Extracts a float vector.
bool extract(std::size_t pos, std::deque<float>& val);
/// Extracts a float deque.
bool extract(std::size_t pos, std::list<float>& val);
/// Extracts a float list.
bool extract(std::size_t pos, double& val);
/// Extracts a double.
bool extract(std::size_t pos, std::vector<double>& val);
/// Extracts a double vector.
bool extract(std::size_t pos, std::deque<double>& val);
/// Extracts a double deque.
bool extract(std::size_t pos, std::list<double>& val);
/// Extracts a double list.
bool extract(std::size_t pos, char& val);
/// Extracts a single character.
bool extract(std::size_t pos, std::vector<char>& val);
/// Extracts a single character vector.
bool extract(std::size_t pos, std::deque<char>& val);
/// Extracts a single character deque.
bool extract(std::size_t pos, std::list<char>& val);
/// Extracts a single character list.
bool extract(std::size_t pos, std::string& val);
/// Extracts a string.
bool extract(std::size_t pos, std::vector<std::string>& val);
/// Extracts a string vector.
bool extract(std::size_t pos, std::deque<std::string>& val);
/// Extracts a string deque.
bool extract(std::size_t pos, std::list<std::string>& val);
/// Extracts a string list.
/// Extracts a single character list.
bool extract(std::size_t pos, UTF16String& val);
/// Extracts a string.
bool extract(std::size_t pos, std::vector<UTF16String>& val);
/// Extracts a string vector.
bool extract(std::size_t pos, std::deque<UTF16String>& val);
/// Extracts a string deque.
bool extract(std::size_t pos, std::list<UTF16String>& val);
/// Extracts a string list.
bool extract(std::size_t pos, Poco::Data::BLOB& val);
/// Extracts a BLOB.
bool extract(std::size_t pos, Poco::Data::CLOB& val);
/// Extracts a CLOB.
bool extract(std::size_t pos, std::vector<Poco::Data::BLOB>& val);
/// Extracts a BLOB vector.
bool extract(std::size_t pos, std::deque<Poco::Data::BLOB>& val);
/// Extracts a BLOB deque.
bool extract(std::size_t pos, std::list<Poco::Data::BLOB>& val);
/// Extracts a BLOB list.
bool extract(std::size_t pos, std::vector<Poco::Data::CLOB>& val);
/// Extracts a CLOB vector.
bool extract(std::size_t pos, std::deque<Poco::Data::CLOB>& val);
/// Extracts a CLOB deque.
bool extract(std::size_t pos, std::list<Poco::Data::CLOB>& val);
/// Extracts a CLOB list.
bool extract(std::size_t pos, Poco::Data::Date& val);
/// Extracts a Date.
bool extract(std::size_t pos, std::vector<Poco::Data::Date>& val);
/// Extracts a Date vector.
bool extract(std::size_t pos, std::deque<Poco::Data::Date>& val);
/// Extracts a Date deque.
bool extract(std::size_t pos, std::list<Poco::Data::Date>& val);
/// Extracts a Date list.
bool extract(std::size_t pos, Poco::Data::Time& val);
/// Extracts a Time.
bool extract(std::size_t pos, std::vector<Poco::Data::Time>& val);
/// Extracts a Time vector.
bool extract(std::size_t pos, std::deque<Poco::Data::Time>& val);
/// Extracts a Time deque.
bool extract(std::size_t pos, std::list<Poco::Data::Time>& val);
/// Extracts a Time list.
bool extract(std::size_t pos, Poco::DateTime& val);
/// Extracts a DateTime.
bool extract(std::size_t pos, std::vector<Poco::DateTime>& val);
/// Extracts a DateTime vector.
bool extract(std::size_t pos, std::deque<Poco::DateTime>& val);
/// Extracts a DateTime deque.
bool extract(std::size_t pos, std::list<Poco::DateTime>& val);
/// Extracts a DateTime list.
bool extract(std::size_t pos, Poco::Any& val);
/// Extracts an Any.
bool extract(std::size_t pos, std::vector<Poco::Any>& val);
/// Extracts an Any vector.
bool extract(std::size_t pos, std::deque<Poco::Any>& val);
/// Extracts an Any deque.
bool extract(std::size_t pos, std::list<Poco::Any>& val);
/// Extracts an Any list.
bool extract(std::size_t pos, Poco::DynamicAny& val);
/// Extracts a DynamicAny.
bool extract(std::size_t pos, std::vector<Poco::DynamicAny>& val);
/// Extracts a DynamicAny vector.
bool extract(std::size_t pos, std::deque<Poco::DynamicAny>& val);
/// Extracts a DynamicAny deque.
bool extract(std::size_t pos, std::list<Poco::DynamicAny>& val);
/// Extracts a DynamicAny list.
void setDataExtraction(Preparator::DataExtraction ext);
/// Set data extraction mode.
Preparator::DataExtraction getDataExtraction() const;
/// Returns data extraction mode.
bool isNull(std::size_t col, std::size_t row = POCO_DATA_INVALID_ROW);
/// Returns true if the value at [col,row] is null.
void reset();
/// Resets the internally cached length indicators.
private:
static const int CHUNK_SIZE = 1024;
/// Amount of data retrieved in one SQLGetData() request when doing manual extract.
static const std::string FLD_SIZE_EXCEEDED_FMT;
/// String format for the exception message when the field size is exceeded.
void checkDataSize(std::size_t size);
/// This check is only performed for bound data
/// retrieval from variable length columns.
/// The reason for this check is to ensure we can
/// accept the value ODBC driver is supplying
/// (i.e. the bound buffer is large enough to receive
/// the returned value)
void resizeLengths(std::size_t pos);
/// Resizes the vector holding extracted data lengths to the
/// appropriate size.
template<typename T>
bool extractBoundImpl(std::size_t pos, T& val)
{
if (isNull(pos)) return false;
poco_assert_dbg (typeid(T) == _pPreparator->at(pos).type());
val = *AnyCast<T>(&_pPreparator->at(pos));
return true;
}
bool extractBoundImpl(std::size_t pos, Poco::Data::BLOB& val);
bool extractBoundImpl(std::size_t pos, Poco::Data::CLOB& val);
template <typename C>
bool extractBoundImplContainer(std::size_t pos, C& val)
{
typedef typename C::value_type Type;
poco_assert_dbg (typeid(std::vector<Type>) == _pPreparator->at(pos).type());
std::vector<Type>& v = RefAnyCast<std::vector<Type> >(_pPreparator->at(pos));
val.assign(v.begin(), v.end());
return true;
}
bool extractBoundImplContainer(std::size_t pos, std::vector<std::string>& values);
bool extractBoundImplContainer(std::size_t pos, std::deque<std::string>& values);
bool extractBoundImplContainer(std::size_t pos, std::list<std::string>& values);
bool extractBoundImplContainer(std::size_t pos, std::vector<Poco::UTF16String>& values);
bool extractBoundImplContainer(std::size_t pos, std::deque<Poco::UTF16String>& values);
bool extractBoundImplContainer(std::size_t pos, std::list<Poco::UTF16String>& values);
bool extractBoundImplContainer(std::size_t pos, std::vector<Poco::Data::CLOB>& values);
bool extractBoundImplContainer(std::size_t pos, std::deque<Poco::Data::CLOB>& values);
bool extractBoundImplContainer(std::size_t pos, std::list<Poco::Data::CLOB>& values);
bool extractBoundImplContainer(std::size_t pos, std::vector<Poco::Data::BLOB>& values);
bool extractBoundImplContainer(std::size_t pos, std::deque<Poco::Data::BLOB>& values);
bool extractBoundImplContainer(std::size_t pos, std::list<Poco::Data::BLOB>& values);
template <typename C>
bool extractBoundImplContainerString(std::size_t pos, C& values)
{
typedef typename C::value_type StringType;
typedef typename C::iterator ItType;
typedef typename StringType::value_type CharType;
CharType** pc = AnyCast<CharType*>(&(_pPreparator->at(pos)));
poco_assert_dbg (pc);
poco_assert_dbg (_pPreparator->bulkSize() == values.size());
std::size_t colWidth = columnSize(pos);
ItType it = values.begin();
ItType end = values.end();
for (int row = 0; it != end; ++it, ++row)
{
it->assign(*pc + row * colWidth / sizeof(CharType), _pPreparator->actualDataSize(pos, row));
// clean up superfluous null chars returned by some drivers
typename StringType::size_type trimLen = 0;
typename StringType::reverse_iterator sIt = it->rbegin();
typename StringType::reverse_iterator sEnd = it->rend();
for (; sIt != sEnd; ++sIt)
{
if (*sIt == '\0') ++trimLen;
else break;
}
if (trimLen) it->assign(it->begin(), it->begin() + it->length() - trimLen);
}
return true;
}
template <typename C>
bool extractBoundImplContainerLOB(std::size_t pos, C& values)
{
typedef typename C::value_type LOBType;
typedef typename LOBType::ValueType CharType;
typedef typename C::iterator ItType;
CharType** pc = AnyCast<CharType*>(&(_pPreparator->at(pos)));
poco_assert_dbg (pc);
poco_assert_dbg (_pPreparator->bulkSize() == values.size());
std::size_t colWidth = _pPreparator->maxDataSize(pos);
ItType it = values.begin();
ItType end = values.end();
for (int row = 0; it != end; ++it, ++row)
it->assignRaw(*pc + row * colWidth, _pPreparator->actualDataSize(pos, row));
return true;
}
template<typename T>
bool extractBoundImplLOB(std::size_t pos, Poco::Data::LOB<T>& val)
{
if (isNull(pos)) return false;
std::size_t dataSize = _pPreparator->actualDataSize(pos);
checkDataSize(dataSize);
T* sp = AnyCast<T*>(_pPreparator->at(pos));
val.assignRaw(sp, dataSize);
return true;
}
template<typename T>
bool extractManualImpl(std::size_t pos, T& val, SQLSMALLINT cType)
{
SQLRETURN rc = 0;
T value = (T) 0;
resizeLengths(pos);
rc = SQLGetData(_rStmt,
(SQLUSMALLINT) pos + 1,
cType, //C data type
&value, //returned value
0, //buffer length (ignored)
&_lengths[pos]); //length indicator
if (Utility::isError(rc))
throw StatementException(_rStmt, "SQLGetData()");
if (isNullLengthIndicator(_lengths[pos]))
return false;
else
{
//for fixed-length data, buffer must be large enough
//otherwise, driver may write past the end
poco_assert_dbg (_lengths[pos] <= sizeof(T));
val = value;
}
return true;
}
template <typename T, typename NT>
bool extAny(std::size_t pos, T& val)
{
NT i;
if (extract(pos, i))
{
val = i;
return true;
}
else
{
val = Nullable<NT>();
return false;
}
}
template <typename T>
bool extractImpl(std::size_t pos, T& val)
/// Utility function for extraction of Any and DynamicAny.
{
ODBCMetaColumn column(_rStmt, pos);
switch (column.type())
{
case MetaColumn::FDT_INT8:
{ return extAny<T, Poco::Int8>(pos, val); }
case MetaColumn::FDT_UINT8:
{ return extAny<T, Poco::UInt8>(pos, val); }
case MetaColumn::FDT_INT16:
{ return extAny<T, Poco::Int16>(pos, val); }
case MetaColumn::FDT_UINT16:
{ return extAny<T, Poco::UInt16>(pos, val); }
case MetaColumn::FDT_INT32:
{ return extAny<T, Poco::Int32>(pos, val); }
case MetaColumn::FDT_UINT32:
{ return extAny<T, Poco::UInt32>(pos, val); }
case MetaColumn::FDT_INT64:
{ return extAny<T, Poco::Int64>(pos, val); }
case MetaColumn::FDT_UINT64:
{ return extAny<T, Poco::UInt64>(pos, val); }
case MetaColumn::FDT_BOOL:
{ return extAny<T, bool>(pos, val); }
case MetaColumn::FDT_FLOAT:
{ return extAny<T, float>(pos, val); }
case MetaColumn::FDT_DOUBLE:
{ return extAny<T, double>(pos, val); }
case MetaColumn::FDT_STRING:
{ return extAny<T, std::string>(pos, val); }
case MetaColumn::FDT_WSTRING:
{ return extAny<T, Poco::UTF16String>(pos, val); }
case MetaColumn::FDT_BLOB:
{ return extAny<T, Poco::Data::BLOB>(pos, val); }
case MetaColumn::FDT_CLOB:
{ return extAny<T, Poco::Data::CLOB>(pos, val); }
case MetaColumn::FDT_DATE:
{ return extAny<T, Poco::Data::Date>(pos, val); }
case MetaColumn::FDT_TIME:
{ return extAny<T, Poco::Data::Time>(pos, val); }
case MetaColumn::FDT_TIMESTAMP:
{ return extAny<T, Poco::DateTime>(pos, val); }
default:
throw DataFormatException("Unsupported data type.");
}
return false;
}
bool isNullLengthIndicator(SQLLEN val) const;
/// The reason for this utility wrapper are platforms where
/// SQLLEN macro (a.k.a. SQLINTEGER) yields 64-bit value,
/// while SQL_NULL_DATA (#define'd as -1 literal) remains 32-bit.
SQLINTEGER columnSize(std::size_t pos) const;
const StatementHandle& _rStmt;
PreparatorPtr _pPreparator;
Preparator::DataExtraction _dataExtraction;
std::vector<SQLLEN> _lengths;
};
///
/// inlines
///
inline bool Extractor::extractBoundImpl(std::size_t pos, Poco::Data::BLOB& val)
{
return extractBoundImplLOB<BLOB::ValueType>(pos, val);
}
inline bool Extractor::extractBoundImpl(std::size_t pos, Poco::Data::CLOB& val)
{
return extractBoundImplLOB<CLOB::ValueType>(pos, val);
}
inline bool Extractor::extractBoundImplContainer(std::size_t pos, std::vector<std::string>& values)
{
return extractBoundImplContainerString(pos, values);
}
inline bool Extractor::extractBoundImplContainer(std::size_t pos, std::deque<std::string>& values)
{
return extractBoundImplContainerString(pos, values);
}
inline bool Extractor::extractBoundImplContainer(std::size_t pos, std::list<std::string>& values)
{
return extractBoundImplContainerString(pos, values);
}
inline bool Extractor::extractBoundImplContainer(std::size_t pos, std::vector<Poco::UTF16String>& values)
{
return extractBoundImplContainerString(pos, values);
}
inline bool Extractor::extractBoundImplContainer(std::size_t pos, std::deque<Poco::UTF16String>& values)
{
return extractBoundImplContainerString(pos, values);
}
inline bool Extractor::extractBoundImplContainer(std::size_t pos, std::list<Poco::UTF16String>& values)
{
return extractBoundImplContainerString(pos, values);
}
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
std::vector<Poco::Data::CLOB>& values)
{
return extractBoundImplContainerLOB(pos, values);
}
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
std::deque<Poco::Data::CLOB>& values)
{
return extractBoundImplContainerLOB(pos, values);
}
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
std::list<Poco::Data::CLOB>& values)
{
return extractBoundImplContainerLOB(pos, values);
}
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
std::vector<Poco::Data::BLOB>& values)
{
return extractBoundImplContainerLOB(pos, values);
}
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
std::deque<Poco::Data::BLOB>& values)
{
return extractBoundImplContainerLOB(pos, values);
}
inline bool Extractor::extractBoundImplContainer(std::size_t pos,
std::list<Poco::Data::BLOB>& values)
{
return extractBoundImplContainerLOB(pos, values);
}
inline void Extractor::setDataExtraction(Preparator::DataExtraction ext)
{
_pPreparator->setDataExtraction(_dataExtraction = ext);
}
inline Preparator::DataExtraction Extractor::getDataExtraction() const
{
return _dataExtraction;
}
inline void Extractor::reset()
{
_lengths.clear();
}
inline void Extractor::resizeLengths(std::size_t pos)
{
if (pos >= _lengths.size())
_lengths.resize(pos + 1, (SQLLEN) 0);
}
inline bool Extractor::isNullLengthIndicator(SQLLEN val) const
{
return SQL_NULL_DATA == (int) val;
}
inline SQLINTEGER Extractor::columnSize(std::size_t pos) const
{
std::size_t size = ODBCMetaColumn(_rStmt, pos).length();
std::size_t maxSize = _pPreparator->maxDataSize(pos);
if (size > maxSize) size = maxSize;
return (SQLINTEGER) size;
}
} } } // namespace Poco::Data::ODBC
#endif // Data_ODBC_Extractor_INCLUDED
+116
View File
@@ -0,0 +1,116 @@
//
// Handle.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: Handle
//
// Definition of Handle.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_Handle_INCLUDED
#define Data_ODBC_Handle_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/ODBC/EnvironmentHandle.h"
#include "Poco/Data/ODBC/ConnectionHandle.h"
#include "Poco/Data/ODBC/ODBCException.h"
#include "Poco/Data/ODBC/Utility.h"
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
#include <sqltypes.h>
namespace Poco {
namespace Data {
namespace ODBC {
template <typename H, SQLSMALLINT handleType>
class Handle
/// ODBC handle class template
{
public:
Handle(const ConnectionHandle& rConnection):
_rConnection(rConnection),
_handle(0)
/// Creates the Handle.
{
if (Utility::isError(SQLAllocHandle(handleType,
_rConnection,
&_handle)))
{
throw ODBCException("Could not allocate statement handle.");
}
}
~Handle()
/// Destroys the Handle.
{
try
{
#if defined(_DEBUG)
SQLRETURN rc =
#endif
SQLFreeHandle(handleType, _handle);
// N.B. Destructors should not throw, but neither do we want to
// leak resources. So, we throw here in debug mode if things go bad.
poco_assert_dbg (!Utility::isError(rc));
}
catch (...)
{
poco_unexpected();
}
}
operator const H& () const
/// Const conversion operator into reference to native type.
{
return handle();
}
const H& handle() const
/// Returns const reference to native type.
{
return _handle;
}
private:
Handle(const Handle&);
const Handle& operator=(const Handle&);
operator H& ()
/// Conversion operator into reference to native type.
{
return handle();
}
H& handle()
/// Returns reference to native type.
{
return _handle;
}
const ConnectionHandle& _rConnection;
H _handle;
friend class ODBCStatementImpl;
};
typedef Handle<SQLHSTMT, SQL_HANDLE_STMT> StatementHandle;
typedef Handle<SQLHDESC, SQL_HANDLE_DESC> DescriptorHandle;
} } } // namespace Poco::Data::ODBC
#endif
+69
View File
@@ -0,0 +1,69 @@
//
// ODBC.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: ODBC
//
// Basic definitions for the Poco ODBC library.
// This file must be the first file included by every other ODBC
// header file.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_ODBC_INCLUDED
#define Data_ODBC_ODBC_INCLUDED
#include "Poco/Foundation.h"
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
//
// The following block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the ODBC_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// ODBC_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
//
#if defined(_WIN32) && defined(POCO_DLL)
#if defined(ODBC_EXPORTS)
#define ODBC_API __declspec(dllexport)
#else
#define ODBC_API __declspec(dllimport)
#endif
#endif
#if !defined(ODBC_API)
#if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined (__GNUC__) && (__GNUC__ >= 4)
#define ODBC_API __attribute__ ((visibility ("default")))
#else
#define ODBC_API
#endif
#endif
#include "Poco/Data/ODBC/Unicode.h"
//
// Automatically link Data library.
//
#if defined(_MSC_VER)
#if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(ODBC_EXPORTS)
#pragma comment(lib, "PocoDataODBC" POCO_LIB_SUFFIX)
#endif
#endif
#endif // ODBC_ODBC_INCLUDED
@@ -0,0 +1,150 @@
//
// ODBCException.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: ODBCException
//
// Definition of ODBCException.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_ODBCException_INCLUDED
#define Data_ODBC_ODBCException_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/ODBC/Utility.h"
#include "Poco/Data/ODBC/Diagnostics.h"
#include "Poco/Data/ODBC/Error.h"
#include "Poco/Data/DataException.h"
#include "Poco/Format.h"
namespace Poco {
namespace Data {
namespace ODBC {
POCO_DECLARE_EXCEPTION(ODBC_API, ODBCException, Poco::Data::DataException)
POCO_DECLARE_EXCEPTION(ODBC_API, InsufficientStorageException, ODBCException)
POCO_DECLARE_EXCEPTION(ODBC_API, UnknownDataLengthException, ODBCException)
POCO_DECLARE_EXCEPTION(ODBC_API, DataTruncatedException, ODBCException)
template <class H, SQLSMALLINT handleType>
class HandleException: public ODBCException
{
public:
HandleException(const H& handle): _error(handle)
/// Creates HandleException
{
message(_error.toString());
}
HandleException(const H& handle, const std::string& msg):
ODBCException(msg),
_error(handle)
/// Creates HandleException
{
extendedMessage(_error.toString());
}
HandleException(const H& handle, const std::string& msg, const std::string& arg):
ODBCException(msg, arg),
_error(handle)
/// Creates HandleException
{
}
HandleException(const H& handle, const std::string& msg, const Poco::Exception& exc):
ODBCException(msg, exc),
_error(handle)
/// Creates HandleException
{
}
HandleException(const HandleException& exc):
ODBCException(exc),
_error(exc._error)
/// Creates HandleException
{
}
~HandleException() noexcept
/// Destroys HandleException
{
}
HandleException& operator = (const HandleException& exc)
/// Assignment operator
{
if (&exc != this) _error = exc._error;
return *this;
}
const char* name() const noexcept
/// Returns the name of the exception
{
return "ODBC handle exception";
}
const char* className() const noexcept
/// Returns the HandleException class name.
{
return typeid(*this).name();
}
Poco::Exception* clone() const
/// Clones the HandleException
{
return new HandleException(*this);
}
void rethrow() const
/// Re-throws the HandleException.
{
throw *this;
}
const Diagnostics<H, handleType>& diagnostics() const
/// Returns error diagnostics.
{
return _error.diagnostics();
}
std::string toString() const
/// Returns the formatted error diagnostics for the handle.
{
return Poco::format("ODBC Error: %s\n===================\n%s\n",
std::string(what()),
_error.toString());
}
static std::string errorString(const H& handle)
/// Returns the error diagnostics string for the handle.
{
return Error<H, handleType>(handle).toString();
}
private:
Error<H, handleType> _error;
};
typedef HandleException<SQLHENV, SQL_HANDLE_ENV> EnvironmentException;
typedef HandleException<SQLHDBC, SQL_HANDLE_DBC> ConnectionException;
typedef HandleException<SQLHSTMT, SQL_HANDLE_STMT> StatementException;
typedef HandleException<SQLHDESC, SQL_HANDLE_DESC> DescriptorException;
} } } // namespace Poco::Data::ODBC
#endif
@@ -0,0 +1,92 @@
//
// ODBCMetaColumn.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: ODBCMetaColumn
//
// Definition of ODBCMetaColumn.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_ODBCColumn_INCLUDED
#define Data_ODBC_ODBCColumn_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/ODBC/Error.h"
#include "Poco/Data/ODBC/Handle.h"
#include "Poco/Data/ODBC/ODBCException.h"
#include "Poco/Data/MetaColumn.h"
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
#include <sqlext.h>
namespace Poco {
namespace Data {
namespace ODBC {
class ODBC_API ODBCMetaColumn: public MetaColumn
{
public:
explicit ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position);
/// Creates the ODBCMetaColumn.
~ODBCMetaColumn();
/// Destroys the ODBCMetaColumn.
std::size_t dataLength() const;
/// A numeric value that is either the maximum or actual character length of a character
/// string or binary data type. It is the maximum character length for a fixed-length data type,
/// or the actual character length for a variable-length data type. Its value always excludes the
/// null-termination byte that ends the character string.
/// This information is returned from the SQL_DESC_LENGTH record field of the IRD.
bool isUnsigned() const;
/// Returns true if column is unsigned or a non-numeric data type.
private:
ODBCMetaColumn();
static const int NAME_BUFFER_LENGTH = 2048;
struct ColumnDescription
{
SQLCHAR name[NAME_BUFFER_LENGTH];
SQLSMALLINT nameBufferLength;
SQLSMALLINT dataType;
SQLULEN size;
SQLSMALLINT decimalDigits;
SQLSMALLINT isNullable;
};
void init();
void getDescription();
SQLLEN _dataLength;
const StatementHandle& _rStmt;
ColumnDescription _columnDesc;
};
///
/// inlines
///
inline std::size_t ODBCMetaColumn::dataLength() const
{
return _dataLength;
}
} } } // namespace Poco::Data::ODBC
#endif
@@ -0,0 +1,206 @@
//
// ODBCStatementImpl.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: ODBCStatementImpl
//
// Definition of the ODBCStatementImpl class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_ODBCStatementImpl_INCLUDED
#define Data_ODBC_ODBCStatementImpl_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/ODBC/SessionImpl.h"
#include "Poco/Data/ODBC/Binder.h"
#include "Poco/Data/ODBC/Extractor.h"
#include "Poco/Data/ODBC/Preparator.h"
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
#include "Poco/Data/StatementImpl.h"
#include "Poco/Data/Column.h"
#include "Poco/SharedPtr.h"
#include "Poco/Format.h"
#include <sstream>
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
#include <sqltypes.h>
namespace Poco {
namespace Data {
namespace ODBC {
class ODBC_API ODBCStatementImpl: public Poco::Data::StatementImpl
/// Implements statement functionality needed for ODBC
{
public:
ODBCStatementImpl(SessionImpl& rSession);
/// Creates the ODBCStatementImpl.
~ODBCStatementImpl();
/// Destroys the ODBCStatementImpl.
protected:
std::size_t columnsReturned() const;
/// Returns number of columns returned by query.
int affectedRowCount() const;
/// Returns the number of affected rows.
/// Used to find out the number of rows affected by insert or update.
const MetaColumn& metaColumn(std::size_t pos) const;
/// Returns column meta data.
bool hasNext();
/// Returns true if a call to next() will return data.
std::size_t next();
/// Retrieves the next row or set of rows from the resultset.
/// Returns the number of rows retrieved.
/// Will throw, if the resultset is empty.
bool canBind() const;
/// Returns true if a valid statement is set and we can bind.
bool canCompile() const;
/// Returns true if another compile is possible.
void compileImpl();
/// Compiles the statement, doesn't bind yet.
/// Does nothing if the statement has already been compiled.
void bindImpl();
/// Binds all parameters and executes the statement.
AbstractExtraction::ExtractorPtr extractor();
/// Returns the concrete extractor used by the statement.
AbstractBinding::BinderPtr binder();
/// Returns the concrete binder used by the statement.
std::string nativeSQL();
/// Returns the SQL string as modified by the driver.
private:
typedef Poco::Data::AbstractBindingVec Bindings;
typedef Poco::SharedPtr<Binder> BinderPtr;
typedef Poco::Data::AbstractExtractionVec Extractions;
typedef Poco::SharedPtr<Preparator> PreparatorPtr;
typedef std::vector<PreparatorPtr> PreparatorVec;
typedef Poco::SharedPtr<Extractor> ExtractorPtr;
typedef std::vector<ExtractorPtr> ExtractorVec;
typedef std::vector<ODBCMetaColumn*> ColumnPtrVec;
typedef std::vector<ColumnPtrVec> ColumnPtrVecVec;
static const std::string INVALID_CURSOR_STATE;
void clear();
/// Closes the cursor and resets indicator variables.
void doBind();
/// Binds parameters.
void makeInternalExtractors();
/// Creates internal extractors if none were supplied from the user.
bool isStoredProcedure() const;
/// Returns true if SQL is a stored procedure call.
void doPrepare();
/// Prepares placeholders for data returned by statement.
/// It is called during statement compilation for SQL statements
/// returning data. For stored procedures returning datasets,
/// it is called upon the first check for data availability
/// (see hasNext() function).
bool hasData() const;
/// Returns true if statement returns data.
void makeStep();
/// Fetches the next row of data.
bool nextRowReady() const;
/// Returns true if there is a row fetched but not yet extracted.
void putData();
/// Called whenever SQLExecute returns SQL_NEED_DATA. This is expected
/// behavior for PB_AT_EXEC binding mode.
void getData();
void addPreparator();
void fillColumns();
void checkError(SQLRETURN rc, const std::string& msg="");
const SQLHDBC& _rConnection;
const StatementHandle _stmt;
PreparatorVec _preparations;
BinderPtr _pBinder;
ExtractorVec _extractors;
bool _stepCalled;
int _nextResponse;
ColumnPtrVecVec _columnPtrs;
bool _prepared;
mutable std::size_t _affectedRowCount;
bool _canCompile;
};
//
// inlines
//
inline AbstractExtraction::ExtractorPtr ODBCStatementImpl::extractor()
{
poco_assert_dbg (currentDataSet() < _extractors.size());
poco_assert_dbg (_extractors[currentDataSet()]);
return _extractors[currentDataSet()];
}
inline AbstractBinding::BinderPtr ODBCStatementImpl::binder()
{
poco_assert_dbg (!_pBinder.isNull());
return _pBinder;
}
inline std::size_t ODBCStatementImpl::columnsReturned() const
{
poco_assert_dbg (currentDataSet() < _preparations.size());
poco_assert_dbg (_preparations[currentDataSet()]);
return static_cast<std::size_t>(_preparations[currentDataSet()]->columns());
}
inline bool ODBCStatementImpl::hasData() const
{
return (columnsReturned() > 0);
}
inline bool ODBCStatementImpl::nextRowReady() const
{
return (!Utility::isError(_nextResponse));
}
inline bool ODBCStatementImpl::canCompile() const
{
return _canCompile;
}
} } } // namespace Poco::Data::ODBC
#endif // Data_ODBC_ODBCStatementImpl_INCLUDED
+111
View File
@@ -0,0 +1,111 @@
//
// Parameter.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: Parameter
//
// Definition of Parameter.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_Parameter_INCLUDED
#define Data_ODBC_Parameter_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/ODBC/Handle.h"
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
#include <sqlext.h>
namespace Poco {
namespace Data {
namespace ODBC {
class ODBC_API Parameter
{
public:
explicit Parameter(const StatementHandle& rStmt, std::size_t colNum);
/// Creates the Parameter.
~Parameter();
/// Destroys the Parameter.
std::size_t number() const;
/// Returns the column number.
std::size_t dataType() const;
/// Returns the SQL data type.
std::size_t columnSize() const;
/// Returns the the size of the column or expression of the corresponding
/// parameter marker as defined by the data source.
std::size_t decimalDigits() const;
/// Returns the number of decimal digits of the column or expression
/// of the corresponding parameter as defined by the data source.
bool isNullable() const;
/// Returns true if column allows null values, false otherwise.
private:
Parameter();
void init();
SQLSMALLINT _dataType;
SQLULEN _columnSize;
SQLSMALLINT _decimalDigits;
SQLSMALLINT _isNullable;
const StatementHandle& _rStmt;
std::size_t _number;
};
///
/// inlines
///
inline std::size_t Parameter::number() const
{
return _number;
}
inline std::size_t Parameter::dataType() const
{
return _dataType;
}
inline std::size_t Parameter::columnSize() const
{
return _columnSize;
}
inline std::size_t Parameter::decimalDigits() const
{
return _decimalDigits;
}
inline bool Parameter::isNullable() const
{
return SQL_NULLABLE == _isNullable;
}
} } } // namespace Poco::Data::ODBC
#endif
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,297 @@
//
// SessionImpl.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: SessionImpl
//
// Definition of the SessionImpl class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_SessionImpl_INCLUDED
#define Data_ODBC_SessionImpl_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/ODBC/Connector.h"
#include "Poco/Data/ODBC/TypeInfo.h"
#include "Poco/Data/ODBC/Binder.h"
#include "Poco/Data/ODBC/Handle.h"
#include "Poco/Data/ODBC/ODBCException.h"
#include "Poco/Data/AbstractSessionImpl.h"
#include "Poco/SharedPtr.h"
#include "Poco/Mutex.h"
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
#include <sqltypes.h>
namespace Poco {
namespace Data {
namespace ODBC {
class ODBC_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
/// Implements SessionImpl interface
{
public:
static const std::size_t ODBC_MAX_FIELD_SIZE = 1024u;
enum TransactionCapability
{
ODBC_TXN_CAPABILITY_UNKNOWN = -1,
ODBC_TXN_CAPABILITY_FALSE = 0,
ODBC_TXN_CAPABILITY_TRUE = 1
};
SessionImpl(const std::string& connect,
std::size_t loginTimeout,
std::size_t maxFieldSize = ODBC_MAX_FIELD_SIZE,
bool autoBind = true,
bool autoExtract = true);
/// Creates the SessionImpl. Opens a connection to the database.
/// Throws NotConnectedException if connection was not succesful.
//@ deprecated
SessionImpl(const std::string& connect,
Poco::Any maxFieldSize = ODBC_MAX_FIELD_SIZE,
bool enforceCapability=false,
bool autoBind = true,
bool autoExtract = true);
/// Creates the SessionImpl. Opens a connection to the database.
~SessionImpl();
/// Destroys the SessionImpl.
Poco::SharedPtr<Poco::Data::StatementImpl> createStatementImpl();
/// Returns an ODBC StatementImpl
void open(const std::string& connect = "");
/// Opens a connection to the Database
void close();
/// Closes the connection
bool isConnected() const;
/// Returns true if session is connected
void setConnectionTimeout(std::size_t timeout);
/// Sets the session connection timeout value.
std::size_t getConnectionTimeout() const;
/// Returns the session connection timeout value.
void begin();
/// Starts a transaction
void commit();
/// Commits and ends a transaction
void rollback();
/// Aborts a transaction
void reset();
/// Do nothing
bool isTransaction() const;
/// Returns true iff a transaction is in progress.
const std::string& connectorName() const;
/// Returns the name of the connector.
bool canTransact() const;
/// Returns true if connection is transaction-capable.
void setTransactionIsolation(Poco::UInt32 ti);
/// Sets the transaction isolation level.
Poco::UInt32 getTransactionIsolation() const;
/// Returns the transaction isolation level.
bool hasTransactionIsolation(Poco::UInt32) const;
/// Returns true iff the transaction isolation level corresponding
/// to the supplied bitmask is supported.
bool isTransactionIsolation(Poco::UInt32) const;
/// Returns true iff the transaction isolation level corresponds
/// to the supplied bitmask.
void autoCommit(const std::string&, bool val);
/// Sets autocommit property for the session.
bool isAutoCommit(const std::string& name="") const;
/// Returns autocommit property value.
void autoBind(const std::string&, bool val);
/// Sets automatic binding for the session.
bool isAutoBind(const std::string& name="") const;
/// Returns true if binding is automatic for this session.
void autoExtract(const std::string&, bool val);
/// Sets automatic extraction for the session.
bool isAutoExtract(const std::string& name="") const;
/// Returns true if extraction is automatic for this session.
void setMaxFieldSize(const std::string& rName, const Poco::Any& rValue);
/// Sets the max field size (the default used when column size is unknown).
Poco::Any getMaxFieldSize(const std::string& rName="") const;
/// Returns the max field size (the default used when column size is unknown).
int maxStatementLength() const;
/// Returns maximum length of SQL statement allowed by driver.
void setQueryTimeout(const std::string&, const Poco::Any& value);
/// Sets the timeout (in seconds) for queries.
/// Value must be of type int.
Poco::Any getQueryTimeout(const std::string&) const;
/// Returns the timeout (in seconds) for queries,
/// or -1 if no timeout has been set.
int queryTimeout() const;
/// Returns the timeout (in seconds) for queries,
/// or -1 if no timeout has been set.
const ConnectionHandle& dbc() const;
/// Returns the connection handle.
Poco::Any dataTypeInfo(const std::string& rName="") const;
/// Returns the data types information.
private:
void setDataTypeInfo(const std::string& rName, const Poco::Any& rValue);
/// No-op. Throws InvalidAccessException.
static const int FUNCTIONS = SQL_API_ODBC3_ALL_FUNCTIONS_SIZE;
void checkError(SQLRETURN rc, const std::string& msg="") const;
Poco::UInt32 getDefaultTransactionIsolation() const;
static Poco::UInt32 transactionIsolation(SQLULEN isolation);
void setTransactionIsolationImpl(Poco::UInt32 ti) const;
/// Sets the transaction isolation level.
/// Called internally from getTransactionIsolation()
std::string _connector;
mutable ConnectionHandle _db;
Poco::Any _maxFieldSize;
bool _autoBind;
bool _autoExtract;
TypeInfo _dataTypes;
mutable char _canTransact;
bool _inTransaction;
int _queryTimeout;
Poco::FastMutex _mutex;
};
///
/// inlines
///
inline void SessionImpl::checkError(SQLRETURN rc, const std::string& msg) const
{
if (Utility::isError(rc))
throw ConnectionException(_db, msg);
}
inline const ConnectionHandle& SessionImpl::dbc() const
{
return _db;
}
inline void SessionImpl::setMaxFieldSize(const std::string& rName, const Poco::Any& rValue)
{
_maxFieldSize = rValue;
}
inline Poco::Any SessionImpl::getMaxFieldSize(const std::string& rName) const
{
return _maxFieldSize;
}
inline void SessionImpl::setDataTypeInfo(const std::string& rName, const Poco::Any& rValue)
{
throw InvalidAccessException();
}
inline Poco::Any SessionImpl::dataTypeInfo(const std::string& rName) const
{
return &_dataTypes;
}
inline void SessionImpl::autoBind(const std::string&, bool val)
{
_autoBind = val;
}
inline bool SessionImpl::isAutoBind(const std::string& name) const
{
return _autoBind;
}
inline void SessionImpl::autoExtract(const std::string&, bool val)
{
_autoExtract = val;
}
inline bool SessionImpl::isAutoExtract(const std::string& name) const
{
return _autoExtract;
}
inline const std::string& SessionImpl::connectorName() const
{
return _connector;
}
inline bool SessionImpl::isTransactionIsolation(Poco::UInt32 ti) const
{
return 0 != (ti & getTransactionIsolation());
}
inline void SessionImpl::setQueryTimeout(const std::string&, const Poco::Any& value)
{
_queryTimeout = Poco::AnyCast<int>(value);
}
inline Poco::Any SessionImpl::getQueryTimeout(const std::string&) const
{
return _queryTimeout;
}
inline int SessionImpl::queryTimeout() const
{
return _queryTimeout;
}
} } } // namespace Poco::Data::ODBC
#endif // Data_ODBC_SessionImpl_INCLUDED
+117
View File
@@ -0,0 +1,117 @@
//
// TypeInfo.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: TypeInfo
//
// Definition of TypeInfo.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_DataTypes_INCLUDED
#define Data_ODBC_DataTypes_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/NamedTuple.h"
#include "Poco/DynamicAny.h"
#include <vector>
#include <map>
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
#include <sqlext.h>
namespace Poco {
namespace Data {
namespace ODBC {
class ODBC_API TypeInfo
/// Datatypes mapping utility class.
///
/// This class provides mapping between C and SQL datatypes as well
/// as datatypes supported by the underlying database. In order for database
/// types to be available, a valid conection handle must be supplied at either
/// object construction time, or at a later point in time, through call to
/// fillTypeInfo member function.
///
/// Class also provides a convenient debugging function that prints
/// tabulated data to an output stream.
{
public:
typedef std::map<int, int> DataTypeMap;
typedef DataTypeMap::value_type ValueType;
typedef Poco::NamedTuple<std::string,
SQLSMALLINT,
SQLINTEGER,
std::string,
std::string,
std::string,
SQLSMALLINT,
SQLSMALLINT,
SQLSMALLINT,
SQLSMALLINT,
SQLSMALLINT,
SQLSMALLINT,
std::string,
SQLSMALLINT,
SQLSMALLINT,
SQLSMALLINT,
SQLSMALLINT,
SQLINTEGER,
SQLSMALLINT> TypeInfoTup;
typedef std::vector<TypeInfoTup> TypeInfoVec;
explicit TypeInfo(SQLHDBC* pHDBC=0);
/// Creates the TypeInfo.
~TypeInfo();
/// Destroys the TypeInfo.
int cDataType(int sqlDataType) const;
/// Returns C data type corresponding to supplied SQL data type.
int sqlDataType(int cDataType) const;
/// Returns SQL data type corresponding to supplied C data type.
void fillTypeInfo(SQLHDBC pHDBC);
/// Fills the data type info structure for the database.
DynamicAny getInfo(SQLSMALLINT type, const std::string& param) const;
/// Returns information about specified data type as specified by parameter 'type'.
/// The requested information is specified by parameter 'param'.
/// Will fail with a Poco::NotFoundException thrown if the param is not found
bool tryGetInfo(SQLSMALLINT type, const std::string& param, DynamicAny& result) const;
/// Returns information about specified data type as specified by parameter 'type' in param result.
/// The requested information is specified by parameter 'param'.
/// Will return false if the param is not found. The value of result will be not changed in this case.
void print(std::ostream& ostr);
/// Prints all the types (as reported by the underlying database)
/// to the supplied output stream.
private:
void fillCTypes();
void fillSQLTypes();
DataTypeMap _cDataTypes;
DataTypeMap _sqlDataTypes;
TypeInfoVec _typeInfo;
SQLHDBC* _pHDBC;
};
} } } // namespace Poco::Data::ODBC
#endif
+985
View File
@@ -0,0 +1,985 @@
//
// Unicode.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: Unicode
//
// Definition of Unicode.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_Unicode_INCLUDED
#define Data_ODBC_Unicode_INCLUDED
#include "Poco/UnicodeConverter.h"
#include "Poco/Buffer.h"
#include "Poco/Exception.h"
#include <cstring>
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
#ifndef SQL_NOUNICODEMAP
#define SQL_NOUNICODEMAP
#endif
#include <sqlext.h>
#include <sqltypes.h>
#include <sqlucode.h>
#if defined(POCO_OS_FAMILY_WINDOWS)
#define POCO_ODBC_UNICODE
#define POCO_ODBC_UNICODE_WINDOWS
#elif defined(POCO_OS_FAMILY_UNIX) && defined(UNICODE)
#define POCO_ODBC_UNICODE
#ifdef POCO_UNIXODBC
#define POCO_ODBC_UNICODE_UNIXODBC
#elif defined(POCO_IODBC)
#error "iODBC Unicode not supported"
#endif
#endif
namespace Poco {
namespace Data {
namespace ODBC {
#if defined(POCO_PTR_IS_64_BIT) || defined(POCO_OS_FAMILY_UNIX) // mkrivos - POCO_OS_FAMILY_UNIX doesn't compile with SQLPOINTER & SQLColAttribute()
typedef SQLLEN* NumAttrPtrType;
#else
typedef SQLPOINTER NumAttrPtrType;
#endif
SQLRETURN ODBC_API SQLColAttribute(SQLHSTMT hstmt,
SQLUSMALLINT iCol,
SQLUSMALLINT iField,
SQLPOINTER pCharAttr,
SQLSMALLINT cbCharAttrMax,
SQLSMALLINT* pcbCharAttr,
NumAttrPtrType pNumAttr);
SQLRETURN ODBC_API SQLColAttributes(SQLHSTMT hstmt,
SQLUSMALLINT icol,
SQLUSMALLINT fDescType,
SQLPOINTER rgbDesc,
SQLSMALLINT cbDescMax,
SQLSMALLINT* pcbDesc,
SQLLEN* pfDesc);
SQLRETURN ODBC_API SQLConnect(SQLHDBC hdbc,
SQLCHAR* szDSN,
SQLSMALLINT cbDSN,
SQLCHAR* szUID,
SQLSMALLINT cbUID,
SQLCHAR* szAuthStr,
SQLSMALLINT cbAuthStr);
SQLRETURN ODBC_API SQLDescribeCol(SQLHSTMT hstmt,
SQLUSMALLINT icol,
SQLCHAR* szColName,
SQLSMALLINT cbColNameMax,
SQLSMALLINT* pcbColName,
SQLSMALLINT* pfSqlType,
SQLULEN* pcbColDef,
SQLSMALLINT* pibScale,
SQLSMALLINT* pfNullable);
SQLRETURN ODBC_API SQLError(SQLHENV henv,
SQLHDBC hdbc,
SQLHSTMT hstmt,
SQLCHAR* szSqlState,
SQLINTEGER* pfNativeError,
SQLCHAR* szErrorMsg,
SQLSMALLINT cbErrorMsgMax,
SQLSMALLINT* pcbErrorMsg);
SQLRETURN ODBC_API SQLExecDirect(SQLHSTMT hstmt,
SQLCHAR* szSqlStr,
SQLINTEGER cbSqlStr);
SQLRETURN ODBC_API SQLGetConnectAttr(SQLHDBC hdbc,
SQLINTEGER fAttribute,
SQLPOINTER rgbValue,
SQLINTEGER cbValueMax,
SQLINTEGER* pcbValue);
SQLRETURN ODBC_API SQLGetCursorName(SQLHSTMT hstmt,
SQLCHAR* szCursor,
SQLSMALLINT cbCursorMax,
SQLSMALLINT* pcbCursor);
SQLRETURN ODBC_API SQLSetDescField(SQLHDESC DescriptorHandle,
SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier,
SQLPOINTER Value,
SQLINTEGER BufferLength);
SQLRETURN ODBC_API SQLGetDescField(SQLHDESC hdesc,
SQLSMALLINT iRecord,
SQLSMALLINT iField,
SQLPOINTER rgbValue,
SQLINTEGER cbValueMax,
SQLINTEGER* pcbValue);
SQLRETURN ODBC_API SQLGetDescRec(SQLHDESC hdesc,
SQLSMALLINT iRecord,
SQLCHAR* szName,
SQLSMALLINT cbNameMax,
SQLSMALLINT* pcbName,
SQLSMALLINT* pfType,
SQLSMALLINT* pfSubType,
SQLLEN* pLength,
SQLSMALLINT* pPrecision,
SQLSMALLINT* pScale,
SQLSMALLINT* pNullable);
SQLRETURN ODBC_API SQLGetDiagField(SQLSMALLINT fHandleType,
SQLHANDLE handle,
SQLSMALLINT iRecord,
SQLSMALLINT fDiagField,
SQLPOINTER rgbDiagInfo,
SQLSMALLINT cbDiagInfoMax,
SQLSMALLINT* pcbDiagInfo);
SQLRETURN ODBC_API SQLGetDiagRec(SQLSMALLINT fHandleType,
SQLHANDLE handle,
SQLSMALLINT iRecord,
SQLCHAR* szSqlState,
SQLINTEGER* pfNativeError,
SQLCHAR* szErrorMsg,
SQLSMALLINT cbErrorMsgMax,
SQLSMALLINT* pcbErrorMsg);
SQLRETURN ODBC_API SQLPrepare(SQLHSTMT hstmt,
SQLCHAR* szSqlStr,
SQLINTEGER cbSqlStr);
SQLRETURN ODBC_API SQLSetConnectAttr(SQLHDBC hdbc,
SQLINTEGER fAttribute,
SQLPOINTER rgbValue,
SQLINTEGER cbValue);
SQLRETURN ODBC_API SQLSetCursorName(SQLHSTMT hstmt,
SQLCHAR* szCursor,
SQLSMALLINT cbCursor);
SQLRETURN ODBC_API SQLSetStmtAttr(SQLHSTMT hstmt,
SQLINTEGER fAttribute,
SQLPOINTER rgbValue,
SQLINTEGER cbValueMax);
SQLRETURN ODBC_API SQLGetStmtAttr(SQLHSTMT hstmt,
SQLINTEGER fAttribute,
SQLPOINTER rgbValue,
SQLINTEGER cbValueMax,
SQLINTEGER* pcbValue);
SQLRETURN ODBC_API SQLColumns(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName,
SQLCHAR* szColumnName,
SQLSMALLINT cbColumnName);
SQLRETURN ODBC_API SQLGetConnectOption(SQLHDBC hdbc,
SQLUSMALLINT fOption,
SQLPOINTER pvParam);
SQLRETURN ODBC_API SQLGetInfo(SQLHDBC hdbc,
SQLUSMALLINT fInfoType,
SQLPOINTER rgbInfoValue,
SQLSMALLINT cbInfoValueMax,
SQLSMALLINT* pcbInfoValue);
SQLRETURN ODBC_API SQLGetTypeInfo(SQLHSTMT StatementHandle,
SQLSMALLINT DataType);
SQLRETURN ODBC_API SQLSetConnectOption(SQLHDBC hdbc,
SQLUSMALLINT fOption,
SQLULEN vParam);
SQLRETURN ODBC_API SQLSpecialColumns(SQLHSTMT hstmt,
SQLUSMALLINT fColType,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName,
SQLUSMALLINT fScope,
SQLUSMALLINT fNullable);
SQLRETURN ODBC_API SQLStatistics(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName,
SQLUSMALLINT fUnique,
SQLUSMALLINT fAccuracy);
SQLRETURN ODBC_API SQLTables(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName,
SQLCHAR* szTableType,
SQLSMALLINT cbTableType);
SQLRETURN ODBC_API SQLDataSources(SQLHENV henv,
SQLUSMALLINT fDirection,
SQLCHAR* szDSN,
SQLSMALLINT cbDSNMax,
SQLSMALLINT* pcbDSN,
SQLCHAR* szDescription,
SQLSMALLINT cbDescriptionMax,
SQLSMALLINT* pcbDescription);
SQLRETURN ODBC_API SQLDriverConnect(SQLHDBC hdbc,
SQLHWND hwnd,
SQLCHAR* szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLCHAR* szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT* pcbConnStrOut,
SQLUSMALLINT fDriverCompletion);
SQLRETURN ODBC_API SQLBrowseConnect(SQLHDBC hdbc,
SQLCHAR* szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLCHAR* szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT* pcbConnStrOut);
SQLRETURN ODBC_API SQLColumnPrivileges(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName,
SQLCHAR* szColumnName,
SQLSMALLINT cbColumnName);
SQLRETURN ODBC_API SQLForeignKeys(SQLHSTMT hstmt,
SQLCHAR* szPkCatalogName,
SQLSMALLINT cbPkCatalogName,
SQLCHAR* szPkSchemaName,
SQLSMALLINT cbPkSchemaName,
SQLCHAR* szPkTableName,
SQLSMALLINT cbPkTableName,
SQLCHAR* szFkCatalogName,
SQLSMALLINT cbFkCatalogName,
SQLCHAR* szFkSchemaName,
SQLSMALLINT cbFkSchemaName,
SQLCHAR* szFkTableName,
SQLSMALLINT cbFkTableName);
SQLRETURN ODBC_API SQLNativeSql(SQLHDBC hdbc,
SQLCHAR* szSqlStrIn,
SQLINTEGER cbSqlStrIn,
SQLCHAR* szSqlStr,
SQLINTEGER cbSqlStrMax,
SQLINTEGER* pcbSqlStr);
SQLRETURN ODBC_API SQLPrimaryKeys(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName);
SQLRETURN ODBC_API SQLProcedureColumns(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szProcName,
SQLSMALLINT cbProcName,
SQLCHAR* szColumnName,
SQLSMALLINT cbColumnName);
SQLRETURN ODBC_API SQLProcedures(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szProcName,
SQLSMALLINT cbProcName);
SQLRETURN ODBC_API SQLTablePrivileges(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName);
SQLRETURN ODBC_API SQLDrivers(SQLHENV henv,
SQLUSMALLINT fDirection,
SQLCHAR* szDriverDesc,
SQLSMALLINT cbDriverDescMax,
SQLSMALLINT* pcbDriverDesc,
SQLCHAR* szDriverAttributes,
SQLSMALLINT cbDrvrAttrMax,
SQLSMALLINT* pcbDrvrAttr);
///
/// inlines
///
inline bool isString(SQLPOINTER pValue, SQLINTEGER length)
{
return (SQL_NTS == length || length > 0) && pValue;
}
inline SQLINTEGER stringLength(SQLPOINTER pValue, SQLINTEGER length)
{
if (SQL_NTS != length) return length;
return (SQLINTEGER) std::strlen((const char*) pValue);
}
#if !defined(POCO_ODBC_UNICODE)
///
/// inlines
///
inline SQLRETURN SQLColAttribute(SQLHSTMT hstmt,
SQLUSMALLINT iCol,
SQLUSMALLINT iField,
SQLPOINTER pCharAttr,
SQLSMALLINT cbCharAttrMax,
SQLSMALLINT* pcbCharAttr,
NumAttrPtrType pNumAttr)
{
return ::SQLColAttributeA(hstmt,
iCol,
iField,
pCharAttr,
cbCharAttrMax,
pcbCharAttr,
pNumAttr);
}
inline SQLRETURN SQLColAttributes(SQLHSTMT hstmt,
SQLUSMALLINT icol,
SQLUSMALLINT fDescType,
SQLPOINTER rgbDesc,
SQLSMALLINT cbDescMax,
SQLSMALLINT* pcbDesc,
SQLLEN* pfDesc)
{
return ::SQLColAttributesA(hstmt,
icol,
fDescType,
rgbDesc,
cbDescMax,
pcbDesc,
pfDesc);
}
inline SQLRETURN SQLConnect(SQLHDBC hdbc,
SQLCHAR* szDSN,
SQLSMALLINT cbDSN,
SQLCHAR* szUID,
SQLSMALLINT cbUID,
SQLCHAR* szAuthStr,
SQLSMALLINT cbAuthStr)
{
return ::SQLConnectA(hdbc,
szDSN,
cbDSN,
szUID,
cbUID,
szAuthStr,
cbAuthStr);
}
inline SQLRETURN SQLDescribeCol(SQLHSTMT hstmt,
SQLUSMALLINT icol,
SQLCHAR* szColName,
SQLSMALLINT cbColNameMax,
SQLSMALLINT* pcbColName,
SQLSMALLINT* pfSqlType,
SQLULEN* pcbColDef,
SQLSMALLINT* pibScale,
SQLSMALLINT* pfNullable)
{
return ::SQLDescribeColA(hstmt,
icol,
szColName,
cbColNameMax,
pcbColName,
pfSqlType,
pcbColDef,
pibScale,
pfNullable);
}
inline SQLRETURN SQLError(SQLHENV henv,
SQLHDBC hdbc,
SQLHSTMT hstmt,
SQLCHAR* szSqlState,
SQLINTEGER* pfNativeError,
SQLCHAR* szErrorMsg,
SQLSMALLINT cbErrorMsgMax,
SQLSMALLINT* pcbErrorMsg)
{
throw Poco::NotImplementedException("SQLError is obsolete. "
"Use SQLGetDiagRec instead.");
}
inline SQLRETURN SQLExecDirect(SQLHSTMT hstmt,
SQLCHAR* szSqlStr,
SQLINTEGER cbSqlStr)
{
return ::SQLExecDirectA(hstmt, szSqlStr, cbSqlStr);
}
inline SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc,
SQLINTEGER fAttribute,
SQLPOINTER rgbValue,
SQLINTEGER cbValueMax,
SQLINTEGER* pcbValue)
{
return ::SQLGetConnectAttrA(hdbc,
fAttribute,
rgbValue,
cbValueMax,
pcbValue);
}
inline SQLRETURN SQLGetCursorName(SQLHSTMT hstmt,
SQLCHAR* szCursor,
SQLSMALLINT cbCursorMax,
SQLSMALLINT* pcbCursor)
{
throw Poco::NotImplementedException("Not implemented");
}
inline SQLRETURN SQLSetDescField(SQLHDESC DescriptorHandle,
SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier,
SQLPOINTER Value,
SQLINTEGER BufferLength)
{
return ::SQLSetDescField(DescriptorHandle,
RecNumber,
FieldIdentifier,
Value,
BufferLength);
}
inline SQLRETURN SQLGetDescField(SQLHDESC hdesc,
SQLSMALLINT iRecord,
SQLSMALLINT iField,
SQLPOINTER rgbValue,
SQLINTEGER cbValueMax,
SQLINTEGER* pcbValue)
{
return ::SQLGetDescFieldA(hdesc,
iRecord,
iField,
rgbValue,
cbValueMax,
pcbValue);
}
inline SQLRETURN SQLGetDescRec(SQLHDESC hdesc,
SQLSMALLINT iRecord,
SQLCHAR* szName,
SQLSMALLINT cbNameMax,
SQLSMALLINT* pcbName,
SQLSMALLINT* pfType,
SQLSMALLINT* pfSubType,
SQLLEN* pLength,
SQLSMALLINT* pPrecision,
SQLSMALLINT* pScale,
SQLSMALLINT* pNullable)
{
return ::SQLGetDescRecA(hdesc,
iRecord,
szName,
cbNameMax,
pcbName,
pfType,
pfSubType,
pLength,
pPrecision,
pScale,
pNullable);
}
inline SQLRETURN SQLGetDiagField(SQLSMALLINT fHandleType,
SQLHANDLE handle,
SQLSMALLINT iRecord,
SQLSMALLINT fDiagField,
SQLPOINTER rgbDiagInfo,
SQLSMALLINT cbDiagInfoMax,
SQLSMALLINT* pcbDiagInfo)
{
return ::SQLGetDiagFieldA(fHandleType,
handle,
iRecord,
fDiagField,
rgbDiagInfo,
cbDiagInfoMax,
pcbDiagInfo);
}
inline SQLRETURN SQLGetDiagRec(SQLSMALLINT fHandleType,
SQLHANDLE handle,
SQLSMALLINT iRecord,
SQLCHAR* szSqlState,
SQLINTEGER* pfNativeError,
SQLCHAR* szErrorMsg,
SQLSMALLINT cbErrorMsgMax,
SQLSMALLINT* pcbErrorMsg)
{
return ::SQLGetDiagRecA(fHandleType,
handle,
iRecord,
szSqlState,
pfNativeError,
szErrorMsg,
cbErrorMsgMax,
pcbErrorMsg);
}
inline SQLRETURN SQLPrepare(SQLHSTMT hstmt,
SQLCHAR* szSqlStr,
SQLINTEGER cbSqlStr)
{
return ::SQLPrepareA(hstmt, szSqlStr, cbSqlStr);
}
inline SQLRETURN SQLSetConnectAttr(SQLHDBC hdbc,
SQLINTEGER fAttribute,
SQLPOINTER rgbValue,
SQLINTEGER cbValue)
{
return ::SQLSetConnectAttrA(hdbc, fAttribute, rgbValue, cbValue);
}
inline SQLRETURN SQLSetCursorName(SQLHSTMT hstmt,
SQLCHAR* szCursor,
SQLSMALLINT cbCursor)
{
throw Poco::NotImplementedException("Not implemented");
}
inline SQLRETURN SQLSetStmtAttr(SQLHSTMT hstmt,
SQLINTEGER fAttribute,
SQLPOINTER rgbValue,
SQLINTEGER cbValueMax)
{
return ::SQLSetStmtAttr(hstmt, fAttribute, rgbValue, cbValueMax);
}
inline SQLRETURN SQLGetStmtAttr(SQLHSTMT hstmt,
SQLINTEGER fAttribute,
SQLPOINTER rgbValue,
SQLINTEGER cbValueMax,
SQLINTEGER* pcbValue)
{
return ::SQLGetStmtAttrA(hstmt,
fAttribute,
rgbValue,
cbValueMax,
pcbValue);
}
inline SQLRETURN SQLColumns(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName,
SQLCHAR* szColumnName,
SQLSMALLINT cbColumnName)
{
return ::SQLColumnsA(hstmt,
szCatalogName,
cbCatalogName,
szSchemaName,
cbSchemaName,
szTableName,
cbTableName,
szColumnName,
cbColumnName);
}
inline SQLRETURN SQLGetConnectOption(SQLHDBC hdbc,
SQLUSMALLINT fOption,
SQLPOINTER pvParam)
{
return ::SQLGetConnectOptionA(hdbc, fOption, pvParam);
}
inline SQLRETURN SQLGetInfo(SQLHDBC hdbc,
SQLUSMALLINT fInfoType,
SQLPOINTER rgbInfoValue,
SQLSMALLINT cbInfoValueMax,
SQLSMALLINT* pcbInfoValue)
{
return ::SQLGetInfoA(hdbc,
fInfoType,
rgbInfoValue,
cbInfoValueMax,
pcbInfoValue);
}
inline SQLRETURN SQLGetTypeInfo(SQLHSTMT StatementHandle,
SQLSMALLINT DataType)
{
return ::SQLGetTypeInfoA(StatementHandle, DataType);
}
inline SQLRETURN SQLSetConnectOption(SQLHDBC hdbc,
SQLUSMALLINT fOption,
SQLULEN vParam)
{
return ::SQLSetConnectOptionA(hdbc, fOption, vParam);
}
inline SQLRETURN SQLSpecialColumns(SQLHSTMT hstmt,
SQLUSMALLINT fColType,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName,
SQLUSMALLINT fScope,
SQLUSMALLINT fNullable)
{
return ::SQLSpecialColumnsA(hstmt,
fColType,
szCatalogName,
cbCatalogName,
szSchemaName,
cbSchemaName,
szTableName,
cbTableName,
fScope,
fNullable);
}
inline SQLRETURN SQLStatistics(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName,
SQLUSMALLINT fUnique,
SQLUSMALLINT fAccuracy)
{
return ::SQLStatisticsA(hstmt,
szCatalogName,
cbCatalogName,
szSchemaName,
cbSchemaName,
szTableName,
cbTableName,
fUnique,
fAccuracy);
}
inline SQLRETURN SQLTables(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName,
SQLCHAR* szTableType,
SQLSMALLINT cbTableType)
{
return ::SQLTablesA(hstmt,
szCatalogName,
cbCatalogName,
szSchemaName,
cbSchemaName,
szTableName,
cbTableName,
szTableType,
cbTableType);
}
inline SQLRETURN SQLDataSources(SQLHENV henv,
SQLUSMALLINT fDirection,
SQLCHAR* szDSN,
SQLSMALLINT cbDSNMax,
SQLSMALLINT* pcbDSN,
SQLCHAR* szDescription,
SQLSMALLINT cbDescriptionMax,
SQLSMALLINT* pcbDescription)
{
return ::SQLDataSourcesA(henv,
fDirection,
szDSN,
cbDSNMax,
pcbDSN,
szDescription,
cbDescriptionMax,
pcbDescription);
}
inline SQLRETURN SQLDriverConnect(SQLHDBC hdbc,
SQLHWND hwnd,
SQLCHAR* szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLCHAR* szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT* pcbConnStrOut,
SQLUSMALLINT fDriverCompletion)
{
return ::SQLDriverConnectA(hdbc,
hwnd,
szConnStrIn,
cbConnStrIn,
szConnStrOut,
cbConnStrOutMax,
pcbConnStrOut,
fDriverCompletion);
}
inline SQLRETURN SQLBrowseConnect(SQLHDBC hdbc,
SQLCHAR* szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLCHAR* szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT* pcbConnStrOut)
{
return ::SQLBrowseConnectA(hdbc,
szConnStrIn,
cbConnStrIn,
szConnStrOut,
cbConnStrOutMax,
pcbConnStrOut);
}
inline SQLRETURN SQLColumnPrivileges(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName,
SQLCHAR* szColumnName,
SQLSMALLINT cbColumnName)
{
return ::SQLColumnPrivilegesA(hstmt,
szCatalogName,
cbCatalogName,
szSchemaName,
cbSchemaName,
szTableName,
cbTableName,
szColumnName,
cbColumnName);
}
inline SQLRETURN SQLForeignKeys(SQLHSTMT hstmt,
SQLCHAR* szPkCatalogName,
SQLSMALLINT cbPkCatalogName,
SQLCHAR* szPkSchemaName,
SQLSMALLINT cbPkSchemaName,
SQLCHAR* szPkTableName,
SQLSMALLINT cbPkTableName,
SQLCHAR* szFkCatalogName,
SQLSMALLINT cbFkCatalogName,
SQLCHAR* szFkSchemaName,
SQLSMALLINT cbFkSchemaName,
SQLCHAR* szFkTableName,
SQLSMALLINT cbFkTableName)
{
return ::SQLForeignKeysA(hstmt,
szPkCatalogName,
cbPkCatalogName,
szPkSchemaName,
cbPkSchemaName,
szPkTableName,
cbPkTableName,
szFkCatalogName,
cbFkCatalogName,
szFkSchemaName,
cbFkSchemaName,
szFkTableName,
cbFkTableName);
}
inline SQLRETURN SQLNativeSql(SQLHDBC hdbc,
SQLCHAR* szSqlStrIn,
SQLINTEGER cbSqlStrIn,
SQLCHAR* szSqlStr,
SQLINTEGER cbSqlStrMax,
SQLINTEGER* pcbSqlStr)
{
return ::SQLNativeSqlA(hdbc,
szSqlStrIn,
cbSqlStrIn,
szSqlStr,
cbSqlStrMax,
pcbSqlStr);
}
inline SQLRETURN SQLPrimaryKeys(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName)
{
return ::SQLPrimaryKeysA(hstmt,
szCatalogName,
cbCatalogName,
szSchemaName,
cbSchemaName,
szTableName,
cbTableName);
}
inline SQLRETURN SQLProcedureColumns(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szProcName,
SQLSMALLINT cbProcName,
SQLCHAR* szColumnName,
SQLSMALLINT cbColumnName)
{
return ::SQLProcedureColumnsA(hstmt,
szCatalogName,
cbCatalogName,
szSchemaName,
cbSchemaName,
szProcName,
cbProcName,
szColumnName,
cbColumnName);
}
inline SQLRETURN SQLProcedures(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szProcName,
SQLSMALLINT cbProcName)
{
return ::SQLProceduresA(hstmt,
szCatalogName,
cbCatalogName,
szSchemaName,
cbSchemaName,
szProcName,
cbProcName);
}
inline SQLRETURN SQLTablePrivileges(SQLHSTMT hstmt,
SQLCHAR* szCatalogName,
SQLSMALLINT cbCatalogName,
SQLCHAR* szSchemaName,
SQLSMALLINT cbSchemaName,
SQLCHAR* szTableName,
SQLSMALLINT cbTableName)
{
return ::SQLTablePrivilegesA(hstmt,
szCatalogName,
cbCatalogName,
szSchemaName,
cbSchemaName,
szTableName,
cbTableName);
}
inline SQLRETURN SQLDrivers(SQLHENV henv,
SQLUSMALLINT fDirection,
SQLCHAR* szDriverDesc,
SQLSMALLINT cbDriverDescMax,
SQLSMALLINT* pcbDriverDesc,
SQLCHAR* szDriverAttributes,
SQLSMALLINT cbDrvrAttrMax,
SQLSMALLINT* pcbDrvrAttr)
{
return ::SQLDriversA(henv,
fDirection,
szDriverDesc,
cbDriverDescMax,
pcbDriverDesc,
szDriverAttributes,
cbDrvrAttrMax,
pcbDrvrAttr);
}
#endif // POCO_ODBC_UNICODE
} } } // namespace Poco::Data::ODBC
#endif // ODBC_Unicode_INCLUDED
@@ -0,0 +1,51 @@
//
// Unicode.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: Unicode
//
// Definition of Unicode_UNIX.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_Unicode_UNIX_INCLUDED
#define Data_ODBC_Unicode_UNIX_INCLUDED
namespace Poco {
namespace Data {
namespace ODBC {
void makeUTF16(SQLCHAR* pSQLChar, SQLINTEGER length, std::string& target);
/// Utility function for conversion from UTF-8 to UTF-16
inline void makeUTF16(SQLCHAR* pSQLChar, SQLSMALLINT length, std::string& target)
/// Utility function for conversion from UTF-8 to UTF-16.
{
makeUTF16(pSQLChar, (SQLINTEGER) length, target);
}
void makeUTF8(Poco::Buffer<SQLWCHAR>& buffer, SQLINTEGER length, SQLPOINTER pTarget, SQLINTEGER targetLength);
/// Utility function for conversion from UTF-16 to UTF-8.
inline void makeUTF8(Poco::Buffer<SQLWCHAR>& buffer, int length, SQLPOINTER pTarget, SQLSMALLINT targetLength)
/// Utility function for conversion from UTF-16 to UTF-8.
{
makeUTF8(buffer, length, pTarget, (SQLINTEGER) targetLength);
}
} } } // namespace Poco::Data::ODBC
#endif // Data_ODBC_Unicode_UNIX_INCLUDED
@@ -0,0 +1,57 @@
//
// Unicode.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: Unicode
//
// Definition of Unicode_WIN32.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_Unicode_WIN32_INCLUDED
#define Data_ODBC_Unicode_WIN32_INCLUDED
namespace Poco {
namespace Data {
namespace ODBC {
inline void makeUTF16(SQLCHAR* pSQLChar, SQLINTEGER length, std::wstring& target)
/// Utility function for conversion from UTF-8 to UTF-16
{
int len = length;
if (SQL_NTS == len)
len = (int) std::strlen((const char *) pSQLChar);
UnicodeConverter::toUTF16((const char *) pSQLChar, len, target);
}
inline void makeUTF8(Poco::Buffer<wchar_t>& buffer, SQLINTEGER length, SQLPOINTER pTarget, SQLINTEGER targetLength)
/// Utility function for conversion from UTF-16 to UTF-8. Length is in bytes.
{
if (buffer.sizeBytes() < length)
throw InvalidArgumentException("Specified length exceeds available length.");
else if ((length % 2) != 0)
throw InvalidArgumentException("Length must be an even number.");
length /= sizeof(wchar_t);
std::string result;
UnicodeConverter::toUTF8(buffer.begin(), length, result);
std::memset(pTarget, 0, targetLength);
std::strncpy((char*) pTarget, result.c_str(), result.size() < targetLength ? result.size() : targetLength);
}
} } } // namespace Poco::Data::ODBC
#endif // Data_ODBC_Unicode_WIN32_INCLUDED
+207
View File
@@ -0,0 +1,207 @@
//
// Utility.h
//
// Library: Data/ODBC
// Package: ODBC
// Module: Utility
//
// Definition of Utility.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_ODBC_Utility_INCLUDED
#define Data_ODBC_Utility_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/ODBC/TypeInfo.h"
#include "Poco/Data/Date.h"
#include "Poco/Data/Time.h"
#include "Poco/DateTime.h"
#include <sstream>
#include <map>
#include <sqltypes.h>
namespace Poco {
namespace Data {
namespace ODBC {
class ODBC_API Utility
/// Various utility functions
{
public:
typedef std::map<std::string, std::string> DSNMap;
typedef DSNMap DriverMap;
static bool isError(SQLRETURN rc);
/// Returns true if return code is error
static DriverMap& drivers(DriverMap& driverMap);
/// Returns driver-attributes map of available ODBC drivers.
static DSNMap& dataSources(DSNMap& dsnMap);
/// Returns DSN-description map of available ODBC data sources.
template<typename MapType, typename KeyArgType, typename ValueArgType>
static typename MapType::iterator mapInsert(MapType& m, const KeyArgType& k, const ValueArgType& v)
/// Utility map "insert or replace" function (from S. Meyers: Effective STL, Item 24)
{
typename MapType::iterator lb = m.lower_bound(k);
if (lb != m.end() && !(m.key_comp()(k, lb->first)))
{
lb->second = v;
return lb;
}
else
{
typedef typename MapType::value_type MVT;
return m.insert(lb, MVT(k,v));
}
}
static int cDataType(int sqlDataType);
/// Returns C data type corresponding to supplied SQL data type.
static int sqlDataType(int cDataType);
/// Returns SQL data type corresponding to supplied C data type.
static void dateSync(Date& dt, const SQL_DATE_STRUCT& ts);
/// Transfers data from ODBC SQL_DATE_STRUCT to Poco::DateTime.
template <typename T, typename F>
static void dateSync(T& d, const F& ds)
/// Transfers data from ODBC SQL_DATE_STRUCT container to Poco::DateTime container.
{
std::size_t size = ds.size();
if (d.size() != size) d.resize(size);
typename T::iterator dIt = d.begin();
typename F::const_iterator it = ds.begin();
typename F::const_iterator end = ds.end();
for (; it != end; ++it, ++dIt) dateSync(*dIt, *it);
}
static void timeSync(Time& dt, const SQL_TIME_STRUCT& ts);
/// Transfers data from ODBC SQL_TIME_STRUCT to Poco::DateTime.
template <typename T, typename F>
static void timeSync(T& t, const F& ts)
/// Transfers data from ODBC SQL_TIME_STRUCT container to Poco::DateTime container.
{
std::size_t size = ts.size();
if (t.size() != size) t.resize(size);
typename T::iterator dIt = t.begin();
typename F::const_iterator it = ts.begin();
typename F::const_iterator end = ts.end();
for (; it != end; ++it, ++dIt) timeSync(*dIt, *it);
}
static void dateTimeSync(Poco::DateTime& dt, const SQL_TIMESTAMP_STRUCT& ts);
/// Transfers data from ODBC SQL_TIMESTAMP_STRUCT to Poco::DateTime.
template <typename T, typename F>
static void dateTimeSync(T& dt, const F& ts)
/// Transfers data from ODBC SQL_TIMESTAMP_STRUCT container to Poco::DateTime container.
{
std::size_t size = ts.size();
if (dt.size() != size) dt.resize(size);
typename T::iterator dIt = dt.begin();
typename F::const_iterator it = ts.begin();
typename F::const_iterator end = ts.end();
for (; it != end; ++it, ++dIt) dateTimeSync(*dIt, *it);
}
static void dateSync(SQL_DATE_STRUCT& ts, const Date& dt);
/// Transfers data from Poco::Data::Date to ODBC SQL_DATE_STRUCT.
template <typename C>
static void dateSync(std::vector<SQL_DATE_STRUCT>& ds, const C& d)
/// Transfers data from Poco::Data::Date vector to ODBC SQL_DATE_STRUCT container.
{
std::size_t size = d.size();
if (ds.size() != size) ds.resize(size);
std::vector<SQL_DATE_STRUCT>::iterator dIt = ds.begin();
typename C::const_iterator it = d.begin();
typename C::const_iterator end = d.end();
for (; it != end; ++it, ++dIt) dateSync(*dIt, *it);
}
static void timeSync(SQL_TIME_STRUCT& ts, const Time& dt);
/// Transfers data from Poco::Data::Time to ODBC SQL_TIME_STRUCT.
template <typename C>
static void timeSync(std::vector<SQL_TIME_STRUCT>& ts, const C& t)
/// Transfers data from Poco::Data::Time container to ODBC SQL_TIME_STRUCT vector.
{
std::size_t size = t.size();
if (ts.size() != size) ts.resize(size);
std::vector<SQL_TIME_STRUCT>::iterator tIt = ts.begin();
typename C::const_iterator it = t.begin();
typename C::const_iterator end = t.end();
for (; it != end; ++it, ++tIt) timeSync(*tIt, *it);
}
static void dateTimeSync(SQL_TIMESTAMP_STRUCT& ts, const Poco::DateTime& dt);
/// Transfers data from Poco::DateTime to ODBC SQL_TIMESTAMP_STRUCT.
template <typename C>
static void dateTimeSync(std::vector<SQL_TIMESTAMP_STRUCT>& ts, const C& dt)
/// Transfers data from Poco::DateTime to ODBC SQL_TIMESTAMP_STRUCT.
{
std::size_t size = dt.size();
if (ts.size() != size) ts.resize(size);
std::vector<SQL_TIMESTAMP_STRUCT>::iterator tIt = ts.begin();
typename C::const_iterator it = dt.begin();
typename C::const_iterator end = dt.end();
for (; it != end; ++it, ++tIt) dateTimeSync(*tIt, *it);
}
private:
static const TypeInfo _dataTypes;
/// C <==> SQL data type mapping
};
///
/// inlines
///
inline bool Utility::isError(SQLRETURN rc)
{
return (0 != (rc & (~1)));
}
inline int Utility::cDataType(int sqlDataType)
{
return _dataTypes.cDataType(sqlDataType);
}
inline int Utility::sqlDataType(int cDataType)
{
return _dataTypes.sqlDataType(cDataType);
}
inline void Utility::dateSync(Date& d, const SQL_DATE_STRUCT& ts)
{
d.assign(ts.year, ts.month, ts.day);
}
inline void Utility::timeSync(Time& t, const SQL_TIME_STRUCT& ts)
{
t.assign(ts.hour, ts.minute, ts.second);
}
} } } // namespace Poco::Data::ODBC
#endif