mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2026-11-15 08:17:08 +01:00
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:
1 parent
e0e34b4030
commit
4a6bfc086c
6219 files changed
+1209835
-454916
No files matched your search
+1508
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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in new issue
Block a user