mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 10:02:01 +00:00
Merge branch 'master' into move-sources
This commit is contained in:
commit
bcc4adf73d
2
.github/workflows/debug.yml
vendored
2
.github/workflows/debug.yml
vendored
@ -2,7 +2,7 @@
|
|||||||
name: Debug
|
name: Debug
|
||||||
|
|
||||||
'on':
|
'on':
|
||||||
[push, pull_request, release, workflow_dispatch, workflow_call]
|
[push, pull_request, pull_request_review, release, workflow_dispatch, workflow_call]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
DebugInfo:
|
DebugInfo:
|
||||||
|
23
.github/workflows/pull_request_approved.yml
vendored
Normal file
23
.github/workflows/pull_request_approved.yml
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
name: PullRequestApprovedCI
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Force the stdout and stderr streams to be unbuffered
|
||||||
|
PYTHONUNBUFFERED: 1
|
||||||
|
|
||||||
|
on: # yamllint disable-line rule:truthy
|
||||||
|
pull_request_review:
|
||||||
|
types:
|
||||||
|
- submitted
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
MergeOnApproval:
|
||||||
|
runs-on: [self-hosted, style-checker]
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: ClickHouse/checkout@v1
|
||||||
|
with:
|
||||||
|
clear-repository: true
|
||||||
|
- name: Merge approved PR
|
||||||
|
run: |
|
||||||
|
cd "$GITHUB_WORKSPACE/tests/ci"
|
||||||
|
python3 merge_pr.py --check-approved
|
@ -476,7 +476,12 @@ enable_testing() # Enable for tests without binary
|
|||||||
|
|
||||||
option(ENABLE_OPENSSL "This option performs a build with OpenSSL. NOTE! This option is insecure and should never be used. By default, ClickHouse uses and only supports BoringSSL" OFF)
|
option(ENABLE_OPENSSL "This option performs a build with OpenSSL. NOTE! This option is insecure and should never be used. By default, ClickHouse uses and only supports BoringSSL" OFF)
|
||||||
|
|
||||||
option(ENABLE_OPENSSL_DYNAMIC "This option removes SSL from ClickHouse and will link to the OpenSSL version supplied by OS." OFF)
|
if (ARCH_S390X)
|
||||||
|
set(ENABLE_OPENSSL_DYNAMIC_DEFAULT ON)
|
||||||
|
else ()
|
||||||
|
set(ENABLE_OPENSSL_DYNAMIC_DEFAULT OFF)
|
||||||
|
endif ()
|
||||||
|
option(ENABLE_OPENSSL_DYNAMIC "This option removes SSL from ClickHouse and will link to the OpenSSL version supplied by OS." ${ENABLE_OPENSSL_DYNAMIC_DEFAULT})
|
||||||
|
|
||||||
# when installing to /usr - place configs to /etc but for /usr/local place to /usr/local/etc
|
# when installing to /usr - place configs to /etc but for /usr/local place to /usr/local/etc
|
||||||
if (CMAKE_INSTALL_PREFIX STREQUAL "/usr")
|
if (CMAKE_INSTALL_PREFIX STREQUAL "/usr")
|
||||||
|
@ -84,7 +84,10 @@ if (OS MATCHES "Linux"
|
|||||||
set (CMAKE_TOOLCHAIN_FILE "cmake/linux/toolchain-aarch64.cmake" CACHE INTERNAL "")
|
set (CMAKE_TOOLCHAIN_FILE "cmake/linux/toolchain-aarch64.cmake" CACHE INTERNAL "")
|
||||||
elseif (ARCH MATCHES "^(ppc64le.*|PPC64LE.*)")
|
elseif (ARCH MATCHES "^(ppc64le.*|PPC64LE.*)")
|
||||||
set (CMAKE_TOOLCHAIN_FILE "cmake/linux/toolchain-ppc64le.cmake" CACHE INTERNAL "")
|
set (CMAKE_TOOLCHAIN_FILE "cmake/linux/toolchain-ppc64le.cmake" CACHE INTERNAL "")
|
||||||
|
elseif (ARCH MATCHES "^(s390x.*|S390X.*)")
|
||||||
|
set (CMAKE_TOOLCHAIN_FILE "cmake/linux/toolchain-s390x.cmake" CACHE INTERNAL "")
|
||||||
else ()
|
else ()
|
||||||
message (FATAL_ERROR "Unsupported architecture: ${ARCH}")
|
message (FATAL_ERROR "Unsupported architecture: ${ARCH}")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
#define NO_INLINE __attribute__((__noinline__))
|
#define NO_INLINE __attribute__((__noinline__))
|
||||||
#define MAY_ALIAS __attribute__((__may_alias__))
|
#define MAY_ALIAS __attribute__((__may_alias__))
|
||||||
|
|
||||||
#if !defined(__x86_64__) && !defined(__aarch64__) && !defined(__PPC__) && !(defined(__riscv) && (__riscv_xlen == 64))
|
#if !defined(__x86_64__) && !defined(__aarch64__) && !defined(__PPC__) && !defined(__s390x__) && !(defined(__riscv) && (__riscv_xlen == 64))
|
||||||
# error "The only supported platforms are x86_64 and AArch64, PowerPC (work in progress) and RISC-V 64 (experimental)"
|
# error "The only supported platforms are x86_64 and AArch64, PowerPC (work in progress), s390x (work in progress) and RISC-V 64 (experimental)"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Check for presence of address sanitizer
|
/// Check for presence of address sanitizer
|
||||||
|
@ -360,7 +360,7 @@ struct integer<Bits, Signed>::_impl
|
|||||||
constexpr const unsigned to_copy = min_bits / base_bits;
|
constexpr const unsigned to_copy = min_bits / base_bits;
|
||||||
|
|
||||||
for (unsigned i = 0; i < to_copy; ++i)
|
for (unsigned i = 0; i < to_copy; ++i)
|
||||||
self.items[little(i)] = rhs.items[little(i)];
|
self.items[little(i)] = rhs.items[integer<Bits2, Signed2>::_impl::little(i)];
|
||||||
|
|
||||||
if constexpr (Bits > Bits2)
|
if constexpr (Bits > Bits2)
|
||||||
{
|
{
|
||||||
|
@ -18,121 +18,124 @@
|
|||||||
#define Crypto_Cipher_INCLUDED
|
#define Crypto_Cipher_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Crypto/Crypto.h"
|
|
||||||
#include "Poco/RefCountedObject.h"
|
|
||||||
#include "Poco/AutoPtr.h"
|
|
||||||
#include <istream>
|
#include <istream>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "Poco/AutoPtr.h"
|
||||||
|
#include "Poco/Crypto/Crypto.h"
|
||||||
|
#include "Poco/RefCountedObject.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
{
|
||||||
|
namespace Crypto
|
||||||
|
|
||||||
class CryptoTransform;
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API Cipher: public Poco::RefCountedObject
|
|
||||||
/// Represents the abstract base class from which all implementations of
|
|
||||||
/// symmetric/asymmetric encryption algorithms must inherit. Use the CipherFactory
|
|
||||||
/// class to obtain an instance of this class:
|
|
||||||
///
|
|
||||||
/// CipherFactory& factory = CipherFactory::defaultFactory();
|
|
||||||
/// // Creates a 256-bit AES cipher
|
|
||||||
/// Cipher* pCipher = factory.createCipher(CipherKey("aes-256"));
|
|
||||||
/// Cipher* pRSACipher = factory.createCipher(RSAKey(RSAKey::KL_1024, RSAKey::EXP_SMALL));
|
|
||||||
///
|
|
||||||
/// Check the different Key constructors on how to initialize/create
|
|
||||||
/// a key. The above example auto-generates random keys.
|
|
||||||
///
|
|
||||||
/// Note that you won't be able to decrypt data encrypted with a random key
|
|
||||||
/// once the Cipher is destroyed unless you persist the generated key and IV.
|
|
||||||
/// An example usage for random keys is to encrypt data saved in a temporary
|
|
||||||
/// file.
|
|
||||||
///
|
|
||||||
/// Once your key is set up, you can use the Cipher object to encrypt or
|
|
||||||
/// decrypt strings or, in conjunction with a CryptoInputStream or a
|
|
||||||
/// CryptoOutputStream, to encrypt streams of data.
|
|
||||||
///
|
|
||||||
/// Since encrypted strings will contain arbitrary binary data that will cause
|
|
||||||
/// problems in applications that are not binary-safe (eg., when sending
|
|
||||||
/// encrypted data in e-mails), the encryptString() and decryptString() can
|
|
||||||
/// encode (or decode, respectively) encrypted data using a "transport encoding".
|
|
||||||
/// Supported encodings are Base64 and BinHex.
|
|
||||||
///
|
|
||||||
/// The following example encrypts and decrypts a string utilizing Base64
|
|
||||||
/// encoding:
|
|
||||||
///
|
|
||||||
/// std::string plainText = "This is my secret information";
|
|
||||||
/// std::string encrypted = pCipher->encryptString(plainText, Cipher::ENC_BASE64);
|
|
||||||
/// std::string decrypted = pCipher->decryptString(encrypted, Cipher::ENC_BASE64);
|
|
||||||
///
|
|
||||||
/// In order to encrypt a stream of data (eg. to encrypt files), you can use
|
|
||||||
/// a CryptoStream:
|
|
||||||
///
|
|
||||||
/// // Create an output stream that will encrypt all data going through it
|
|
||||||
/// // and write pass it to the underlying file stream.
|
|
||||||
/// Poco::FileOutputStream sink("encrypted.dat");
|
|
||||||
/// CryptoOutputStream encryptor(sink, pCipher->createEncryptor());
|
|
||||||
///
|
|
||||||
/// Poco::FileInputStream source("source.txt");
|
|
||||||
/// Poco::StreamCopier::copyStream(source, encryptor);
|
|
||||||
///
|
|
||||||
/// // Always close output streams to flush all internal buffers
|
|
||||||
/// encryptor.close();
|
|
||||||
/// sink.close();
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
typedef Poco::AutoPtr<Cipher> Ptr;
|
|
||||||
typedef std::vector<unsigned char> ByteVec;
|
|
||||||
|
|
||||||
enum Encoding
|
|
||||||
/// Transport encoding to use for encryptString() and decryptString().
|
|
||||||
{
|
|
||||||
ENC_NONE = 0x00, /// Plain binary output
|
|
||||||
ENC_BASE64 = 0x01, /// Base64-encoded output
|
|
||||||
ENC_BINHEX = 0x02, /// BinHex-encoded output
|
|
||||||
ENC_BASE64_NO_LF = 0x81, /// Base64-encoded output, no linefeeds
|
|
||||||
ENC_BINHEX_NO_LF = 0x82 /// BinHex-encoded output, no linefeeds
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~Cipher();
|
|
||||||
/// Destroys the Cipher.
|
|
||||||
|
|
||||||
virtual const std::string& name() const = 0;
|
|
||||||
/// Returns the name of the Cipher.
|
|
||||||
|
|
||||||
virtual CryptoTransform* createEncryptor() = 0;
|
|
||||||
/// Creates an encryptor object to be used with a CryptoStream.
|
|
||||||
|
|
||||||
virtual CryptoTransform* createDecryptor() = 0;
|
|
||||||
/// Creates a decryptor object to be used with a CryptoStream.
|
|
||||||
|
|
||||||
virtual std::string encryptString(const std::string& str, Encoding encoding = ENC_NONE);
|
|
||||||
/// Directly encrypt a string and encode it using the given encoding.
|
|
||||||
|
|
||||||
virtual std::string decryptString(const std::string& str, Encoding encoding = ENC_NONE);
|
|
||||||
/// Directly decrypt a string that is encoded with the given encoding.
|
|
||||||
|
|
||||||
virtual void encrypt(std::istream& source, std::ostream& sink, Encoding encoding = ENC_NONE);
|
|
||||||
/// Directly encrypts an input stream and encodes it using the given encoding.
|
|
||||||
|
|
||||||
virtual void decrypt(std::istream& source, std::ostream& sink, Encoding encoding = ENC_NONE);
|
|
||||||
/// Directly decrypt an input stream that is encoded with the given encoding.
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Cipher();
|
|
||||||
/// Creates a new Cipher object.
|
|
||||||
|
|
||||||
private:
|
|
||||||
Cipher(const Cipher&);
|
|
||||||
Cipher& operator = (const Cipher&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
class CryptoTransform;
|
||||||
|
|
||||||
|
|
||||||
|
class Crypto_API Cipher : public Poco::RefCountedObject
|
||||||
|
/// Represents the abstract base class from which all implementations of
|
||||||
|
/// symmetric/asymmetric encryption algorithms must inherit. Use the CipherFactory
|
||||||
|
/// class to obtain an instance of this class:
|
||||||
|
///
|
||||||
|
/// CipherFactory& factory = CipherFactory::defaultFactory();
|
||||||
|
/// // Creates a 256-bit AES cipher
|
||||||
|
/// Cipher* pCipher = factory.createCipher(CipherKey("aes-256"));
|
||||||
|
/// Cipher* pRSACipher = factory.createCipher(RSAKey(RSAKey::KL_1024, RSAKey::EXP_SMALL));
|
||||||
|
///
|
||||||
|
/// Check the different Key constructors on how to initialize/create
|
||||||
|
/// a key. The above example auto-generates random keys.
|
||||||
|
///
|
||||||
|
/// Note that you won't be able to decrypt data encrypted with a random key
|
||||||
|
/// once the Cipher is destroyed unless you persist the generated key and IV.
|
||||||
|
/// An example usage for random keys is to encrypt data saved in a temporary
|
||||||
|
/// file.
|
||||||
|
///
|
||||||
|
/// Once your key is set up, you can use the Cipher object to encrypt or
|
||||||
|
/// decrypt strings or, in conjunction with a CryptoInputStream or a
|
||||||
|
/// CryptoOutputStream, to encrypt streams of data.
|
||||||
|
///
|
||||||
|
/// Since encrypted strings will contain arbitrary binary data that will cause
|
||||||
|
/// problems in applications that are not binary-safe (eg., when sending
|
||||||
|
/// encrypted data in e-mails), the encryptString() and decryptString() can
|
||||||
|
/// encode (or decode, respectively) encrypted data using a "transport encoding".
|
||||||
|
/// Supported encodings are Base64 and BinHex.
|
||||||
|
///
|
||||||
|
/// The following example encrypts and decrypts a string utilizing Base64
|
||||||
|
/// encoding:
|
||||||
|
///
|
||||||
|
/// std::string plainText = "This is my secret information";
|
||||||
|
/// std::string encrypted = pCipher->encryptString(plainText, Cipher::ENC_BASE64);
|
||||||
|
/// std::string decrypted = pCipher->decryptString(encrypted, Cipher::ENC_BASE64);
|
||||||
|
///
|
||||||
|
/// In order to encrypt a stream of data (eg. to encrypt files), you can use
|
||||||
|
/// a CryptoStream:
|
||||||
|
///
|
||||||
|
/// // Create an output stream that will encrypt all data going through it
|
||||||
|
/// // and write pass it to the underlying file stream.
|
||||||
|
/// Poco::FileOutputStream sink("encrypted.dat");
|
||||||
|
/// CryptoOutputStream encryptor(sink, pCipher->createEncryptor());
|
||||||
|
///
|
||||||
|
/// Poco::FileInputStream source("source.txt");
|
||||||
|
/// Poco::StreamCopier::copyStream(source, encryptor);
|
||||||
|
///
|
||||||
|
/// // Always close output streams to flush all internal buffers
|
||||||
|
/// encryptor.close();
|
||||||
|
/// sink.close();
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Poco::AutoPtr<Cipher> Ptr;
|
||||||
|
typedef std::vector<unsigned char> ByteVec;
|
||||||
|
|
||||||
|
enum Encoding
|
||||||
|
/// Transport encoding to use for encryptString() and decryptString().
|
||||||
|
{
|
||||||
|
ENC_NONE = 0x00, /// Plain binary output
|
||||||
|
ENC_BASE64 = 0x01, /// Base64-encoded output
|
||||||
|
ENC_BINHEX = 0x02, /// BinHex-encoded output
|
||||||
|
ENC_BASE64_NO_LF = 0x81, /// Base64-encoded output, no linefeeds
|
||||||
|
ENC_BINHEX_NO_LF = 0x82 /// BinHex-encoded output, no linefeeds
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual ~Cipher();
|
||||||
|
/// Destroys the Cipher.
|
||||||
|
|
||||||
|
virtual const std::string & name() const = 0;
|
||||||
|
/// Returns the name of the Cipher.
|
||||||
|
|
||||||
|
virtual CryptoTransform * createEncryptor() = 0;
|
||||||
|
/// Creates an encryptor object to be used with a CryptoStream.
|
||||||
|
|
||||||
|
virtual CryptoTransform * createDecryptor() = 0;
|
||||||
|
/// Creates a decryptor object to be used with a CryptoStream.
|
||||||
|
|
||||||
|
virtual std::string encryptString(const std::string & str, Encoding encoding = ENC_NONE);
|
||||||
|
/// Directly encrypt a string and encode it using the given encoding.
|
||||||
|
|
||||||
|
virtual std::string decryptString(const std::string & str, Encoding encoding = ENC_NONE);
|
||||||
|
/// Directly decrypt a string that is encoded with the given encoding.
|
||||||
|
|
||||||
|
virtual void encrypt(std::istream & source, std::ostream & sink, Encoding encoding = ENC_NONE);
|
||||||
|
/// Directly encrypts an input stream and encodes it using the given encoding.
|
||||||
|
|
||||||
|
virtual void decrypt(std::istream & source, std::ostream & sink, Encoding encoding = ENC_NONE);
|
||||||
|
/// Directly decrypt an input stream that is encoded with the given encoding.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Cipher();
|
||||||
|
/// Creates a new Cipher object.
|
||||||
|
|
||||||
|
private:
|
||||||
|
Cipher(const Cipher &);
|
||||||
|
Cipher & operator=(const Cipher &);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_Cipher_INCLUDED
|
#endif // Crypto_Cipher_INCLUDED
|
||||||
|
@ -21,55 +21,58 @@
|
|||||||
#include "Poco/Crypto/Crypto.h"
|
#include "Poco/Crypto/Crypto.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
{
|
||||||
|
namespace Crypto
|
||||||
|
|
||||||
class Cipher;
|
|
||||||
class CipherKey;
|
|
||||||
class RSAKey;
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API CipherFactory
|
|
||||||
/// A factory for Cipher objects. See the Cipher class for examples on how to
|
|
||||||
/// use the CipherFactory.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
CipherFactory();
|
|
||||||
/// Creates a new CipherFactory object.
|
|
||||||
|
|
||||||
virtual ~CipherFactory();
|
|
||||||
/// Destroys the CipherFactory.
|
|
||||||
|
|
||||||
Cipher* createCipher(const CipherKey& key);
|
|
||||||
/// Creates a Cipher object for the given Cipher name. Valid cipher
|
|
||||||
/// names depend on the OpenSSL version the library is linked with;
|
|
||||||
/// see the output of
|
|
||||||
///
|
|
||||||
/// openssl enc --help
|
|
||||||
///
|
|
||||||
/// for a list of supported block and stream ciphers.
|
|
||||||
///
|
|
||||||
/// Common examples are:
|
|
||||||
///
|
|
||||||
/// * AES: "aes-128", "aes-256"
|
|
||||||
/// * DES: "des", "des3"
|
|
||||||
/// * Blowfish: "bf"
|
|
||||||
|
|
||||||
Cipher* createCipher(const RSAKey& key, RSAPaddingMode paddingMode = RSA_PADDING_PKCS1);
|
|
||||||
/// Creates a RSACipher using the given RSA key and padding mode
|
|
||||||
/// for public key encryption/private key decryption.
|
|
||||||
|
|
||||||
static CipherFactory& defaultFactory();
|
|
||||||
/// Returns the default CipherFactory.
|
|
||||||
|
|
||||||
private:
|
|
||||||
CipherFactory(const CipherFactory&);
|
|
||||||
CipherFactory& operator = (const CipherFactory&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
class Cipher;
|
||||||
|
class CipherKey;
|
||||||
|
class RSAKey;
|
||||||
|
|
||||||
|
|
||||||
|
class Crypto_API CipherFactory
|
||||||
|
/// A factory for Cipher objects. See the Cipher class for examples on how to
|
||||||
|
/// use the CipherFactory.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CipherFactory();
|
||||||
|
/// Creates a new CipherFactory object.
|
||||||
|
|
||||||
|
virtual ~CipherFactory();
|
||||||
|
/// Destroys the CipherFactory.
|
||||||
|
|
||||||
|
Cipher * createCipher(const CipherKey & key);
|
||||||
|
/// Creates a Cipher object for the given Cipher name. Valid cipher
|
||||||
|
/// names depend on the OpenSSL version the library is linked with;
|
||||||
|
/// see the output of
|
||||||
|
///
|
||||||
|
/// openssl enc --help
|
||||||
|
///
|
||||||
|
/// for a list of supported block and stream ciphers.
|
||||||
|
///
|
||||||
|
/// Common examples are:
|
||||||
|
///
|
||||||
|
/// * AES: "aes-128", "aes-256"
|
||||||
|
/// * DES: "des", "des3"
|
||||||
|
/// * Blowfish: "bf"
|
||||||
|
|
||||||
|
Cipher * createCipher(const RSAKey & key, RSAPaddingMode paddingMode = RSA_PADDING_PKCS1);
|
||||||
|
/// Creates a RSACipher using the given RSA key and padding mode
|
||||||
|
/// for public key encryption/private key decryption.
|
||||||
|
|
||||||
|
static CipherFactory & defaultFactory();
|
||||||
|
/// Returns the default CipherFactory.
|
||||||
|
|
||||||
|
private:
|
||||||
|
CipherFactory(const CipherFactory &);
|
||||||
|
CipherFactory & operator=(const CipherFactory &);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_CipherFactory_INCLUDED
|
#endif // Crypto_CipherFactory_INCLUDED
|
||||||
|
@ -18,52 +18,55 @@
|
|||||||
#define Crypto_CipherImpl_INCLUDED
|
#define Crypto_CipherImpl_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Crypto/Crypto.h"
|
#include <openssl/evp.h>
|
||||||
#include "Poco/Crypto/Cipher.h"
|
#include "Poco/Crypto/Cipher.h"
|
||||||
#include "Poco/Crypto/CipherKey.h"
|
#include "Poco/Crypto/CipherKey.h"
|
||||||
|
#include "Poco/Crypto/Crypto.h"
|
||||||
#include "Poco/Crypto/OpenSSLInitializer.h"
|
#include "Poco/Crypto/OpenSSLInitializer.h"
|
||||||
#include <openssl/evp.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class CipherImpl: public Cipher
|
|
||||||
/// An implementation of the Cipher class for OpenSSL's crypto library.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Crypto
|
||||||
CipherImpl(const CipherKey& key);
|
|
||||||
/// Creates a new CipherImpl object for the given CipherKey.
|
|
||||||
|
|
||||||
virtual ~CipherImpl();
|
|
||||||
/// Destroys the CipherImpl.
|
|
||||||
|
|
||||||
const std::string& name() const;
|
|
||||||
/// Returns the name of the cipher.
|
|
||||||
|
|
||||||
CryptoTransform* createEncryptor();
|
|
||||||
/// Creates an encryptor object.
|
|
||||||
|
|
||||||
CryptoTransform* createDecryptor();
|
|
||||||
/// Creates a decryptor object.
|
|
||||||
|
|
||||||
private:
|
|
||||||
CipherKey _key;
|
|
||||||
OpenSSLInitializer _openSSLInitializer;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Inlines
|
|
||||||
//
|
|
||||||
inline const std::string& CipherImpl::name() const
|
|
||||||
{
|
{
|
||||||
return _key.name();
|
|
||||||
|
|
||||||
|
class CipherImpl : public Cipher
|
||||||
|
/// An implementation of the Cipher class for OpenSSL's crypto library.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CipherImpl(const CipherKey & key);
|
||||||
|
/// Creates a new CipherImpl object for the given CipherKey.
|
||||||
|
|
||||||
|
virtual ~CipherImpl();
|
||||||
|
/// Destroys the CipherImpl.
|
||||||
|
|
||||||
|
const std::string & name() const;
|
||||||
|
/// Returns the name of the cipher.
|
||||||
|
|
||||||
|
CryptoTransform * createEncryptor();
|
||||||
|
/// Creates an encryptor object.
|
||||||
|
|
||||||
|
CryptoTransform * createDecryptor();
|
||||||
|
/// Creates a decryptor object.
|
||||||
|
|
||||||
|
private:
|
||||||
|
CipherKey _key;
|
||||||
|
OpenSSLInitializer _openSSLInitializer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inlines
|
||||||
|
//
|
||||||
|
inline const std::string & CipherImpl::name() const
|
||||||
|
{
|
||||||
|
return _key.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_CipherImpl_INCLUDED
|
#endif // Crypto_CipherImpl_INCLUDED
|
||||||
|
@ -18,184 +18,186 @@
|
|||||||
#define Crypto_CipherKey_INCLUDED
|
#define Crypto_CipherKey_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Crypto/Crypto.h"
|
|
||||||
#include "Poco/Crypto/CipherKeyImpl.h"
|
#include "Poco/Crypto/CipherKeyImpl.h"
|
||||||
|
#include "Poco/Crypto/Crypto.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API CipherKey
|
|
||||||
/// CipherKey stores the key information for decryption/encryption of data.
|
|
||||||
/// To create a random key, using the following code:
|
|
||||||
///
|
|
||||||
/// CipherKey key("aes-256");
|
|
||||||
///
|
|
||||||
/// Note that you won't be able to decrypt data encrypted with a random key
|
|
||||||
/// once the Cipher is destroyed unless you persist the generated key and IV.
|
|
||||||
/// An example usage for random keys is to encrypt data saved in a temporary
|
|
||||||
/// file.
|
|
||||||
///
|
|
||||||
/// To create a key using a human-readable password
|
|
||||||
/// string, use the following code. We create a AES Cipher and
|
|
||||||
/// use a salt value to make the key more robust:
|
|
||||||
///
|
|
||||||
/// std::string password = "secret";
|
|
||||||
/// std::string salt("asdff8723lasdf(**923412");
|
|
||||||
/// CipherKey key("aes-256", password, salt);
|
|
||||||
///
|
|
||||||
/// You may also control the digest and the number of iterations used to generate the key
|
|
||||||
/// by specifying the specific values. Here we create a key with the same data as before,
|
|
||||||
/// except that we use 100 iterations instead of DEFAULT_ITERATION_COUNT, and sha1 instead of
|
|
||||||
/// the default md5:
|
|
||||||
///
|
|
||||||
/// std::string password = "secret";
|
|
||||||
/// std::string salt("asdff8723lasdf(**923412");
|
|
||||||
/// std::string digest ("sha1");
|
|
||||||
/// CipherKey key("aes-256", password, salt, 100, digest);
|
|
||||||
///
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Crypto
|
||||||
typedef CipherKeyImpl::Mode Mode;
|
|
||||||
typedef CipherKeyImpl::ByteVec ByteVec;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
DEFAULT_ITERATION_COUNT = 2000
|
|
||||||
/// Default iteration count to use with
|
|
||||||
/// generateKey(). RSA security recommends
|
|
||||||
/// an iteration count of at least 1000.
|
|
||||||
};
|
|
||||||
|
|
||||||
CipherKey(const std::string& name,
|
|
||||||
const std::string& passphrase,
|
|
||||||
const std::string& salt = "",
|
|
||||||
int iterationCount = DEFAULT_ITERATION_COUNT,
|
|
||||||
const std::string& digest = "md5");
|
|
||||||
/// Creates a new CipherKeyImpl object using the given
|
|
||||||
/// cipher name, passphrase, salt value, iteration count and digest.
|
|
||||||
|
|
||||||
CipherKey(const std::string& name,
|
|
||||||
const ByteVec& key,
|
|
||||||
const ByteVec& iv);
|
|
||||||
/// Creates a new CipherKeyImpl object using the given cipher
|
|
||||||
/// name, key and initialization vector (IV).
|
|
||||||
///
|
|
||||||
/// The size of the IV must match the cipher's expected
|
|
||||||
/// IV size (see ivSize()), except for GCM mode, which allows
|
|
||||||
/// a custom IV size.
|
|
||||||
|
|
||||||
CipherKey(const std::string& name);
|
|
||||||
/// Creates a new CipherKeyImpl object. Autoinitializes key and
|
|
||||||
/// initialization vector.
|
|
||||||
|
|
||||||
~CipherKey();
|
|
||||||
/// Destroys the CipherKeyImpl.
|
|
||||||
|
|
||||||
const std::string& name() const;
|
|
||||||
/// Returns the name of the Cipher.
|
|
||||||
|
|
||||||
int keySize() const;
|
|
||||||
/// Returns the key size of the Cipher.
|
|
||||||
|
|
||||||
int blockSize() const;
|
|
||||||
/// Returns the block size of the Cipher.
|
|
||||||
|
|
||||||
int ivSize() const;
|
|
||||||
/// Returns the IV size of the Cipher.
|
|
||||||
|
|
||||||
Mode mode() const;
|
|
||||||
/// Returns the Cipher's mode of operation.
|
|
||||||
|
|
||||||
const ByteVec& getKey() const;
|
|
||||||
/// Returns the key for the Cipher.
|
|
||||||
|
|
||||||
void setKey(const ByteVec& key);
|
|
||||||
/// Sets the key for the Cipher.
|
|
||||||
|
|
||||||
const ByteVec& getIV() const;
|
|
||||||
/// Returns the initialization vector (IV) for the Cipher.
|
|
||||||
|
|
||||||
void setIV(const ByteVec& iv);
|
|
||||||
/// Sets the initialization vector (IV) for the Cipher.
|
|
||||||
///
|
|
||||||
/// The size of the vector must match the cipher's expected
|
|
||||||
/// IV size (see ivSize()), except for GCM mode, which allows
|
|
||||||
/// a custom IV size.
|
|
||||||
|
|
||||||
CipherKeyImpl::Ptr impl();
|
|
||||||
/// Returns the impl object
|
|
||||||
|
|
||||||
private:
|
|
||||||
CipherKeyImpl::Ptr _pImpl;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline const std::string& CipherKey::name() const
|
|
||||||
{
|
{
|
||||||
return _pImpl->name();
|
|
||||||
|
|
||||||
|
class Crypto_API CipherKey
|
||||||
|
/// CipherKey stores the key information for decryption/encryption of data.
|
||||||
|
/// To create a random key, using the following code:
|
||||||
|
///
|
||||||
|
/// CipherKey key("aes-256");
|
||||||
|
///
|
||||||
|
/// Note that you won't be able to decrypt data encrypted with a random key
|
||||||
|
/// once the Cipher is destroyed unless you persist the generated key and IV.
|
||||||
|
/// An example usage for random keys is to encrypt data saved in a temporary
|
||||||
|
/// file.
|
||||||
|
///
|
||||||
|
/// To create a key using a human-readable password
|
||||||
|
/// string, use the following code. We create a AES Cipher and
|
||||||
|
/// use a salt value to make the key more robust:
|
||||||
|
///
|
||||||
|
/// std::string password = "secret";
|
||||||
|
/// std::string salt("asdff8723lasdf(**923412");
|
||||||
|
/// CipherKey key("aes-256", password, salt);
|
||||||
|
///
|
||||||
|
/// You may also control the digest and the number of iterations used to generate the key
|
||||||
|
/// by specifying the specific values. Here we create a key with the same data as before,
|
||||||
|
/// except that we use 100 iterations instead of DEFAULT_ITERATION_COUNT, and sha1 instead of
|
||||||
|
/// the default md5:
|
||||||
|
///
|
||||||
|
/// std::string password = "secret";
|
||||||
|
/// std::string salt("asdff8723lasdf(**923412");
|
||||||
|
/// std::string digest ("sha1");
|
||||||
|
/// CipherKey key("aes-256", password, salt, 100, digest);
|
||||||
|
///
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef CipherKeyImpl::Mode Mode;
|
||||||
|
typedef CipherKeyImpl::ByteVec ByteVec;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
DEFAULT_ITERATION_COUNT = 2000
|
||||||
|
/// Default iteration count to use with
|
||||||
|
/// generateKey(). RSA security recommends
|
||||||
|
/// an iteration count of at least 1000.
|
||||||
|
};
|
||||||
|
|
||||||
|
CipherKey(
|
||||||
|
const std::string & name,
|
||||||
|
const std::string & passphrase,
|
||||||
|
const std::string & salt = "",
|
||||||
|
int iterationCount = DEFAULT_ITERATION_COUNT,
|
||||||
|
const std::string & digest = "md5");
|
||||||
|
/// Creates a new CipherKeyImpl object using the given
|
||||||
|
/// cipher name, passphrase, salt value, iteration count and digest.
|
||||||
|
|
||||||
|
CipherKey(const std::string & name, const ByteVec & key, const ByteVec & iv);
|
||||||
|
/// Creates a new CipherKeyImpl object using the given cipher
|
||||||
|
/// name, key and initialization vector (IV).
|
||||||
|
///
|
||||||
|
/// The size of the IV must match the cipher's expected
|
||||||
|
/// IV size (see ivSize()), except for GCM mode, which allows
|
||||||
|
/// a custom IV size.
|
||||||
|
|
||||||
|
CipherKey(const std::string & name);
|
||||||
|
/// Creates a new CipherKeyImpl object. Autoinitializes key and
|
||||||
|
/// initialization vector.
|
||||||
|
|
||||||
|
~CipherKey();
|
||||||
|
/// Destroys the CipherKeyImpl.
|
||||||
|
|
||||||
|
const std::string & name() const;
|
||||||
|
/// Returns the name of the Cipher.
|
||||||
|
|
||||||
|
int keySize() const;
|
||||||
|
/// Returns the key size of the Cipher.
|
||||||
|
|
||||||
|
int blockSize() const;
|
||||||
|
/// Returns the block size of the Cipher.
|
||||||
|
|
||||||
|
int ivSize() const;
|
||||||
|
/// Returns the IV size of the Cipher.
|
||||||
|
|
||||||
|
Mode mode() const;
|
||||||
|
/// Returns the Cipher's mode of operation.
|
||||||
|
|
||||||
|
const ByteVec & getKey() const;
|
||||||
|
/// Returns the key for the Cipher.
|
||||||
|
|
||||||
|
void setKey(const ByteVec & key);
|
||||||
|
/// Sets the key for the Cipher.
|
||||||
|
|
||||||
|
const ByteVec & getIV() const;
|
||||||
|
/// Returns the initialization vector (IV) for the Cipher.
|
||||||
|
|
||||||
|
void setIV(const ByteVec & iv);
|
||||||
|
/// Sets the initialization vector (IV) for the Cipher.
|
||||||
|
///
|
||||||
|
/// The size of the vector must match the cipher's expected
|
||||||
|
/// IV size (see ivSize()), except for GCM mode, which allows
|
||||||
|
/// a custom IV size.
|
||||||
|
|
||||||
|
CipherKeyImpl::Ptr impl();
|
||||||
|
/// Returns the impl object
|
||||||
|
|
||||||
|
private:
|
||||||
|
CipherKeyImpl::Ptr _pImpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline const std::string & CipherKey::name() const
|
||||||
|
{
|
||||||
|
return _pImpl->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int CipherKey::keySize() const
|
||||||
|
{
|
||||||
|
return _pImpl->keySize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int CipherKey::blockSize() const
|
||||||
|
{
|
||||||
|
return _pImpl->blockSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int CipherKey::ivSize() const
|
||||||
|
{
|
||||||
|
return _pImpl->ivSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline CipherKey::Mode CipherKey::mode() const
|
||||||
|
{
|
||||||
|
return _pImpl->mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const CipherKey::ByteVec & CipherKey::getKey() const
|
||||||
|
{
|
||||||
|
return _pImpl->getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void CipherKey::setKey(const CipherKey::ByteVec & key)
|
||||||
|
{
|
||||||
|
_pImpl->setKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const CipherKey::ByteVec & CipherKey::getIV() const
|
||||||
|
{
|
||||||
|
return _pImpl->getIV();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void CipherKey::setIV(const CipherKey::ByteVec & iv)
|
||||||
|
{
|
||||||
|
_pImpl->setIV(iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline CipherKeyImpl::Ptr CipherKey::impl()
|
||||||
|
{
|
||||||
|
return _pImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
inline int CipherKey::keySize() const
|
|
||||||
{
|
|
||||||
return _pImpl->keySize();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline int CipherKey::blockSize() const
|
|
||||||
{
|
|
||||||
return _pImpl->blockSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline int CipherKey::ivSize() const
|
|
||||||
{
|
|
||||||
return _pImpl->ivSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline CipherKey::Mode CipherKey::mode() const
|
|
||||||
{
|
|
||||||
return _pImpl->mode();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const CipherKey::ByteVec& CipherKey::getKey() const
|
|
||||||
{
|
|
||||||
return _pImpl->getKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void CipherKey::setKey(const CipherKey::ByteVec& key)
|
|
||||||
{
|
|
||||||
_pImpl->setKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const CipherKey::ByteVec& CipherKey::getIV() const
|
|
||||||
{
|
|
||||||
return _pImpl->getIV();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void CipherKey::setIV(const CipherKey::ByteVec& iv)
|
|
||||||
{
|
|
||||||
_pImpl->setIV(iv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline CipherKeyImpl::Ptr CipherKey::impl()
|
|
||||||
{
|
|
||||||
return _pImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_CipherKey_INCLUDED
|
#endif // Crypto_CipherKey_INCLUDED
|
||||||
|
@ -18,151 +18,151 @@
|
|||||||
#define Crypto_CipherKeyImpl_INCLUDED
|
#define Crypto_CipherKeyImpl_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "Poco/AutoPtr.h"
|
||||||
#include "Poco/Crypto/Crypto.h"
|
#include "Poco/Crypto/Crypto.h"
|
||||||
#include "Poco/Crypto/OpenSSLInitializer.h"
|
#include "Poco/Crypto/OpenSSLInitializer.h"
|
||||||
#include "Poco/RefCountedObject.h"
|
#include "Poco/RefCountedObject.h"
|
||||||
#include "Poco/AutoPtr.h"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
struct evp_cipher_st;
|
struct evp_cipher_st;
|
||||||
typedef struct evp_cipher_st EVP_CIPHER;
|
typedef struct evp_cipher_st EVP_CIPHER;
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class CipherKeyImpl: public RefCountedObject
|
|
||||||
/// An implementation of the CipherKey class for OpenSSL's crypto library.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Crypto
|
||||||
typedef std::vector<unsigned char> ByteVec;
|
|
||||||
typedef Poco::AutoPtr<CipherKeyImpl> Ptr;
|
|
||||||
|
|
||||||
enum Mode
|
|
||||||
/// Cipher mode of operation. This mode determines how multiple blocks
|
|
||||||
/// are connected; this is essential to improve security.
|
|
||||||
{
|
|
||||||
MODE_STREAM_CIPHER, /// Stream cipher
|
|
||||||
MODE_ECB, /// Electronic codebook (plain concatenation)
|
|
||||||
MODE_CBC, /// Cipher block chaining (default)
|
|
||||||
MODE_CFB, /// Cipher feedback
|
|
||||||
MODE_OFB, /// Output feedback
|
|
||||||
MODE_CTR, /// Counter mode
|
|
||||||
MODE_GCM, /// Galois/Counter mode
|
|
||||||
MODE_CCM /// Counter with CBC-MAC
|
|
||||||
};
|
|
||||||
|
|
||||||
CipherKeyImpl(const std::string& name,
|
|
||||||
const std::string& passphrase,
|
|
||||||
const std::string& salt,
|
|
||||||
int iterationCount,
|
|
||||||
const std::string& digest);
|
|
||||||
/// Creates a new CipherKeyImpl object, using
|
|
||||||
/// the given cipher name, passphrase, salt value
|
|
||||||
/// and iteration count.
|
|
||||||
|
|
||||||
CipherKeyImpl(const std::string& name,
|
|
||||||
const ByteVec& key,
|
|
||||||
const ByteVec& iv);
|
|
||||||
/// Creates a new CipherKeyImpl object, using the
|
|
||||||
/// given cipher name, key and initialization vector.
|
|
||||||
|
|
||||||
CipherKeyImpl(const std::string& name);
|
|
||||||
/// Creates a new CipherKeyImpl object. Autoinitializes key
|
|
||||||
/// and initialization vector.
|
|
||||||
|
|
||||||
virtual ~CipherKeyImpl();
|
|
||||||
/// Destroys the CipherKeyImpl.
|
|
||||||
|
|
||||||
const std::string& name() const;
|
|
||||||
/// Returns the name of the Cipher.
|
|
||||||
|
|
||||||
int keySize() const;
|
|
||||||
/// Returns the key size of the Cipher.
|
|
||||||
|
|
||||||
int blockSize() const;
|
|
||||||
/// Returns the block size of the Cipher.
|
|
||||||
|
|
||||||
int ivSize() const;
|
|
||||||
/// Returns the IV size of the Cipher.
|
|
||||||
|
|
||||||
Mode mode() const;
|
|
||||||
/// Returns the Cipher's mode of operation.
|
|
||||||
|
|
||||||
const ByteVec& getKey() const;
|
|
||||||
/// Returns the key for the Cipher.
|
|
||||||
|
|
||||||
void setKey(const ByteVec& key);
|
|
||||||
/// Sets the key for the Cipher.
|
|
||||||
|
|
||||||
const ByteVec& getIV() const;
|
|
||||||
/// Returns the initialization vector (IV) for the Cipher.
|
|
||||||
|
|
||||||
void setIV(const ByteVec& iv);
|
|
||||||
/// Sets the initialization vector (IV) for the Cipher.
|
|
||||||
|
|
||||||
const EVP_CIPHER* cipher();
|
|
||||||
/// Returns the cipher object
|
|
||||||
|
|
||||||
private:
|
|
||||||
void generateKey(const std::string& passphrase,
|
|
||||||
const std::string& salt,
|
|
||||||
int iterationCount);
|
|
||||||
/// Generates key and IV from a password and optional salt string.
|
|
||||||
|
|
||||||
void generateKey();
|
|
||||||
/// Generates key and IV from random data.
|
|
||||||
|
|
||||||
void getRandomBytes(ByteVec& vec, std::size_t count);
|
|
||||||
/// Stores random bytes in vec.
|
|
||||||
|
|
||||||
private:
|
|
||||||
const EVP_CIPHER* _pCipher;
|
|
||||||
const EVP_MD* _pDigest;
|
|
||||||
std::string _name;
|
|
||||||
ByteVec _key;
|
|
||||||
ByteVec _iv;
|
|
||||||
OpenSSLInitializer _openSSLInitializer;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Inlines
|
|
||||||
//
|
|
||||||
inline const std::string& CipherKeyImpl::name() const
|
|
||||||
{
|
{
|
||||||
return _name;
|
|
||||||
|
|
||||||
|
class CipherKeyImpl : public RefCountedObject
|
||||||
|
/// An implementation of the CipherKey class for OpenSSL's crypto library.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::vector<unsigned char> ByteVec;
|
||||||
|
typedef Poco::AutoPtr<CipherKeyImpl> Ptr;
|
||||||
|
|
||||||
|
enum Mode
|
||||||
|
/// Cipher mode of operation. This mode determines how multiple blocks
|
||||||
|
/// are connected; this is essential to improve security.
|
||||||
|
{
|
||||||
|
MODE_STREAM_CIPHER, /// Stream cipher
|
||||||
|
MODE_ECB, /// Electronic codebook (plain concatenation)
|
||||||
|
MODE_CBC, /// Cipher block chaining (default)
|
||||||
|
MODE_CFB, /// Cipher feedback
|
||||||
|
MODE_OFB, /// Output feedback
|
||||||
|
MODE_CTR, /// Counter mode
|
||||||
|
MODE_GCM, /// Galois/Counter mode
|
||||||
|
MODE_CCM /// Counter with CBC-MAC
|
||||||
|
};
|
||||||
|
|
||||||
|
CipherKeyImpl(
|
||||||
|
const std::string & name,
|
||||||
|
const std::string & passphrase,
|
||||||
|
const std::string & salt,
|
||||||
|
int iterationCount,
|
||||||
|
const std::string & digest);
|
||||||
|
/// Creates a new CipherKeyImpl object, using
|
||||||
|
/// the given cipher name, passphrase, salt value
|
||||||
|
/// and iteration count.
|
||||||
|
|
||||||
|
CipherKeyImpl(const std::string & name, const ByteVec & key, const ByteVec & iv);
|
||||||
|
/// Creates a new CipherKeyImpl object, using the
|
||||||
|
/// given cipher name, key and initialization vector.
|
||||||
|
|
||||||
|
CipherKeyImpl(const std::string & name);
|
||||||
|
/// Creates a new CipherKeyImpl object. Autoinitializes key
|
||||||
|
/// and initialization vector.
|
||||||
|
|
||||||
|
virtual ~CipherKeyImpl();
|
||||||
|
/// Destroys the CipherKeyImpl.
|
||||||
|
|
||||||
|
const std::string & name() const;
|
||||||
|
/// Returns the name of the Cipher.
|
||||||
|
|
||||||
|
int keySize() const;
|
||||||
|
/// Returns the key size of the Cipher.
|
||||||
|
|
||||||
|
int blockSize() const;
|
||||||
|
/// Returns the block size of the Cipher.
|
||||||
|
|
||||||
|
int ivSize() const;
|
||||||
|
/// Returns the IV size of the Cipher.
|
||||||
|
|
||||||
|
Mode mode() const;
|
||||||
|
/// Returns the Cipher's mode of operation.
|
||||||
|
|
||||||
|
const ByteVec & getKey() const;
|
||||||
|
/// Returns the key for the Cipher.
|
||||||
|
|
||||||
|
void setKey(const ByteVec & key);
|
||||||
|
/// Sets the key for the Cipher.
|
||||||
|
|
||||||
|
const ByteVec & getIV() const;
|
||||||
|
/// Returns the initialization vector (IV) for the Cipher.
|
||||||
|
|
||||||
|
void setIV(const ByteVec & iv);
|
||||||
|
/// Sets the initialization vector (IV) for the Cipher.
|
||||||
|
|
||||||
|
const EVP_CIPHER * cipher();
|
||||||
|
/// Returns the cipher object
|
||||||
|
|
||||||
|
private:
|
||||||
|
void generateKey(const std::string & passphrase, const std::string & salt, int iterationCount);
|
||||||
|
/// Generates key and IV from a password and optional salt string.
|
||||||
|
|
||||||
|
void generateKey();
|
||||||
|
/// Generates key and IV from random data.
|
||||||
|
|
||||||
|
void getRandomBytes(ByteVec & vec, std::size_t count);
|
||||||
|
/// Stores random bytes in vec.
|
||||||
|
|
||||||
|
private:
|
||||||
|
const EVP_CIPHER * _pCipher;
|
||||||
|
const EVP_MD * _pDigest;
|
||||||
|
std::string _name;
|
||||||
|
ByteVec _key;
|
||||||
|
ByteVec _iv;
|
||||||
|
OpenSSLInitializer _openSSLInitializer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inlines
|
||||||
|
//
|
||||||
|
inline const std::string & CipherKeyImpl::name() const
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const CipherKeyImpl::ByteVec & CipherKeyImpl::getKey() const
|
||||||
|
{
|
||||||
|
return _key;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void CipherKeyImpl::setKey(const ByteVec & key)
|
||||||
|
{
|
||||||
|
poco_assert(key.size() == static_cast<ByteVec::size_type>(keySize()));
|
||||||
|
_key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const CipherKeyImpl::ByteVec & CipherKeyImpl::getIV() const
|
||||||
|
{
|
||||||
|
return _iv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const EVP_CIPHER * CipherKeyImpl::cipher()
|
||||||
|
{
|
||||||
|
return _pCipher;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
inline const CipherKeyImpl::ByteVec& CipherKeyImpl::getKey() const
|
|
||||||
{
|
|
||||||
return _key;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void CipherKeyImpl::setKey(const ByteVec& key)
|
|
||||||
{
|
|
||||||
poco_assert(key.size() == static_cast<ByteVec::size_type>(keySize()));
|
|
||||||
_key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const CipherKeyImpl::ByteVec& CipherKeyImpl::getIV() const
|
|
||||||
{
|
|
||||||
return _iv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const EVP_CIPHER* CipherKeyImpl::cipher()
|
|
||||||
{
|
|
||||||
return _pCipher;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_CipherKeyImpl_INCLUDED
|
#endif // Crypto_CipherKeyImpl_INCLUDED
|
||||||
|
@ -24,39 +24,37 @@
|
|||||||
#define POCO_EXTERNAL_OPENSSL_SLPRO 2
|
#define POCO_EXTERNAL_OPENSSL_SLPRO 2
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Foundation.h"
|
|
||||||
#include <openssl/opensslv.h>
|
#include <openssl/opensslv.h>
|
||||||
|
#include "Poco/Foundation.h"
|
||||||
|
|
||||||
|
|
||||||
#ifndef OPENSSL_VERSION_PREREQ
|
#ifndef OPENSSL_VERSION_PREREQ
|
||||||
#if defined(OPENSSL_VERSION_MAJOR) && defined(OPENSSL_VERSION_MINOR)
|
# if defined(OPENSSL_VERSION_MAJOR) && defined(OPENSSL_VERSION_MINOR)
|
||||||
#define OPENSSL_VERSION_PREREQ(maj, min) \
|
# define OPENSSL_VERSION_PREREQ(maj, min) ((OPENSSL_VERSION_MAJOR << 16) + OPENSSL_VERSION_MINOR >= ((maj) << 16) + (min))
|
||||||
((OPENSSL_VERSION_MAJOR << 16) + OPENSSL_VERSION_MINOR >= ((maj) << 16) + (min))
|
# else
|
||||||
#else
|
# define OPENSSL_VERSION_PREREQ(maj, min) (OPENSSL_VERSION_NUMBER >= (((maj) << 28) | ((min) << 20)))
|
||||||
#define OPENSSL_VERSION_PREREQ(maj, min) \
|
# endif
|
||||||
(OPENSSL_VERSION_NUMBER >= (((maj) << 28) | ((min) << 20)))
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
enum RSAPaddingMode
|
enum RSAPaddingMode
|
||||||
/// The padding mode used for RSA public key encryption.
|
/// The padding mode used for RSA public key encryption.
|
||||||
{
|
{
|
||||||
RSA_PADDING_PKCS1,
|
RSA_PADDING_PKCS1,
|
||||||
/// PKCS #1 v1.5 padding. This currently is the most widely used mode.
|
/// PKCS #1 v1.5 padding. This currently is the most widely used mode.
|
||||||
|
|
||||||
RSA_PADDING_PKCS1_OAEP,
|
RSA_PADDING_PKCS1_OAEP,
|
||||||
/// EME-OAEP as defined in PKCS #1 v2.0 with SHA-1, MGF1 and an empty
|
/// EME-OAEP as defined in PKCS #1 v2.0 with SHA-1, MGF1 and an empty
|
||||||
/// encoding parameter. This mode is recommended for all new applications.
|
/// encoding parameter. This mode is recommended for all new applications.
|
||||||
|
|
||||||
RSA_PADDING_SSLV23,
|
RSA_PADDING_SSLV23,
|
||||||
/// PKCS #1 v1.5 padding with an SSL-specific modification that denotes
|
/// PKCS #1 v1.5 padding with an SSL-specific modification that denotes
|
||||||
/// that the server is SSL3 capable.
|
/// that the server is SSL3 capable.
|
||||||
|
|
||||||
RSA_PADDING_NONE
|
RSA_PADDING_NONE
|
||||||
/// Raw RSA encryption. This mode should only be used to implement cryptographically
|
/// Raw RSA encryption. This mode should only be used to implement cryptographically
|
||||||
/// sound padding modes in the application code. Encrypting user data directly with RSA
|
/// sound padding modes in the application code. Encrypting user data directly with RSA
|
||||||
/// is insecure.
|
/// is insecure.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -69,22 +67,22 @@ enum RSAPaddingMode
|
|||||||
// defined with this macro as being exported.
|
// defined with this macro as being exported.
|
||||||
//
|
//
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#if defined(POCO_DLL)
|
# if defined(POCO_DLL)
|
||||||
#if defined(Crypto_EXPORTS)
|
# if defined(Crypto_EXPORTS)
|
||||||
#define Crypto_API __declspec(dllexport)
|
# define Crypto_API __declspec(dllexport)
|
||||||
#else
|
# else
|
||||||
#define Crypto_API __declspec(dllimport)
|
# define Crypto_API __declspec(dllimport)
|
||||||
#endif
|
# endif
|
||||||
#endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(Crypto_API)
|
#if !defined(Crypto_API)
|
||||||
#if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined (__GNUC__) && (__GNUC__ >= 4)
|
# if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined(__GNUC__) && (__GNUC__ >= 4)
|
||||||
#define Crypto_API __attribute__ ((visibility ("default")))
|
# define Crypto_API __attribute__((visibility("default")))
|
||||||
#else
|
# else
|
||||||
#define Crypto_API
|
# define Crypto_API
|
||||||
#endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -92,104 +90,106 @@ enum RSAPaddingMode
|
|||||||
// Automatically link Crypto and OpenSSL libraries.
|
// Automatically link Crypto and OpenSSL libraries.
|
||||||
//
|
//
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#if !defined(POCO_NO_AUTOMATIC_LIBS)
|
# if !defined(POCO_NO_AUTOMATIC_LIBS)
|
||||||
#if defined(POCO_INTERNAL_OPENSSL_MSVC_VER)
|
# if defined(POCO_INTERNAL_OPENSSL_MSVC_VER)
|
||||||
#if defined(POCO_EXTERNAL_OPENSSL)
|
# if defined(POCO_EXTERNAL_OPENSSL)
|
||||||
#pragma message("External OpenSSL defined but internal headers used - possible mismatch!")
|
# pragma message("External OpenSSL defined but internal headers used - possible mismatch!")
|
||||||
#endif // POCO_EXTERNAL_OPENSSL
|
# endif // POCO_EXTERNAL_OPENSSL
|
||||||
#if !defined(_DEBUG)
|
# if !defined(_DEBUG)
|
||||||
#define POCO_DEBUG_SUFFIX ""
|
# define POCO_DEBUG_SUFFIX ""
|
||||||
#if !defined (_DLL)
|
# if !defined(_DLL)
|
||||||
#define POCO_STATIC_SUFFIX "mt"
|
# define POCO_STATIC_SUFFIX "mt"
|
||||||
#else // _DLL
|
# else // _DLL
|
||||||
#define POCO_STATIC_SUFFIX ""
|
# define POCO_STATIC_SUFFIX ""
|
||||||
#endif
|
# endif
|
||||||
#else // _DEBUG
|
# else // _DEBUG
|
||||||
#define POCO_DEBUG_SUFFIX "d"
|
# define POCO_DEBUG_SUFFIX "d"
|
||||||
#if !defined (_DLL)
|
# if !defined(_DLL)
|
||||||
#define POCO_STATIC_SUFFIX "mt"
|
# define POCO_STATIC_SUFFIX "mt"
|
||||||
#else // _DLL
|
# else // _DLL
|
||||||
#define POCO_STATIC_SUFFIX ""
|
# define POCO_STATIC_SUFFIX ""
|
||||||
#endif
|
# endif
|
||||||
#endif
|
# endif
|
||||||
#pragma comment(lib, "libcrypto" POCO_STATIC_SUFFIX POCO_DEBUG_SUFFIX ".lib")
|
# pragma comment(lib, "libcrypto" POCO_STATIC_SUFFIX POCO_DEBUG_SUFFIX ".lib")
|
||||||
#pragma comment(lib, "libssl" POCO_STATIC_SUFFIX POCO_DEBUG_SUFFIX ".lib")
|
# pragma comment(lib, "libssl" POCO_STATIC_SUFFIX POCO_DEBUG_SUFFIX ".lib")
|
||||||
#if !defined(_WIN64) && !defined (_DLL) && \
|
# if !defined(_WIN64) && !defined(_DLL) && (POCO_INTERNAL_OPENSSL_MSVC_VER == 120) \
|
||||||
(POCO_INTERNAL_OPENSSL_MSVC_VER == 120) && \
|
&& (POCO_MSVC_VERSION < POCO_INTERNAL_OPENSSL_MSVC_VER)
|
||||||
(POCO_MSVC_VERSION < POCO_INTERNAL_OPENSSL_MSVC_VER)
|
# pragma comment(lib, "libPreVS2013CRT" POCO_STATIC_SUFFIX POCO_DEBUG_SUFFIX ".lib")
|
||||||
#pragma comment(lib, "libPreVS2013CRT" POCO_STATIC_SUFFIX POCO_DEBUG_SUFFIX ".lib")
|
# endif
|
||||||
#endif
|
# if !defined(_DLL) && (POCO_MSVS_VERSION >= 2015)
|
||||||
#if !defined (_DLL) && (POCO_MSVS_VERSION >= 2015)
|
# pragma comment(lib, "legacy_stdio_definitions.lib")
|
||||||
#pragma comment(lib, "legacy_stdio_definitions.lib")
|
# pragma comment(lib, "legacy_stdio_wide_specifiers.lib")
|
||||||
#pragma comment(lib, "legacy_stdio_wide_specifiers.lib")
|
# endif
|
||||||
#endif
|
# elif defined(POCO_EXTERNAL_OPENSSL)
|
||||||
#elif defined(POCO_EXTERNAL_OPENSSL)
|
# if POCO_EXTERNAL_OPENSSL == POCO_EXTERNAL_OPENSSL_SLPRO
|
||||||
#if POCO_EXTERNAL_OPENSSL == POCO_EXTERNAL_OPENSSL_SLPRO
|
# if defined(POCO_DLL)
|
||||||
#if defined(POCO_DLL)
|
# if OPENSSL_VERSION_PREREQ(1, 1)
|
||||||
#if OPENSSL_VERSION_PREREQ(1,1)
|
# pragma comment(lib, "libcrypto.lib")
|
||||||
#pragma comment(lib, "libcrypto.lib")
|
# pragma comment(lib, "libssl.lib")
|
||||||
#pragma comment(lib, "libssl.lib")
|
# else
|
||||||
#else
|
# pragma comment(lib, "libeay32.lib")
|
||||||
#pragma comment(lib, "libeay32.lib")
|
# pragma comment(lib, "ssleay32.lib")
|
||||||
#pragma comment(lib, "ssleay32.lib")
|
# endif
|
||||||
#endif
|
# else
|
||||||
#else
|
# if OPENSSL_VERSION_PREREQ(1, 1)
|
||||||
#if OPENSSL_VERSION_PREREQ(1,1)
|
# if defined(_WIN64)
|
||||||
#if defined(_WIN64)
|
# pragma comment(lib, "libcrypto64" POCO_LIB_SUFFIX)
|
||||||
#pragma comment(lib, "libcrypto64" POCO_LIB_SUFFIX)
|
# pragma comment(lib, "libssl64" POCO_LIB_SUFFIX)
|
||||||
#pragma comment(lib, "libssl64" POCO_LIB_SUFFIX)
|
# else
|
||||||
#else
|
# pragma comment(lib, "libcrypto32" POCO_LIB_SUFFIX)
|
||||||
#pragma comment(lib, "libcrypto32" POCO_LIB_SUFFIX)
|
# pragma comment(lib, "libssl32" POCO_LIB_SUFFIX)
|
||||||
#pragma comment(lib, "libssl32" POCO_LIB_SUFFIX)
|
# endif
|
||||||
#endif
|
# else
|
||||||
#else
|
# pragma comment(lib, "libeay32" POCO_LIB_SUFFIX)
|
||||||
#pragma comment(lib, "libeay32" POCO_LIB_SUFFIX)
|
# pragma comment(lib, "ssleay32" POCO_LIB_SUFFIX)
|
||||||
#pragma comment(lib, "ssleay32" POCO_LIB_SUFFIX)
|
# endif
|
||||||
#endif
|
# endif
|
||||||
#endif
|
# elif POCO_EXTERNAL_OPENSSL == POCO_EXTERNAL_OPENSSL_DEFAULT
|
||||||
#elif POCO_EXTERNAL_OPENSSL == POCO_EXTERNAL_OPENSSL_DEFAULT
|
# if OPENSSL_VERSION_PREREQ(1, 1)
|
||||||
#if OPENSSL_VERSION_PREREQ(1,1)
|
# pragma comment(lib, "libcrypto.lib")
|
||||||
#pragma comment(lib, "libcrypto.lib")
|
# pragma comment(lib, "libssl.lib")
|
||||||
#pragma comment(lib, "libssl.lib")
|
# else
|
||||||
#else
|
# pragma comment(lib, "libeay32.lib")
|
||||||
#pragma comment(lib, "libeay32.lib")
|
# pragma comment(lib, "ssleay32.lib")
|
||||||
#pragma comment(lib, "ssleay32.lib")
|
# endif
|
||||||
#endif
|
# endif
|
||||||
#endif
|
# endif // POCO_INTERNAL_OPENSSL_MSVC_VER
|
||||||
#endif // POCO_INTERNAL_OPENSSL_MSVC_VER
|
# if !defined(Crypto_EXPORTS)
|
||||||
#if !defined(Crypto_EXPORTS)
|
# pragma comment(lib, "PocoCrypto" POCO_LIB_SUFFIX)
|
||||||
#pragma comment(lib, "PocoCrypto" POCO_LIB_SUFFIX)
|
# endif
|
||||||
#endif
|
# endif // POCO_NO_AUTOMATIC_LIBS
|
||||||
#endif // POCO_NO_AUTOMATIC_LIBS
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
{
|
||||||
|
namespace Crypto
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
void Crypto_API initializeCrypto();
|
void Crypto_API initializeCrypto();
|
||||||
/// Initialize the Crypto library, as well as the underlying OpenSSL
|
/// Initialize the Crypto library, as well as the underlying OpenSSL
|
||||||
/// libraries, by calling OpenSSLInitializer::initialize().
|
/// libraries, by calling OpenSSLInitializer::initialize().
|
||||||
///
|
///
|
||||||
/// Should be called before using any class from the Crypto library.
|
/// Should be called before using any class from the Crypto library.
|
||||||
/// The Crypto library will be initialized automatically, through
|
/// The Crypto library will be initialized automatically, through
|
||||||
/// OpenSSLInitializer instances held by various Crypto classes
|
/// OpenSSLInitializer instances held by various Crypto classes
|
||||||
/// (Cipher, CipherKey, RSAKey, X509Certificate).
|
/// (Cipher, CipherKey, RSAKey, X509Certificate).
|
||||||
/// However, it is recommended to call initializeCrypto()
|
/// However, it is recommended to call initializeCrypto()
|
||||||
/// in any case at application startup.
|
/// in any case at application startup.
|
||||||
///
|
///
|
||||||
/// Can be called multiple times; however, for every call to
|
/// Can be called multiple times; however, for every call to
|
||||||
/// initializeCrypto(), a matching call to uninitializeCrypto()
|
/// initializeCrypto(), a matching call to uninitializeCrypto()
|
||||||
/// must be performed.
|
/// must be performed.
|
||||||
|
|
||||||
|
|
||||||
void Crypto_API uninitializeCrypto();
|
void Crypto_API uninitializeCrypto();
|
||||||
/// Uninitializes the Crypto library by calling
|
/// Uninitializes the Crypto library by calling
|
||||||
/// OpenSSLInitializer::uninitialize().
|
/// OpenSSLInitializer::uninitialize().
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_Crypto_INCLUDED
|
#endif // Crypto_Crypto_INCLUDED
|
||||||
|
@ -23,34 +23,37 @@
|
|||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
{
|
||||||
|
namespace Crypto
|
||||||
|
|
||||||
POCO_DECLARE_EXCEPTION(Crypto_API, CryptoException, Poco::Exception)
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API OpenSSLException : public CryptoException
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
OpenSSLException(int code = 0);
|
|
||||||
OpenSSLException(const std::string& msg, int code = 0);
|
|
||||||
OpenSSLException(const std::string& msg, const std::string& arg, int code = 0);
|
|
||||||
OpenSSLException(const std::string& msg, const Poco::Exception& exc, int code = 0);
|
|
||||||
OpenSSLException(const OpenSSLException& exc);
|
|
||||||
~OpenSSLException() throw();
|
|
||||||
OpenSSLException& operator = (const OpenSSLException& exc);
|
|
||||||
const char* name() const throw();
|
|
||||||
const char* className() const throw();
|
|
||||||
Poco::Exception* clone() const;
|
|
||||||
void rethrow() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setExtMessage();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
POCO_DECLARE_EXCEPTION(Crypto_API, CryptoException, Poco::Exception)
|
||||||
|
|
||||||
|
|
||||||
|
class Crypto_API OpenSSLException : public CryptoException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OpenSSLException(int code = 0);
|
||||||
|
OpenSSLException(const std::string & msg, int code = 0);
|
||||||
|
OpenSSLException(const std::string & msg, const std::string & arg, int code = 0);
|
||||||
|
OpenSSLException(const std::string & msg, const Poco::Exception & exc, int code = 0);
|
||||||
|
OpenSSLException(const OpenSSLException & exc);
|
||||||
|
~OpenSSLException() throw();
|
||||||
|
OpenSSLException & operator=(const OpenSSLException & exc);
|
||||||
|
const char * name() const throw();
|
||||||
|
const char * className() const throw();
|
||||||
|
Poco::Exception * clone() const;
|
||||||
|
void rethrow() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setExtMessage();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_CryptoException_INCLUDED
|
#endif // Crypto_CryptoException_INCLUDED
|
||||||
|
@ -19,174 +19,177 @@
|
|||||||
#define Crypto_CryptoStream_INCLUDED
|
#define Crypto_CryptoStream_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Crypto/Crypto.h"
|
|
||||||
#include "Poco/BufferedStreamBuf.h"
|
|
||||||
#include "Poco/Buffer.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "Poco/Buffer.h"
|
||||||
|
#include "Poco/BufferedStreamBuf.h"
|
||||||
|
#include "Poco/Crypto/Crypto.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class CryptoTransform;
|
|
||||||
class Cipher;
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API CryptoStreamBuf: public Poco::BufferedStreamBuf
|
|
||||||
/// This stream buffer performs cryptographic transformation on the data
|
|
||||||
/// going through it.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Crypto
|
||||||
CryptoStreamBuf(std::istream& istr, CryptoTransform* pTransform, std::streamsize bufferSize = 8192);
|
|
||||||
CryptoStreamBuf(std::ostream& ostr, CryptoTransform* pTransform, std::streamsize bufferSize = 8192);
|
|
||||||
|
|
||||||
virtual ~CryptoStreamBuf();
|
|
||||||
|
|
||||||
void close();
|
|
||||||
/// Flushes all buffers and finishes the encryption.
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int readFromDevice(char* buffer, std::streamsize length);
|
|
||||||
int writeToDevice(const char* buffer, std::streamsize length);
|
|
||||||
|
|
||||||
private:
|
|
||||||
CryptoTransform* _pTransform;
|
|
||||||
std::istream* _pIstr;
|
|
||||||
std::ostream* _pOstr;
|
|
||||||
bool _eof;
|
|
||||||
|
|
||||||
Poco::Buffer<unsigned char> _buffer;
|
|
||||||
|
|
||||||
CryptoStreamBuf(const CryptoStreamBuf&);
|
|
||||||
CryptoStreamBuf& operator = (const CryptoStreamBuf&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API CryptoIOS: public virtual std::ios
|
|
||||||
/// The base class for CryptoInputStream and CryptoOutputStream.
|
|
||||||
///
|
|
||||||
/// This class is needed to ensure correct initialization order of the
|
|
||||||
/// stream buffer and base classes.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
CryptoIOS(std::istream& istr, CryptoTransform* pTransform, std::streamsize bufferSize = 8192);
|
|
||||||
CryptoIOS(std::ostream& ostr, CryptoTransform* pTransform, std::streamsize bufferSize = 8192);
|
|
||||||
~CryptoIOS();
|
|
||||||
CryptoStreamBuf* rdbuf();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
CryptoStreamBuf _buf;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API CryptoInputStream: public CryptoIOS, public std::istream
|
class CryptoTransform;
|
||||||
/// This stream transforms all data passing through it using the given
|
class Cipher;
|
||||||
/// CryptoTransform.
|
|
||||||
///
|
|
||||||
/// Use a CryptoTransform object provided by Cipher::createEncrytor() or
|
|
||||||
/// Cipher::createDecryptor() to create an encrypting or decrypting stream,
|
|
||||||
/// respectively.
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CryptoInputStream(std::istream& istr, CryptoTransform* pTransform, std::streamsize bufferSize = 8192);
|
|
||||||
/// Create a new CryptoInputStream object. The CryptoInputStream takes the
|
|
||||||
/// ownership of the given CryptoTransform object.
|
|
||||||
|
|
||||||
CryptoInputStream(std::istream& istr, Cipher& cipher, std::streamsize bufferSize = 8192);
|
|
||||||
/// Create a new encrypting CryptoInputStream object using the given cipher.
|
|
||||||
|
|
||||||
~CryptoInputStream();
|
|
||||||
/// Destroys the CryptoInputStream.
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API CryptoOutputStream: public CryptoIOS, public std::ostream
|
class Crypto_API CryptoStreamBuf : public Poco::BufferedStreamBuf
|
||||||
/// This stream transforms all data passing through it using the given
|
/// This stream buffer performs cryptographic transformation on the data
|
||||||
/// CryptoTransform.
|
/// going through it.
|
||||||
///
|
{
|
||||||
/// Use a CryptoTransform object provided by Cipher::createEncrytor() or
|
public:
|
||||||
/// Cipher::createDecryptor() to create an encrypting or decrypting stream,
|
CryptoStreamBuf(std::istream & istr, CryptoTransform * pTransform, std::streamsize bufferSize = 8192);
|
||||||
/// respectively.
|
CryptoStreamBuf(std::ostream & ostr, CryptoTransform * pTransform, std::streamsize bufferSize = 8192);
|
||||||
///
|
|
||||||
/// After all data has been passed through the stream, close() must be called
|
|
||||||
/// to ensure completion of cryptographic transformation.
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CryptoOutputStream(std::ostream& ostr, CryptoTransform* pTransform, std::streamsize bufferSize = 8192);
|
|
||||||
/// Create a new CryptoOutputStream object. The CryptoOutputStream takes the
|
|
||||||
/// ownership of the given CryptoTransform object.
|
|
||||||
|
|
||||||
CryptoOutputStream(std::ostream& ostr, Cipher& cipher, std::streamsize bufferSize = 8192);
|
virtual ~CryptoStreamBuf();
|
||||||
/// Create a new decrypting CryptoOutputStream object using the given cipher.
|
|
||||||
|
|
||||||
~CryptoOutputStream();
|
void close();
|
||||||
/// Destroys the CryptoOutputStream.
|
/// Flushes all buffers and finishes the encryption.
|
||||||
|
|
||||||
void close();
|
protected:
|
||||||
/// Flushes all buffers and finishes the encryption.
|
int readFromDevice(char * buffer, std::streamsize length);
|
||||||
};
|
int writeToDevice(const char * buffer, std::streamsize length);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CryptoTransform * _pTransform;
|
||||||
|
std::istream * _pIstr;
|
||||||
|
std::ostream * _pOstr;
|
||||||
|
bool _eof;
|
||||||
|
|
||||||
|
Poco::Buffer<unsigned char> _buffer;
|
||||||
|
|
||||||
|
CryptoStreamBuf(const CryptoStreamBuf &);
|
||||||
|
CryptoStreamBuf & operator=(const CryptoStreamBuf &);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API DecryptingInputStream: public CryptoIOS, public std::istream
|
class Crypto_API CryptoIOS : public virtual std::ios
|
||||||
/// This stream decrypts all data passing through it using the given
|
/// The base class for CryptoInputStream and CryptoOutputStream.
|
||||||
/// Cipher.
|
///
|
||||||
{
|
/// This class is needed to ensure correct initialization order of the
|
||||||
public:
|
/// stream buffer and base classes.
|
||||||
DecryptingInputStream(std::istream& istr, Cipher& cipher, std::streamsize bufferSize = 8192);
|
{
|
||||||
/// Create a new DecryptingInputStream object using the given cipher.
|
public:
|
||||||
|
CryptoIOS(std::istream & istr, CryptoTransform * pTransform, std::streamsize bufferSize = 8192);
|
||||||
|
CryptoIOS(std::ostream & ostr, CryptoTransform * pTransform, std::streamsize bufferSize = 8192);
|
||||||
|
~CryptoIOS();
|
||||||
|
CryptoStreamBuf * rdbuf();
|
||||||
|
|
||||||
~DecryptingInputStream();
|
protected:
|
||||||
/// Destroys the DecryptingInputStream.
|
CryptoStreamBuf _buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API DecryptingOutputStream: public CryptoIOS, public std::ostream
|
class Crypto_API CryptoInputStream : public CryptoIOS, public std::istream
|
||||||
/// This stream decrypts all data passing through it using the given
|
/// This stream transforms all data passing through it using the given
|
||||||
/// Cipher.
|
/// CryptoTransform.
|
||||||
{
|
///
|
||||||
public:
|
/// Use a CryptoTransform object provided by Cipher::createEncrytor() or
|
||||||
DecryptingOutputStream(std::ostream& ostr, Cipher& cipher, std::streamsize bufferSize = 8192);
|
/// Cipher::createDecryptor() to create an encrypting or decrypting stream,
|
||||||
/// Create a new DecryptingOutputStream object using the given cipher.
|
/// respectively.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CryptoInputStream(std::istream & istr, CryptoTransform * pTransform, std::streamsize bufferSize = 8192);
|
||||||
|
/// Create a new CryptoInputStream object. The CryptoInputStream takes the
|
||||||
|
/// ownership of the given CryptoTransform object.
|
||||||
|
|
||||||
~DecryptingOutputStream();
|
CryptoInputStream(std::istream & istr, Cipher & cipher, std::streamsize bufferSize = 8192);
|
||||||
/// Destroys the DecryptingOutputStream.
|
/// Create a new encrypting CryptoInputStream object using the given cipher.
|
||||||
|
|
||||||
void close();
|
~CryptoInputStream();
|
||||||
/// Flushes all buffers and finishes the decryption.
|
/// Destroys the CryptoInputStream.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API EncryptingInputStream: public CryptoIOS, public std::istream
|
class Crypto_API CryptoOutputStream : public CryptoIOS, public std::ostream
|
||||||
/// This stream encrypts all data passing through it using the given
|
/// This stream transforms all data passing through it using the given
|
||||||
/// Cipher.
|
/// CryptoTransform.
|
||||||
{
|
///
|
||||||
public:
|
/// Use a CryptoTransform object provided by Cipher::createEncrytor() or
|
||||||
EncryptingInputStream(std::istream& istr, Cipher& cipher, std::streamsize bufferSize = 8192);
|
/// Cipher::createDecryptor() to create an encrypting or decrypting stream,
|
||||||
/// Create a new EncryptingInputStream object using the given cipher.
|
/// respectively.
|
||||||
|
///
|
||||||
|
/// After all data has been passed through the stream, close() must be called
|
||||||
|
/// to ensure completion of cryptographic transformation.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CryptoOutputStream(std::ostream & ostr, CryptoTransform * pTransform, std::streamsize bufferSize = 8192);
|
||||||
|
/// Create a new CryptoOutputStream object. The CryptoOutputStream takes the
|
||||||
|
/// ownership of the given CryptoTransform object.
|
||||||
|
|
||||||
~EncryptingInputStream();
|
CryptoOutputStream(std::ostream & ostr, Cipher & cipher, std::streamsize bufferSize = 8192);
|
||||||
/// Destroys the EncryptingInputStream.
|
/// Create a new decrypting CryptoOutputStream object using the given cipher.
|
||||||
};
|
|
||||||
|
~CryptoOutputStream();
|
||||||
|
/// Destroys the CryptoOutputStream.
|
||||||
|
|
||||||
|
void close();
|
||||||
|
/// Flushes all buffers and finishes the encryption.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API EncryptingOutputStream: public CryptoIOS, public std::ostream
|
class Crypto_API DecryptingInputStream : public CryptoIOS, public std::istream
|
||||||
/// This stream encrypts all data passing through it using the given
|
/// This stream decrypts all data passing through it using the given
|
||||||
/// Cipher.
|
/// Cipher.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EncryptingOutputStream(std::ostream& ostr, Cipher& cipher, std::streamsize bufferSize = 8192);
|
DecryptingInputStream(std::istream & istr, Cipher & cipher, std::streamsize bufferSize = 8192);
|
||||||
/// Create a new EncryptingOutputStream object using the given cipher.
|
/// Create a new DecryptingInputStream object using the given cipher.
|
||||||
|
|
||||||
~EncryptingOutputStream();
|
~DecryptingInputStream();
|
||||||
/// Destroys the EncryptingOutputStream.
|
/// Destroys the DecryptingInputStream.
|
||||||
|
};
|
||||||
void close();
|
|
||||||
/// Flushes all buffers and finishes the encryption.
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
class Crypto_API DecryptingOutputStream : public CryptoIOS, public std::ostream
|
||||||
|
/// This stream decrypts all data passing through it using the given
|
||||||
|
/// Cipher.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DecryptingOutputStream(std::ostream & ostr, Cipher & cipher, std::streamsize bufferSize = 8192);
|
||||||
|
/// Create a new DecryptingOutputStream object using the given cipher.
|
||||||
|
|
||||||
|
~DecryptingOutputStream();
|
||||||
|
/// Destroys the DecryptingOutputStream.
|
||||||
|
|
||||||
|
void close();
|
||||||
|
/// Flushes all buffers and finishes the decryption.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Crypto_API EncryptingInputStream : public CryptoIOS, public std::istream
|
||||||
|
/// This stream encrypts all data passing through it using the given
|
||||||
|
/// Cipher.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EncryptingInputStream(std::istream & istr, Cipher & cipher, std::streamsize bufferSize = 8192);
|
||||||
|
/// Create a new EncryptingInputStream object using the given cipher.
|
||||||
|
|
||||||
|
~EncryptingInputStream();
|
||||||
|
/// Destroys the EncryptingInputStream.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Crypto_API EncryptingOutputStream : public CryptoIOS, public std::ostream
|
||||||
|
/// This stream encrypts all data passing through it using the given
|
||||||
|
/// Cipher.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EncryptingOutputStream(std::ostream & ostr, Cipher & cipher, std::streamsize bufferSize = 8192);
|
||||||
|
/// Create a new EncryptingOutputStream object using the given cipher.
|
||||||
|
|
||||||
|
~EncryptingOutputStream();
|
||||||
|
/// Destroys the EncryptingOutputStream.
|
||||||
|
|
||||||
|
void close();
|
||||||
|
/// Flushes all buffers and finishes the encryption.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_CryptoStream_INCLUDED
|
#endif // Crypto_CryptoStream_INCLUDED
|
||||||
|
@ -18,70 +18,71 @@
|
|||||||
#define Crypto_CryptoTransform_INCLUDED
|
#define Crypto_CryptoTransform_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Crypto/Crypto.h"
|
|
||||||
#include <ios>
|
#include <ios>
|
||||||
|
#include "Poco/Crypto/Crypto.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
{
|
||||||
|
namespace Crypto
|
||||||
|
|
||||||
class Crypto_API CryptoTransform
|
|
||||||
/// This interface represents the basic operations for cryptographic
|
|
||||||
/// transformations to be used with a CryptoInputStream or a
|
|
||||||
/// CryptoOutputStream.
|
|
||||||
///
|
|
||||||
/// Implementations of this class are returned by the Cipher class to
|
|
||||||
/// perform encryption or decryption of data.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
CryptoTransform();
|
|
||||||
/// Creates a new CryptoTransform object.
|
|
||||||
|
|
||||||
virtual ~CryptoTransform();
|
|
||||||
/// Destroys the CryptoTransform.
|
|
||||||
|
|
||||||
virtual std::size_t blockSize() const = 0;
|
|
||||||
/// Returns the block size for this CryptoTransform.
|
|
||||||
|
|
||||||
virtual int setPadding(int padding);
|
|
||||||
/// Enables or disables padding. By default encryption operations are padded using standard block
|
|
||||||
/// padding and the padding is checked and removed when decrypting. If the padding parameter is zero then
|
|
||||||
/// no padding is performed, the total amount of data encrypted or decrypted must then be a multiple of
|
|
||||||
/// the block size or an error will occur.
|
|
||||||
|
|
||||||
virtual std::string getTag(std::size_t tagSize = 16) = 0;
|
|
||||||
/// Returns the GCM tag after encrypting using GCM mode.
|
|
||||||
///
|
|
||||||
/// Must be called after finalize().
|
|
||||||
|
|
||||||
virtual void setTag(const std::string& tag) = 0;
|
|
||||||
/// Sets the GCM tag for authenticated decryption using GCM mode.
|
|
||||||
///
|
|
||||||
/// Must be set before finalize() is called, otherwise
|
|
||||||
/// decryption will fail.
|
|
||||||
|
|
||||||
virtual std::streamsize transform(
|
|
||||||
const unsigned char* input,
|
|
||||||
std::streamsize inputLength,
|
|
||||||
unsigned char* output,
|
|
||||||
std::streamsize outputLength) = 0;
|
|
||||||
/// Transforms a chunk of data. The inputLength is arbitrary and does not
|
|
||||||
/// need to be a multiple of the block size. The output buffer has a maximum
|
|
||||||
/// capacity of the given outputLength that must be at least
|
|
||||||
/// inputLength + blockSize() - 1
|
|
||||||
/// Returns the number of bytes written to the output buffer.
|
|
||||||
|
|
||||||
virtual std::streamsize finalize(unsigned char* output, std::streamsize length) = 0;
|
|
||||||
/// Finalizes the transformation. The output buffer must contain enough
|
|
||||||
/// space for at least two blocks, ie.
|
|
||||||
/// length >= 2*blockSize()
|
|
||||||
/// must be true. Returns the number of bytes written to the output
|
|
||||||
/// buffer.
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
class Crypto_API CryptoTransform
|
||||||
|
/// This interface represents the basic operations for cryptographic
|
||||||
|
/// transformations to be used with a CryptoInputStream or a
|
||||||
|
/// CryptoOutputStream.
|
||||||
|
///
|
||||||
|
/// Implementations of this class are returned by the Cipher class to
|
||||||
|
/// perform encryption or decryption of data.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CryptoTransform();
|
||||||
|
/// Creates a new CryptoTransform object.
|
||||||
|
|
||||||
|
virtual ~CryptoTransform();
|
||||||
|
/// Destroys the CryptoTransform.
|
||||||
|
|
||||||
|
virtual std::size_t blockSize() const = 0;
|
||||||
|
/// Returns the block size for this CryptoTransform.
|
||||||
|
|
||||||
|
virtual int setPadding(int padding);
|
||||||
|
/// Enables or disables padding. By default encryption operations are padded using standard block
|
||||||
|
/// padding and the padding is checked and removed when decrypting. If the padding parameter is zero then
|
||||||
|
/// no padding is performed, the total amount of data encrypted or decrypted must then be a multiple of
|
||||||
|
/// the block size or an error will occur.
|
||||||
|
|
||||||
|
virtual std::string getTag(std::size_t tagSize = 16) = 0;
|
||||||
|
/// Returns the GCM tag after encrypting using GCM mode.
|
||||||
|
///
|
||||||
|
/// Must be called after finalize().
|
||||||
|
|
||||||
|
virtual void setTag(const std::string & tag) = 0;
|
||||||
|
/// Sets the GCM tag for authenticated decryption using GCM mode.
|
||||||
|
///
|
||||||
|
/// Must be set before finalize() is called, otherwise
|
||||||
|
/// decryption will fail.
|
||||||
|
|
||||||
|
virtual std::streamsize
|
||||||
|
transform(const unsigned char * input, std::streamsize inputLength, unsigned char * output, std::streamsize outputLength)
|
||||||
|
= 0;
|
||||||
|
/// Transforms a chunk of data. The inputLength is arbitrary and does not
|
||||||
|
/// need to be a multiple of the block size. The output buffer has a maximum
|
||||||
|
/// capacity of the given outputLength that must be at least
|
||||||
|
/// inputLength + blockSize() - 1
|
||||||
|
/// Returns the number of bytes written to the output buffer.
|
||||||
|
|
||||||
|
virtual std::streamsize finalize(unsigned char * output, std::streamsize length) = 0;
|
||||||
|
/// Finalizes the transformation. The output buffer must contain enough
|
||||||
|
/// space for at least two blocks, ie.
|
||||||
|
/// length >= 2*blockSize()
|
||||||
|
/// must be true. Returns the number of bytes written to the output
|
||||||
|
/// buffer.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_CryptoTransform_INCLUDED
|
#endif // Crypto_CryptoTransform_INCLUDED
|
||||||
|
@ -18,63 +18,66 @@
|
|||||||
#define Crypto_DigestEngine_INCLUDED
|
#define Crypto_DigestEngine_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <openssl/evp.h>
|
||||||
#include "Poco/Crypto/Crypto.h"
|
#include "Poco/Crypto/Crypto.h"
|
||||||
#include "Poco/Crypto/OpenSSLInitializer.h"
|
#include "Poco/Crypto/OpenSSLInitializer.h"
|
||||||
#include "Poco/DigestEngine.h"
|
#include "Poco/DigestEngine.h"
|
||||||
#include <openssl/evp.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API DigestEngine: public Poco::DigestEngine
|
|
||||||
/// This class implements a Poco::DigestEngine for all
|
|
||||||
/// digest algorithms supported by OpenSSL.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Crypto
|
||||||
DigestEngine(const std::string& name);
|
|
||||||
/// Creates a DigestEngine using the digest with the given name
|
|
||||||
/// (e.g., "MD5", "SHA1", "SHA256", "SHA512", etc.).
|
|
||||||
/// See the OpenSSL documentation for a list of supported digest algorithms.
|
|
||||||
///
|
|
||||||
/// Throws a Poco::NotFoundException if no algorithm with the given name exists.
|
|
||||||
|
|
||||||
~DigestEngine();
|
|
||||||
/// Destroys the DigestEngine.
|
|
||||||
|
|
||||||
const std::string& algorithm() const;
|
|
||||||
/// Returns the name of the digest algorithm.
|
|
||||||
|
|
||||||
int nid() const;
|
|
||||||
/// Returns the NID (OpenSSL object identifier) of the digest algorithm.
|
|
||||||
|
|
||||||
// DigestEngine
|
|
||||||
std::size_t digestLength() const;
|
|
||||||
void reset();
|
|
||||||
const Poco::DigestEngine::Digest& digest();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void updateImpl(const void* data, std::size_t length);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string _name;
|
|
||||||
EVP_MD_CTX* _pContext;
|
|
||||||
Poco::DigestEngine::Digest _digest;
|
|
||||||
OpenSSLInitializer _openSSLInitializer;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline const std::string& DigestEngine::algorithm() const
|
|
||||||
{
|
{
|
||||||
return _name;
|
|
||||||
|
|
||||||
|
class Crypto_API DigestEngine : public Poco::DigestEngine
|
||||||
|
/// This class implements a Poco::DigestEngine for all
|
||||||
|
/// digest algorithms supported by OpenSSL.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DigestEngine(const std::string & name);
|
||||||
|
/// Creates a DigestEngine using the digest with the given name
|
||||||
|
/// (e.g., "MD5", "SHA1", "SHA256", "SHA512", etc.).
|
||||||
|
/// See the OpenSSL documentation for a list of supported digest algorithms.
|
||||||
|
///
|
||||||
|
/// Throws a Poco::NotFoundException if no algorithm with the given name exists.
|
||||||
|
|
||||||
|
~DigestEngine();
|
||||||
|
/// Destroys the DigestEngine.
|
||||||
|
|
||||||
|
const std::string & algorithm() const;
|
||||||
|
/// Returns the name of the digest algorithm.
|
||||||
|
|
||||||
|
int nid() const;
|
||||||
|
/// Returns the NID (OpenSSL object identifier) of the digest algorithm.
|
||||||
|
|
||||||
|
// DigestEngine
|
||||||
|
std::size_t digestLength() const;
|
||||||
|
void reset();
|
||||||
|
const Poco::DigestEngine::Digest & digest();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateImpl(const void * data, std::size_t length);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string _name;
|
||||||
|
EVP_MD_CTX * _pContext;
|
||||||
|
Poco::DigestEngine::Digest _digest;
|
||||||
|
OpenSSLInitializer _openSSLInitializer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline const std::string & DigestEngine::algorithm() const
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_DigestEngine_INCLUDED
|
#endif // Crypto_DigestEngine_INCLUDED
|
||||||
|
@ -19,83 +19,85 @@
|
|||||||
#define Crypto_ECDSADigestEngine_INCLUDED
|
#define Crypto_ECDSADigestEngine_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Crypto/Crypto.h"
|
|
||||||
#include "Poco/Crypto/ECKey.h"
|
|
||||||
#include "Poco/DigestEngine.h"
|
|
||||||
#include "Poco/Crypto/DigestEngine.h"
|
|
||||||
#include <istream>
|
#include <istream>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include "Poco/Crypto/Crypto.h"
|
||||||
|
#include "Poco/Crypto/DigestEngine.h"
|
||||||
|
#include "Poco/Crypto/ECKey.h"
|
||||||
|
#include "Poco/DigestEngine.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
{
|
||||||
|
namespace Crypto
|
||||||
|
|
||||||
class Crypto_API ECDSADigestEngine: public Poco::DigestEngine
|
|
||||||
/// This class implements a Poco::DigestEngine that can be
|
|
||||||
/// used to compute a secure digital signature.
|
|
||||||
///
|
|
||||||
/// First another Poco::Crypto::DigestEngine is created and
|
|
||||||
/// used to compute a cryptographic hash of the data to be
|
|
||||||
/// signed. Then, the hash value is encrypted, using
|
|
||||||
/// the ECDSA private key.
|
|
||||||
///
|
|
||||||
/// To verify a signature, pass it to the verify()
|
|
||||||
/// member function. It will decrypt the signature
|
|
||||||
/// using the ECDSA public key and compare the resulting
|
|
||||||
/// hash with the actual hash of the data.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
|
|
||||||
ECDSADigestEngine(const ECKey& key, const std::string &name);
|
|
||||||
/// Creates the ECDSADigestEngine with the given ECDSA key,
|
|
||||||
/// using the hash algorithm with the given name
|
|
||||||
/// (e.g., "SHA1", "SHA256", "SHA512", etc.).
|
|
||||||
/// See the OpenSSL documentation for a list of supported digest algorithms.
|
|
||||||
///
|
|
||||||
/// Throws a Poco::NotFoundException if no algorithm with the given name exists.
|
|
||||||
|
|
||||||
~ECDSADigestEngine();
|
|
||||||
/// Destroys the ECDSADigestEngine.
|
|
||||||
|
|
||||||
std::size_t digestLength() const;
|
|
||||||
/// Returns the length of the digest in bytes.
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
/// Resets the engine so that a new
|
|
||||||
/// digest can be computed.
|
|
||||||
|
|
||||||
const DigestEngine::Digest& digest();
|
|
||||||
/// Finishes the computation of the digest
|
|
||||||
/// (the first time it's called) and
|
|
||||||
/// returns the message digest.
|
|
||||||
///
|
|
||||||
/// Can be called multiple times.
|
|
||||||
|
|
||||||
const DigestEngine::Digest& signature();
|
|
||||||
/// Signs the digest using the ECDSADSA algorithm
|
|
||||||
/// and the private key (the first time it's
|
|
||||||
/// called) and returns the result.
|
|
||||||
///
|
|
||||||
/// Can be called multiple times.
|
|
||||||
|
|
||||||
bool verify(const DigestEngine::Digest& signature);
|
|
||||||
/// Verifies the data against the signature.
|
|
||||||
///
|
|
||||||
/// Returns true if the signature can be verified, false otherwise.
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void updateImpl(const void* data, std::size_t length);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ECKey _key;
|
|
||||||
Poco::Crypto::DigestEngine _engine;
|
|
||||||
Poco::DigestEngine::Digest _digest;
|
|
||||||
Poco::DigestEngine::Digest _signature;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
class Crypto_API ECDSADigestEngine : public Poco::DigestEngine
|
||||||
|
/// This class implements a Poco::DigestEngine that can be
|
||||||
|
/// used to compute a secure digital signature.
|
||||||
|
///
|
||||||
|
/// First another Poco::Crypto::DigestEngine is created and
|
||||||
|
/// used to compute a cryptographic hash of the data to be
|
||||||
|
/// signed. Then, the hash value is encrypted, using
|
||||||
|
/// the ECDSA private key.
|
||||||
|
///
|
||||||
|
/// To verify a signature, pass it to the verify()
|
||||||
|
/// member function. It will decrypt the signature
|
||||||
|
/// using the ECDSA public key and compare the resulting
|
||||||
|
/// hash with the actual hash of the data.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ECDSADigestEngine(const ECKey & key, const std::string & name);
|
||||||
|
/// Creates the ECDSADigestEngine with the given ECDSA key,
|
||||||
|
/// using the hash algorithm with the given name
|
||||||
|
/// (e.g., "SHA1", "SHA256", "SHA512", etc.).
|
||||||
|
/// See the OpenSSL documentation for a list of supported digest algorithms.
|
||||||
|
///
|
||||||
|
/// Throws a Poco::NotFoundException if no algorithm with the given name exists.
|
||||||
|
|
||||||
|
~ECDSADigestEngine();
|
||||||
|
/// Destroys the ECDSADigestEngine.
|
||||||
|
|
||||||
|
std::size_t digestLength() const;
|
||||||
|
/// Returns the length of the digest in bytes.
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
/// Resets the engine so that a new
|
||||||
|
/// digest can be computed.
|
||||||
|
|
||||||
|
const DigestEngine::Digest & digest();
|
||||||
|
/// Finishes the computation of the digest
|
||||||
|
/// (the first time it's called) and
|
||||||
|
/// returns the message digest.
|
||||||
|
///
|
||||||
|
/// Can be called multiple times.
|
||||||
|
|
||||||
|
const DigestEngine::Digest & signature();
|
||||||
|
/// Signs the digest using the ECDSADSA algorithm
|
||||||
|
/// and the private key (the first time it's
|
||||||
|
/// called) and returns the result.
|
||||||
|
///
|
||||||
|
/// Can be called multiple times.
|
||||||
|
|
||||||
|
bool verify(const DigestEngine::Digest & signature);
|
||||||
|
/// Verifies the data against the signature.
|
||||||
|
///
|
||||||
|
/// Returns true if the signature can be verified, false otherwise.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateImpl(const void * data, std::size_t length);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ECKey _key;
|
||||||
|
Poco::Crypto::DigestEngine _engine;
|
||||||
|
Poco::DigestEngine::Digest _digest;
|
||||||
|
Poco::DigestEngine::Digest _signature;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_ECDSADigestEngine_INCLUDED
|
#endif // Crypto_ECDSADigestEngine_INCLUDED
|
||||||
|
@ -20,116 +20,119 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "Poco/Crypto/Crypto.h"
|
#include "Poco/Crypto/Crypto.h"
|
||||||
#include "Poco/Crypto/KeyPair.h"
|
|
||||||
#include "Poco/Crypto/ECKeyImpl.h"
|
#include "Poco/Crypto/ECKeyImpl.h"
|
||||||
|
#include "Poco/Crypto/KeyPair.h"
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class X509Certificate;
|
|
||||||
class PKCS12Container;
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API ECKey : public KeyPair
|
|
||||||
/// This class stores an EC key pair, consisting
|
|
||||||
/// of private and public key. Storage of the private
|
|
||||||
/// key is optional.
|
|
||||||
///
|
|
||||||
/// If a private key is available, the ECKey can be
|
|
||||||
/// used for decrypting data (encrypted with the public key)
|
|
||||||
/// or computing secure digital signatures.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Crypto
|
||||||
ECKey(const EVPPKey& key);
|
|
||||||
/// Constructs ECKeyImpl by extracting the EC key.
|
|
||||||
|
|
||||||
ECKey(const X509Certificate& cert);
|
|
||||||
/// Extracts the EC public key from the given certificate.
|
|
||||||
|
|
||||||
ECKey(const PKCS12Container& cert);
|
|
||||||
/// Extracts the EC private key from the given certificate.
|
|
||||||
|
|
||||||
ECKey(const std::string& eccGroup);
|
|
||||||
/// Creates the ECKey. Creates a new public/private key pair using the given parameters.
|
|
||||||
/// Can be used to sign data and verify signatures.
|
|
||||||
|
|
||||||
ECKey(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase = "");
|
|
||||||
/// Creates the ECKey, by reading public and private key from the given files and
|
|
||||||
/// using the given passphrase for the private key.
|
|
||||||
///
|
|
||||||
/// Cannot be used for signing or decryption unless a private key is available.
|
|
||||||
///
|
|
||||||
/// If a private key is specified, you don't need to specify a public key file.
|
|
||||||
/// OpenSSL will auto-create the public key from the private key.
|
|
||||||
|
|
||||||
ECKey(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream = 0, const std::string& privateKeyPassphrase = "");
|
|
||||||
/// Creates the ECKey, by reading public and private key from the given streams and
|
|
||||||
/// using the given passphrase for the private key.
|
|
||||||
///
|
|
||||||
/// Cannot be used for signing or decryption unless a private key is available.
|
|
||||||
///
|
|
||||||
/// If a private key is specified, you don't need to specify a public key file.
|
|
||||||
/// OpenSSL will auto-create the public key from the private key.
|
|
||||||
|
|
||||||
~ECKey();
|
|
||||||
/// Destroys the ECKey.
|
|
||||||
|
|
||||||
ECKeyImpl::Ptr impl() const;
|
|
||||||
/// Returns the impl object.
|
|
||||||
|
|
||||||
static std::string getCurveName(int nid = -1);
|
|
||||||
/// Returns elliptical curve name corresponding to
|
|
||||||
/// the given nid; if nid is not found, returns
|
|
||||||
/// empty string.
|
|
||||||
///
|
|
||||||
/// If nid is -1, returns first curve name.
|
|
||||||
///
|
|
||||||
/// If no curves are found, returns empty string;
|
|
||||||
|
|
||||||
static int getCurveNID(std::string& name);
|
|
||||||
/// Returns the NID of the specified curve.
|
|
||||||
///
|
|
||||||
/// If name is empty, returns the first curve NID
|
|
||||||
/// and updates the name accordingly.
|
|
||||||
|
|
||||||
static bool hasCurve(const std::string& name);
|
|
||||||
/// Returns true if the named curve is found,
|
|
||||||
/// false otherwise.
|
|
||||||
|
|
||||||
private:
|
|
||||||
ECKeyImpl::Ptr _pImpl;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline ECKeyImpl::Ptr ECKey::impl() const
|
|
||||||
{
|
{
|
||||||
return _pImpl;
|
|
||||||
|
|
||||||
|
class X509Certificate;
|
||||||
|
class PKCS12Container;
|
||||||
|
|
||||||
|
|
||||||
|
class Crypto_API ECKey : public KeyPair
|
||||||
|
/// This class stores an EC key pair, consisting
|
||||||
|
/// of private and public key. Storage of the private
|
||||||
|
/// key is optional.
|
||||||
|
///
|
||||||
|
/// If a private key is available, the ECKey can be
|
||||||
|
/// used for decrypting data (encrypted with the public key)
|
||||||
|
/// or computing secure digital signatures.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ECKey(const EVPPKey & key);
|
||||||
|
/// Constructs ECKeyImpl by extracting the EC key.
|
||||||
|
|
||||||
|
ECKey(const X509Certificate & cert);
|
||||||
|
/// Extracts the EC public key from the given certificate.
|
||||||
|
|
||||||
|
ECKey(const PKCS12Container & cert);
|
||||||
|
/// Extracts the EC private key from the given certificate.
|
||||||
|
|
||||||
|
ECKey(const std::string & eccGroup);
|
||||||
|
/// Creates the ECKey. Creates a new public/private key pair using the given parameters.
|
||||||
|
/// Can be used to sign data and verify signatures.
|
||||||
|
|
||||||
|
ECKey(const std::string & publicKeyFile, const std::string & privateKeyFile, const std::string & privateKeyPassphrase = "");
|
||||||
|
/// Creates the ECKey, by reading public and private key from the given files and
|
||||||
|
/// using the given passphrase for the private key.
|
||||||
|
///
|
||||||
|
/// Cannot be used for signing or decryption unless a private key is available.
|
||||||
|
///
|
||||||
|
/// If a private key is specified, you don't need to specify a public key file.
|
||||||
|
/// OpenSSL will auto-create the public key from the private key.
|
||||||
|
|
||||||
|
ECKey(std::istream * pPublicKeyStream, std::istream * pPrivateKeyStream = 0, const std::string & privateKeyPassphrase = "");
|
||||||
|
/// Creates the ECKey, by reading public and private key from the given streams and
|
||||||
|
/// using the given passphrase for the private key.
|
||||||
|
///
|
||||||
|
/// Cannot be used for signing or decryption unless a private key is available.
|
||||||
|
///
|
||||||
|
/// If a private key is specified, you don't need to specify a public key file.
|
||||||
|
/// OpenSSL will auto-create the public key from the private key.
|
||||||
|
|
||||||
|
~ECKey();
|
||||||
|
/// Destroys the ECKey.
|
||||||
|
|
||||||
|
ECKeyImpl::Ptr impl() const;
|
||||||
|
/// Returns the impl object.
|
||||||
|
|
||||||
|
static std::string getCurveName(int nid = -1);
|
||||||
|
/// Returns elliptical curve name corresponding to
|
||||||
|
/// the given nid; if nid is not found, returns
|
||||||
|
/// empty string.
|
||||||
|
///
|
||||||
|
/// If nid is -1, returns first curve name.
|
||||||
|
///
|
||||||
|
/// If no curves are found, returns empty string;
|
||||||
|
|
||||||
|
static int getCurveNID(std::string & name);
|
||||||
|
/// Returns the NID of the specified curve.
|
||||||
|
///
|
||||||
|
/// If name is empty, returns the first curve NID
|
||||||
|
/// and updates the name accordingly.
|
||||||
|
|
||||||
|
static bool hasCurve(const std::string & name);
|
||||||
|
/// Returns true if the named curve is found,
|
||||||
|
/// false otherwise.
|
||||||
|
|
||||||
|
private:
|
||||||
|
ECKeyImpl::Ptr _pImpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline ECKeyImpl::Ptr ECKey::impl() const
|
||||||
|
{
|
||||||
|
return _pImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::string ECKey::getCurveName(int nid)
|
||||||
|
{
|
||||||
|
return ECKeyImpl::getCurveName(nid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int ECKey::getCurveNID(std::string & name)
|
||||||
|
{
|
||||||
|
return ECKeyImpl::getCurveNID(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool ECKey::hasCurve(const std::string & name)
|
||||||
|
{
|
||||||
|
return ECKeyImpl::hasCurve(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
inline std::string ECKey::getCurveName(int nid)
|
|
||||||
{
|
|
||||||
return ECKeyImpl::getCurveName(nid);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline int ECKey::getCurveNID(std::string& name)
|
|
||||||
{
|
|
||||||
return ECKeyImpl::getCurveNID(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool ECKey::hasCurve(const std::string& name)
|
|
||||||
{
|
|
||||||
return ECKeyImpl::hasCurve(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_ECKey_INCLUDED
|
#endif // Crypto_ECKey_INCLUDED
|
||||||
|
@ -19,156 +19,155 @@
|
|||||||
#define Crypto_ECKeyImplImpl_INCLUDED
|
#define Crypto_ECKeyImplImpl_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <istream>
|
||||||
|
#include <ostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <openssl/ec.h>
|
||||||
|
#include <openssl/objects.h>
|
||||||
|
#include "Poco/AutoPtr.h"
|
||||||
#include "Poco/Crypto/Crypto.h"
|
#include "Poco/Crypto/Crypto.h"
|
||||||
#include "Poco/Crypto/EVPPKey.h"
|
#include "Poco/Crypto/EVPPKey.h"
|
||||||
#include "Poco/Crypto/KeyPairImpl.h"
|
#include "Poco/Crypto/KeyPairImpl.h"
|
||||||
#include "Poco/Crypto/OpenSSLInitializer.h"
|
#include "Poco/Crypto/OpenSSLInitializer.h"
|
||||||
#include "Poco/RefCountedObject.h"
|
#include "Poco/RefCountedObject.h"
|
||||||
#include "Poco/AutoPtr.h"
|
|
||||||
#include <istream>
|
|
||||||
#include <ostream>
|
|
||||||
#include <vector>
|
|
||||||
#include <openssl/objects.h>
|
|
||||||
#include <openssl/ec.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class X509Certificate;
|
|
||||||
class PKCS12Container;
|
|
||||||
|
|
||||||
|
|
||||||
class ECKeyImpl: public KeyPairImpl
|
|
||||||
/// Elliptic Curve key clas implementation.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Crypto
|
||||||
typedef Poco::AutoPtr<ECKeyImpl> Ptr;
|
|
||||||
typedef std::vector<unsigned char> ByteVec;
|
|
||||||
|
|
||||||
ECKeyImpl(const EVPPKey& key);
|
|
||||||
/// Constructs ECKeyImpl by extracting the EC key.
|
|
||||||
|
|
||||||
ECKeyImpl(const X509Certificate& cert);
|
|
||||||
/// Constructs ECKeyImpl by extracting the EC public key from the given certificate.
|
|
||||||
|
|
||||||
ECKeyImpl(const PKCS12Container& cert);
|
|
||||||
/// Constructs ECKeyImpl by extracting the EC private key from the given certificate.
|
|
||||||
|
|
||||||
ECKeyImpl(int eccGroup);
|
|
||||||
/// Creates the ECKey of the specified group. Creates a new public/private keypair using the given parameters.
|
|
||||||
/// Can be used to sign data and verify signatures.
|
|
||||||
|
|
||||||
ECKeyImpl(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase);
|
|
||||||
/// Creates the ECKey, by reading public and private key from the given files and
|
|
||||||
/// using the given passphrase for the private key. Can only by used for signing if
|
|
||||||
/// a private key is available.
|
|
||||||
|
|
||||||
ECKeyImpl(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase);
|
|
||||||
/// Creates the ECKey. Can only by used for signing if pPrivKey
|
|
||||||
/// is not null. If a private key file is specified, you don't need to
|
|
||||||
/// specify a public key file. OpenSSL will auto-create it from the private key.
|
|
||||||
|
|
||||||
~ECKeyImpl();
|
|
||||||
/// Destroys the ECKeyImpl.
|
|
||||||
|
|
||||||
EC_KEY* getECKey();
|
|
||||||
/// Returns the OpenSSL EC key.
|
|
||||||
|
|
||||||
const EC_KEY* getECKey() const;
|
|
||||||
/// Returns the OpenSSL EC key.
|
|
||||||
|
|
||||||
int size() const;
|
|
||||||
/// Returns the EC key length in bits.
|
|
||||||
|
|
||||||
int groupId() const;
|
|
||||||
/// Returns the EC key group integer Id.
|
|
||||||
|
|
||||||
std::string groupName() const;
|
|
||||||
/// Returns the EC key group name.
|
|
||||||
|
|
||||||
void save(const std::string& publicKeyFile,
|
|
||||||
const std::string& privateKeyFile = "",
|
|
||||||
const std::string& privateKeyPassphrase = "") const;
|
|
||||||
/// Exports the public and private keys to the given files.
|
|
||||||
///
|
|
||||||
/// If an empty filename is specified, the corresponding key
|
|
||||||
/// is not exported.
|
|
||||||
|
|
||||||
void save(std::ostream* pPublicKeyStream,
|
|
||||||
std::ostream* pPrivateKeyStream = 0,
|
|
||||||
const std::string& privateKeyPassphrase = "") const;
|
|
||||||
/// Exports the public and private key to the given streams.
|
|
||||||
///
|
|
||||||
/// If a null pointer is passed for a stream, the corresponding
|
|
||||||
/// key is not exported.
|
|
||||||
|
|
||||||
static std::string getCurveName(int nid = -1);
|
|
||||||
/// Returns elliptical curve name corresponding to
|
|
||||||
/// the given nid; if nid is not found, returns
|
|
||||||
/// empty string.
|
|
||||||
///
|
|
||||||
/// If nid is -1, returns first curve name.
|
|
||||||
///
|
|
||||||
/// If no curves are found, returns empty string;
|
|
||||||
|
|
||||||
static int getCurveNID(std::string& name);
|
|
||||||
/// Returns the NID of the specified curve.
|
|
||||||
///
|
|
||||||
/// If name is empty, returns the first curve NID
|
|
||||||
/// and updates the name accordingly.
|
|
||||||
|
|
||||||
static bool hasCurve(const std::string& name);
|
|
||||||
/// Returns true if the named curve is found,
|
|
||||||
/// false otherwise.
|
|
||||||
|
|
||||||
private:
|
|
||||||
void checkEC(const std::string& method, const std::string& func) const;
|
|
||||||
void freeEC();
|
|
||||||
|
|
||||||
EC_KEY* _pEC;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline EC_KEY* ECKeyImpl::getECKey()
|
|
||||||
{
|
{
|
||||||
return _pEC;
|
|
||||||
|
|
||||||
|
class X509Certificate;
|
||||||
|
class PKCS12Container;
|
||||||
|
|
||||||
|
|
||||||
|
class ECKeyImpl : public KeyPairImpl
|
||||||
|
/// Elliptic Curve key clas implementation.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Poco::AutoPtr<ECKeyImpl> Ptr;
|
||||||
|
typedef std::vector<unsigned char> ByteVec;
|
||||||
|
|
||||||
|
ECKeyImpl(const EVPPKey & key);
|
||||||
|
/// Constructs ECKeyImpl by extracting the EC key.
|
||||||
|
|
||||||
|
ECKeyImpl(const X509Certificate & cert);
|
||||||
|
/// Constructs ECKeyImpl by extracting the EC public key from the given certificate.
|
||||||
|
|
||||||
|
ECKeyImpl(const PKCS12Container & cert);
|
||||||
|
/// Constructs ECKeyImpl by extracting the EC private key from the given certificate.
|
||||||
|
|
||||||
|
ECKeyImpl(int eccGroup);
|
||||||
|
/// Creates the ECKey of the specified group. Creates a new public/private keypair using the given parameters.
|
||||||
|
/// Can be used to sign data and verify signatures.
|
||||||
|
|
||||||
|
ECKeyImpl(const std::string & publicKeyFile, const std::string & privateKeyFile, const std::string & privateKeyPassphrase);
|
||||||
|
/// Creates the ECKey, by reading public and private key from the given files and
|
||||||
|
/// using the given passphrase for the private key. Can only by used for signing if
|
||||||
|
/// a private key is available.
|
||||||
|
|
||||||
|
ECKeyImpl(std::istream * pPublicKeyStream, std::istream * pPrivateKeyStream, const std::string & privateKeyPassphrase);
|
||||||
|
/// Creates the ECKey. Can only by used for signing if pPrivKey
|
||||||
|
/// is not null. If a private key file is specified, you don't need to
|
||||||
|
/// specify a public key file. OpenSSL will auto-create it from the private key.
|
||||||
|
|
||||||
|
~ECKeyImpl();
|
||||||
|
/// Destroys the ECKeyImpl.
|
||||||
|
|
||||||
|
EC_KEY * getECKey();
|
||||||
|
/// Returns the OpenSSL EC key.
|
||||||
|
|
||||||
|
const EC_KEY * getECKey() const;
|
||||||
|
/// Returns the OpenSSL EC key.
|
||||||
|
|
||||||
|
int size() const;
|
||||||
|
/// Returns the EC key length in bits.
|
||||||
|
|
||||||
|
int groupId() const;
|
||||||
|
/// Returns the EC key group integer Id.
|
||||||
|
|
||||||
|
std::string groupName() const;
|
||||||
|
/// Returns the EC key group name.
|
||||||
|
|
||||||
|
void save(const std::string & publicKeyFile, const std::string & privateKeyFile = "", const std::string & privateKeyPassphrase = "")
|
||||||
|
const;
|
||||||
|
/// Exports the public and private keys to the given files.
|
||||||
|
///
|
||||||
|
/// If an empty filename is specified, the corresponding key
|
||||||
|
/// is not exported.
|
||||||
|
|
||||||
|
void
|
||||||
|
save(std::ostream * pPublicKeyStream, std::ostream * pPrivateKeyStream = 0, const std::string & privateKeyPassphrase = "") const;
|
||||||
|
/// Exports the public and private key to the given streams.
|
||||||
|
///
|
||||||
|
/// If a null pointer is passed for a stream, the corresponding
|
||||||
|
/// key is not exported.
|
||||||
|
|
||||||
|
static std::string getCurveName(int nid = -1);
|
||||||
|
/// Returns elliptical curve name corresponding to
|
||||||
|
/// the given nid; if nid is not found, returns
|
||||||
|
/// empty string.
|
||||||
|
///
|
||||||
|
/// If nid is -1, returns first curve name.
|
||||||
|
///
|
||||||
|
/// If no curves are found, returns empty string;
|
||||||
|
|
||||||
|
static int getCurveNID(std::string & name);
|
||||||
|
/// Returns the NID of the specified curve.
|
||||||
|
///
|
||||||
|
/// If name is empty, returns the first curve NID
|
||||||
|
/// and updates the name accordingly.
|
||||||
|
|
||||||
|
static bool hasCurve(const std::string & name);
|
||||||
|
/// Returns true if the named curve is found,
|
||||||
|
/// false otherwise.
|
||||||
|
|
||||||
|
private:
|
||||||
|
void checkEC(const std::string & method, const std::string & func) const;
|
||||||
|
void freeEC();
|
||||||
|
|
||||||
|
EC_KEY * _pEC;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline EC_KEY * ECKeyImpl::getECKey()
|
||||||
|
{
|
||||||
|
return _pEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const EC_KEY * ECKeyImpl::getECKey() const
|
||||||
|
{
|
||||||
|
return _pEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::string ECKeyImpl::groupName() const
|
||||||
|
{
|
||||||
|
return OBJ_nid2sn(groupId());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
ECKeyImpl::save(const std::string & publicKeyFile, const std::string & privateKeyFile, const std::string & privateKeyPassphrase) const
|
||||||
|
{
|
||||||
|
EVPPKey(_pEC).save(publicKeyFile, privateKeyFile, privateKeyPassphrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
ECKeyImpl::save(std::ostream * pPublicKeyStream, std::ostream * pPrivateKeyStream, const std::string & privateKeyPassphrase) const
|
||||||
|
{
|
||||||
|
EVPPKey(_pEC).save(pPublicKeyStream, pPrivateKeyStream, privateKeyPassphrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
inline const EC_KEY* ECKeyImpl::getECKey() const
|
|
||||||
{
|
|
||||||
return _pEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::string ECKeyImpl::groupName() const
|
|
||||||
{
|
|
||||||
return OBJ_nid2sn(groupId());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void ECKeyImpl::save(const std::string& publicKeyFile,
|
|
||||||
const std::string& privateKeyFile,
|
|
||||||
const std::string& privateKeyPassphrase) const
|
|
||||||
{
|
|
||||||
EVPPKey(_pEC).save(publicKeyFile, privateKeyFile, privateKeyPassphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void ECKeyImpl::save(std::ostream* pPublicKeyStream,
|
|
||||||
std::ostream* pPrivateKeyStream,
|
|
||||||
const std::string& privateKeyPassphrase) const
|
|
||||||
{
|
|
||||||
EVPPKey(_pEC).save(pPublicKeyStream, pPrivateKeyStream, privateKeyPassphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_ECKeyImplImpl_INCLUDED
|
#endif // Crypto_ECKeyImplImpl_INCLUDED
|
||||||
|
@ -19,336 +19,351 @@
|
|||||||
#define Crypto_EVPPKeyImpl_INCLUDED
|
#define Crypto_EVPPKeyImpl_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <openssl/ec.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/rsa.h>
|
||||||
#include "Poco/Crypto/Crypto.h"
|
#include "Poco/Crypto/Crypto.h"
|
||||||
#include "Poco/Crypto/CryptoException.h"
|
#include "Poco/Crypto/CryptoException.h"
|
||||||
#include "Poco/StreamCopier.h"
|
#include "Poco/StreamCopier.h"
|
||||||
#include <openssl/ec.h>
|
|
||||||
#include <openssl/rsa.h>
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#include <openssl/pem.h>
|
|
||||||
#include <sstream>
|
|
||||||
#include <typeinfo>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
{
|
||||||
|
namespace Crypto
|
||||||
|
|
||||||
class ECKey;
|
|
||||||
class RSAKey;
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API EVPPKey
|
|
||||||
/// Utility class for conversion of native keys to EVP.
|
|
||||||
/// Currently, only RSA and EC keys are supported.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
explicit EVPPKey(const std::string& ecCurveName);
|
|
||||||
/// Constructs EVPPKey from ECC curve name.
|
|
||||||
///
|
|
||||||
/// Only EC keys can be wrapped by an EVPPKey
|
|
||||||
/// created using this constructor.
|
|
||||||
|
|
||||||
explicit EVPPKey(const char* ecCurveName);
|
|
||||||
/// Constructs EVPPKey from ECC curve name.
|
|
||||||
///
|
|
||||||
/// Only EC keys can be wrapped by an EVPPKey
|
|
||||||
/// created using this constructor.
|
|
||||||
|
|
||||||
explicit EVPPKey(EVP_PKEY* pEVPPKey);
|
class ECKey;
|
||||||
/// Constructs EVPPKey from EVP_PKEY pointer.
|
class RSAKey;
|
||||||
/// The content behind the supplied pointer is internally duplicated.
|
|
||||||
|
|
||||||
template<typename K>
|
|
||||||
explicit EVPPKey(K* pKey): _pEVPPKey(EVP_PKEY_new())
|
|
||||||
/// Constructs EVPPKey from a "native" OpenSSL (RSA or EC_KEY),
|
|
||||||
/// or a Poco wrapper (RSAKey, ECKey) key pointer.
|
|
||||||
{
|
|
||||||
if (!_pEVPPKey) throw OpenSSLException();
|
|
||||||
setKey(pKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
EVPPKey(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase = "");
|
class Crypto_API EVPPKey
|
||||||
/// Creates the EVPPKey, by reading public and private key from the given files and
|
/// Utility class for conversion of native keys to EVP.
|
||||||
/// using the given passphrase for the private key. Can only by used for signing if
|
/// Currently, only RSA and EC keys are supported.
|
||||||
/// a private key is available.
|
{
|
||||||
|
public:
|
||||||
|
explicit EVPPKey(const std::string & ecCurveName);
|
||||||
|
/// Constructs EVPPKey from ECC curve name.
|
||||||
|
///
|
||||||
|
/// Only EC keys can be wrapped by an EVPPKey
|
||||||
|
/// created using this constructor.
|
||||||
|
|
||||||
EVPPKey(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase = "");
|
explicit EVPPKey(const char * ecCurveName);
|
||||||
/// Creates the EVPPKey. Can only by used for signing if pPrivKey
|
/// Constructs EVPPKey from ECC curve name.
|
||||||
/// is not null. If a private key file is specified, you don't need to
|
///
|
||||||
/// specify a public key file. OpenSSL will auto-create it from the private key.
|
/// Only EC keys can be wrapped by an EVPPKey
|
||||||
|
/// created using this constructor.
|
||||||
|
|
||||||
EVPPKey(const EVPPKey& other);
|
explicit EVPPKey(EVP_PKEY * pEVPPKey);
|
||||||
/// Copy constructor.
|
/// Constructs EVPPKey from EVP_PKEY pointer.
|
||||||
|
/// The content behind the supplied pointer is internally duplicated.
|
||||||
|
|
||||||
EVPPKey& operator=(const EVPPKey& other);
|
template <typename K>
|
||||||
/// Assignment operator.
|
explicit EVPPKey(K * pKey) : _pEVPPKey(EVP_PKEY_new())
|
||||||
|
/// Constructs EVPPKey from a "native" OpenSSL (RSA or EC_KEY),
|
||||||
|
/// or a Poco wrapper (RSAKey, ECKey) key pointer.
|
||||||
|
{
|
||||||
|
if (!_pEVPPKey)
|
||||||
|
throw OpenSSLException();
|
||||||
|
setKey(pKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
EVPPKey(const std::string & publicKeyFile, const std::string & privateKeyFile, const std::string & privateKeyPassphrase = "");
|
||||||
|
/// Creates the EVPPKey, by reading public and private key from the given files and
|
||||||
|
/// using the given passphrase for the private key. Can only by used for signing if
|
||||||
|
/// a private key is available.
|
||||||
|
|
||||||
|
EVPPKey(std::istream * pPublicKeyStream, std::istream * pPrivateKeyStream, const std::string & privateKeyPassphrase = "");
|
||||||
|
/// Creates the EVPPKey. Can only by used for signing if pPrivKey
|
||||||
|
/// is not null. If a private key file is specified, you don't need to
|
||||||
|
/// specify a public key file. OpenSSL will auto-create it from the private key.
|
||||||
|
|
||||||
|
EVPPKey(const EVPPKey & other);
|
||||||
|
/// Copy constructor.
|
||||||
|
|
||||||
|
EVPPKey & operator=(const EVPPKey & other);
|
||||||
|
/// Assignment operator.
|
||||||
|
|
||||||
#ifdef POCO_ENABLE_CPP11
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
|
||||||
EVPPKey(EVPPKey&& other);
|
EVPPKey(EVPPKey && other);
|
||||||
/// Move constructor.
|
/// Move constructor.
|
||||||
|
|
||||||
EVPPKey& operator=(EVPPKey&& other);
|
EVPPKey & operator=(EVPPKey && other);
|
||||||
/// Assignment move operator.
|
/// Assignment move operator.
|
||||||
|
|
||||||
#endif // POCO_ENABLE_CPP11
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
|
||||||
~EVPPKey();
|
~EVPPKey();
|
||||||
/// Destroys the EVPPKey.
|
/// Destroys the EVPPKey.
|
||||||
|
|
||||||
bool operator == (const EVPPKey& other) const;
|
bool operator==(const EVPPKey & other) const;
|
||||||
/// Comparison operator.
|
/// Comparison operator.
|
||||||
/// Returns true if public key components and parameters
|
/// Returns true if public key components and parameters
|
||||||
/// of the other key are equal to this key.
|
/// of the other key are equal to this key.
|
||||||
///
|
///
|
||||||
/// Works as expected when one key contains only public key,
|
/// Works as expected when one key contains only public key,
|
||||||
/// while the other one contains private (thus also public) key.
|
/// while the other one contains private (thus also public) key.
|
||||||
|
|
||||||
bool operator != (const EVPPKey& other) const;
|
bool operator!=(const EVPPKey & other) const;
|
||||||
/// Comparison operator.
|
/// Comparison operator.
|
||||||
/// Returns true if public key components and parameters
|
/// Returns true if public key components and parameters
|
||||||
/// of the other key are different from this key.
|
/// of the other key are different from this key.
|
||||||
///
|
///
|
||||||
/// Works as expected when one key contains only public key,
|
/// Works as expected when one key contains only public key,
|
||||||
/// while the other one contains private (thus also public) key.
|
/// while the other one contains private (thus also public) key.
|
||||||
|
|
||||||
void save(const std::string& publicKeyFile, const std::string& privateKeyFile = "", const std::string& privateKeyPassphrase = "") const;
|
void save(const std::string & publicKeyFile, const std::string & privateKeyFile = "", const std::string & privateKeyPassphrase = "")
|
||||||
/// Exports the public and/or private keys to the given files.
|
const;
|
||||||
///
|
/// Exports the public and/or private keys to the given files.
|
||||||
/// If an empty filename is specified, the corresponding key
|
///
|
||||||
/// is not exported.
|
/// If an empty filename is specified, the corresponding key
|
||||||
|
/// is not exported.
|
||||||
|
|
||||||
void save(std::ostream* pPublicKeyStream, std::ostream* pPrivateKeyStream = 0, const std::string& privateKeyPassphrase = "") const;
|
void
|
||||||
/// Exports the public and/or private key to the given streams.
|
save(std::ostream * pPublicKeyStream, std::ostream * pPrivateKeyStream = 0, const std::string & privateKeyPassphrase = "") const;
|
||||||
///
|
/// Exports the public and/or private key to the given streams.
|
||||||
/// If a null pointer is passed for a stream, the corresponding
|
///
|
||||||
/// key is not exported.
|
/// If a null pointer is passed for a stream, the corresponding
|
||||||
|
/// key is not exported.
|
||||||
|
|
||||||
int type() const;
|
int type() const;
|
||||||
/// Returns the EVPPKey type NID.
|
/// Returns the EVPPKey type NID.
|
||||||
|
|
||||||
bool isSupported(int type) const;
|
bool isSupported(int type) const;
|
||||||
/// Returns true if OpenSSL type is supported
|
/// Returns true if OpenSSL type is supported
|
||||||
|
|
||||||
operator const EVP_PKEY*() const;
|
operator const EVP_PKEY *() const;
|
||||||
/// Returns const pointer to the OpenSSL EVP_PKEY structure.
|
/// Returns const pointer to the OpenSSL EVP_PKEY structure.
|
||||||
|
|
||||||
operator EVP_PKEY*();
|
operator EVP_PKEY *();
|
||||||
/// Returns pointer to the OpenSSL EVP_PKEY structure.
|
/// Returns pointer to the OpenSSL EVP_PKEY structure.
|
||||||
|
|
||||||
static EVP_PKEY* duplicate(const EVP_PKEY* pFromKey, EVP_PKEY** pToKey);
|
static EVP_PKEY * duplicate(const EVP_PKEY * pFromKey, EVP_PKEY ** pToKey);
|
||||||
/// Duplicates pFromKey into *pToKey and returns
|
/// Duplicates pFromKey into *pToKey and returns
|
||||||
// the pointer to duplicated EVP_PKEY.
|
// the pointer to duplicated EVP_PKEY.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EVPPKey();
|
EVPPKey();
|
||||||
|
|
||||||
static int type(const EVP_PKEY* pEVPPKey);
|
static int type(const EVP_PKEY * pEVPPKey);
|
||||||
void newECKey(const char* group);
|
void newECKey(const char * group);
|
||||||
void duplicate(EVP_PKEY* pEVPPKey);
|
void duplicate(EVP_PKEY * pEVPPKey);
|
||||||
|
|
||||||
void setKey(ECKey* pKey);
|
void setKey(ECKey * pKey);
|
||||||
void setKey(RSAKey* pKey);
|
void setKey(RSAKey * pKey);
|
||||||
void setKey(EC_KEY* pKey);
|
void setKey(EC_KEY * pKey);
|
||||||
void setKey(RSA* pKey);
|
void setKey(RSA * pKey);
|
||||||
static int passCB(char* buf, int size, int, void* pass);
|
static int passCB(char * buf, int size, int, void * pass);
|
||||||
|
|
||||||
typedef EVP_PKEY* (*PEM_read_FILE_Key_fn)(FILE*, EVP_PKEY**, pem_password_cb*, void*);
|
typedef EVP_PKEY * (*PEM_read_FILE_Key_fn)(FILE *, EVP_PKEY **, pem_password_cb *, void *);
|
||||||
typedef EVP_PKEY* (*PEM_read_BIO_Key_fn)(BIO*, EVP_PKEY**, pem_password_cb*, void*);
|
typedef EVP_PKEY * (*PEM_read_BIO_Key_fn)(BIO *, EVP_PKEY **, pem_password_cb *, void *);
|
||||||
typedef void* (*EVP_PKEY_get_Key_fn)(EVP_PKEY*);
|
typedef void * (*EVP_PKEY_get_Key_fn)(EVP_PKEY *);
|
||||||
|
|
||||||
// The following load*() functions are used by both native and EVP_PKEY type key
|
// The following load*() functions are used by both native and EVP_PKEY type key
|
||||||
// loading from BIO/FILE.
|
// loading from BIO/FILE.
|
||||||
// When used for EVP key loading, getFunc is null (ie. native key is not extracted
|
// When used for EVP key loading, getFunc is null (ie. native key is not extracted
|
||||||
// from the loaded EVP_PKEY).
|
// from the loaded EVP_PKEY).
|
||||||
template <typename K, typename F>
|
template <typename K, typename F>
|
||||||
static bool loadKey(K** ppKey,
|
static bool
|
||||||
PEM_read_FILE_Key_fn readFunc,
|
loadKey(K ** ppKey, PEM_read_FILE_Key_fn readFunc, F getFunc, const std::string & keyFile, const std::string & pass = "")
|
||||||
F getFunc,
|
{
|
||||||
const std::string& keyFile,
|
poco_assert_dbg(
|
||||||
const std::string& pass = "")
|
((typeid(K *) == typeid(RSA *) || typeid(K *) == typeid(EC_KEY *)) && getFunc)
|
||||||
{
|
|| ((typeid(K *) == typeid(EVP_PKEY *)) && !getFunc));
|
||||||
poco_assert_dbg (((typeid(K*) == typeid(RSA*) || typeid(K*) == typeid(EC_KEY*)) && getFunc) ||
|
poco_check_ptr(ppKey);
|
||||||
((typeid(K*) == typeid(EVP_PKEY*)) && !getFunc));
|
poco_assert_dbg(!*ppKey);
|
||||||
poco_check_ptr (ppKey);
|
|
||||||
poco_assert_dbg (!*ppKey);
|
|
||||||
|
|
||||||
FILE* pFile = 0;
|
FILE * pFile = 0;
|
||||||
if (!keyFile.empty())
|
if (!keyFile.empty())
|
||||||
{
|
{
|
||||||
if (!getFunc) *ppKey = (K*)EVP_PKEY_new();
|
if (!getFunc)
|
||||||
EVP_PKEY* pKey = getFunc ? EVP_PKEY_new() : (EVP_PKEY*)*ppKey;
|
*ppKey = (K *)EVP_PKEY_new();
|
||||||
if (pKey)
|
EVP_PKEY * pKey = getFunc ? EVP_PKEY_new() : (EVP_PKEY *)*ppKey;
|
||||||
{
|
if (pKey)
|
||||||
pFile = fopen(keyFile.c_str(), "r");
|
{
|
||||||
if (pFile)
|
pFile = fopen(keyFile.c_str(), "r");
|
||||||
{
|
if (pFile)
|
||||||
pem_password_cb* pCB = pass.empty() ? (pem_password_cb*)0 : &passCB;
|
{
|
||||||
void* pPassword = pass.empty() ? (void*)0 : (void*)pass.c_str();
|
pem_password_cb * pCB = pass.empty() ? (pem_password_cb *)0 : &passCB;
|
||||||
if (readFunc(pFile, &pKey, pCB, pPassword))
|
void * pPassword = pass.empty() ? (void *)0 : (void *)pass.c_str();
|
||||||
{
|
if (readFunc(pFile, &pKey, pCB, pPassword))
|
||||||
fclose(pFile); pFile = 0;
|
{
|
||||||
if(getFunc)
|
fclose(pFile);
|
||||||
{
|
pFile = 0;
|
||||||
*ppKey = (K*)getFunc(pKey);
|
if (getFunc)
|
||||||
EVP_PKEY_free(pKey);
|
{
|
||||||
}
|
*ppKey = (K *)getFunc(pKey);
|
||||||
else
|
EVP_PKEY_free(pKey);
|
||||||
{
|
}
|
||||||
poco_assert_dbg (typeid(K*) == typeid(EVP_PKEY*));
|
else
|
||||||
*ppKey = (K*)pKey;
|
{
|
||||||
}
|
poco_assert_dbg(typeid(K *) == typeid(EVP_PKEY *));
|
||||||
if(!*ppKey) goto error;
|
*ppKey = (K *)pKey;
|
||||||
return true;
|
}
|
||||||
}
|
if (!*ppKey)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
return true;
|
||||||
else
|
}
|
||||||
{
|
goto error;
|
||||||
if (getFunc) EVP_PKEY_free(pKey);
|
}
|
||||||
throw IOException("ECKeyImpl, cannot open file", keyFile);
|
else
|
||||||
}
|
{
|
||||||
}
|
if (getFunc)
|
||||||
else goto error;
|
EVP_PKEY_free(pKey);
|
||||||
}
|
throw IOException("ECKeyImpl, cannot open file", keyFile);
|
||||||
return false;
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (pFile) fclose(pFile);
|
if (pFile)
|
||||||
throw OpenSSLException("EVPKey::loadKey(string)");
|
fclose(pFile);
|
||||||
}
|
throw OpenSSLException("EVPKey::loadKey(string)");
|
||||||
|
}
|
||||||
|
|
||||||
template <typename K, typename F>
|
template <typename K, typename F>
|
||||||
static bool loadKey(K** ppKey,
|
static bool loadKey(K ** ppKey, PEM_read_BIO_Key_fn readFunc, F getFunc, std::istream * pIstr, const std::string & pass = "")
|
||||||
PEM_read_BIO_Key_fn readFunc,
|
{
|
||||||
F getFunc,
|
poco_assert_dbg(
|
||||||
std::istream* pIstr,
|
((typeid(K *) == typeid(RSA *) || typeid(K *) == typeid(EC_KEY *)) && getFunc)
|
||||||
const std::string& pass = "")
|
|| ((typeid(K *) == typeid(EVP_PKEY *)) && !getFunc));
|
||||||
{
|
poco_check_ptr(ppKey);
|
||||||
poco_assert_dbg (((typeid(K*) == typeid(RSA*) || typeid(K*) == typeid(EC_KEY*)) && getFunc) ||
|
poco_assert_dbg(!*ppKey);
|
||||||
((typeid(K*) == typeid(EVP_PKEY*)) && !getFunc));
|
|
||||||
poco_check_ptr(ppKey);
|
|
||||||
poco_assert_dbg(!*ppKey);
|
|
||||||
|
|
||||||
BIO* pBIO = 0;
|
BIO * pBIO = 0;
|
||||||
if (pIstr)
|
if (pIstr)
|
||||||
{
|
{
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
Poco::StreamCopier::copyStream(*pIstr, ostr);
|
Poco::StreamCopier::copyStream(*pIstr, ostr);
|
||||||
std::string key = ostr.str();
|
std::string key = ostr.str();
|
||||||
pBIO = BIO_new_mem_buf(const_cast<char*>(key.data()), static_cast<int>(key.size()));
|
pBIO = BIO_new_mem_buf(const_cast<char *>(key.data()), static_cast<int>(key.size()));
|
||||||
if (pBIO)
|
if (pBIO)
|
||||||
{
|
{
|
||||||
if (!getFunc) *ppKey = (K*)EVP_PKEY_new();
|
if (!getFunc)
|
||||||
EVP_PKEY* pKey = getFunc ? EVP_PKEY_new() : (EVP_PKEY*)*ppKey;
|
*ppKey = (K *)EVP_PKEY_new();
|
||||||
if (pKey)
|
EVP_PKEY * pKey = getFunc ? EVP_PKEY_new() : (EVP_PKEY *)*ppKey;
|
||||||
{
|
if (pKey)
|
||||||
pem_password_cb* pCB = pass.empty() ? (pem_password_cb*)0 : &passCB;
|
{
|
||||||
void* pPassword = pass.empty() ? (void*)0 : (void*)pass.c_str();
|
pem_password_cb * pCB = pass.empty() ? (pem_password_cb *)0 : &passCB;
|
||||||
if (readFunc(pBIO, &pKey, pCB, pPassword))
|
void * pPassword = pass.empty() ? (void *)0 : (void *)pass.c_str();
|
||||||
{
|
if (readFunc(pBIO, &pKey, pCB, pPassword))
|
||||||
BIO_free(pBIO); pBIO = 0;
|
{
|
||||||
if (getFunc)
|
BIO_free(pBIO);
|
||||||
{
|
pBIO = 0;
|
||||||
*ppKey = (K*)getFunc(pKey);
|
if (getFunc)
|
||||||
EVP_PKEY_free(pKey);
|
{
|
||||||
}
|
*ppKey = (K *)getFunc(pKey);
|
||||||
else
|
EVP_PKEY_free(pKey);
|
||||||
{
|
}
|
||||||
poco_assert_dbg (typeid(K*) == typeid(EVP_PKEY*));
|
else
|
||||||
*ppKey = (K*)pKey;
|
{
|
||||||
}
|
poco_assert_dbg(typeid(K *) == typeid(EVP_PKEY *));
|
||||||
if (!*ppKey) goto error;
|
*ppKey = (K *)pKey;
|
||||||
return true;
|
}
|
||||||
}
|
if (!*ppKey)
|
||||||
if (getFunc) EVP_PKEY_free(pKey);
|
goto error;
|
||||||
goto error;
|
return true;
|
||||||
}
|
}
|
||||||
else goto error;
|
if (getFunc)
|
||||||
}
|
EVP_PKEY_free(pKey);
|
||||||
else goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
return false;
|
else
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (pBIO) BIO_free(pBIO);
|
if (pBIO)
|
||||||
throw OpenSSLException("EVPKey::loadKey(stream)");
|
BIO_free(pBIO);
|
||||||
}
|
throw OpenSSLException("EVPKey::loadKey(stream)");
|
||||||
|
}
|
||||||
|
|
||||||
EVP_PKEY* _pEVPPKey;
|
EVP_PKEY * _pEVPPKey;
|
||||||
|
|
||||||
friend class ECKeyImpl;
|
friend class ECKeyImpl;
|
||||||
friend class RSAKeyImpl;
|
friend class RSAKeyImpl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// inlines
|
// inlines
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
inline bool EVPPKey::operator==(const EVPPKey & other) const
|
||||||
|
{
|
||||||
|
poco_check_ptr(other._pEVPPKey);
|
||||||
|
poco_check_ptr(_pEVPPKey);
|
||||||
|
return (1 == EVP_PKEY_cmp(_pEVPPKey, other._pEVPPKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool EVPPKey::operator!=(const EVPPKey & other) const
|
||||||
|
{
|
||||||
|
return !(other == *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int EVPPKey::type(const EVP_PKEY * pEVPPKey)
|
||||||
|
{
|
||||||
|
if (!pEVPPKey)
|
||||||
|
return NID_undef;
|
||||||
|
|
||||||
|
return EVP_PKEY_type(EVP_PKEY_id(pEVPPKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int EVPPKey::type() const
|
||||||
|
{
|
||||||
|
return type(_pEVPPKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool EVPPKey::isSupported(int type) const
|
||||||
|
{
|
||||||
|
return type == EVP_PKEY_EC || type == EVP_PKEY_RSA;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline EVPPKey::operator const EVP_PKEY *() const
|
||||||
|
{
|
||||||
|
return _pEVPPKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline EVPPKey::operator EVP_PKEY *()
|
||||||
|
{
|
||||||
|
return _pEVPPKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void EVPPKey::setKey(EC_KEY * pKey)
|
||||||
|
{
|
||||||
|
if (!EVP_PKEY_set1_EC_KEY(_pEVPPKey, pKey))
|
||||||
|
throw OpenSSLException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void EVPPKey::setKey(RSA * pKey)
|
||||||
|
{
|
||||||
|
if (!EVP_PKEY_set1_RSA(_pEVPPKey, pKey))
|
||||||
|
throw OpenSSLException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool EVPPKey::operator == (const EVPPKey& other) const
|
|
||||||
{
|
|
||||||
poco_check_ptr (other._pEVPPKey);
|
|
||||||
poco_check_ptr (_pEVPPKey);
|
|
||||||
return (1 == EVP_PKEY_cmp(_pEVPPKey, other._pEVPPKey));
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
inline bool EVPPKey::operator != (const EVPPKey& other) const
|
|
||||||
{
|
|
||||||
return !(other == *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline int EVPPKey::type(const EVP_PKEY* pEVPPKey)
|
|
||||||
{
|
|
||||||
if (!pEVPPKey) return NID_undef;
|
|
||||||
|
|
||||||
return EVP_PKEY_type(EVP_PKEY_id(pEVPPKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline int EVPPKey::type() const
|
|
||||||
{
|
|
||||||
return type(_pEVPPKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool EVPPKey::isSupported(int type) const
|
|
||||||
{
|
|
||||||
return type == EVP_PKEY_EC || type == EVP_PKEY_RSA;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline EVPPKey::operator const EVP_PKEY*() const
|
|
||||||
{
|
|
||||||
return _pEVPPKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline EVPPKey::operator EVP_PKEY*()
|
|
||||||
{
|
|
||||||
return _pEVPPKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void EVPPKey::setKey(EC_KEY* pKey)
|
|
||||||
{
|
|
||||||
if (!EVP_PKEY_set1_EC_KEY(_pEVPPKey, pKey))
|
|
||||||
throw OpenSSLException();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void EVPPKey::setKey(RSA* pKey)
|
|
||||||
{
|
|
||||||
if (!EVP_PKEY_set1_RSA(_pEVPPKey, pKey))
|
|
||||||
throw OpenSSLException();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_EVPPKeyImpl_INCLUDED
|
#endif // Crypto_EVPPKeyImpl_INCLUDED
|
||||||
|
@ -23,111 +23,114 @@
|
|||||||
#include "Poco/Crypto/KeyPairImpl.h"
|
#include "Poco/Crypto/KeyPairImpl.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class X509Certificate;
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API KeyPair
|
|
||||||
/// This is a parent class for classes storing a key pair, consisting
|
|
||||||
/// of private and public key. Storage of the private key is optional.
|
|
||||||
///
|
|
||||||
/// If a private key is available, the KeyPair can be
|
|
||||||
/// used for decrypting data (encrypted with the public key)
|
|
||||||
/// or computing secure digital signatures.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Crypto
|
||||||
enum Type
|
|
||||||
{
|
|
||||||
KT_RSA = KeyPairImpl::KT_RSA_IMPL,
|
|
||||||
KT_EC = KeyPairImpl::KT_EC_IMPL
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit KeyPair(KeyPairImpl::Ptr pKeyPairImpl = 0);
|
|
||||||
/// Extracts the RSA public key from the given certificate.
|
|
||||||
|
|
||||||
virtual ~KeyPair();
|
|
||||||
/// Destroys the KeyPair.
|
|
||||||
|
|
||||||
virtual int size() const;
|
|
||||||
/// Returns the RSA modulus size.
|
|
||||||
|
|
||||||
virtual void save(const std::string& publicKeyPairFile,
|
|
||||||
const std::string& privateKeyPairFile = "",
|
|
||||||
const std::string& privateKeyPairPassphrase = "") const;
|
|
||||||
/// Exports the public and private keys to the given files.
|
|
||||||
///
|
|
||||||
/// If an empty filename is specified, the corresponding key
|
|
||||||
/// is not exported.
|
|
||||||
|
|
||||||
virtual void save(std::ostream* pPublicKeyPairStream,
|
|
||||||
std::ostream* pPrivateKeyPairStream = 0,
|
|
||||||
const std::string& privateKeyPairPassphrase = "") const;
|
|
||||||
/// Exports the public and private key to the given streams.
|
|
||||||
///
|
|
||||||
/// If a null pointer is passed for a stream, the corresponding
|
|
||||||
/// key is not exported.
|
|
||||||
|
|
||||||
KeyPairImpl::Ptr impl() const;
|
|
||||||
/// Returns the impl object.
|
|
||||||
|
|
||||||
const std::string& name() const;
|
|
||||||
/// Returns key pair name
|
|
||||||
|
|
||||||
Type type() const;
|
|
||||||
/// Returns key pair type
|
|
||||||
|
|
||||||
private:
|
|
||||||
KeyPairImpl::Ptr _pImpl;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
|
|
||||||
inline int KeyPair::size() const
|
|
||||||
{
|
{
|
||||||
return _pImpl->size();
|
|
||||||
|
|
||||||
|
class X509Certificate;
|
||||||
|
|
||||||
|
|
||||||
|
class Crypto_API KeyPair
|
||||||
|
/// This is a parent class for classes storing a key pair, consisting
|
||||||
|
/// of private and public key. Storage of the private key is optional.
|
||||||
|
///
|
||||||
|
/// If a private key is available, the KeyPair can be
|
||||||
|
/// used for decrypting data (encrypted with the public key)
|
||||||
|
/// or computing secure digital signatures.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
KT_RSA = KeyPairImpl::KT_RSA_IMPL,
|
||||||
|
KT_EC = KeyPairImpl::KT_EC_IMPL
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit KeyPair(KeyPairImpl::Ptr pKeyPairImpl = 0);
|
||||||
|
/// Extracts the RSA public key from the given certificate.
|
||||||
|
|
||||||
|
virtual ~KeyPair();
|
||||||
|
/// Destroys the KeyPair.
|
||||||
|
|
||||||
|
virtual int size() const;
|
||||||
|
/// Returns the RSA modulus size.
|
||||||
|
|
||||||
|
virtual void save(
|
||||||
|
const std::string & publicKeyPairFile,
|
||||||
|
const std::string & privateKeyPairFile = "",
|
||||||
|
const std::string & privateKeyPairPassphrase = "") const;
|
||||||
|
/// Exports the public and private keys to the given files.
|
||||||
|
///
|
||||||
|
/// If an empty filename is specified, the corresponding key
|
||||||
|
/// is not exported.
|
||||||
|
|
||||||
|
virtual void save(
|
||||||
|
std::ostream * pPublicKeyPairStream,
|
||||||
|
std::ostream * pPrivateKeyPairStream = 0,
|
||||||
|
const std::string & privateKeyPairPassphrase = "") const;
|
||||||
|
/// Exports the public and private key to the given streams.
|
||||||
|
///
|
||||||
|
/// If a null pointer is passed for a stream, the corresponding
|
||||||
|
/// key is not exported.
|
||||||
|
|
||||||
|
KeyPairImpl::Ptr impl() const;
|
||||||
|
/// Returns the impl object.
|
||||||
|
|
||||||
|
const std::string & name() const;
|
||||||
|
/// Returns key pair name
|
||||||
|
|
||||||
|
Type type() const;
|
||||||
|
/// Returns key pair type
|
||||||
|
|
||||||
|
private:
|
||||||
|
KeyPairImpl::Ptr _pImpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
|
||||||
|
inline int KeyPair::size() const
|
||||||
|
{
|
||||||
|
return _pImpl->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
KeyPair::save(const std::string & publicKeyFile, const std::string & privateKeyFile, const std::string & privateKeyPassphrase) const
|
||||||
|
{
|
||||||
|
_pImpl->save(publicKeyFile, privateKeyFile, privateKeyPassphrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
KeyPair::save(std::ostream * pPublicKeyStream, std::ostream * pPrivateKeyStream, const std::string & privateKeyPassphrase) const
|
||||||
|
{
|
||||||
|
_pImpl->save(pPublicKeyStream, pPrivateKeyStream, privateKeyPassphrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const std::string & KeyPair::name() const
|
||||||
|
{
|
||||||
|
return _pImpl->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline KeyPairImpl::Ptr KeyPair::impl() const
|
||||||
|
{
|
||||||
|
return _pImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline KeyPair::Type KeyPair::type() const
|
||||||
|
{
|
||||||
|
return (KeyPair::Type)impl()->type();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
inline void KeyPair::save(const std::string& publicKeyFile,
|
|
||||||
const std::string& privateKeyFile,
|
|
||||||
const std::string& privateKeyPassphrase) const
|
|
||||||
{
|
|
||||||
_pImpl->save(publicKeyFile, privateKeyFile, privateKeyPassphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void KeyPair::save(std::ostream* pPublicKeyStream,
|
|
||||||
std::ostream* pPrivateKeyStream,
|
|
||||||
const std::string& privateKeyPassphrase) const
|
|
||||||
{
|
|
||||||
_pImpl->save(pPublicKeyStream, pPrivateKeyStream, privateKeyPassphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& KeyPair::name() const
|
|
||||||
{
|
|
||||||
return _pImpl->name();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline KeyPairImpl::Ptr KeyPair::impl() const
|
|
||||||
{
|
|
||||||
return _pImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline KeyPair::Type KeyPair::type() const
|
|
||||||
{
|
|
||||||
return (KeyPair::Type)impl()->type();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_KeyPair_INCLUDED
|
#endif // Crypto_KeyPair_INCLUDED
|
||||||
|
@ -19,89 +19,92 @@
|
|||||||
#define Crypto_KeyPairImplImpl_INCLUDED
|
#define Crypto_KeyPairImplImpl_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "Poco/AutoPtr.h"
|
||||||
#include "Poco/Crypto/Crypto.h"
|
#include "Poco/Crypto/Crypto.h"
|
||||||
#include "Poco/Crypto/OpenSSLInitializer.h"
|
#include "Poco/Crypto/OpenSSLInitializer.h"
|
||||||
#include "Poco/RefCountedObject.h"
|
#include "Poco/RefCountedObject.h"
|
||||||
#include "Poco/AutoPtr.h"
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class KeyPairImpl: public Poco::RefCountedObject
|
|
||||||
/// Class KeyPairImpl
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Crypto
|
||||||
enum Type
|
|
||||||
{
|
|
||||||
KT_RSA_IMPL = 0,
|
|
||||||
KT_EC_IMPL
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef Poco::AutoPtr<KeyPairImpl> Ptr;
|
|
||||||
typedef std::vector<unsigned char> ByteVec;
|
|
||||||
|
|
||||||
KeyPairImpl(const std::string& name, Type type);
|
|
||||||
/// Create KeyPairImpl with specified type and name.
|
|
||||||
|
|
||||||
virtual ~KeyPairImpl();
|
|
||||||
/// Destroys the KeyPairImpl.
|
|
||||||
|
|
||||||
virtual int size() const = 0;
|
|
||||||
/// Returns the key size.
|
|
||||||
|
|
||||||
virtual void save(const std::string& publicKeyFile,
|
|
||||||
const std::string& privateKeyFile = "",
|
|
||||||
const std::string& privateKeyPassphrase = "") const = 0;
|
|
||||||
/// Exports the public and private keys to the given files.
|
|
||||||
///
|
|
||||||
/// If an empty filename is specified, the corresponding key
|
|
||||||
/// is not exported.
|
|
||||||
|
|
||||||
virtual void save(std::ostream* pPublicKeyStream,
|
|
||||||
std::ostream* pPrivateKeyStream = 0,
|
|
||||||
const std::string& privateKeyPassphrase = "") const = 0;
|
|
||||||
/// Exports the public and private key to the given streams.
|
|
||||||
///
|
|
||||||
/// If a null pointer is passed for a stream, the corresponding
|
|
||||||
/// key is not exported.
|
|
||||||
|
|
||||||
const std::string& name() const;
|
|
||||||
/// Returns key pair name
|
|
||||||
|
|
||||||
Type type() const;
|
|
||||||
/// Returns key pair type
|
|
||||||
|
|
||||||
private:
|
|
||||||
KeyPairImpl();
|
|
||||||
|
|
||||||
std::string _name;
|
|
||||||
Type _type;
|
|
||||||
OpenSSLInitializer _openSSLInitializer;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& KeyPairImpl::name() const
|
|
||||||
{
|
{
|
||||||
return _name;
|
|
||||||
|
|
||||||
|
class KeyPairImpl : public Poco::RefCountedObject
|
||||||
|
/// Class KeyPairImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
KT_RSA_IMPL = 0,
|
||||||
|
KT_EC_IMPL
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Poco::AutoPtr<KeyPairImpl> Ptr;
|
||||||
|
typedef std::vector<unsigned char> ByteVec;
|
||||||
|
|
||||||
|
KeyPairImpl(const std::string & name, Type type);
|
||||||
|
/// Create KeyPairImpl with specified type and name.
|
||||||
|
|
||||||
|
virtual ~KeyPairImpl();
|
||||||
|
/// Destroys the KeyPairImpl.
|
||||||
|
|
||||||
|
virtual int size() const = 0;
|
||||||
|
/// Returns the key size.
|
||||||
|
|
||||||
|
virtual void save(
|
||||||
|
const std::string & publicKeyFile,
|
||||||
|
const std::string & privateKeyFile = "",
|
||||||
|
const std::string & privateKeyPassphrase = "") const = 0;
|
||||||
|
/// Exports the public and private keys to the given files.
|
||||||
|
///
|
||||||
|
/// If an empty filename is specified, the corresponding key
|
||||||
|
/// is not exported.
|
||||||
|
|
||||||
|
virtual void save(
|
||||||
|
std::ostream * pPublicKeyStream, std::ostream * pPrivateKeyStream = 0, const std::string & privateKeyPassphrase = "") const = 0;
|
||||||
|
/// Exports the public and private key to the given streams.
|
||||||
|
///
|
||||||
|
/// If a null pointer is passed for a stream, the corresponding
|
||||||
|
/// key is not exported.
|
||||||
|
|
||||||
|
const std::string & name() const;
|
||||||
|
/// Returns key pair name
|
||||||
|
|
||||||
|
Type type() const;
|
||||||
|
/// Returns key pair type
|
||||||
|
|
||||||
|
private:
|
||||||
|
KeyPairImpl();
|
||||||
|
|
||||||
|
std::string _name;
|
||||||
|
Type _type;
|
||||||
|
OpenSSLInitializer _openSSLInitializer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
inline const std::string & KeyPairImpl::name() const
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline KeyPairImpl::Type KeyPairImpl::type() const
|
||||||
|
{
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
inline KeyPairImpl::Type KeyPairImpl::type() const
|
|
||||||
{
|
|
||||||
return _type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_KeyPairImplImpl_INCLUDED
|
#endif // Crypto_KeyPairImplImpl_INCLUDED
|
||||||
|
@ -18,98 +18,100 @@
|
|||||||
#define Crypto_OpenSSLInitializer_INCLUDED
|
#define Crypto_OpenSSLInitializer_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
#include "Poco/AtomicCounter.h"
|
||||||
#include "Poco/Crypto/Crypto.h"
|
#include "Poco/Crypto/Crypto.h"
|
||||||
#include "Poco/Mutex.h"
|
#include "Poco/Mutex.h"
|
||||||
#include "Poco/AtomicCounter.h"
|
|
||||||
#include <openssl/crypto.h>
|
|
||||||
|
|
||||||
#if defined(OPENSSL_FIPS) && OPENSSL_VERSION_NUMBER < 0x010001000L
|
#if defined(OPENSSL_FIPS) && OPENSSL_VERSION_NUMBER < 0x010001000L
|
||||||
#include <openssl/fips.h>
|
# include <openssl/fips.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
extern "C" {
|
||||||
|
struct CRYPTO_dynlock_value
|
||||||
{
|
{
|
||||||
struct CRYPTO_dynlock_value
|
Poco::FastMutex _mutex;
|
||||||
{
|
|
||||||
Poco::FastMutex _mutex;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API OpenSSLInitializer
|
|
||||||
/// Initializes the OpenSSL library.
|
|
||||||
///
|
|
||||||
/// The class ensures the earliest initialization and the
|
|
||||||
/// latest shutdown of the OpenSSL library.
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
OpenSSLInitializer();
|
|
||||||
/// Automatically initialize OpenSSL on startup.
|
|
||||||
|
|
||||||
~OpenSSLInitializer();
|
|
||||||
/// Automatically shut down OpenSSL on exit.
|
|
||||||
|
|
||||||
static void initialize();
|
|
||||||
/// Initializes the OpenSSL machinery.
|
|
||||||
|
|
||||||
static void uninitialize();
|
|
||||||
/// Shuts down the OpenSSL machinery.
|
|
||||||
|
|
||||||
static bool isFIPSEnabled();
|
|
||||||
// Returns true if FIPS mode is enabled, false otherwise.
|
|
||||||
|
|
||||||
static void enableFIPSMode(bool enabled);
|
|
||||||
// Enable or disable FIPS mode. If FIPS is not available, this method doesn't do anything.
|
|
||||||
|
|
||||||
protected:
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
SEEDSIZE = 256
|
|
||||||
};
|
|
||||||
|
|
||||||
// OpenSSL multithreading support
|
|
||||||
static void lock(int mode, int n, const char* file, int line);
|
|
||||||
static unsigned long id();
|
|
||||||
static struct CRYPTO_dynlock_value* dynlockCreate(const char* file, int line);
|
|
||||||
static void dynlock(int mode, struct CRYPTO_dynlock_value* lock, const char* file, int line);
|
|
||||||
static void dynlockDestroy(struct CRYPTO_dynlock_value* lock, const char* file, int line);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static Poco::FastMutex* _mutexes;
|
|
||||||
static Poco::AtomicCounter _rc;
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
namespace Poco
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline bool OpenSSLInitializer::isFIPSEnabled()
|
|
||||||
{
|
{
|
||||||
|
namespace Crypto
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class Crypto_API OpenSSLInitializer
|
||||||
|
/// Initializes the OpenSSL library.
|
||||||
|
///
|
||||||
|
/// The class ensures the earliest initialization and the
|
||||||
|
/// latest shutdown of the OpenSSL library.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OpenSSLInitializer();
|
||||||
|
/// Automatically initialize OpenSSL on startup.
|
||||||
|
|
||||||
|
~OpenSSLInitializer();
|
||||||
|
/// Automatically shut down OpenSSL on exit.
|
||||||
|
|
||||||
|
static void initialize();
|
||||||
|
/// Initializes the OpenSSL machinery.
|
||||||
|
|
||||||
|
static void uninitialize();
|
||||||
|
/// Shuts down the OpenSSL machinery.
|
||||||
|
|
||||||
|
static bool isFIPSEnabled();
|
||||||
|
// Returns true if FIPS mode is enabled, false otherwise.
|
||||||
|
|
||||||
|
static void enableFIPSMode(bool enabled);
|
||||||
|
// Enable or disable FIPS mode. If FIPS is not available, this method doesn't do anything.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SEEDSIZE = 256
|
||||||
|
};
|
||||||
|
|
||||||
|
// OpenSSL multithreading support
|
||||||
|
static void lock(int mode, int n, const char * file, int line);
|
||||||
|
static unsigned long id();
|
||||||
|
static struct CRYPTO_dynlock_value * dynlockCreate(const char * file, int line);
|
||||||
|
static void dynlock(int mode, struct CRYPTO_dynlock_value * lock, const char * file, int line);
|
||||||
|
static void dynlockDestroy(struct CRYPTO_dynlock_value * lock, const char * file, int line);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Poco::FastMutex * _mutexes;
|
||||||
|
static Poco::AtomicCounter _rc;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline bool OpenSSLInitializer::isFIPSEnabled()
|
||||||
|
{
|
||||||
#ifdef OPENSSL_FIPS
|
#ifdef OPENSSL_FIPS
|
||||||
return FIPS_mode() ? true : false;
|
return FIPS_mode() ? true : false;
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPENSSL_FIPS
|
#ifdef OPENSSL_FIPS
|
||||||
inline void OpenSSLInitializer::enableFIPSMode(bool enabled)
|
inline void OpenSSLInitializer::enableFIPSMode(bool enabled)
|
||||||
{
|
{
|
||||||
FIPS_mode_set(enabled);
|
FIPS_mode_set(enabled);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
inline void OpenSSLInitializer::enableFIPSMode(bool /*enabled*/)
|
inline void OpenSSLInitializer::enableFIPSMode(bool /*enabled*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_OpenSSLInitializer_INCLUDED
|
#endif // Crypto_OpenSSLInitializer_INCLUDED
|
||||||
|
@ -18,142 +18,145 @@
|
|||||||
#define Crypto_PKCS12Container_INCLUDED
|
#define Crypto_PKCS12Container_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <istream>
|
||||||
|
#include <memory>
|
||||||
|
#include <openssl/pkcs12.h>
|
||||||
#include "Poco/Crypto/Crypto.h"
|
#include "Poco/Crypto/Crypto.h"
|
||||||
|
#include "Poco/Crypto/EVPPKey.h"
|
||||||
#include "Poco/Crypto/OpenSSLInitializer.h"
|
#include "Poco/Crypto/OpenSSLInitializer.h"
|
||||||
#include "Poco/Crypto/X509Certificate.h"
|
#include "Poco/Crypto/X509Certificate.h"
|
||||||
#include "Poco/Crypto/EVPPKey.h"
|
|
||||||
#include "Poco/Path.h"
|
#include "Poco/Path.h"
|
||||||
#include <memory>
|
|
||||||
#include <istream>
|
|
||||||
#include <openssl/pkcs12.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
{
|
||||||
|
namespace Crypto
|
||||||
|
|
||||||
class Crypto_API PKCS12Container
|
|
||||||
/// This class implements PKCS#12 container functionality.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
typedef X509Certificate::List CAList;
|
|
||||||
typedef std::vector<std::string> CANameList;
|
|
||||||
|
|
||||||
explicit PKCS12Container(std::istream& istr, const std::string& password = "");
|
|
||||||
/// Creates the PKCS12Container object from a stream.
|
|
||||||
|
|
||||||
explicit PKCS12Container(const std::string& path, const std::string& password = "");
|
class Crypto_API PKCS12Container
|
||||||
/// Creates the PKCS12Container object from a file.
|
/// This class implements PKCS#12 container functionality.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef X509Certificate::List CAList;
|
||||||
|
typedef std::vector<std::string> CANameList;
|
||||||
|
|
||||||
PKCS12Container(const PKCS12Container& cont);
|
explicit PKCS12Container(std::istream & istr, const std::string & password = "");
|
||||||
/// Copy constructor.
|
/// Creates the PKCS12Container object from a stream.
|
||||||
|
|
||||||
PKCS12Container& operator = (const PKCS12Container& cont);
|
explicit PKCS12Container(const std::string & path, const std::string & password = "");
|
||||||
/// Assignment operator.
|
/// Creates the PKCS12Container object from a file.
|
||||||
|
|
||||||
|
PKCS12Container(const PKCS12Container & cont);
|
||||||
|
/// Copy constructor.
|
||||||
|
|
||||||
|
PKCS12Container & operator=(const PKCS12Container & cont);
|
||||||
|
/// Assignment operator.
|
||||||
|
|
||||||
#ifdef POCO_ENABLE_CPP11
|
#ifdef POCO_ENABLE_CPP11
|
||||||
|
|
||||||
PKCS12Container(PKCS12Container&& cont);
|
PKCS12Container(PKCS12Container && cont);
|
||||||
/// Move constructor.
|
/// Move constructor.
|
||||||
|
|
||||||
PKCS12Container& operator = (PKCS12Container&& cont);
|
PKCS12Container & operator=(PKCS12Container && cont);
|
||||||
/// Move assignment operator.
|
/// Move assignment operator.
|
||||||
|
|
||||||
#endif // POCO_ENABLE_CPP11
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
|
||||||
~PKCS12Container();
|
~PKCS12Container();
|
||||||
/// Destroys the PKCS12Container.
|
/// Destroys the PKCS12Container.
|
||||||
|
|
||||||
bool hasKey() const;
|
bool hasKey() const;
|
||||||
/// Returns true if container contains the key.
|
/// Returns true if container contains the key.
|
||||||
|
|
||||||
EVPPKey getKey() const;
|
EVPPKey getKey() const;
|
||||||
/// Return key as openssl EVP_PKEY wrapper object.
|
/// Return key as openssl EVP_PKEY wrapper object.
|
||||||
|
|
||||||
bool hasX509Certificate() const;
|
bool hasX509Certificate() const;
|
||||||
/// Returns true if container has X509 certificate.
|
/// Returns true if container has X509 certificate.
|
||||||
|
|
||||||
const X509Certificate& getX509Certificate() const;
|
const X509Certificate & getX509Certificate() const;
|
||||||
/// Returns the X509 certificate.
|
/// Returns the X509 certificate.
|
||||||
/// Throws NotFoundException if there is no certificate.
|
/// Throws NotFoundException if there is no certificate.
|
||||||
|
|
||||||
const CAList& getCACerts() const;
|
const CAList & getCACerts() const;
|
||||||
/// Returns the list of CA certificates in this container.
|
/// Returns the list of CA certificates in this container.
|
||||||
|
|
||||||
const std::string& getFriendlyName() const;
|
const std::string & getFriendlyName() const;
|
||||||
/// Returns the friendly name of the certificate bag.
|
/// Returns the friendly name of the certificate bag.
|
||||||
|
|
||||||
const CANameList& getFriendlyNamesCA() const;
|
const CANameList & getFriendlyNamesCA() const;
|
||||||
/// Returns a list of CA certificates friendly names.
|
/// Returns a list of CA certificates friendly names.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void load(PKCS12* pPKCS12, const std::string& password = "");
|
void load(PKCS12 * pPKCS12, const std::string & password = "");
|
||||||
std::string extractFriendlyName(X509* pCert);
|
std::string extractFriendlyName(X509 * pCert);
|
||||||
|
|
||||||
#ifdef POCO_ENABLE_CPP11
|
#ifdef POCO_ENABLE_CPP11
|
||||||
typedef std::unique_ptr<X509Certificate> CertPtr;
|
typedef std::unique_ptr<X509Certificate> CertPtr;
|
||||||
#else
|
#else
|
||||||
typedef std::auto_ptr<X509Certificate> CertPtr;
|
typedef std::auto_ptr<X509Certificate> CertPtr;
|
||||||
#endif // #ifdef POCO_ENABLE_CPP11
|
#endif // #ifdef POCO_ENABLE_CPP11
|
||||||
|
|
||||||
OpenSSLInitializer _openSSLInitializer;
|
OpenSSLInitializer _openSSLInitializer;
|
||||||
EVP_PKEY* _pKey;
|
EVP_PKEY * _pKey;
|
||||||
CertPtr _pX509Cert;
|
CertPtr _pX509Cert;
|
||||||
CAList _caCertList;
|
CAList _caCertList;
|
||||||
CANameList _caCertNames;
|
CANameList _caCertNames;
|
||||||
std::string _pkcsFriendlyName;
|
std::string _pkcsFriendlyName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// inlines
|
// inlines
|
||||||
//
|
//
|
||||||
|
|
||||||
|
inline bool PKCS12Container::hasX509Certificate() const
|
||||||
|
{
|
||||||
|
return _pX509Cert.get() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const X509Certificate & PKCS12Container::getX509Certificate() const
|
||||||
|
{
|
||||||
|
if (!hasX509Certificate())
|
||||||
|
throw NotFoundException("PKCS12Container X509 certificate");
|
||||||
|
return *_pX509Cert;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const std::string & PKCS12Container::getFriendlyName() const
|
||||||
|
{
|
||||||
|
return _pkcsFriendlyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const PKCS12Container::CAList & PKCS12Container::getCACerts() const
|
||||||
|
{
|
||||||
|
return _caCertList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const PKCS12Container::CANameList & PKCS12Container::getFriendlyNamesCA() const
|
||||||
|
{
|
||||||
|
return _caCertNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool PKCS12Container::hasKey() const
|
||||||
|
{
|
||||||
|
return _pKey != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline EVPPKey PKCS12Container::getKey() const
|
||||||
|
{
|
||||||
|
return EVPPKey(_pKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool PKCS12Container::hasX509Certificate() const
|
|
||||||
{
|
|
||||||
return _pX509Cert.get() != 0;
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
inline const X509Certificate& PKCS12Container::getX509Certificate() const
|
|
||||||
{
|
|
||||||
if (!hasX509Certificate())
|
|
||||||
throw NotFoundException("PKCS12Container X509 certificate");
|
|
||||||
return *_pX509Cert;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& PKCS12Container::getFriendlyName() const
|
|
||||||
{
|
|
||||||
return _pkcsFriendlyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const PKCS12Container::CAList& PKCS12Container::getCACerts() const
|
|
||||||
{
|
|
||||||
return _caCertList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const PKCS12Container::CANameList& PKCS12Container::getFriendlyNamesCA() const
|
|
||||||
{
|
|
||||||
return _caCertNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool PKCS12Container::hasKey() const
|
|
||||||
{
|
|
||||||
return _pKey != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline EVPPKey PKCS12Container::getKey() const
|
|
||||||
{
|
|
||||||
return EVPPKey(_pKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_PKCS12Container_INCLUDED
|
#endif // Crypto_PKCS12Container_INCLUDED
|
||||||
|
@ -18,60 +18,63 @@
|
|||||||
#define Crypto_RSACipherImpl_INCLUDED
|
#define Crypto_RSACipherImpl_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Crypto/Crypto.h"
|
|
||||||
#include "Poco/Crypto/Cipher.h"
|
|
||||||
#include "Poco/Crypto/RSAKey.h"
|
|
||||||
#include "Poco/Crypto/OpenSSLInitializer.h"
|
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
#include "Poco/Crypto/Cipher.h"
|
||||||
|
#include "Poco/Crypto/Crypto.h"
|
||||||
|
#include "Poco/Crypto/OpenSSLInitializer.h"
|
||||||
|
#include "Poco/Crypto/RSAKey.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class RSACipherImpl: public Cipher
|
|
||||||
/// An implementation of the Cipher class for
|
|
||||||
/// asymmetric (public-private key) encryption
|
|
||||||
/// based on the the RSA algorithm in OpenSSL's
|
|
||||||
/// crypto library.
|
|
||||||
///
|
|
||||||
/// Encryption is using the public key, decryption
|
|
||||||
/// requires the private key.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Crypto
|
||||||
RSACipherImpl(const RSAKey& key, RSAPaddingMode paddingMode);
|
|
||||||
/// Creates a new RSACipherImpl object for the given RSAKey
|
|
||||||
/// and using the given padding mode.
|
|
||||||
|
|
||||||
virtual ~RSACipherImpl();
|
|
||||||
/// Destroys the RSACipherImpl.
|
|
||||||
|
|
||||||
const std::string& name() const;
|
|
||||||
/// Returns the name of the Cipher.
|
|
||||||
|
|
||||||
CryptoTransform* createEncryptor();
|
|
||||||
/// Creates an encryptor object.
|
|
||||||
|
|
||||||
CryptoTransform* createDecryptor();
|
|
||||||
/// Creates a decryptor object.
|
|
||||||
|
|
||||||
private:
|
|
||||||
RSAKey _key;
|
|
||||||
RSAPaddingMode _paddingMode;
|
|
||||||
OpenSSLInitializer _openSSLInitializer;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Inlines
|
|
||||||
//
|
|
||||||
inline const std::string& RSACipherImpl::name() const
|
|
||||||
{
|
{
|
||||||
return _key.name();
|
|
||||||
|
|
||||||
|
class RSACipherImpl : public Cipher
|
||||||
|
/// An implementation of the Cipher class for
|
||||||
|
/// asymmetric (public-private key) encryption
|
||||||
|
/// based on the the RSA algorithm in OpenSSL's
|
||||||
|
/// crypto library.
|
||||||
|
///
|
||||||
|
/// Encryption is using the public key, decryption
|
||||||
|
/// requires the private key.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RSACipherImpl(const RSAKey & key, RSAPaddingMode paddingMode);
|
||||||
|
/// Creates a new RSACipherImpl object for the given RSAKey
|
||||||
|
/// and using the given padding mode.
|
||||||
|
|
||||||
|
virtual ~RSACipherImpl();
|
||||||
|
/// Destroys the RSACipherImpl.
|
||||||
|
|
||||||
|
const std::string & name() const;
|
||||||
|
/// Returns the name of the Cipher.
|
||||||
|
|
||||||
|
CryptoTransform * createEncryptor();
|
||||||
|
/// Creates an encryptor object.
|
||||||
|
|
||||||
|
CryptoTransform * createDecryptor();
|
||||||
|
/// Creates a decryptor object.
|
||||||
|
|
||||||
|
private:
|
||||||
|
RSAKey _key;
|
||||||
|
RSAPaddingMode _paddingMode;
|
||||||
|
OpenSSLInitializer _openSSLInitializer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inlines
|
||||||
|
//
|
||||||
|
inline const std::string & RSACipherImpl::name() const
|
||||||
|
{
|
||||||
|
return _key.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_RSACipherImpl_INCLUDED
|
#endif // Crypto_RSACipherImpl_INCLUDED
|
||||||
|
@ -18,94 +18,97 @@
|
|||||||
#define Crypto_RSADigestEngine_INCLUDED
|
#define Crypto_RSADigestEngine_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Crypto/Crypto.h"
|
|
||||||
#include "Poco/Crypto/RSAKey.h"
|
|
||||||
#include "Poco/DigestEngine.h"
|
|
||||||
#include "Poco/Crypto/DigestEngine.h"
|
|
||||||
#include <istream>
|
#include <istream>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include "Poco/Crypto/Crypto.h"
|
||||||
|
#include "Poco/Crypto/DigestEngine.h"
|
||||||
|
#include "Poco/Crypto/RSAKey.h"
|
||||||
|
#include "Poco/DigestEngine.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
{
|
||||||
|
namespace Crypto
|
||||||
|
|
||||||
class Crypto_API RSADigestEngine: public Poco::DigestEngine
|
|
||||||
/// This class implements a Poco::DigestEngine that can be
|
|
||||||
/// used to compute a secure digital signature.
|
|
||||||
///
|
|
||||||
/// First another Poco::Crypto::DigestEngine is created and
|
|
||||||
/// used to compute a cryptographic hash of the data to be
|
|
||||||
/// signed. Then, the hash value is encrypted, using
|
|
||||||
/// the RSA private key.
|
|
||||||
///
|
|
||||||
/// To verify a signature, pass it to the verify()
|
|
||||||
/// member function. It will decrypt the signature
|
|
||||||
/// using the RSA public key and compare the resulting
|
|
||||||
/// hash with the actual hash of the data.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
enum DigestType
|
|
||||||
{
|
|
||||||
DIGEST_MD5,
|
|
||||||
DIGEST_SHA1
|
|
||||||
};
|
|
||||||
|
|
||||||
//@ deprecated
|
|
||||||
RSADigestEngine(const RSAKey& key, DigestType digestType = DIGEST_SHA1);
|
|
||||||
/// Creates the RSADigestEngine with the given RSA key,
|
|
||||||
/// using the MD5 or SHA-1 hash algorithm.
|
|
||||||
/// Kept for backward compatibility
|
|
||||||
|
|
||||||
RSADigestEngine(const RSAKey& key, const std::string &name);
|
|
||||||
/// Creates the RSADigestEngine with the given RSA key,
|
|
||||||
/// using the hash algorithm with the given name
|
|
||||||
/// (e.g., "MD5", "SHA1", "SHA256", "SHA512", etc.).
|
|
||||||
/// See the OpenSSL documentation for a list of supported digest algorithms.
|
|
||||||
///
|
|
||||||
/// Throws a Poco::NotFoundException if no algorithm with the given name exists.
|
|
||||||
|
|
||||||
~RSADigestEngine();
|
|
||||||
/// Destroys the RSADigestEngine.
|
|
||||||
|
|
||||||
std::size_t digestLength() const;
|
|
||||||
/// Returns the length of the digest in bytes.
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
/// Resets the engine so that a new
|
|
||||||
/// digest can be computed.
|
|
||||||
|
|
||||||
const DigestEngine::Digest& digest();
|
|
||||||
/// Finishes the computation of the digest
|
|
||||||
/// (the first time it's called) and
|
|
||||||
/// returns the message digest.
|
|
||||||
///
|
|
||||||
/// Can be called multiple times.
|
|
||||||
|
|
||||||
const DigestEngine::Digest& signature();
|
|
||||||
/// Signs the digest using the RSA algorithm
|
|
||||||
/// and the private key (the first time it's
|
|
||||||
/// called) and returns the result.
|
|
||||||
///
|
|
||||||
/// Can be called multiple times.
|
|
||||||
|
|
||||||
bool verify(const DigestEngine::Digest& signature);
|
|
||||||
/// Verifies the data against the signature.
|
|
||||||
///
|
|
||||||
/// Returns true if the signature can be verified, false otherwise.
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void updateImpl(const void* data, std::size_t length);
|
|
||||||
|
|
||||||
private:
|
|
||||||
RSAKey _key;
|
|
||||||
Poco::Crypto::DigestEngine _engine;
|
|
||||||
Poco::DigestEngine::Digest _digest;
|
|
||||||
Poco::DigestEngine::Digest _signature;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
class Crypto_API RSADigestEngine : public Poco::DigestEngine
|
||||||
|
/// This class implements a Poco::DigestEngine that can be
|
||||||
|
/// used to compute a secure digital signature.
|
||||||
|
///
|
||||||
|
/// First another Poco::Crypto::DigestEngine is created and
|
||||||
|
/// used to compute a cryptographic hash of the data to be
|
||||||
|
/// signed. Then, the hash value is encrypted, using
|
||||||
|
/// the RSA private key.
|
||||||
|
///
|
||||||
|
/// To verify a signature, pass it to the verify()
|
||||||
|
/// member function. It will decrypt the signature
|
||||||
|
/// using the RSA public key and compare the resulting
|
||||||
|
/// hash with the actual hash of the data.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum DigestType
|
||||||
|
{
|
||||||
|
DIGEST_MD5,
|
||||||
|
DIGEST_SHA1
|
||||||
|
};
|
||||||
|
|
||||||
|
//@ deprecated
|
||||||
|
RSADigestEngine(const RSAKey & key, DigestType digestType = DIGEST_SHA1);
|
||||||
|
/// Creates the RSADigestEngine with the given RSA key,
|
||||||
|
/// using the MD5 or SHA-1 hash algorithm.
|
||||||
|
/// Kept for backward compatibility
|
||||||
|
|
||||||
|
RSADigestEngine(const RSAKey & key, const std::string & name);
|
||||||
|
/// Creates the RSADigestEngine with the given RSA key,
|
||||||
|
/// using the hash algorithm with the given name
|
||||||
|
/// (e.g., "MD5", "SHA1", "SHA256", "SHA512", etc.).
|
||||||
|
/// See the OpenSSL documentation for a list of supported digest algorithms.
|
||||||
|
///
|
||||||
|
/// Throws a Poco::NotFoundException if no algorithm with the given name exists.
|
||||||
|
|
||||||
|
~RSADigestEngine();
|
||||||
|
/// Destroys the RSADigestEngine.
|
||||||
|
|
||||||
|
std::size_t digestLength() const;
|
||||||
|
/// Returns the length of the digest in bytes.
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
/// Resets the engine so that a new
|
||||||
|
/// digest can be computed.
|
||||||
|
|
||||||
|
const DigestEngine::Digest & digest();
|
||||||
|
/// Finishes the computation of the digest
|
||||||
|
/// (the first time it's called) and
|
||||||
|
/// returns the message digest.
|
||||||
|
///
|
||||||
|
/// Can be called multiple times.
|
||||||
|
|
||||||
|
const DigestEngine::Digest & signature();
|
||||||
|
/// Signs the digest using the RSA algorithm
|
||||||
|
/// and the private key (the first time it's
|
||||||
|
/// called) and returns the result.
|
||||||
|
///
|
||||||
|
/// Can be called multiple times.
|
||||||
|
|
||||||
|
bool verify(const DigestEngine::Digest & signature);
|
||||||
|
/// Verifies the data against the signature.
|
||||||
|
///
|
||||||
|
/// Returns true if the signature can be verified, false otherwise.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateImpl(const void * data, std::size_t length);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RSAKey _key;
|
||||||
|
Poco::Crypto::DigestEngine _engine;
|
||||||
|
Poco::DigestEngine::Digest _digest;
|
||||||
|
Poco::DigestEngine::Digest _signature;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_RSADigestEngine_INCLUDED
|
#endif // Crypto_RSADigestEngine_INCLUDED
|
||||||
|
@ -23,103 +23,102 @@
|
|||||||
#include "Poco/Crypto/RSAKeyImpl.h"
|
#include "Poco/Crypto/RSAKeyImpl.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class X509Certificate;
|
|
||||||
class PKCS12Container;
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API RSAKey : public KeyPair
|
|
||||||
/// This class stores an RSA key pair, consisting
|
|
||||||
/// of private and public key. Storage of the private
|
|
||||||
/// key is optional.
|
|
||||||
///
|
|
||||||
/// If a private key is available, the RSAKey can be
|
|
||||||
/// used for decrypting data (encrypted with the public key)
|
|
||||||
/// or computing secure digital signatures.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Crypto
|
||||||
enum KeyLength
|
|
||||||
{
|
|
||||||
KL_512 = 512,
|
|
||||||
KL_1024 = 1024,
|
|
||||||
KL_2048 = 2048,
|
|
||||||
KL_4096 = 4096
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Exponent
|
|
||||||
{
|
|
||||||
EXP_SMALL = 0,
|
|
||||||
EXP_LARGE
|
|
||||||
};
|
|
||||||
|
|
||||||
RSAKey(const EVPPKey& key);
|
|
||||||
/// Constructs ECKeyImpl by extracting the EC key.
|
|
||||||
|
|
||||||
RSAKey(const X509Certificate& cert);
|
|
||||||
/// Extracts the RSA public key from the given certificate.
|
|
||||||
|
|
||||||
RSAKey(const PKCS12Container& cert);
|
|
||||||
/// Extracts the RSA private key from the given certificate.
|
|
||||||
|
|
||||||
RSAKey(KeyLength keyLength, Exponent exp);
|
|
||||||
/// Creates the RSAKey. Creates a new public/private keypair using the given parameters.
|
|
||||||
/// Can be used to sign data and verify signatures.
|
|
||||||
|
|
||||||
RSAKey(const std::string& publicKeyFile,
|
|
||||||
const std::string& privateKeyFile = "",
|
|
||||||
const std::string& privateKeyPassphrase = "");
|
|
||||||
/// Creates the RSAKey, by reading public and private key from the given files and
|
|
||||||
/// using the given passphrase for the private key.
|
|
||||||
///
|
|
||||||
/// Cannot be used for signing or decryption unless a private key is available.
|
|
||||||
///
|
|
||||||
/// If a private key is specified, you don't need to specify a public key file.
|
|
||||||
/// OpenSSL will auto-create the public key from the private key.
|
|
||||||
|
|
||||||
RSAKey(std::istream* pPublicKeyStream,
|
|
||||||
std::istream* pPrivateKeyStream = 0,
|
|
||||||
const std::string& privateKeyPassphrase = "");
|
|
||||||
/// Creates the RSAKey, by reading public and private key from the given streams and
|
|
||||||
/// using the given passphrase for the private key.
|
|
||||||
///
|
|
||||||
/// Cannot be used for signing or decryption unless a private key is available.
|
|
||||||
///
|
|
||||||
/// If a private key is specified, you don't need to specify a public key file.
|
|
||||||
/// OpenSSL will auto-create the public key from the private key.
|
|
||||||
|
|
||||||
~RSAKey();
|
|
||||||
/// Destroys the RSAKey.
|
|
||||||
|
|
||||||
RSAKeyImpl::ByteVec modulus() const;
|
|
||||||
/// Returns the RSA modulus.
|
|
||||||
|
|
||||||
RSAKeyImpl::ByteVec encryptionExponent() const;
|
|
||||||
/// Returns the RSA encryption exponent.
|
|
||||||
|
|
||||||
RSAKeyImpl::ByteVec decryptionExponent() const;
|
|
||||||
/// Returns the RSA decryption exponent.
|
|
||||||
|
|
||||||
RSAKeyImpl::Ptr impl() const;
|
|
||||||
/// Returns the impl object.
|
|
||||||
|
|
||||||
private:
|
|
||||||
RSAKeyImpl::Ptr _pImpl;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline RSAKeyImpl::Ptr RSAKey::impl() const
|
|
||||||
{
|
{
|
||||||
return _pImpl;
|
|
||||||
|
|
||||||
|
class X509Certificate;
|
||||||
|
class PKCS12Container;
|
||||||
|
|
||||||
|
|
||||||
|
class Crypto_API RSAKey : public KeyPair
|
||||||
|
/// This class stores an RSA key pair, consisting
|
||||||
|
/// of private and public key. Storage of the private
|
||||||
|
/// key is optional.
|
||||||
|
///
|
||||||
|
/// If a private key is available, the RSAKey can be
|
||||||
|
/// used for decrypting data (encrypted with the public key)
|
||||||
|
/// or computing secure digital signatures.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum KeyLength
|
||||||
|
{
|
||||||
|
KL_512 = 512,
|
||||||
|
KL_1024 = 1024,
|
||||||
|
KL_2048 = 2048,
|
||||||
|
KL_4096 = 4096
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Exponent
|
||||||
|
{
|
||||||
|
EXP_SMALL = 0,
|
||||||
|
EXP_LARGE
|
||||||
|
};
|
||||||
|
|
||||||
|
RSAKey(const EVPPKey & key);
|
||||||
|
/// Constructs ECKeyImpl by extracting the EC key.
|
||||||
|
|
||||||
|
RSAKey(const X509Certificate & cert);
|
||||||
|
/// Extracts the RSA public key from the given certificate.
|
||||||
|
|
||||||
|
RSAKey(const PKCS12Container & cert);
|
||||||
|
/// Extracts the RSA private key from the given certificate.
|
||||||
|
|
||||||
|
RSAKey(KeyLength keyLength, Exponent exp);
|
||||||
|
/// Creates the RSAKey. Creates a new public/private keypair using the given parameters.
|
||||||
|
/// Can be used to sign data and verify signatures.
|
||||||
|
|
||||||
|
RSAKey(const std::string & publicKeyFile, const std::string & privateKeyFile = "", const std::string & privateKeyPassphrase = "");
|
||||||
|
/// Creates the RSAKey, by reading public and private key from the given files and
|
||||||
|
/// using the given passphrase for the private key.
|
||||||
|
///
|
||||||
|
/// Cannot be used for signing or decryption unless a private key is available.
|
||||||
|
///
|
||||||
|
/// If a private key is specified, you don't need to specify a public key file.
|
||||||
|
/// OpenSSL will auto-create the public key from the private key.
|
||||||
|
|
||||||
|
RSAKey(std::istream * pPublicKeyStream, std::istream * pPrivateKeyStream = 0, const std::string & privateKeyPassphrase = "");
|
||||||
|
/// Creates the RSAKey, by reading public and private key from the given streams and
|
||||||
|
/// using the given passphrase for the private key.
|
||||||
|
///
|
||||||
|
/// Cannot be used for signing or decryption unless a private key is available.
|
||||||
|
///
|
||||||
|
/// If a private key is specified, you don't need to specify a public key file.
|
||||||
|
/// OpenSSL will auto-create the public key from the private key.
|
||||||
|
|
||||||
|
~RSAKey();
|
||||||
|
/// Destroys the RSAKey.
|
||||||
|
|
||||||
|
RSAKeyImpl::ByteVec modulus() const;
|
||||||
|
/// Returns the RSA modulus.
|
||||||
|
|
||||||
|
RSAKeyImpl::ByteVec encryptionExponent() const;
|
||||||
|
/// Returns the RSA encryption exponent.
|
||||||
|
|
||||||
|
RSAKeyImpl::ByteVec decryptionExponent() const;
|
||||||
|
/// Returns the RSA decryption exponent.
|
||||||
|
|
||||||
|
RSAKeyImpl::Ptr impl() const;
|
||||||
|
/// Returns the impl object.
|
||||||
|
|
||||||
|
private:
|
||||||
|
RSAKeyImpl::Ptr _pImpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline RSAKeyImpl::Ptr RSAKey::impl() const
|
||||||
|
{
|
||||||
|
return _pImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_RSAKey_INCLUDED
|
#endif // Crypto_RSAKey_INCLUDED
|
@ -18,15 +18,15 @@
|
|||||||
#define Crypto_RSAKeyImplImpl_INCLUDED
|
#define Crypto_RSAKeyImplImpl_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <istream>
|
||||||
|
#include <ostream>
|
||||||
|
#include <vector>
|
||||||
|
#include "Poco/AutoPtr.h"
|
||||||
#include "Poco/Crypto/Crypto.h"
|
#include "Poco/Crypto/Crypto.h"
|
||||||
#include "Poco/Crypto/EVPPKey.h"
|
#include "Poco/Crypto/EVPPKey.h"
|
||||||
#include "Poco/Crypto/KeyPairImpl.h"
|
#include "Poco/Crypto/KeyPairImpl.h"
|
||||||
#include "Poco/Crypto/OpenSSLInitializer.h"
|
#include "Poco/Crypto/OpenSSLInitializer.h"
|
||||||
#include "Poco/RefCountedObject.h"
|
#include "Poco/RefCountedObject.h"
|
||||||
#include "Poco/AutoPtr.h"
|
|
||||||
#include <istream>
|
|
||||||
#include <ostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
struct bignum_st;
|
struct bignum_st;
|
||||||
@ -35,107 +35,108 @@ typedef struct bignum_st BIGNUM;
|
|||||||
typedef struct rsa_st RSA;
|
typedef struct rsa_st RSA;
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class X509Certificate;
|
|
||||||
class PKCS12Container;
|
|
||||||
|
|
||||||
|
|
||||||
class RSAKeyImpl: public KeyPairImpl
|
|
||||||
/// class RSAKeyImpl
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Crypto
|
||||||
typedef Poco::AutoPtr<RSAKeyImpl> Ptr;
|
|
||||||
typedef std::vector<unsigned char> ByteVec;
|
|
||||||
|
|
||||||
RSAKeyImpl(const EVPPKey& key);
|
|
||||||
/// Constructs ECKeyImpl by extracting the EC key.
|
|
||||||
|
|
||||||
RSAKeyImpl(const X509Certificate& cert);
|
|
||||||
/// Extracts the RSA public key from the given certificate.
|
|
||||||
|
|
||||||
RSAKeyImpl(const PKCS12Container& cert);
|
|
||||||
/// Extracts the EC private key from the given certificate.
|
|
||||||
|
|
||||||
RSAKeyImpl(int keyLength, unsigned long exponent);
|
|
||||||
/// Creates the RSAKey. Creates a new public/private keypair using the given parameters.
|
|
||||||
/// Can be used to sign data and verify signatures.
|
|
||||||
|
|
||||||
RSAKeyImpl(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase);
|
|
||||||
/// Creates the RSAKey, by reading public and private key from the given files and
|
|
||||||
/// using the given passphrase for the private key. Can only by used for signing if
|
|
||||||
/// a private key is available.
|
|
||||||
|
|
||||||
RSAKeyImpl(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase);
|
|
||||||
/// Creates the RSAKey. Can only by used for signing if pPrivKey
|
|
||||||
/// is not null. If a private key file is specified, you don't need to
|
|
||||||
/// specify a public key file. OpenSSL will auto-create it from the private key.
|
|
||||||
|
|
||||||
~RSAKeyImpl();
|
|
||||||
/// Destroys the RSAKeyImpl.
|
|
||||||
|
|
||||||
RSA* getRSA();
|
|
||||||
/// Returns the OpenSSL RSA object.
|
|
||||||
|
|
||||||
const RSA* getRSA() const;
|
|
||||||
/// Returns the OpenSSL RSA object.
|
|
||||||
|
|
||||||
int size() const;
|
|
||||||
/// Returns the RSA modulus size.
|
|
||||||
|
|
||||||
ByteVec modulus() const;
|
|
||||||
/// Returns the RSA modulus.
|
|
||||||
|
|
||||||
ByteVec encryptionExponent() const;
|
|
||||||
/// Returns the RSA encryption exponent.
|
|
||||||
|
|
||||||
ByteVec decryptionExponent() const;
|
|
||||||
/// Returns the RSA decryption exponent.
|
|
||||||
|
|
||||||
void save(const std::string& publicKeyFile,
|
|
||||||
const std::string& privateKeyFile = "",
|
|
||||||
const std::string& privateKeyPassphrase = "") const;
|
|
||||||
/// Exports the public and private keys to the given files.
|
|
||||||
///
|
|
||||||
/// If an empty filename is specified, the corresponding key
|
|
||||||
/// is not exported.
|
|
||||||
|
|
||||||
void save(std::ostream* pPublicKeyStream,
|
|
||||||
std::ostream* pPrivateKeyStream = 0,
|
|
||||||
const std::string& privateKeyPassphrase = "") const;
|
|
||||||
/// Exports the public and private key to the given streams.
|
|
||||||
///
|
|
||||||
/// If a null pointer is passed for a stream, the corresponding
|
|
||||||
/// key is not exported.
|
|
||||||
|
|
||||||
private:
|
|
||||||
RSAKeyImpl();
|
|
||||||
|
|
||||||
void freeRSA();
|
|
||||||
static ByteVec convertToByteVec(const BIGNUM* bn);
|
|
||||||
|
|
||||||
RSA* _pRSA;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline RSA* RSAKeyImpl::getRSA()
|
|
||||||
{
|
{
|
||||||
return _pRSA;
|
|
||||||
|
|
||||||
|
class X509Certificate;
|
||||||
|
class PKCS12Container;
|
||||||
|
|
||||||
|
|
||||||
|
class RSAKeyImpl : public KeyPairImpl
|
||||||
|
/// class RSAKeyImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Poco::AutoPtr<RSAKeyImpl> Ptr;
|
||||||
|
typedef std::vector<unsigned char> ByteVec;
|
||||||
|
|
||||||
|
RSAKeyImpl(const EVPPKey & key);
|
||||||
|
/// Constructs ECKeyImpl by extracting the EC key.
|
||||||
|
|
||||||
|
RSAKeyImpl(const X509Certificate & cert);
|
||||||
|
/// Extracts the RSA public key from the given certificate.
|
||||||
|
|
||||||
|
RSAKeyImpl(const PKCS12Container & cert);
|
||||||
|
/// Extracts the EC private key from the given certificate.
|
||||||
|
|
||||||
|
RSAKeyImpl(int keyLength, unsigned long exponent);
|
||||||
|
/// Creates the RSAKey. Creates a new public/private keypair using the given parameters.
|
||||||
|
/// Can be used to sign data and verify signatures.
|
||||||
|
|
||||||
|
RSAKeyImpl(const std::string & publicKeyFile, const std::string & privateKeyFile, const std::string & privateKeyPassphrase);
|
||||||
|
/// Creates the RSAKey, by reading public and private key from the given files and
|
||||||
|
/// using the given passphrase for the private key. Can only by used for signing if
|
||||||
|
/// a private key is available.
|
||||||
|
|
||||||
|
RSAKeyImpl(std::istream * pPublicKeyStream, std::istream * pPrivateKeyStream, const std::string & privateKeyPassphrase);
|
||||||
|
/// Creates the RSAKey. Can only by used for signing if pPrivKey
|
||||||
|
/// is not null. If a private key file is specified, you don't need to
|
||||||
|
/// specify a public key file. OpenSSL will auto-create it from the private key.
|
||||||
|
|
||||||
|
~RSAKeyImpl();
|
||||||
|
/// Destroys the RSAKeyImpl.
|
||||||
|
|
||||||
|
RSA * getRSA();
|
||||||
|
/// Returns the OpenSSL RSA object.
|
||||||
|
|
||||||
|
const RSA * getRSA() const;
|
||||||
|
/// Returns the OpenSSL RSA object.
|
||||||
|
|
||||||
|
int size() const;
|
||||||
|
/// Returns the RSA modulus size.
|
||||||
|
|
||||||
|
ByteVec modulus() const;
|
||||||
|
/// Returns the RSA modulus.
|
||||||
|
|
||||||
|
ByteVec encryptionExponent() const;
|
||||||
|
/// Returns the RSA encryption exponent.
|
||||||
|
|
||||||
|
ByteVec decryptionExponent() const;
|
||||||
|
/// Returns the RSA decryption exponent.
|
||||||
|
|
||||||
|
void save(const std::string & publicKeyFile, const std::string & privateKeyFile = "", const std::string & privateKeyPassphrase = "")
|
||||||
|
const;
|
||||||
|
/// Exports the public and private keys to the given files.
|
||||||
|
///
|
||||||
|
/// If an empty filename is specified, the corresponding key
|
||||||
|
/// is not exported.
|
||||||
|
|
||||||
|
void
|
||||||
|
save(std::ostream * pPublicKeyStream, std::ostream * pPrivateKeyStream = 0, const std::string & privateKeyPassphrase = "") const;
|
||||||
|
/// Exports the public and private key to the given streams.
|
||||||
|
///
|
||||||
|
/// If a null pointer is passed for a stream, the corresponding
|
||||||
|
/// key is not exported.
|
||||||
|
|
||||||
|
private:
|
||||||
|
RSAKeyImpl();
|
||||||
|
|
||||||
|
void freeRSA();
|
||||||
|
static ByteVec convertToByteVec(const BIGNUM * bn);
|
||||||
|
|
||||||
|
RSA * _pRSA;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline RSA * RSAKeyImpl::getRSA()
|
||||||
|
{
|
||||||
|
return _pRSA;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const RSA * RSAKeyImpl::getRSA() const
|
||||||
|
{
|
||||||
|
return _pRSA;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
inline const RSA* RSAKeyImpl::getRSA() const
|
|
||||||
{
|
|
||||||
return _pRSA;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_RSAKeyImplImpl_INCLUDED
|
#endif // Crypto_RSAKeyImplImpl_INCLUDED
|
@ -18,228 +18,231 @@
|
|||||||
#define Crypto_X509Certificate_INCLUDED
|
#define Crypto_X509Certificate_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <istream>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
#include "Poco/Crypto/Crypto.h"
|
#include "Poco/Crypto/Crypto.h"
|
||||||
#include "Poco/Crypto/OpenSSLInitializer.h"
|
#include "Poco/Crypto/OpenSSLInitializer.h"
|
||||||
#include "Poco/DateTime.h"
|
#include "Poco/DateTime.h"
|
||||||
#include "Poco/SharedPtr.h"
|
#include "Poco/SharedPtr.h"
|
||||||
#include <vector>
|
|
||||||
#include <set>
|
|
||||||
#include <istream>
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Crypto {
|
|
||||||
|
|
||||||
|
|
||||||
class Crypto_API X509Certificate
|
|
||||||
/// This class represents a X509 Certificate.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Crypto
|
||||||
typedef std::vector<X509Certificate> List;
|
|
||||||
|
|
||||||
enum NID
|
|
||||||
/// Name identifier for extracting information from
|
|
||||||
/// a certificate subject's or issuer's distinguished name.
|
|
||||||
{
|
|
||||||
NID_COMMON_NAME = 13,
|
|
||||||
NID_COUNTRY = 14,
|
|
||||||
NID_LOCALITY_NAME = 15,
|
|
||||||
NID_STATE_OR_PROVINCE = 16,
|
|
||||||
NID_ORGANIZATION_NAME = 17,
|
|
||||||
NID_ORGANIZATION_UNIT_NAME = 18,
|
|
||||||
NID_PKCS9_EMAIL_ADDRESS = 48,
|
|
||||||
NID_SERIAL_NUMBER = 105
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit X509Certificate(std::istream& istr);
|
|
||||||
/// Creates the X509Certificate object by reading
|
|
||||||
/// a certificate in PEM format from a stream.
|
|
||||||
|
|
||||||
explicit X509Certificate(const std::string& path);
|
|
||||||
/// Creates the X509Certificate object by reading
|
|
||||||
/// a certificate in PEM format from a file.
|
|
||||||
|
|
||||||
explicit X509Certificate(X509* pCert);
|
|
||||||
/// Creates the X509Certificate from an existing
|
|
||||||
/// OpenSSL certificate. Ownership is taken of
|
|
||||||
/// the certificate.
|
|
||||||
|
|
||||||
X509Certificate(X509* pCert, bool shared);
|
|
||||||
/// Creates the X509Certificate from an existing
|
|
||||||
/// OpenSSL certificate. Ownership is taken of
|
|
||||||
/// the certificate. If shared is true, the
|
|
||||||
/// certificate's reference count is incremented.
|
|
||||||
|
|
||||||
X509Certificate(const X509Certificate& cert);
|
|
||||||
/// Creates the certificate by copying another one.
|
|
||||||
|
|
||||||
X509Certificate& operator = (const X509Certificate& cert);
|
|
||||||
/// Assigns a certificate.
|
|
||||||
|
|
||||||
void swap(X509Certificate& cert);
|
|
||||||
/// Exchanges the certificate with another one.
|
|
||||||
|
|
||||||
~X509Certificate();
|
|
||||||
/// Destroys the X509Certificate.
|
|
||||||
|
|
||||||
long version() const;
|
|
||||||
/// Returns the version of the certificate.
|
|
||||||
|
|
||||||
const std::string& serialNumber() const;
|
|
||||||
/// Returns the certificate serial number as a
|
|
||||||
/// string in decimal encoding.
|
|
||||||
|
|
||||||
const std::string& issuerName() const;
|
|
||||||
/// Returns the certificate issuer's distinguished name.
|
|
||||||
|
|
||||||
std::string issuerName(NID nid) const;
|
|
||||||
/// Extracts the information specified by the given
|
|
||||||
/// NID (name identifier) from the certificate issuer's
|
|
||||||
/// distinguished name.
|
|
||||||
|
|
||||||
const std::string& subjectName() const;
|
|
||||||
/// Returns the certificate subject's distinguished name.
|
|
||||||
|
|
||||||
std::string subjectName(NID nid) const;
|
|
||||||
/// Extracts the information specified by the given
|
|
||||||
/// NID (name identifier) from the certificate subject's
|
|
||||||
/// distinguished name.
|
|
||||||
|
|
||||||
std::string commonName() const;
|
|
||||||
/// Returns the common name stored in the certificate
|
|
||||||
/// subject's distinguished name.
|
|
||||||
|
|
||||||
void extractNames(std::string& commonName, std::set<std::string>& domainNames) const;
|
|
||||||
/// Extracts the common name and the alias domain names from the
|
|
||||||
/// certificate.
|
|
||||||
|
|
||||||
Poco::DateTime validFrom() const;
|
|
||||||
/// Returns the date and time the certificate is valid from.
|
|
||||||
|
|
||||||
Poco::DateTime expiresOn() const;
|
|
||||||
/// Returns the date and time the certificate expires.
|
|
||||||
|
|
||||||
void save(std::ostream& stream) const;
|
|
||||||
/// Writes the certificate to the given stream.
|
|
||||||
/// The certificate is written in PEM format.
|
|
||||||
|
|
||||||
void save(const std::string& path) const;
|
|
||||||
/// Writes the certificate to the file given by path.
|
|
||||||
/// The certificate is written in PEM format.
|
|
||||||
|
|
||||||
bool issuedBy(const X509Certificate& issuerCertificate) const;
|
|
||||||
/// Checks whether the certificate has been issued by
|
|
||||||
/// the issuer given by issuerCertificate. This can be
|
|
||||||
/// used to validate a certificate chain.
|
|
||||||
///
|
|
||||||
/// Verifies if the certificate has been signed with the
|
|
||||||
/// issuer's private key, using the public key from the issuer
|
|
||||||
/// certificate.
|
|
||||||
///
|
|
||||||
/// Returns true if verification against the issuer certificate
|
|
||||||
/// was successful, false otherwise.
|
|
||||||
|
|
||||||
bool equals(const X509Certificate& otherCertificate) const;
|
|
||||||
/// Checks whether the certificate is equal to
|
|
||||||
/// the other certificate, by comparing the hashes
|
|
||||||
/// of both certificates.
|
|
||||||
///
|
|
||||||
/// Returns true if both certificates are identical,
|
|
||||||
/// otherwise false.
|
|
||||||
|
|
||||||
const X509* certificate() const;
|
|
||||||
/// Returns the underlying OpenSSL certificate.
|
|
||||||
|
|
||||||
X509* dup() const;
|
|
||||||
/// Duplicates and returns the underlying OpenSSL certificate. Note that
|
|
||||||
/// the caller assumes responsibility for the lifecycle of the created
|
|
||||||
/// certificate.
|
|
||||||
|
|
||||||
std::string signatureAlgorithm() const;
|
|
||||||
/// Returns the certificate signature algorithm long name.
|
|
||||||
|
|
||||||
void print(std::ostream& out) const;
|
|
||||||
/// Prints the certificate information to ostream.
|
|
||||||
|
|
||||||
static List readPEM(const std::string& pemFileName);
|
|
||||||
/// Reads and returns a list of certificates from
|
|
||||||
/// the specified PEM file.
|
|
||||||
|
|
||||||
static void writePEM(const std::string& pemFileName, const List& list);
|
|
||||||
/// Writes the list of certificates to the specified PEM file.
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void load(std::istream& stream);
|
|
||||||
/// Loads the certificate from the given stream. The
|
|
||||||
/// certificate must be in PEM format.
|
|
||||||
|
|
||||||
void load(const std::string& path);
|
|
||||||
/// Loads the certificate from the given file. The
|
|
||||||
/// certificate must be in PEM format.
|
|
||||||
|
|
||||||
void init();
|
|
||||||
/// Extracts issuer and subject name from the certificate.
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
NAME_BUFFER_SIZE = 256
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string _issuerName;
|
|
||||||
std::string _subjectName;
|
|
||||||
std::string _serialNumber;
|
|
||||||
X509* _pCert;
|
|
||||||
OpenSSLInitializer _openSSLInitializer;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
inline long X509Certificate::version() const
|
|
||||||
{
|
{
|
||||||
// This is defined by standards (X.509 et al) to be
|
|
||||||
// one less than the certificate version.
|
|
||||||
// So, eg. a version 3 certificate will return 2.
|
class Crypto_API X509Certificate
|
||||||
return X509_get_version(_pCert) + 1;
|
/// This class represents a X509 Certificate.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::vector<X509Certificate> List;
|
||||||
|
|
||||||
|
enum NID
|
||||||
|
/// Name identifier for extracting information from
|
||||||
|
/// a certificate subject's or issuer's distinguished name.
|
||||||
|
{
|
||||||
|
NID_COMMON_NAME = 13,
|
||||||
|
NID_COUNTRY = 14,
|
||||||
|
NID_LOCALITY_NAME = 15,
|
||||||
|
NID_STATE_OR_PROVINCE = 16,
|
||||||
|
NID_ORGANIZATION_NAME = 17,
|
||||||
|
NID_ORGANIZATION_UNIT_NAME = 18,
|
||||||
|
NID_PKCS9_EMAIL_ADDRESS = 48,
|
||||||
|
NID_SERIAL_NUMBER = 105
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit X509Certificate(std::istream & istr);
|
||||||
|
/// Creates the X509Certificate object by reading
|
||||||
|
/// a certificate in PEM format from a stream.
|
||||||
|
|
||||||
|
explicit X509Certificate(const std::string & path);
|
||||||
|
/// Creates the X509Certificate object by reading
|
||||||
|
/// a certificate in PEM format from a file.
|
||||||
|
|
||||||
|
explicit X509Certificate(X509 * pCert);
|
||||||
|
/// Creates the X509Certificate from an existing
|
||||||
|
/// OpenSSL certificate. Ownership is taken of
|
||||||
|
/// the certificate.
|
||||||
|
|
||||||
|
X509Certificate(X509 * pCert, bool shared);
|
||||||
|
/// Creates the X509Certificate from an existing
|
||||||
|
/// OpenSSL certificate. Ownership is taken of
|
||||||
|
/// the certificate. If shared is true, the
|
||||||
|
/// certificate's reference count is incremented.
|
||||||
|
|
||||||
|
X509Certificate(const X509Certificate & cert);
|
||||||
|
/// Creates the certificate by copying another one.
|
||||||
|
|
||||||
|
X509Certificate & operator=(const X509Certificate & cert);
|
||||||
|
/// Assigns a certificate.
|
||||||
|
|
||||||
|
void swap(X509Certificate & cert);
|
||||||
|
/// Exchanges the certificate with another one.
|
||||||
|
|
||||||
|
~X509Certificate();
|
||||||
|
/// Destroys the X509Certificate.
|
||||||
|
|
||||||
|
long version() const;
|
||||||
|
/// Returns the version of the certificate.
|
||||||
|
|
||||||
|
const std::string & serialNumber() const;
|
||||||
|
/// Returns the certificate serial number as a
|
||||||
|
/// string in decimal encoding.
|
||||||
|
|
||||||
|
const std::string & issuerName() const;
|
||||||
|
/// Returns the certificate issuer's distinguished name.
|
||||||
|
|
||||||
|
std::string issuerName(NID nid) const;
|
||||||
|
/// Extracts the information specified by the given
|
||||||
|
/// NID (name identifier) from the certificate issuer's
|
||||||
|
/// distinguished name.
|
||||||
|
|
||||||
|
const std::string & subjectName() const;
|
||||||
|
/// Returns the certificate subject's distinguished name.
|
||||||
|
|
||||||
|
std::string subjectName(NID nid) const;
|
||||||
|
/// Extracts the information specified by the given
|
||||||
|
/// NID (name identifier) from the certificate subject's
|
||||||
|
/// distinguished name.
|
||||||
|
|
||||||
|
std::string commonName() const;
|
||||||
|
/// Returns the common name stored in the certificate
|
||||||
|
/// subject's distinguished name.
|
||||||
|
|
||||||
|
void extractNames(std::string & commonName, std::set<std::string> & domainNames) const;
|
||||||
|
/// Extracts the common name and the alias domain names from the
|
||||||
|
/// certificate.
|
||||||
|
|
||||||
|
Poco::DateTime validFrom() const;
|
||||||
|
/// Returns the date and time the certificate is valid from.
|
||||||
|
|
||||||
|
Poco::DateTime expiresOn() const;
|
||||||
|
/// Returns the date and time the certificate expires.
|
||||||
|
|
||||||
|
void save(std::ostream & stream) const;
|
||||||
|
/// Writes the certificate to the given stream.
|
||||||
|
/// The certificate is written in PEM format.
|
||||||
|
|
||||||
|
void save(const std::string & path) const;
|
||||||
|
/// Writes the certificate to the file given by path.
|
||||||
|
/// The certificate is written in PEM format.
|
||||||
|
|
||||||
|
bool issuedBy(const X509Certificate & issuerCertificate) const;
|
||||||
|
/// Checks whether the certificate has been issued by
|
||||||
|
/// the issuer given by issuerCertificate. This can be
|
||||||
|
/// used to validate a certificate chain.
|
||||||
|
///
|
||||||
|
/// Verifies if the certificate has been signed with the
|
||||||
|
/// issuer's private key, using the public key from the issuer
|
||||||
|
/// certificate.
|
||||||
|
///
|
||||||
|
/// Returns true if verification against the issuer certificate
|
||||||
|
/// was successful, false otherwise.
|
||||||
|
|
||||||
|
bool equals(const X509Certificate & otherCertificate) const;
|
||||||
|
/// Checks whether the certificate is equal to
|
||||||
|
/// the other certificate, by comparing the hashes
|
||||||
|
/// of both certificates.
|
||||||
|
///
|
||||||
|
/// Returns true if both certificates are identical,
|
||||||
|
/// otherwise false.
|
||||||
|
|
||||||
|
const X509 * certificate() const;
|
||||||
|
/// Returns the underlying OpenSSL certificate.
|
||||||
|
|
||||||
|
X509 * dup() const;
|
||||||
|
/// Duplicates and returns the underlying OpenSSL certificate. Note that
|
||||||
|
/// the caller assumes responsibility for the lifecycle of the created
|
||||||
|
/// certificate.
|
||||||
|
|
||||||
|
std::string signatureAlgorithm() const;
|
||||||
|
/// Returns the certificate signature algorithm long name.
|
||||||
|
|
||||||
|
void print(std::ostream & out) const;
|
||||||
|
/// Prints the certificate information to ostream.
|
||||||
|
|
||||||
|
static List readPEM(const std::string & pemFileName);
|
||||||
|
/// Reads and returns a list of certificates from
|
||||||
|
/// the specified PEM file.
|
||||||
|
|
||||||
|
static void writePEM(const std::string & pemFileName, const List & list);
|
||||||
|
/// Writes the list of certificates to the specified PEM file.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void load(std::istream & stream);
|
||||||
|
/// Loads the certificate from the given stream. The
|
||||||
|
/// certificate must be in PEM format.
|
||||||
|
|
||||||
|
void load(const std::string & path);
|
||||||
|
/// Loads the certificate from the given file. The
|
||||||
|
/// certificate must be in PEM format.
|
||||||
|
|
||||||
|
void init();
|
||||||
|
/// Extracts issuer and subject name from the certificate.
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
NAME_BUFFER_SIZE = 256
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string _issuerName;
|
||||||
|
std::string _subjectName;
|
||||||
|
std::string _serialNumber;
|
||||||
|
X509 * _pCert;
|
||||||
|
OpenSSLInitializer _openSSLInitializer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
inline long X509Certificate::version() const
|
||||||
|
{
|
||||||
|
// This is defined by standards (X.509 et al) to be
|
||||||
|
// one less than the certificate version.
|
||||||
|
// So, eg. a version 3 certificate will return 2.
|
||||||
|
return X509_get_version(_pCert) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const std::string & X509Certificate::serialNumber() const
|
||||||
|
{
|
||||||
|
return _serialNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const std::string & X509Certificate::issuerName() const
|
||||||
|
{
|
||||||
|
return _issuerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const std::string & X509Certificate::subjectName() const
|
||||||
|
{
|
||||||
|
return _subjectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const X509 * X509Certificate::certificate() const
|
||||||
|
{
|
||||||
|
return _pCert;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline X509 * X509Certificate::dup() const
|
||||||
|
{
|
||||||
|
return X509_dup(_pCert);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Crypto
|
||||||
|
|
||||||
inline const std::string& X509Certificate::serialNumber() const
|
|
||||||
{
|
|
||||||
return _serialNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& X509Certificate::issuerName() const
|
|
||||||
{
|
|
||||||
return _issuerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& X509Certificate::subjectName() const
|
|
||||||
{
|
|
||||||
return _subjectName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const X509* X509Certificate::certificate() const
|
|
||||||
{
|
|
||||||
return _pCert;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline X509* X509Certificate::dup() const
|
|
||||||
{
|
|
||||||
return X509_dup(_pCert);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Crypto
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Crypto_X509Certificate_INCLUDED
|
#endif // Crypto_X509Certificate_INCLUDED
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,79 +18,84 @@
|
|||||||
#define Data_ODBC_ConnectionHandle_INCLUDED
|
#define Data_ODBC_ConnectionHandle_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/ODBC/ODBC.h"
|
|
||||||
#include "Poco/Data/ODBC/EnvironmentHandle.h"
|
#include "Poco/Data/ODBC/EnvironmentHandle.h"
|
||||||
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sqltypes.h>
|
#include <sqltypes.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
namespace ODBC {
|
|
||||||
|
|
||||||
|
|
||||||
class ODBC_API ConnectionHandle
|
|
||||||
/// ODBC connection handle class
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline ConnectionHandle::operator const SQLHDBC& () const
|
|
||||||
{
|
{
|
||||||
return handle();
|
namespace ODBC
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
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
|
#endif
|
||||||
|
@ -18,79 +18,84 @@
|
|||||||
#define Data_ODBC_Connector_INCLUDED
|
#define Data_ODBC_Connector_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/ODBC/ODBC.h"
|
|
||||||
#include "Poco/Data/Connector.h"
|
#include "Poco/Data/Connector.h"
|
||||||
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
namespace ODBC {
|
|
||||||
|
|
||||||
|
|
||||||
class ODBC_API Connector: public Poco::Data::Connector
|
|
||||||
/// Connector instantiates SqLite SessionImpl objects.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
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;
|
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
|
||||||
|
|
||||||
inline bool Connector::stringBoundToLongVarChar()
|
|
||||||
{
|
|
||||||
return _bindStringToLongVarChar;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } } // namespace Poco::Data::ODBC
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_ODBC_Connector_INCLUDED
|
#endif // Data_ODBC_Connector_INCLUDED
|
||||||
|
@ -18,222 +18,203 @@
|
|||||||
#define Data_ODBC_Diagnostics_INCLUDED
|
#define Data_ODBC_Diagnostics_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/ODBC/ODBC.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <vector>
|
||||||
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
|
#include "Poco/Data/ODBC/Utility.h"
|
||||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sqlext.h>
|
#include <sqlext.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
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:
|
namespace Data
|
||||||
|
{
|
||||||
static const unsigned int SQL_STATE_SIZE = SQL_SQLSTATE_SIZE + 1;
|
namespace ODBC
|
||||||
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;
|
template <typename H, SQLSMALLINT handleType>
|
||||||
typedef Diagnostics<SQLHDBC, SQL_HANDLE_DBC> ConnectionDiagnostics;
|
class Diagnostics
|
||||||
typedef Diagnostics<SQLHSTMT, SQL_HANDLE_STMT> StatementDiagnostics;
|
/// Utility class providing functionality for retrieving ODBC diagnostic
|
||||||
typedef Diagnostics<SQLHDESC, SQL_HANDLE_DESC> DescriptorDiagnostics;
|
/// 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} } } // namespace Poco::Data::ODBC
|
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
|
#endif
|
||||||
|
@ -20,75 +20,80 @@
|
|||||||
|
|
||||||
#include "Poco/Data/ODBC/ODBC.h"
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sqltypes.h>
|
#include <sqltypes.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
namespace ODBC {
|
|
||||||
|
|
||||||
|
|
||||||
class ODBC_API EnvironmentHandle
|
|
||||||
/// ODBC environment handle class
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
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();
|
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
|
||||||
|
|
||||||
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
|
#endif
|
||||||
|
@ -18,107 +18,110 @@
|
|||||||
#define Data_ODBC_Error_INCLUDED
|
#define Data_ODBC_Error_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "Poco/Data/ODBC/Diagnostics.h"
|
||||||
#include "Poco/Data/ODBC/ODBC.h"
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
#include "Poco/Data/ODBC/Utility.h"
|
#include "Poco/Data/ODBC/Utility.h"
|
||||||
#include "Poco/Data/ODBC/Diagnostics.h"
|
|
||||||
#include "Poco/Format.h"
|
#include "Poco/Format.h"
|
||||||
#include <vector>
|
|
||||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sqlext.h>
|
#include <sqlext.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
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:
|
namespace Data
|
||||||
explicit Error(const H& handle) : _diagnostics(handle)
|
{
|
||||||
/// Creates the Error.
|
namespace ODBC
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
~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;
|
template <typename H, SQLSMALLINT handleType>
|
||||||
typedef Error<SQLHDBC, SQL_HANDLE_DBC> ConnectionError;
|
class Error
|
||||||
typedef Error<SQLHSTMT, SQL_HANDLE_STMT> StatementError;
|
/// Class encapsulating ODBC diagnostic record collection. Collection is generated
|
||||||
typedef Error<SQLHSTMT, SQL_HANDLE_DESC> DescriptorError;
|
/// 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} } } // namespace Poco::Data::ODBC
|
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
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,96 +18,97 @@
|
|||||||
#define 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/ConnectionHandle.h"
|
||||||
|
#include "Poco/Data/ODBC/EnvironmentHandle.h"
|
||||||
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
#include "Poco/Data/ODBC/ODBCException.h"
|
#include "Poco/Data/ODBC/ODBCException.h"
|
||||||
#include "Poco/Data/ODBC/Utility.h"
|
#include "Poco/Data/ODBC/Utility.h"
|
||||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sqltypes.h>
|
#include <sqltypes.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
namespace ODBC {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename H, SQLSMALLINT handleType>
|
|
||||||
class Handle
|
|
||||||
/// ODBC handle class template
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
Handle(const ConnectionHandle& rConnection):
|
{
|
||||||
_rConnection(rConnection),
|
namespace ODBC
|
||||||
_handle(0)
|
{
|
||||||
/// Creates the Handle.
|
|
||||||
{
|
|
||||||
if (Utility::isError(SQLAllocHandle(handleType,
|
|
||||||
_rConnection,
|
|
||||||
&_handle)))
|
|
||||||
{
|
|
||||||
throw ODBCException("Could not allocate statement handle.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~Handle()
|
|
||||||
/// Destroys the Handle.
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
SQLRETURN rc = 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;
|
template <typename H, SQLSMALLINT handleType>
|
||||||
typedef Handle<SQLHDESC, SQL_HANDLE_DESC> DescriptorHandle;
|
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
|
||||||
|
{
|
||||||
|
SQLRETURN rc = 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} } } // namespace Poco::Data::ODBC
|
typedef Handle<SQLHSTMT, SQL_HANDLE_STMT> StatementHandle;
|
||||||
|
typedef Handle<SQLHDESC, SQL_HANDLE_DESC> DescriptorHandle;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace Poco::Data::ODBC
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "Poco/Foundation.h"
|
#include "Poco/Foundation.h"
|
||||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -35,24 +35,23 @@
|
|||||||
// defined with this macro as being exported.
|
// defined with this macro as being exported.
|
||||||
//
|
//
|
||||||
#if defined(_WIN32) && defined(POCO_DLL)
|
#if defined(_WIN32) && defined(POCO_DLL)
|
||||||
#if defined(ODBC_EXPORTS)
|
# if defined(ODBC_EXPORTS)
|
||||||
#define ODBC_API __declspec(dllexport)
|
# define ODBC_API __declspec(dllexport)
|
||||||
#else
|
# else
|
||||||
#define ODBC_API __declspec(dllimport)
|
# define ODBC_API __declspec(dllimport)
|
||||||
#endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(ODBC_API)
|
#if !defined(ODBC_API)
|
||||||
#if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined (__GNUC__) && (__GNUC__ >= 4)
|
# if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined(__GNUC__) && (__GNUC__ >= 4)
|
||||||
#define ODBC_API __attribute__ ((visibility ("default")))
|
# define ODBC_API __attribute__((visibility("default")))
|
||||||
#else
|
# else
|
||||||
#define ODBC_API
|
# define ODBC_API
|
||||||
#endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/ODBC/Unicode.h"
|
#include "Poco/Data/ODBC/Unicode.h"
|
||||||
|
|
||||||
|
|
||||||
@ -60,9 +59,9 @@
|
|||||||
// Automatically link Data library.
|
// Automatically link Data library.
|
||||||
//
|
//
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(ODBC_EXPORTS)
|
# if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(ODBC_EXPORTS)
|
||||||
#pragma comment(lib, "PocoDataODBC" POCO_LIB_SUFFIX)
|
# pragma comment(lib, "PocoDataODBC" POCO_LIB_SUFFIX)
|
||||||
#endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,133 +18,130 @@
|
|||||||
#define Data_ODBC_ODBCException_INCLUDED
|
#define Data_ODBC_ODBCException_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/ODBC/ODBC.h"
|
#include "Poco/Data/DataException.h"
|
||||||
#include "Poco/Data/ODBC/Utility.h"
|
|
||||||
#include "Poco/Data/ODBC/Diagnostics.h"
|
#include "Poco/Data/ODBC/Diagnostics.h"
|
||||||
#include "Poco/Data/ODBC/Error.h"
|
#include "Poco/Data/ODBC/Error.h"
|
||||||
#include "Poco/Data/DataException.h"
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
|
#include "Poco/Data/ODBC/Utility.h"
|
||||||
#include "Poco/Format.h"
|
#include "Poco/Format.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
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:
|
namespace Data
|
||||||
HandleException(const H& handle): _error(handle)
|
{
|
||||||
/// Creates HandleException
|
namespace ODBC
|
||||||
{
|
{
|
||||||
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() throw()
|
|
||||||
/// Destroys HandleException
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
HandleException& operator = (const HandleException& exc)
|
|
||||||
/// Assignment operator
|
|
||||||
{
|
|
||||||
if (&exc != this) _error = exc._error;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* name() const throw()
|
|
||||||
/// Returns the name of the exception
|
|
||||||
{
|
|
||||||
return "ODBC handle exception";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* className() const throw()
|
|
||||||
/// 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;
|
POCO_DECLARE_EXCEPTION(ODBC_API, ODBCException, Poco::Data::DataException)
|
||||||
typedef HandleException<SQLHDBC, SQL_HANDLE_DBC> ConnectionException;
|
POCO_DECLARE_EXCEPTION(ODBC_API, InsufficientStorageException, ODBCException)
|
||||||
typedef HandleException<SQLHSTMT, SQL_HANDLE_STMT> StatementException;
|
POCO_DECLARE_EXCEPTION(ODBC_API, UnknownDataLengthException, ODBCException)
|
||||||
typedef HandleException<SQLHDESC, SQL_HANDLE_DESC> DescriptorException;
|
POCO_DECLARE_EXCEPTION(ODBC_API, DataTruncatedException, ODBCException)
|
||||||
|
|
||||||
|
|
||||||
} } } // namespace Poco::Data::ODBC
|
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() throw()
|
||||||
|
/// Destroys HandleException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleException & operator=(const HandleException & exc)
|
||||||
|
/// Assignment operator
|
||||||
|
{
|
||||||
|
if (&exc != this)
|
||||||
|
_error = exc._error;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * name() const throw()
|
||||||
|
/// Returns the name of the exception
|
||||||
|
{
|
||||||
|
return "ODBC handle exception";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * className() const throw()
|
||||||
|
/// 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
|
#endif
|
||||||
|
@ -18,75 +18,80 @@
|
|||||||
#define Data_ODBC_ODBCColumn_INCLUDED
|
#define Data_ODBC_ODBCColumn_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/ODBC/ODBC.h"
|
#include "Poco/Data/MetaColumn.h"
|
||||||
#include "Poco/Data/ODBC/Error.h"
|
#include "Poco/Data/ODBC/Error.h"
|
||||||
#include "Poco/Data/ODBC/Handle.h"
|
#include "Poco/Data/ODBC/Handle.h"
|
||||||
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
#include "Poco/Data/ODBC/ODBCException.h"
|
#include "Poco/Data/ODBC/ODBCException.h"
|
||||||
#include "Poco/Data/MetaColumn.h"
|
|
||||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sqlext.h>
|
#include <sqlext.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
namespace ODBC {
|
|
||||||
|
|
||||||
|
|
||||||
class ODBC_API ODBCMetaColumn: public MetaColumn
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
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 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
|
||||||
|
|
||||||
} } } // namespace Poco::Data::ODBC
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,189 +18,194 @@
|
|||||||
#define Data_ODBC_ODBCStatementImpl_INCLUDED
|
#define Data_ODBC_ODBCStatementImpl_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/ODBC/ODBC.h"
|
#include <sstream>
|
||||||
#include "Poco/Data/ODBC/SessionImpl.h"
|
#include "Poco/Data/Column.h"
|
||||||
#include "Poco/Data/ODBC/Binder.h"
|
#include "Poco/Data/ODBC/Binder.h"
|
||||||
#include "Poco/Data/ODBC/Extractor.h"
|
#include "Poco/Data/ODBC/Extractor.h"
|
||||||
#include "Poco/Data/ODBC/Preparator.h"
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
|
#include "Poco/Data/ODBC/ODBCMetaColumn.h"
|
||||||
|
#include "Poco/Data/ODBC/Preparator.h"
|
||||||
|
#include "Poco/Data/ODBC/SessionImpl.h"
|
||||||
#include "Poco/Data/StatementImpl.h"
|
#include "Poco/Data/StatementImpl.h"
|
||||||
#include "Poco/Data/Column.h"
|
|
||||||
#include "Poco/SharedPtr.h"
|
|
||||||
#include "Poco/Format.h"
|
#include "Poco/Format.h"
|
||||||
#include <sstream>
|
#include "Poco/SharedPtr.h"
|
||||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sqltypes.h>
|
#include <sqltypes.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
namespace ODBC {
|
|
||||||
|
|
||||||
|
|
||||||
class ODBC_API ODBCStatementImpl: public Poco::Data::StatementImpl
|
|
||||||
/// Implements statement functionality needed for ODBC
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
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());
|
namespace ODBC
|
||||||
poco_assert_dbg (_extractors[currentDataSet()]);
|
{
|
||||||
return _extractors[currentDataSet()];
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
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
|
#endif // Data_ODBC_ODBCStatementImpl_INCLUDED
|
||||||
|
@ -18,94 +18,99 @@
|
|||||||
#define Data_ODBC_Parameter_INCLUDED
|
#define Data_ODBC_Parameter_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/ODBC/ODBC.h"
|
|
||||||
#include "Poco/Data/ODBC/Handle.h"
|
#include "Poco/Data/ODBC/Handle.h"
|
||||||
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sqlext.h>
|
#include <sqlext.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
namespace ODBC {
|
|
||||||
|
|
||||||
|
|
||||||
class ODBC_API Parameter
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
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;
|
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
|
||||||
|
|
||||||
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
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,273 +18,280 @@
|
|||||||
#define 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/Data/AbstractSessionImpl.h"
|
||||||
#include "Poco/SharedPtr.h"
|
#include "Poco/Data/ODBC/Binder.h"
|
||||||
|
#include "Poco/Data/ODBC/Connector.h"
|
||||||
|
#include "Poco/Data/ODBC/Handle.h"
|
||||||
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
|
#include "Poco/Data/ODBC/ODBCException.h"
|
||||||
|
#include "Poco/Data/ODBC/TypeInfo.h"
|
||||||
#include "Poco/Mutex.h"
|
#include "Poco/Mutex.h"
|
||||||
|
#include "Poco/SharedPtr.h"
|
||||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sqltypes.h>
|
#include <sqltypes.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
namespace ODBC {
|
|
||||||
|
|
||||||
|
|
||||||
class ODBC_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
|
|
||||||
/// Implements SessionImpl interface
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
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 successful.
|
|
||||||
|
|
||||||
//@ 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::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();
|
|
||||||
/// Returns true if session is connected
|
|
||||||
|
|
||||||
void setConnectionTimeout(std::size_t timeout);
|
|
||||||
/// Sets the session connection timeout value.
|
|
||||||
|
|
||||||
std::size_t getConnectionTimeout();
|
|
||||||
/// Returns the session connection timeout value.
|
|
||||||
|
|
||||||
void begin();
|
|
||||||
/// Starts a transaction
|
|
||||||
|
|
||||||
void commit();
|
|
||||||
/// Commits and ends a transaction
|
|
||||||
|
|
||||||
void rollback();
|
|
||||||
/// Aborts a transaction
|
|
||||||
|
|
||||||
bool isTransaction();
|
|
||||||
/// Returns true iff a transaction is in progress.
|
|
||||||
|
|
||||||
const std::string& connectorName() const;
|
|
||||||
/// Returns the name of the connector.
|
|
||||||
|
|
||||||
bool canTransact();
|
|
||||||
/// Returns true if connection is transaction-capable.
|
|
||||||
|
|
||||||
void setTransactionIsolation(Poco::UInt32 ti);
|
|
||||||
/// Sets the transaction isolation level.
|
|
||||||
|
|
||||||
Poco::UInt32 getTransactionIsolation();
|
|
||||||
/// Returns the transaction isolation level.
|
|
||||||
|
|
||||||
bool hasTransactionIsolation(Poco::UInt32);
|
|
||||||
/// Returns true iff the transaction isolation level corresponding
|
|
||||||
/// to the supplied bitmask is supported.
|
|
||||||
|
|
||||||
bool isTransactionIsolation(Poco::UInt32);
|
|
||||||
/// 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="");
|
|
||||||
/// Returns autocommit property value.
|
|
||||||
|
|
||||||
void autoBind(const std::string&, bool val);
|
|
||||||
/// Sets automatic binding for the session.
|
|
||||||
|
|
||||||
bool isAutoBind(const std::string& name="");
|
|
||||||
/// 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="");
|
|
||||||
/// 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="");
|
|
||||||
/// Returns the max field size (the default used when column size is unknown).
|
|
||||||
|
|
||||||
int maxStatementLength();
|
|
||||||
/// 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&);
|
|
||||||
/// 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="");
|
|
||||||
/// 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="");
|
|
||||||
|
|
||||||
Poco::UInt32 getDefaultTransactionIsolation();
|
|
||||||
|
|
||||||
Poco::UInt32 transactionIsolation(SQLULEN isolation);
|
|
||||||
|
|
||||||
std::string _connector;
|
|
||||||
const ConnectionHandle _db;
|
|
||||||
Poco::Any _maxFieldSize;
|
|
||||||
bool _autoBind;
|
|
||||||
bool _autoExtract;
|
|
||||||
TypeInfo _dataTypes;
|
|
||||||
char _canTransact;
|
|
||||||
bool _inTransaction;
|
|
||||||
int _queryTimeout;
|
|
||||||
Poco::FastMutex _mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// inlines
|
|
||||||
///
|
|
||||||
inline void SessionImpl::checkError(SQLRETURN rc, const std::string& msg)
|
|
||||||
{
|
{
|
||||||
if (Utility::isError(rc))
|
namespace ODBC
|
||||||
throw ConnectionException(_db, msg);
|
{
|
||||||
|
|
||||||
|
|
||||||
|
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 successful.
|
||||||
|
|
||||||
|
//@ 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::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();
|
||||||
|
/// Returns true if session is connected
|
||||||
|
|
||||||
|
void setConnectionTimeout(std::size_t timeout);
|
||||||
|
/// Sets the session connection timeout value.
|
||||||
|
|
||||||
|
std::size_t getConnectionTimeout();
|
||||||
|
/// Returns the session connection timeout value.
|
||||||
|
|
||||||
|
void begin();
|
||||||
|
/// Starts a transaction
|
||||||
|
|
||||||
|
void commit();
|
||||||
|
/// Commits and ends a transaction
|
||||||
|
|
||||||
|
void rollback();
|
||||||
|
/// Aborts a transaction
|
||||||
|
|
||||||
|
bool isTransaction();
|
||||||
|
/// Returns true iff a transaction is in progress.
|
||||||
|
|
||||||
|
const std::string & connectorName() const;
|
||||||
|
/// Returns the name of the connector.
|
||||||
|
|
||||||
|
bool canTransact();
|
||||||
|
/// Returns true if connection is transaction-capable.
|
||||||
|
|
||||||
|
void setTransactionIsolation(Poco::UInt32 ti);
|
||||||
|
/// Sets the transaction isolation level.
|
||||||
|
|
||||||
|
Poco::UInt32 getTransactionIsolation();
|
||||||
|
/// Returns the transaction isolation level.
|
||||||
|
|
||||||
|
bool hasTransactionIsolation(Poco::UInt32);
|
||||||
|
/// Returns true iff the transaction isolation level corresponding
|
||||||
|
/// to the supplied bitmask is supported.
|
||||||
|
|
||||||
|
bool isTransactionIsolation(Poco::UInt32);
|
||||||
|
/// 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 = "");
|
||||||
|
/// Returns autocommit property value.
|
||||||
|
|
||||||
|
void autoBind(const std::string &, bool val);
|
||||||
|
/// Sets automatic binding for the session.
|
||||||
|
|
||||||
|
bool isAutoBind(const std::string & name = "");
|
||||||
|
/// 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 = "");
|
||||||
|
/// 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 = "");
|
||||||
|
/// Returns the max field size (the default used when column size is unknown).
|
||||||
|
|
||||||
|
int maxStatementLength();
|
||||||
|
/// 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 &);
|
||||||
|
/// 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 = "");
|
||||||
|
/// 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 = "");
|
||||||
|
|
||||||
|
Poco::UInt32 getDefaultTransactionIsolation();
|
||||||
|
|
||||||
|
Poco::UInt32 transactionIsolation(SQLULEN isolation);
|
||||||
|
|
||||||
|
std::string _connector;
|
||||||
|
const ConnectionHandle _db;
|
||||||
|
Poco::Any _maxFieldSize;
|
||||||
|
bool _autoBind;
|
||||||
|
bool _autoExtract;
|
||||||
|
TypeInfo _dataTypes;
|
||||||
|
char _canTransact;
|
||||||
|
bool _inTransaction;
|
||||||
|
int _queryTimeout;
|
||||||
|
Poco::FastMutex _mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// inlines
|
||||||
|
///
|
||||||
|
inline void SessionImpl::checkError(SQLRETURN rc, const std::string & msg)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return &_dataTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void SessionImpl::autoBind(const std::string &, bool val)
|
||||||
|
{
|
||||||
|
_autoBind = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool SessionImpl::isAutoBind(const std::string & name)
|
||||||
|
{
|
||||||
|
return _autoBind;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void SessionImpl::autoExtract(const std::string &, bool val)
|
||||||
|
{
|
||||||
|
_autoExtract = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool SessionImpl::isAutoExtract(const std::string & name)
|
||||||
|
{
|
||||||
|
return _autoExtract;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const std::string & SessionImpl::connectorName() const
|
||||||
|
{
|
||||||
|
return _connector;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool SessionImpl::isTransactionIsolation(Poco::UInt32 ti)
|
||||||
|
{
|
||||||
|
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 &)
|
||||||
|
{
|
||||||
|
return _queryTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int SessionImpl::queryTimeout() const
|
||||||
|
{
|
||||||
|
return _queryTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data::ODBC
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
return &_dataTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void SessionImpl::autoBind(const std::string&, bool val)
|
|
||||||
{
|
|
||||||
_autoBind = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool SessionImpl::isAutoBind(const std::string& name)
|
|
||||||
{
|
|
||||||
return _autoBind;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void SessionImpl::autoExtract(const std::string&, bool val)
|
|
||||||
{
|
|
||||||
_autoExtract = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool SessionImpl::isAutoExtract(const std::string& name)
|
|
||||||
{
|
|
||||||
return _autoExtract;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& SessionImpl::connectorName() const
|
|
||||||
{
|
|
||||||
return _connector;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool SessionImpl::isTransactionIsolation(Poco::UInt32 ti)
|
|
||||||
{
|
|
||||||
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&)
|
|
||||||
{
|
|
||||||
return _queryTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline int SessionImpl::queryTimeout() const
|
|
||||||
{
|
|
||||||
return _queryTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } } // namespace Poco::Data::ODBC
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_ODBC_SessionImpl_INCLUDED
|
#endif // Data_ODBC_SessionImpl_INCLUDED
|
||||||
|
@ -18,100 +18,107 @@
|
|||||||
#define 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>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
|
#include "Poco/DynamicAny.h"
|
||||||
|
#include "Poco/NamedTuple.h"
|
||||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||||
#include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sqlext.h>
|
#include <sqlext.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
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 connection 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:
|
namespace Data
|
||||||
typedef std::map<int, int> DataTypeMap;
|
{
|
||||||
typedef DataTypeMap::value_type ValueType;
|
namespace ODBC
|
||||||
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
|
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 connection 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
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,34 +18,39 @@
|
|||||||
#define Data_ODBC_Unicode_UNIX_INCLUDED
|
#define Data_ODBC_Unicode_UNIX_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
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);
|
namespace Data
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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 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
|
||||||
|
|
||||||
} } } // namespace Poco::Data::ODBC
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_ODBC_Unicode_UNIX_INCLUDED
|
#endif // Data_ODBC_Unicode_UNIX_INCLUDED
|
||||||
|
@ -18,40 +18,45 @@
|
|||||||
#define Data_ODBC_Unicode_WIN32_INCLUDED
|
#define Data_ODBC_Unicode_WIN32_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
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;
|
namespace Data
|
||||||
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)
|
namespace ODBC
|
||||||
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;
|
inline void makeUTF16(SQLCHAR * pSQLChar, SQLINTEGER length, std::wstring & target)
|
||||||
UnicodeConverter::toUTF8(buffer.begin(), length, result);
|
/// Utility function for conversion from UTF-8 to UTF-16
|
||||||
|
{
|
||||||
std::memset(pTarget, 0, targetLength);
|
int len = length;
|
||||||
std::strncpy((char*) pTarget, result.c_str(), result.size() < targetLength ? result.size() : targetLength);
|
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
|
||||||
|
|
||||||
} } } // namespace Poco::Data::ODBC
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_ODBC_Unicode_WIN32_INCLUDED
|
#endif // Data_ODBC_Unicode_WIN32_INCLUDED
|
||||||
|
@ -18,190 +18,207 @@
|
|||||||
#define Data_ODBC_Utility_INCLUDED
|
#define Data_ODBC_Utility_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <sstream>
|
||||||
|
#include <sqltypes.h>
|
||||||
|
#include "Poco/Data/Date.h"
|
||||||
#include "Poco/Data/ODBC/ODBC.h"
|
#include "Poco/Data/ODBC/ODBC.h"
|
||||||
#include "Poco/Data/ODBC/TypeInfo.h"
|
#include "Poco/Data/ODBC/TypeInfo.h"
|
||||||
#include "Poco/Data/Date.h"
|
|
||||||
#include "Poco/Data/Time.h"
|
#include "Poco/Data/Time.h"
|
||||||
#include "Poco/DateTime.h"
|
#include "Poco/DateTime.h"
|
||||||
#include <sstream>
|
|
||||||
#include <map>
|
|
||||||
#include <sqltypes.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
namespace ODBC {
|
|
||||||
|
|
||||||
|
|
||||||
class ODBC_API Utility
|
|
||||||
/// Various utility functions
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
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)));
|
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
|
||||||
|
|
||||||
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
|
#endif
|
||||||
|
@ -18,356 +18,360 @@
|
|||||||
#define Data_AbstractBinder_INCLUDED
|
#define Data_AbstractBinder_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
#include <cstddef>
|
||||||
#include "Poco/Data/Date.h"
|
|
||||||
#include "Poco/Data/Time.h"
|
|
||||||
#include "Poco/Data/LOB.h"
|
|
||||||
#include "Poco/DateTime.h"
|
|
||||||
#include "Poco/Nullable.h"
|
|
||||||
#include "Poco/Any.h"
|
|
||||||
#include "Poco/Dynamic/Var.h"
|
|
||||||
#include "Poco/UTFString.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <cstddef>
|
#include <vector>
|
||||||
|
#include "Poco/Any.h"
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
|
#include "Poco/Data/Date.h"
|
||||||
|
#include "Poco/Data/LOB.h"
|
||||||
|
#include "Poco/Data/Time.h"
|
||||||
|
#include "Poco/DateTime.h"
|
||||||
|
#include "Poco/Dynamic/Var.h"
|
||||||
|
#include "Poco/Nullable.h"
|
||||||
|
#include "Poco/UTFString.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
{
|
||||||
|
namespace Data
|
||||||
|
|
||||||
typedef NullType NullData;
|
|
||||||
|
|
||||||
|
|
||||||
namespace Keywords {
|
|
||||||
|
|
||||||
|
|
||||||
static const NullData null = NULL_GENERIC;
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Keywords
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API AbstractBinder
|
|
||||||
/// Interface for Binding data types to placeholders.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
typedef SharedPtr<AbstractBinder> Ptr;
|
|
||||||
|
|
||||||
enum Direction
|
|
||||||
/// Binding direction for a parameter.
|
|
||||||
{
|
|
||||||
PD_IN,
|
|
||||||
PD_OUT,
|
|
||||||
PD_IN_OUT
|
|
||||||
};
|
|
||||||
|
|
||||||
AbstractBinder();
|
typedef NullType NullData;
|
||||||
/// Creates the AbstractBinder.
|
|
||||||
|
|
||||||
virtual ~AbstractBinder();
|
|
||||||
/// Destroys the AbstractBinder.
|
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::Int8& val, Direction dir = PD_IN) = 0;
|
namespace Keywords
|
||||||
/// Binds an Int8.
|
{
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir = PD_IN);
|
|
||||||
/// Binds an Int8 vector.
|
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<Poco::Int8>& val, Direction dir = PD_IN);
|
static const NullData null = NULL_GENERIC;
|
||||||
/// Binds an Int8 deque.
|
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<Poco::Int8>& val, Direction dir = PD_IN);
|
|
||||||
/// Binds an Int8 list.
|
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::UInt8& val, Direction dir = PD_IN) = 0;
|
} // namespace Keywords
|
||||||
/// Binds an UInt8.
|
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir = PD_IN);
|
|
||||||
/// Binds an UInt8 vector.
|
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<Poco::UInt8>& val, Direction dir = PD_IN);
|
class Data_API AbstractBinder
|
||||||
/// Binds an UInt8 deque.
|
/// Interface for Binding data types to placeholders.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef SharedPtr<AbstractBinder> Ptr;
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<Poco::UInt8>& val, Direction dir = PD_IN);
|
enum Direction
|
||||||
/// Binds an UInt8 list.
|
/// Binding direction for a parameter.
|
||||||
|
{
|
||||||
|
PD_IN,
|
||||||
|
PD_OUT,
|
||||||
|
PD_IN_OUT
|
||||||
|
};
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::Int16& val, Direction dir = PD_IN) = 0;
|
AbstractBinder();
|
||||||
/// Binds an Int16.
|
/// Creates the AbstractBinder.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir = PD_IN);
|
virtual ~AbstractBinder();
|
||||||
/// Binds an Int16 vector.
|
/// Destroys the AbstractBinder.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<Poco::Int16>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const Poco::Int8 & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an Int16 deque.
|
/// Binds an Int8.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<Poco::Int16>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<Poco::Int8> & val, Direction dir = PD_IN);
|
||||||
/// Binds an Int16 list.
|
/// Binds an Int8 vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::UInt16& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const std::deque<Poco::Int8> & val, Direction dir = PD_IN);
|
||||||
/// Binds an UInt16.
|
/// Binds an Int8 deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<Poco::Int8> & val, Direction dir = PD_IN);
|
||||||
/// Binds an UInt16 vector.
|
/// Binds an Int8 list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<Poco::UInt16>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const Poco::UInt8 & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an UInt16 deque.
|
/// Binds an UInt8.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<Poco::UInt16>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<Poco::UInt8> & val, Direction dir = PD_IN);
|
||||||
/// Binds an UInt16 list.
|
/// Binds an UInt8 vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::Int32& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const std::deque<Poco::UInt8> & val, Direction dir = PD_IN);
|
||||||
/// Binds an Int32.
|
/// Binds an UInt8 deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<Poco::UInt8> & val, Direction dir = PD_IN);
|
||||||
/// Binds an Int32 vector.
|
/// Binds an UInt8 list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<Poco::Int32>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const Poco::Int16 & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an Int32 deque.
|
/// Binds an Int16.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<Poco::Int32>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<Poco::Int16> & val, Direction dir = PD_IN);
|
||||||
/// Binds an Int32 list.
|
/// Binds an Int16 vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::UInt32& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const std::deque<Poco::Int16> & val, Direction dir = PD_IN);
|
||||||
/// Binds an UInt32.
|
/// Binds an Int16 deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<Poco::Int16> & val, Direction dir = PD_IN);
|
||||||
/// Binds an UInt32 vector.
|
/// Binds an Int16 list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<Poco::UInt32>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const Poco::UInt16 & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an UInt32 deque.
|
/// Binds an UInt16.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<Poco::UInt32>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<Poco::UInt16> & val, Direction dir = PD_IN);
|
||||||
/// Binds an UInt32 list.
|
/// Binds an UInt16 vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::Int64& val, Direction dir = PD_IN) = 0;
|
|
||||||
/// Binds an Int64.
|
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<Poco::UInt16> & val, Direction dir = PD_IN);
|
||||||
/// Binds an Int64 vector.
|
/// Binds an UInt16 deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<Poco::Int64>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<Poco::UInt16> & val, Direction dir = PD_IN);
|
||||||
/// Binds an Int64 deque.
|
/// Binds an UInt16 list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<Poco::Int64>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const Poco::Int32 & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an Int64 list.
|
/// Binds an Int32.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Poco::UInt64& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const std::vector<Poco::Int32> & val, Direction dir = PD_IN);
|
||||||
/// Binds an UInt64.
|
/// Binds an Int32 vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<Poco::Int32> & val, Direction dir = PD_IN);
|
||||||
/// Binds an UInt64 vector.
|
/// Binds an Int32 deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<Poco::UInt64>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<Poco::Int32> & val, Direction dir = PD_IN);
|
||||||
/// Binds an UInt64 deque.
|
/// Binds an Int32 list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<Poco::UInt64>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const Poco::UInt32 & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an UInt64 list.
|
/// Binds an UInt32.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<Poco::UInt32> & val, Direction dir = PD_IN);
|
||||||
|
/// Binds an UInt32 vector.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<Poco::UInt32> & val, Direction dir = PD_IN);
|
||||||
|
/// Binds an UInt32 deque.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<Poco::UInt32> & val, Direction dir = PD_IN);
|
||||||
|
/// Binds an UInt32 list.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Poco::Int64 & val, Direction dir = PD_IN) = 0;
|
||||||
|
/// Binds an Int64.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<Poco::Int64> & val, Direction dir = PD_IN);
|
||||||
|
/// Binds an Int64 vector.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<Poco::Int64> & val, Direction dir = PD_IN);
|
||||||
|
/// Binds an Int64 deque.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<Poco::Int64> & val, Direction dir = PD_IN);
|
||||||
|
/// Binds an Int64 list.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const Poco::UInt64 & val, Direction dir = PD_IN) = 0;
|
||||||
|
/// Binds an UInt64.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::vector<Poco::UInt64> & val, Direction dir = PD_IN);
|
||||||
|
/// Binds an UInt64 vector.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::deque<Poco::UInt64> & val, Direction dir = PD_IN);
|
||||||
|
/// Binds an UInt64 deque.
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos, const std::list<Poco::UInt64> & val, Direction dir = PD_IN);
|
||||||
|
/// Binds an UInt64 list.
|
||||||
|
|
||||||
#ifndef POCO_LONG_IS_64_BIT
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
virtual void bind(std::size_t pos, const long& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const long & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a long.
|
/// Binds a long.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const unsigned long& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const unsigned long & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds an unsigned long.
|
/// Binds an unsigned long.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<long>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<long> & val, Direction dir = PD_IN);
|
||||||
/// Binds a long vector.
|
/// Binds a long vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<long>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<long> & val, Direction dir = PD_IN);
|
||||||
/// Binds a long deque.
|
/// Binds a long deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<long>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<long> & val, Direction dir = PD_IN);
|
||||||
/// Binds a long list.
|
/// Binds a long list.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const bool& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const bool & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a boolean.
|
/// Binds a boolean.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<bool>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<bool> & val, Direction dir = PD_IN);
|
||||||
/// Binds a boolean vector.
|
/// Binds a boolean vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<bool>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<bool> & val, Direction dir = PD_IN);
|
||||||
/// Binds a boolean deque.
|
/// Binds a boolean deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<bool>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<bool> & val, Direction dir = PD_IN);
|
||||||
/// Binds a boolean list.
|
/// Binds a boolean list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const float& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const float & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a float.
|
/// Binds a float.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<float>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<float> & val, Direction dir = PD_IN);
|
||||||
/// Binds a float vector.
|
/// Binds a float vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<float>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<float> & val, Direction dir = PD_IN);
|
||||||
/// Binds a float deque.
|
/// Binds a float deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<float>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<float> & val, Direction dir = PD_IN);
|
||||||
/// Binds a float list.
|
/// Binds a float list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const double& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const double & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a double.
|
/// Binds a double.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<double>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<double> & val, Direction dir = PD_IN);
|
||||||
/// Binds a double vector.
|
/// Binds a double vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<double>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<double> & val, Direction dir = PD_IN);
|
||||||
/// Binds a double deque.
|
/// Binds a double deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<double>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<double> & val, Direction dir = PD_IN);
|
||||||
/// Binds a double list.
|
/// Binds a double list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const char& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const char & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a single character.
|
/// Binds a single character.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<char>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<char> & val, Direction dir = PD_IN);
|
||||||
/// Binds a character vector.
|
/// Binds a character vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<char>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<char> & val, Direction dir = PD_IN);
|
||||||
/// Binds a character deque.
|
/// Binds a character deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<char>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<char> & val, Direction dir = PD_IN);
|
||||||
/// Binds a character list.
|
/// Binds a character list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const char* const& pVal, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const char * const & pVal, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a const char ptr.
|
/// Binds a const char ptr.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::string& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const std::string & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a string.
|
/// Binds a string.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<std::string>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<std::string> & val, Direction dir = PD_IN);
|
||||||
/// Binds a string vector.
|
/// Binds a string vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<std::string>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<std::string> & val, Direction dir = PD_IN);
|
||||||
/// Binds a string deque.
|
/// Binds a string deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<std::string>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<std::string> & val, Direction dir = PD_IN);
|
||||||
/// Binds a string list.
|
/// Binds a string list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const UTF16String& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const UTF16String & val, Direction dir = PD_IN);
|
||||||
/// Binds a UTF-16 Unicode string.
|
/// Binds a UTF-16 Unicode string.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<UTF16String>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<UTF16String> & val, Direction dir = PD_IN);
|
||||||
/// Binds a UTF-16 Unicode string vector.
|
/// Binds a UTF-16 Unicode string vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<UTF16String>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<UTF16String> & val, Direction dir = PD_IN);
|
||||||
/// Binds a UTF-16 Unicode string deque.
|
/// Binds a UTF-16 Unicode string deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<UTF16String>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<UTF16String> & val, Direction dir = PD_IN);
|
||||||
/// Binds a UTF-16 Unicode string list.
|
/// Binds a UTF-16 Unicode string list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const BLOB& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const BLOB & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a BLOB.
|
/// Binds a BLOB.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const CLOB& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const CLOB & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a CLOB.
|
/// Binds a CLOB.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<BLOB>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<BLOB> & val, Direction dir = PD_IN);
|
||||||
/// Binds a BLOB vector.
|
/// Binds a BLOB vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<BLOB>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<BLOB> & val, Direction dir = PD_IN);
|
||||||
/// Binds a BLOB deque.
|
/// Binds a BLOB deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<BLOB>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<BLOB> & val, Direction dir = PD_IN);
|
||||||
/// Binds a BLOB list.
|
/// Binds a BLOB list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<CLOB>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<CLOB> & val, Direction dir = PD_IN);
|
||||||
/// Binds a CLOB vector.
|
/// Binds a CLOB vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<CLOB>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<CLOB> & val, Direction dir = PD_IN);
|
||||||
/// Binds a CLOB deque.
|
/// Binds a CLOB deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<CLOB>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<CLOB> & val, Direction dir = PD_IN);
|
||||||
/// Binds a CLOB list.
|
/// Binds a CLOB list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const DateTime& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const DateTime & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a DateTime.
|
/// Binds a DateTime.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<DateTime>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<DateTime> & val, Direction dir = PD_IN);
|
||||||
/// Binds a DateTime vector.
|
/// Binds a DateTime vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<DateTime>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<DateTime> & val, Direction dir = PD_IN);
|
||||||
/// Binds a DateTime deque.
|
/// Binds a DateTime deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<DateTime>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<DateTime> & val, Direction dir = PD_IN);
|
||||||
/// Binds a DateTime list.
|
/// Binds a DateTime list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Date& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const Date & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a Date.
|
/// Binds a Date.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<Date>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<Date> & val, Direction dir = PD_IN);
|
||||||
/// Binds a Date vector.
|
/// Binds a Date vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<Date>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<Date> & val, Direction dir = PD_IN);
|
||||||
/// Binds a Date deque.
|
/// Binds a Date deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<Date>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<Date> & val, Direction dir = PD_IN);
|
||||||
/// Binds a Date list.
|
/// Binds a Date list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const Time& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const Time & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a Time.
|
/// Binds a Time.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<Time>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<Time> & val, Direction dir = PD_IN);
|
||||||
/// Binds a Time vector.
|
/// Binds a Time vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<Time>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<Time> & val, Direction dir = PD_IN);
|
||||||
/// Binds a Time deque.
|
/// Binds a Time deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<Time>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<Time> & val, Direction dir = PD_IN);
|
||||||
/// Binds a Time list.
|
/// Binds a Time list.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const NullData& val, Direction dir = PD_IN) = 0;
|
virtual void bind(std::size_t pos, const NullData & val, Direction dir = PD_IN) = 0;
|
||||||
/// Binds a null.
|
/// Binds a null.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::vector<NullData>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::vector<NullData> & val, Direction dir = PD_IN);
|
||||||
/// Binds a null vector.
|
/// Binds a null vector.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::deque<NullData>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::deque<NullData> & val, Direction dir = PD_IN);
|
||||||
/// Binds a null deque.
|
/// Binds a null deque.
|
||||||
|
|
||||||
virtual void bind(std::size_t pos, const std::list<NullData>& val, Direction dir = PD_IN);
|
virtual void bind(std::size_t pos, const std::list<NullData> & val, Direction dir = PD_IN);
|
||||||
/// Binds a null list.
|
/// Binds a null list.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Any& val, Direction dir = PD_IN);
|
void bind(std::size_t pos, const Any & val, Direction dir = PD_IN);
|
||||||
/// Binds an Any.
|
/// Binds an Any.
|
||||||
|
|
||||||
void bind(std::size_t pos, const Poco::Dynamic::Var& val, Direction dir = PD_IN);
|
|
||||||
/// Binds a Var.
|
|
||||||
|
|
||||||
virtual void reset();
|
void bind(std::size_t pos, const Poco::Dynamic::Var & val, Direction dir = PD_IN);
|
||||||
/// Resets a binder. No-op by default. Implement for binders that cache data.
|
/// Binds a Var.
|
||||||
|
|
||||||
static bool isOutBound(Direction dir);
|
virtual void reset();
|
||||||
/// Returns true if direction is out bound;
|
/// Resets a binder. No-op by default. Implement for binders that cache data.
|
||||||
|
|
||||||
static bool isInBound(Direction dir);
|
static bool isOutBound(Direction dir);
|
||||||
/// Returns true if direction is in bound;
|
/// Returns true if direction is out bound;
|
||||||
};
|
|
||||||
|
static bool isInBound(Direction dir);
|
||||||
|
/// Returns true if direction is in bound;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline void AbstractBinder::reset()
|
||||||
|
{
|
||||||
|
//no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool AbstractBinder::isOutBound(Direction dir)
|
||||||
|
{
|
||||||
|
return PD_OUT == dir || PD_IN_OUT == dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool AbstractBinder::isInBound(Direction dir)
|
||||||
|
{
|
||||||
|
return PD_IN == dir || PD_IN_OUT == dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline void AbstractBinder::reset()
|
|
||||||
{
|
|
||||||
//no-op
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline bool AbstractBinder::isOutBound(Direction dir)
|
|
||||||
{
|
|
||||||
return PD_OUT == dir || PD_IN_OUT == dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool AbstractBinder::isInBound(Direction dir)
|
|
||||||
{
|
|
||||||
return PD_IN == dir || PD_IN_OUT == dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_AbstractBinder_INCLUDED
|
#endif // Data_AbstractBinder_INCLUDED
|
||||||
|
@ -18,127 +18,130 @@
|
|||||||
#define Data_AbstractBinding_INCLUDED
|
#define Data_AbstractBinding_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
|
||||||
#include "Poco/Data/AbstractBinder.h"
|
|
||||||
#include "Poco/Any.h"
|
|
||||||
#include "Poco/RefCountedObject.h"
|
|
||||||
#include "Poco/AutoPtr.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <list>
|
|
||||||
#include <deque>
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <deque>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
#include "Poco/Any.h"
|
||||||
|
#include "Poco/AutoPtr.h"
|
||||||
|
#include "Poco/Data/AbstractBinder.h"
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
|
#include "Poco/RefCountedObject.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API AbstractBinding
|
|
||||||
/// AbstractBinding connects a value with a placeholder via an AbstractBinder interface.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
typedef SharedPtr<AbstractBinding> Ptr;
|
|
||||||
typedef AbstractBinder::Ptr BinderPtr;
|
|
||||||
|
|
||||||
enum Direction
|
|
||||||
{
|
|
||||||
PD_IN = AbstractBinder::PD_IN,
|
|
||||||
PD_OUT = AbstractBinder::PD_OUT,
|
|
||||||
PD_IN_OUT = AbstractBinder::PD_IN_OUT
|
|
||||||
};
|
|
||||||
|
|
||||||
AbstractBinding(const std::string& name = "", Direction direction = PD_IN, Poco::UInt32 bulkSize = 0);
|
|
||||||
/// Creates the AbstractBinding.
|
|
||||||
|
|
||||||
virtual ~AbstractBinding();
|
|
||||||
/// Destroys the AbstractBinding.
|
|
||||||
|
|
||||||
void setBinder(BinderPtr pBinder);
|
|
||||||
/// Sets the object used for binding; object does NOT take ownership of the pointer.
|
|
||||||
|
|
||||||
BinderPtr getBinder() const;
|
|
||||||
/// Returns the AbstractBinder used for binding data.
|
|
||||||
|
|
||||||
virtual std::size_t numOfColumnsHandled() const = 0;
|
|
||||||
/// Returns the number of columns that the binding handles.
|
|
||||||
///
|
|
||||||
/// The trivial case will be one single column but when
|
|
||||||
/// complex types are used this value can be larger than one.
|
|
||||||
|
|
||||||
virtual std::size_t numOfRowsHandled() const = 0;
|
|
||||||
/// Returns the number of rows that the binding handles.
|
|
||||||
///
|
|
||||||
/// The trivial case will be one single row but
|
|
||||||
/// for collection data types it can be larger.
|
|
||||||
|
|
||||||
virtual bool canBind() const = 0;
|
|
||||||
/// Returns true if we have enough data to bind
|
|
||||||
|
|
||||||
virtual void bind(std::size_t pos) = 0;
|
|
||||||
/// Binds a value to the given column position
|
|
||||||
|
|
||||||
virtual void reset() = 0;
|
|
||||||
/// Allows a binding to be reused.
|
|
||||||
|
|
||||||
AbstractBinder::Direction getDirection() const;
|
|
||||||
/// Returns the binding direction.
|
|
||||||
|
|
||||||
const std::string& name() const;
|
|
||||||
/// Returns the name for this binding.
|
|
||||||
|
|
||||||
bool isBulk() const;
|
|
||||||
/// Returns true if extraction is bulk.
|
|
||||||
|
|
||||||
Poco::UInt32 bulkSize() const;
|
|
||||||
/// Returns the size of the bulk binding.
|
|
||||||
|
|
||||||
private:
|
|
||||||
BinderPtr _pBinder;
|
|
||||||
std::string _name;
|
|
||||||
Direction _direction;
|
|
||||||
Poco::UInt32 _bulkSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef std::vector<AbstractBinding::Ptr> AbstractBindingVec;
|
|
||||||
typedef std::deque<AbstractBinding::Ptr> AbstractBindingDeq;
|
|
||||||
typedef std::list<AbstractBinding::Ptr> AbstractBindingLst;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline AbstractBinder::Ptr AbstractBinding::getBinder() const
|
|
||||||
{
|
{
|
||||||
return _pBinder;
|
|
||||||
|
|
||||||
|
class Data_API AbstractBinding
|
||||||
|
/// AbstractBinding connects a value with a placeholder via an AbstractBinder interface.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef SharedPtr<AbstractBinding> Ptr;
|
||||||
|
typedef AbstractBinder::Ptr BinderPtr;
|
||||||
|
|
||||||
|
enum Direction
|
||||||
|
{
|
||||||
|
PD_IN = AbstractBinder::PD_IN,
|
||||||
|
PD_OUT = AbstractBinder::PD_OUT,
|
||||||
|
PD_IN_OUT = AbstractBinder::PD_IN_OUT
|
||||||
|
};
|
||||||
|
|
||||||
|
AbstractBinding(const std::string & name = "", Direction direction = PD_IN, Poco::UInt32 bulkSize = 0);
|
||||||
|
/// Creates the AbstractBinding.
|
||||||
|
|
||||||
|
virtual ~AbstractBinding();
|
||||||
|
/// Destroys the AbstractBinding.
|
||||||
|
|
||||||
|
void setBinder(BinderPtr pBinder);
|
||||||
|
/// Sets the object used for binding; object does NOT take ownership of the pointer.
|
||||||
|
|
||||||
|
BinderPtr getBinder() const;
|
||||||
|
/// Returns the AbstractBinder used for binding data.
|
||||||
|
|
||||||
|
virtual std::size_t numOfColumnsHandled() const = 0;
|
||||||
|
/// Returns the number of columns that the binding handles.
|
||||||
|
///
|
||||||
|
/// The trivial case will be one single column but when
|
||||||
|
/// complex types are used this value can be larger than one.
|
||||||
|
|
||||||
|
virtual std::size_t numOfRowsHandled() const = 0;
|
||||||
|
/// Returns the number of rows that the binding handles.
|
||||||
|
///
|
||||||
|
/// The trivial case will be one single row but
|
||||||
|
/// for collection data types it can be larger.
|
||||||
|
|
||||||
|
virtual bool canBind() const = 0;
|
||||||
|
/// Returns true if we have enough data to bind
|
||||||
|
|
||||||
|
virtual void bind(std::size_t pos) = 0;
|
||||||
|
/// Binds a value to the given column position
|
||||||
|
|
||||||
|
virtual void reset() = 0;
|
||||||
|
/// Allows a binding to be reused.
|
||||||
|
|
||||||
|
AbstractBinder::Direction getDirection() const;
|
||||||
|
/// Returns the binding direction.
|
||||||
|
|
||||||
|
const std::string & name() const;
|
||||||
|
/// Returns the name for this binding.
|
||||||
|
|
||||||
|
bool isBulk() const;
|
||||||
|
/// Returns true if extraction is bulk.
|
||||||
|
|
||||||
|
Poco::UInt32 bulkSize() const;
|
||||||
|
/// Returns the size of the bulk binding.
|
||||||
|
|
||||||
|
private:
|
||||||
|
BinderPtr _pBinder;
|
||||||
|
std::string _name;
|
||||||
|
Direction _direction;
|
||||||
|
Poco::UInt32 _bulkSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::vector<AbstractBinding::Ptr> AbstractBindingVec;
|
||||||
|
typedef std::deque<AbstractBinding::Ptr> AbstractBindingDeq;
|
||||||
|
typedef std::list<AbstractBinding::Ptr> AbstractBindingLst;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline AbstractBinder::Ptr AbstractBinding::getBinder() const
|
||||||
|
{
|
||||||
|
return _pBinder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const std::string & AbstractBinding::name() const
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline AbstractBinder::Direction AbstractBinding::getDirection() const
|
||||||
|
{
|
||||||
|
return (AbstractBinder::Direction)_direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool AbstractBinding::isBulk() const
|
||||||
|
{
|
||||||
|
return _bulkSize > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Poco::UInt32 AbstractBinding::bulkSize() const
|
||||||
|
{
|
||||||
|
return _bulkSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline const std::string& AbstractBinding::name() const
|
|
||||||
{
|
|
||||||
return _name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline AbstractBinder::Direction AbstractBinding::getDirection() const
|
|
||||||
{
|
|
||||||
return (AbstractBinder::Direction) _direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool AbstractBinding::isBulk() const
|
|
||||||
{
|
|
||||||
return _bulkSize > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Poco::UInt32 AbstractBinding::bulkSize() const
|
|
||||||
{
|
|
||||||
return _bulkSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_AbstractBinding_INCLUDED
|
#endif // Data_AbstractBinding_INCLUDED
|
||||||
|
@ -18,261 +18,264 @@
|
|||||||
#define Data_AbstractExtraction_INCLUDED
|
#define Data_AbstractExtraction_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
#include <cstddef>
|
||||||
|
#include <deque>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
#include "Poco/AutoPtr.h"
|
||||||
#include "Poco/Data/AbstractExtractor.h"
|
#include "Poco/Data/AbstractExtractor.h"
|
||||||
#include "Poco/Data/AbstractPreparation.h"
|
#include "Poco/Data/AbstractPreparation.h"
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/Limit.h"
|
#include "Poco/Data/Limit.h"
|
||||||
#include "Poco/RefCountedObject.h"
|
#include "Poco/RefCountedObject.h"
|
||||||
#include "Poco/UTFString.h"
|
#include "Poco/UTFString.h"
|
||||||
#include "Poco/AutoPtr.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <deque>
|
|
||||||
#include <list>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class AbstractPreparator;
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API AbstractExtraction
|
|
||||||
/// AbstractExtraction is the interface class that connects output positions to concrete values
|
|
||||||
/// retrieved via an AbstractExtractor.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
typedef SharedPtr<AbstractExtraction> Ptr;
|
|
||||||
typedef SharedPtr<AbstractExtractor> ExtractorPtr;
|
|
||||||
typedef SharedPtr<AbstractPreparator> PreparatorPtr;
|
|
||||||
|
|
||||||
AbstractExtraction(Poco::UInt32 limit = Limit::LIMIT_UNLIMITED,
|
|
||||||
Poco::UInt32 position = 0, bool bulk = false);
|
|
||||||
/// Creates the AbstractExtraction. A limit value equal to EXTRACT_UNLIMITED (0xffffffffu)
|
|
||||||
/// means that we extract as much data as possible during one execute.
|
|
||||||
/// Otherwise the limit value is used to partition data extracting to a limited amount of rows.
|
|
||||||
|
|
||||||
virtual ~AbstractExtraction();
|
|
||||||
/// Destroys the AbstractExtraction.
|
|
||||||
|
|
||||||
void setExtractor(ExtractorPtr pExtractor);
|
|
||||||
/// Sets the class used for extracting the data. Does not take ownership of the pointer.
|
|
||||||
|
|
||||||
ExtractorPtr getExtractor() const;
|
|
||||||
/// Retrieves the extractor object
|
|
||||||
|
|
||||||
Poco::UInt32 position() const;
|
|
||||||
/// Returns the extraction position.
|
|
||||||
|
|
||||||
virtual std::size_t numOfColumnsHandled() const = 0;
|
|
||||||
/// Returns the number of columns that the extraction handles.
|
|
||||||
///
|
|
||||||
/// The trivial case will be one single column but when
|
|
||||||
/// complex types are used this value can be larger than one.
|
|
||||||
|
|
||||||
virtual std::size_t numOfRowsHandled() const = 0;
|
|
||||||
/// Returns the number of rows that the extraction handles.
|
|
||||||
///
|
|
||||||
/// The trivial case will be one single row but
|
|
||||||
/// for collection data types (ie vector) it can be larger.
|
|
||||||
|
|
||||||
virtual std::size_t numOfRowsAllowed() const = 0;
|
|
||||||
/// Returns the upper limit on number of rows that the extraction will handle.
|
|
||||||
|
|
||||||
virtual std::size_t extract(std::size_t pos) = 0;
|
|
||||||
/// Extracts a value from the param, starting at the given column position.
|
|
||||||
/// Returns the number of rows extracted.
|
|
||||||
|
|
||||||
virtual void reset();
|
|
||||||
/// Resets the extractor so that it can be re-used.
|
|
||||||
/// Does nothing in this implementation.
|
|
||||||
/// Implementations should override it for different behavior.
|
|
||||||
|
|
||||||
virtual bool canExtract() const;
|
|
||||||
/// Returns true. Implementations should override it for different behavior.
|
|
||||||
|
|
||||||
virtual AbstractPreparation::Ptr createPreparation(PreparatorPtr& pPrep, std::size_t pos) = 0;
|
|
||||||
/// Creates and returns shared pointer to Preparation object for the extracting object.
|
|
||||||
|
|
||||||
void setLimit(Poco::UInt32 limit);
|
|
||||||
/// Sets the limit.
|
|
||||||
|
|
||||||
Poco::UInt32 getLimit() const;
|
|
||||||
/// Gets the limit.
|
|
||||||
|
|
||||||
virtual bool isNull(std::size_t row) const;
|
|
||||||
/// In implementations, this function returns true if value at row is null,
|
|
||||||
/// false otherwise.
|
|
||||||
/// Normal behavior is to replace nulls with default values.
|
|
||||||
/// However, extraction implementations may remember the underlying database
|
|
||||||
/// null values and be able to later provide information about them.
|
|
||||||
/// Here, this function throws NotImplementedException.
|
|
||||||
|
|
||||||
bool isBulk() const;
|
|
||||||
/// Returns true if this is bulk extraction.
|
|
||||||
|
|
||||||
void setEmptyStringIsNull(bool emptyStringIsNull);
|
|
||||||
/// Sets the empty string handling flag.
|
|
||||||
|
|
||||||
bool getEmptyStringIsNull() const;
|
|
||||||
/// Returns the empty string handling flag.
|
|
||||||
|
|
||||||
void setForceEmptyString(bool forceEmptyString);
|
|
||||||
/// Sets the force empty string flag.
|
|
||||||
|
|
||||||
bool getForceEmptyString() const;
|
|
||||||
/// Returns the force empty string flag.
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool isValueNull(const T& str, bool deflt)
|
|
||||||
/// Utility function to determine the nullness of the value.
|
|
||||||
/// This generic version always returns default value
|
|
||||||
/// (i.e. does nothing). The std::string overload does
|
|
||||||
/// the actual work.
|
|
||||||
///
|
|
||||||
{
|
|
||||||
return deflt;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isValueNull(const std::string& str, bool deflt);
|
|
||||||
/// Overload for const reference to std::string.
|
|
||||||
///
|
|
||||||
/// Returns true when following conditions are met:
|
|
||||||
///
|
|
||||||
/// - string is empty
|
|
||||||
/// - getEmptyStringIsNull() returns true
|
|
||||||
|
|
||||||
bool isValueNull(const Poco::UTF16String& str, bool deflt);
|
|
||||||
/// Overload for const reference to UTF16String.
|
|
||||||
///
|
|
||||||
/// Returns true when following conditions are met:
|
|
||||||
///
|
|
||||||
/// - string is empty
|
|
||||||
/// - getEmptyStringIsNull() returns true
|
|
||||||
|
|
||||||
private:
|
|
||||||
template <typename S>
|
|
||||||
bool isStringNull(const S& str, bool deflt)
|
|
||||||
{
|
|
||||||
if (getForceEmptyString()) return false;
|
|
||||||
|
|
||||||
if (getEmptyStringIsNull() && str.empty())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return deflt;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExtractorPtr _pExtractor;
|
|
||||||
Poco::UInt32 _limit;
|
|
||||||
Poco::UInt32 _position;
|
|
||||||
bool _bulk;
|
|
||||||
bool _emptyStringIsNull;
|
|
||||||
bool _forceEmptyString;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef std::vector<AbstractExtraction::Ptr> AbstractExtractionVec;
|
|
||||||
typedef std::vector<AbstractExtractionVec> AbstractExtractionVecVec;
|
|
||||||
typedef std::deque<AbstractExtraction::Ptr> AbstractExtractionDeq;
|
|
||||||
typedef std::vector<AbstractExtractionDeq> AbstractExtractionDeqVec;
|
|
||||||
typedef std::list<AbstractExtraction::Ptr> AbstractExtractionLst;
|
|
||||||
typedef std::vector<AbstractExtractionLst> AbstractExtractionLstVec;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline void AbstractExtraction::setExtractor(ExtractorPtr pExtractor)
|
|
||||||
{
|
{
|
||||||
_pExtractor = pExtractor;
|
|
||||||
|
|
||||||
|
class AbstractPreparator;
|
||||||
|
|
||||||
|
|
||||||
|
class Data_API AbstractExtraction
|
||||||
|
/// AbstractExtraction is the interface class that connects output positions to concrete values
|
||||||
|
/// retrieved via an AbstractExtractor.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef SharedPtr<AbstractExtraction> Ptr;
|
||||||
|
typedef SharedPtr<AbstractExtractor> ExtractorPtr;
|
||||||
|
typedef SharedPtr<AbstractPreparator> PreparatorPtr;
|
||||||
|
|
||||||
|
AbstractExtraction(Poco::UInt32 limit = Limit::LIMIT_UNLIMITED, Poco::UInt32 position = 0, bool bulk = false);
|
||||||
|
/// Creates the AbstractExtraction. A limit value equal to EXTRACT_UNLIMITED (0xffffffffu)
|
||||||
|
/// means that we extract as much data as possible during one execute.
|
||||||
|
/// Otherwise the limit value is used to partition data extracting to a limited amount of rows.
|
||||||
|
|
||||||
|
virtual ~AbstractExtraction();
|
||||||
|
/// Destroys the AbstractExtraction.
|
||||||
|
|
||||||
|
void setExtractor(ExtractorPtr pExtractor);
|
||||||
|
/// Sets the class used for extracting the data. Does not take ownership of the pointer.
|
||||||
|
|
||||||
|
ExtractorPtr getExtractor() const;
|
||||||
|
/// Retrieves the extractor object
|
||||||
|
|
||||||
|
Poco::UInt32 position() const;
|
||||||
|
/// Returns the extraction position.
|
||||||
|
|
||||||
|
virtual std::size_t numOfColumnsHandled() const = 0;
|
||||||
|
/// Returns the number of columns that the extraction handles.
|
||||||
|
///
|
||||||
|
/// The trivial case will be one single column but when
|
||||||
|
/// complex types are used this value can be larger than one.
|
||||||
|
|
||||||
|
virtual std::size_t numOfRowsHandled() const = 0;
|
||||||
|
/// Returns the number of rows that the extraction handles.
|
||||||
|
///
|
||||||
|
/// The trivial case will be one single row but
|
||||||
|
/// for collection data types (ie vector) it can be larger.
|
||||||
|
|
||||||
|
virtual std::size_t numOfRowsAllowed() const = 0;
|
||||||
|
/// Returns the upper limit on number of rows that the extraction will handle.
|
||||||
|
|
||||||
|
virtual std::size_t extract(std::size_t pos) = 0;
|
||||||
|
/// Extracts a value from the param, starting at the given column position.
|
||||||
|
/// Returns the number of rows extracted.
|
||||||
|
|
||||||
|
virtual void reset();
|
||||||
|
/// Resets the extractor so that it can be re-used.
|
||||||
|
/// Does nothing in this implementation.
|
||||||
|
/// Implementations should override it for different behavior.
|
||||||
|
|
||||||
|
virtual bool canExtract() const;
|
||||||
|
/// Returns true. Implementations should override it for different behavior.
|
||||||
|
|
||||||
|
virtual AbstractPreparation::Ptr createPreparation(PreparatorPtr & pPrep, std::size_t pos) = 0;
|
||||||
|
/// Creates and returns shared pointer to Preparation object for the extracting object.
|
||||||
|
|
||||||
|
void setLimit(Poco::UInt32 limit);
|
||||||
|
/// Sets the limit.
|
||||||
|
|
||||||
|
Poco::UInt32 getLimit() const;
|
||||||
|
/// Gets the limit.
|
||||||
|
|
||||||
|
virtual bool isNull(std::size_t row) const;
|
||||||
|
/// In implementations, this function returns true if value at row is null,
|
||||||
|
/// false otherwise.
|
||||||
|
/// Normal behavior is to replace nulls with default values.
|
||||||
|
/// However, extraction implementations may remember the underlying database
|
||||||
|
/// null values and be able to later provide information about them.
|
||||||
|
/// Here, this function throws NotImplementedException.
|
||||||
|
|
||||||
|
bool isBulk() const;
|
||||||
|
/// Returns true if this is bulk extraction.
|
||||||
|
|
||||||
|
void setEmptyStringIsNull(bool emptyStringIsNull);
|
||||||
|
/// Sets the empty string handling flag.
|
||||||
|
|
||||||
|
bool getEmptyStringIsNull() const;
|
||||||
|
/// Returns the empty string handling flag.
|
||||||
|
|
||||||
|
void setForceEmptyString(bool forceEmptyString);
|
||||||
|
/// Sets the force empty string flag.
|
||||||
|
|
||||||
|
bool getForceEmptyString() const;
|
||||||
|
/// Returns the force empty string flag.
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool isValueNull(const T & str, bool deflt)
|
||||||
|
/// Utility function to determine the nullness of the value.
|
||||||
|
/// This generic version always returns default value
|
||||||
|
/// (i.e. does nothing). The std::string overload does
|
||||||
|
/// the actual work.
|
||||||
|
///
|
||||||
|
{
|
||||||
|
return deflt;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValueNull(const std::string & str, bool deflt);
|
||||||
|
/// Overload for const reference to std::string.
|
||||||
|
///
|
||||||
|
/// Returns true when following conditions are met:
|
||||||
|
///
|
||||||
|
/// - string is empty
|
||||||
|
/// - getEmptyStringIsNull() returns true
|
||||||
|
|
||||||
|
bool isValueNull(const Poco::UTF16String & str, bool deflt);
|
||||||
|
/// Overload for const reference to UTF16String.
|
||||||
|
///
|
||||||
|
/// Returns true when following conditions are met:
|
||||||
|
///
|
||||||
|
/// - string is empty
|
||||||
|
/// - getEmptyStringIsNull() returns true
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename S>
|
||||||
|
bool isStringNull(const S & str, bool deflt)
|
||||||
|
{
|
||||||
|
if (getForceEmptyString())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (getEmptyStringIsNull() && str.empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return deflt;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtractorPtr _pExtractor;
|
||||||
|
Poco::UInt32 _limit;
|
||||||
|
Poco::UInt32 _position;
|
||||||
|
bool _bulk;
|
||||||
|
bool _emptyStringIsNull;
|
||||||
|
bool _forceEmptyString;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::vector<AbstractExtraction::Ptr> AbstractExtractionVec;
|
||||||
|
typedef std::vector<AbstractExtractionVec> AbstractExtractionVecVec;
|
||||||
|
typedef std::deque<AbstractExtraction::Ptr> AbstractExtractionDeq;
|
||||||
|
typedef std::vector<AbstractExtractionDeq> AbstractExtractionDeqVec;
|
||||||
|
typedef std::list<AbstractExtraction::Ptr> AbstractExtractionLst;
|
||||||
|
typedef std::vector<AbstractExtractionLst> AbstractExtractionLstVec;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline void AbstractExtraction::setExtractor(ExtractorPtr pExtractor)
|
||||||
|
{
|
||||||
|
_pExtractor = pExtractor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline AbstractExtraction::ExtractorPtr AbstractExtraction::getExtractor() const
|
||||||
|
{
|
||||||
|
return _pExtractor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void AbstractExtraction::setLimit(Poco::UInt32 limit)
|
||||||
|
{
|
||||||
|
_limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Poco::UInt32 AbstractExtraction::getLimit() const
|
||||||
|
{
|
||||||
|
return _limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool AbstractExtraction::isNull(std::size_t row) const
|
||||||
|
{
|
||||||
|
throw NotImplementedException("Check for null values not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Poco::UInt32 AbstractExtraction::position() const
|
||||||
|
{
|
||||||
|
return _position;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool AbstractExtraction::isBulk() const
|
||||||
|
{
|
||||||
|
return _bulk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void AbstractExtraction::reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool AbstractExtraction::canExtract() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void AbstractExtraction::setEmptyStringIsNull(bool emptyStringIsNull)
|
||||||
|
{
|
||||||
|
_emptyStringIsNull = emptyStringIsNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool AbstractExtraction::getEmptyStringIsNull() const
|
||||||
|
{
|
||||||
|
return _emptyStringIsNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void AbstractExtraction::setForceEmptyString(bool forceEmptyString)
|
||||||
|
{
|
||||||
|
_forceEmptyString = forceEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool AbstractExtraction::getForceEmptyString() const
|
||||||
|
{
|
||||||
|
return _forceEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool AbstractExtraction::isValueNull(const std::string & str, bool deflt)
|
||||||
|
{
|
||||||
|
return isStringNull(str, deflt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool AbstractExtraction::isValueNull(const Poco::UTF16String & str, bool deflt)
|
||||||
|
{
|
||||||
|
return isStringNull(str, deflt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline AbstractExtraction::ExtractorPtr AbstractExtraction::getExtractor() const
|
|
||||||
{
|
|
||||||
return _pExtractor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void AbstractExtraction::setLimit(Poco::UInt32 limit)
|
|
||||||
{
|
|
||||||
_limit = limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Poco::UInt32 AbstractExtraction::getLimit() const
|
|
||||||
{
|
|
||||||
return _limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool AbstractExtraction::isNull(std::size_t row) const
|
|
||||||
{
|
|
||||||
throw NotImplementedException("Check for null values not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Poco::UInt32 AbstractExtraction::position() const
|
|
||||||
{
|
|
||||||
return _position;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool AbstractExtraction::isBulk() const
|
|
||||||
{
|
|
||||||
return _bulk;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void AbstractExtraction::reset()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool AbstractExtraction::canExtract() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void AbstractExtraction::setEmptyStringIsNull(bool emptyStringIsNull)
|
|
||||||
{
|
|
||||||
_emptyStringIsNull = emptyStringIsNull;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool AbstractExtraction::getEmptyStringIsNull() const
|
|
||||||
{
|
|
||||||
return _emptyStringIsNull;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void AbstractExtraction::setForceEmptyString(bool forceEmptyString)
|
|
||||||
{
|
|
||||||
_forceEmptyString = forceEmptyString;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool AbstractExtraction::getForceEmptyString() const
|
|
||||||
{
|
|
||||||
return _forceEmptyString;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool AbstractExtraction::isValueNull(const std::string& str, bool deflt)
|
|
||||||
{
|
|
||||||
return isStringNull(str, deflt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool AbstractExtraction::isValueNull(const Poco::UTF16String& str, bool deflt)
|
|
||||||
{
|
|
||||||
return isStringNull(str, deflt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_AbstractExtraction_INCLUDED
|
#endif // Data_AbstractExtraction_INCLUDED
|
||||||
|
@ -18,334 +18,338 @@
|
|||||||
#define Data_AbstractExtractor_INCLUDED
|
#define Data_AbstractExtractor_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
#include <cstddef>
|
||||||
#include "Poco/Data/Constants.h"
|
|
||||||
#include "Poco/Data/LOB.h"
|
|
||||||
#include "Poco/UTFString.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstddef>
|
#include <vector>
|
||||||
|
#include "Poco/Data/Constants.h"
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
|
#include "Poco/Data/LOB.h"
|
||||||
|
#include "Poco/UTFString.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
class DateTime;
|
class DateTime;
|
||||||
class Any;
|
class Any;
|
||||||
|
|
||||||
namespace Dynamic {
|
namespace Dynamic
|
||||||
class Var;
|
{
|
||||||
|
class Var;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Data {
|
namespace Data
|
||||||
|
|
||||||
|
|
||||||
class Date;
|
|
||||||
class Time;
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API AbstractExtractor
|
|
||||||
/// Interface used to extract data from a single result row.
|
|
||||||
/// If an extractor receives null it is not allowed to change val!
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
typedef SharedPtr<AbstractExtractor> Ptr;
|
|
||||||
|
|
||||||
AbstractExtractor();
|
|
||||||
/// Creates the AbstractExtractor.
|
|
||||||
|
|
||||||
virtual ~AbstractExtractor();
|
class Date;
|
||||||
/// Destroys the AbstractExtractor.
|
class Time;
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, Poco::Int8& val) = 0;
|
|
||||||
/// Extracts an Int8. Returns false if null was received.
|
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<Poco::Int8>& val);
|
class Data_API AbstractExtractor
|
||||||
/// Extracts an Int8 vector.
|
/// Interface used to extract data from a single result row.
|
||||||
|
/// If an extractor receives null it is not allowed to change val!
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef SharedPtr<AbstractExtractor> Ptr;
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<Poco::Int8>& val);
|
AbstractExtractor();
|
||||||
/// Extracts an Int8 deque.
|
/// Creates the AbstractExtractor.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<Poco::Int8>& val);
|
virtual ~AbstractExtractor();
|
||||||
/// Extracts an Int8 list.
|
/// Destroys the AbstractExtractor.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, Poco::UInt8& val) = 0;
|
virtual bool extract(std::size_t pos, Poco::Int8 & val) = 0;
|
||||||
/// Extracts an UInt8. Returns false if null was received.
|
/// Extracts an Int8. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<Poco::UInt8>& val);
|
virtual bool extract(std::size_t pos, std::vector<Poco::Int8> & val);
|
||||||
/// Extracts an UInt8 vector.
|
/// Extracts an Int8 vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<Poco::UInt8>& val);
|
virtual bool extract(std::size_t pos, std::deque<Poco::Int8> & val);
|
||||||
/// Extracts an UInt8 deque.
|
/// Extracts an Int8 deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<Poco::UInt8>& val);
|
virtual bool extract(std::size_t pos, std::list<Poco::Int8> & val);
|
||||||
/// Extracts an UInt8 list.
|
/// Extracts an Int8 list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, Poco::Int16& val) = 0;
|
virtual bool extract(std::size_t pos, Poco::UInt8 & val) = 0;
|
||||||
/// Extracts an Int16. Returns false if null was received.
|
/// Extracts an UInt8. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<Poco::Int16>& val);
|
virtual bool extract(std::size_t pos, std::vector<Poco::UInt8> & val);
|
||||||
/// Extracts an Int16 vector.
|
/// Extracts an UInt8 vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<Poco::Int16>& val);
|
virtual bool extract(std::size_t pos, std::deque<Poco::UInt8> & val);
|
||||||
/// Extracts an Int16 deque.
|
/// Extracts an UInt8 deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<Poco::Int16>& val);
|
virtual bool extract(std::size_t pos, std::list<Poco::UInt8> & val);
|
||||||
/// Extracts an Int16 list.
|
/// Extracts an UInt8 list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, Poco::UInt16& val) = 0;
|
virtual bool extract(std::size_t pos, Poco::Int16 & val) = 0;
|
||||||
/// Extracts an UInt16. Returns false if null was received.
|
/// Extracts an Int16. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<Poco::UInt16>& val);
|
virtual bool extract(std::size_t pos, std::vector<Poco::Int16> & val);
|
||||||
/// Extracts an UInt16 vector.
|
/// Extracts an Int16 vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<Poco::UInt16>& val);
|
virtual bool extract(std::size_t pos, std::deque<Poco::Int16> & val);
|
||||||
/// Extracts an UInt16 deque.
|
/// Extracts an Int16 deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<Poco::UInt16>& val);
|
virtual bool extract(std::size_t pos, std::list<Poco::Int16> & val);
|
||||||
/// Extracts an UInt16 list.
|
/// Extracts an Int16 list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, Poco::Int32& val) = 0;
|
virtual bool extract(std::size_t pos, Poco::UInt16 & val) = 0;
|
||||||
/// Extracts an Int32. Returns false if null was received.
|
/// Extracts an UInt16. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<Poco::Int32>& val);
|
virtual bool extract(std::size_t pos, std::vector<Poco::UInt16> & val);
|
||||||
/// Extracts an Int32 vector.
|
/// Extracts an UInt16 vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<Poco::Int32>& val);
|
virtual bool extract(std::size_t pos, std::deque<Poco::UInt16> & val);
|
||||||
/// Extracts an Int32 deque.
|
/// Extracts an UInt16 deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<Poco::Int32>& val);
|
virtual bool extract(std::size_t pos, std::list<Poco::UInt16> & val);
|
||||||
/// Extracts an Int32 list.
|
/// Extracts an UInt16 list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, Poco::UInt32& val) = 0;
|
virtual bool extract(std::size_t pos, Poco::Int32 & val) = 0;
|
||||||
/// Extracts an UInt32. Returns false if null was received.
|
/// Extracts an Int32. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<Poco::UInt32>& val);
|
virtual bool extract(std::size_t pos, std::vector<Poco::Int32> & val);
|
||||||
/// Extracts an UInt32 vector.
|
/// Extracts an Int32 vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<Poco::UInt32>& val);
|
virtual bool extract(std::size_t pos, std::deque<Poco::Int32> & val);
|
||||||
/// Extracts an UInt32 deque.
|
/// Extracts an Int32 deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<Poco::UInt32>& val);
|
virtual bool extract(std::size_t pos, std::list<Poco::Int32> & val);
|
||||||
/// Extracts an UInt32 list.
|
/// Extracts an Int32 list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, Poco::Int64& val) = 0;
|
virtual bool extract(std::size_t pos, Poco::UInt32 & val) = 0;
|
||||||
/// Extracts an Int64. Returns false if null was received.
|
/// Extracts an UInt32. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<Poco::Int64>& val);
|
virtual bool extract(std::size_t pos, std::vector<Poco::UInt32> & val);
|
||||||
/// Extracts an Int64 vector.
|
/// Extracts an UInt32 vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<Poco::Int64>& val);
|
virtual bool extract(std::size_t pos, std::deque<Poco::UInt32> & val);
|
||||||
/// Extracts an Int64 deque.
|
/// Extracts an UInt32 deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<Poco::Int64>& val);
|
virtual bool extract(std::size_t pos, std::list<Poco::UInt32> & val);
|
||||||
/// Extracts an Int64 list.
|
/// Extracts an UInt32 list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, Poco::UInt64& val) = 0;
|
virtual bool extract(std::size_t pos, Poco::Int64 & val) = 0;
|
||||||
/// Extracts an UInt64. Returns false if null was received.
|
/// Extracts an Int64. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<Poco::UInt64>& val);
|
virtual bool extract(std::size_t pos, std::vector<Poco::Int64> & val);
|
||||||
/// Extracts an UInt64 vector.
|
/// Extracts an Int64 vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<Poco::UInt64>& val);
|
virtual bool extract(std::size_t pos, std::deque<Poco::Int64> & val);
|
||||||
/// Extracts an UInt64 deque.
|
/// Extracts an Int64 deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<Poco::UInt64>& val);
|
virtual bool extract(std::size_t pos, std::list<Poco::Int64> & val);
|
||||||
/// Extracts an UInt64 list.
|
/// Extracts an Int64 list.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, Poco::UInt64 & val) = 0;
|
||||||
|
/// Extracts an UInt64. Returns false if null was received.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::vector<Poco::UInt64> & val);
|
||||||
|
/// Extracts an UInt64 vector.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::deque<Poco::UInt64> & val);
|
||||||
|
/// Extracts an UInt64 deque.
|
||||||
|
|
||||||
|
virtual bool extract(std::size_t pos, std::list<Poco::UInt64> & val);
|
||||||
|
/// Extracts an UInt64 list.
|
||||||
|
|
||||||
#ifndef POCO_LONG_IS_64_BIT
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
virtual bool extract(std::size_t pos, long& val) = 0;
|
virtual bool extract(std::size_t pos, long & val) = 0;
|
||||||
/// Extracts a long. Returns false if null was received.
|
/// Extracts a long. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, unsigned long& val) = 0;
|
virtual bool extract(std::size_t pos, unsigned long & val) = 0;
|
||||||
/// Extracts an unsigned long. Returns false if null was received.
|
/// Extracts an unsigned long. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<long>& val);
|
virtual bool extract(std::size_t pos, std::vector<long> & val);
|
||||||
/// Extracts a long vector.
|
/// Extracts a long vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<long>& val);
|
virtual bool extract(std::size_t pos, std::deque<long> & val);
|
||||||
/// Extracts a long deque.
|
/// Extracts a long deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<long>& val);
|
virtual bool extract(std::size_t pos, std::list<long> & val);
|
||||||
/// Extracts a long list.
|
/// Extracts a long list.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, bool& val) = 0;
|
virtual bool extract(std::size_t pos, bool & val) = 0;
|
||||||
/// Extracts a boolean. Returns false if null was received.
|
/// Extracts a boolean. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<bool>& val);
|
virtual bool extract(std::size_t pos, std::vector<bool> & val);
|
||||||
/// Extracts a boolean vector.
|
/// Extracts a boolean vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<bool>& val);
|
virtual bool extract(std::size_t pos, std::deque<bool> & val);
|
||||||
/// Extracts a boolean deque.
|
/// Extracts a boolean deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<bool>& val);
|
virtual bool extract(std::size_t pos, std::list<bool> & val);
|
||||||
/// Extracts a boolean list.
|
/// Extracts a boolean list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, float& val) = 0;
|
virtual bool extract(std::size_t pos, float & val) = 0;
|
||||||
/// Extracts a float. Returns false if null was received.
|
/// Extracts a float. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<float>& val);
|
virtual bool extract(std::size_t pos, std::vector<float> & val);
|
||||||
/// Extracts a float vector.
|
/// Extracts a float vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<float>& val);
|
virtual bool extract(std::size_t pos, std::deque<float> & val);
|
||||||
/// Extracts a float deque.
|
/// Extracts a float deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<float>& val);
|
virtual bool extract(std::size_t pos, std::list<float> & val);
|
||||||
/// Extracts a float list.
|
/// Extracts a float list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, double& val) = 0;
|
virtual bool extract(std::size_t pos, double & val) = 0;
|
||||||
/// Extracts a double. Returns false if null was received.
|
/// Extracts a double. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<double>& val);
|
virtual bool extract(std::size_t pos, std::vector<double> & val);
|
||||||
/// Extracts a double vector.
|
/// Extracts a double vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<double>& val);
|
virtual bool extract(std::size_t pos, std::deque<double> & val);
|
||||||
/// Extracts a double deque.
|
/// Extracts a double deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<double>& val);
|
virtual bool extract(std::size_t pos, std::list<double> & val);
|
||||||
/// Extracts a double list.
|
/// Extracts a double list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, char& val) = 0;
|
virtual bool extract(std::size_t pos, char & val) = 0;
|
||||||
/// Extracts a single character. Returns false if null was received.
|
/// Extracts a single character. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<char>& val);
|
virtual bool extract(std::size_t pos, std::vector<char> & val);
|
||||||
/// Extracts a character vector.
|
/// Extracts a character vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<char>& val);
|
virtual bool extract(std::size_t pos, std::deque<char> & val);
|
||||||
/// Extracts a character deque.
|
/// Extracts a character deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<char>& val);
|
virtual bool extract(std::size_t pos, std::list<char> & val);
|
||||||
/// Extracts a character list.
|
/// Extracts a character list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::string& val) = 0;
|
virtual bool extract(std::size_t pos, std::string & val) = 0;
|
||||||
/// Extracts a string. Returns false if null was received.
|
/// Extracts a string. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<std::string>& val);
|
virtual bool extract(std::size_t pos, std::vector<std::string> & val);
|
||||||
/// Extracts a string vector.
|
/// Extracts a string vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<std::string>& val);
|
virtual bool extract(std::size_t pos, std::deque<std::string> & val);
|
||||||
/// Extracts a string deque.
|
/// Extracts a string deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<std::string>& val);
|
virtual bool extract(std::size_t pos, std::list<std::string> & val);
|
||||||
/// Extracts a string list.
|
/// Extracts a string list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, UTF16String& val);
|
virtual bool extract(std::size_t pos, UTF16String & val);
|
||||||
/// Extracts a UTF16String. Returns false if null was received.
|
/// Extracts a UTF16String. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<UTF16String>& val);
|
virtual bool extract(std::size_t pos, std::vector<UTF16String> & val);
|
||||||
/// Extracts a UTF16String vector.
|
/// Extracts a UTF16String vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<UTF16String>& val);
|
virtual bool extract(std::size_t pos, std::deque<UTF16String> & val);
|
||||||
/// Extracts a UTF16String deque.
|
/// Extracts a UTF16String deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<UTF16String>& val);
|
virtual bool extract(std::size_t pos, std::list<UTF16String> & val);
|
||||||
/// Extracts a UTF16String list.
|
/// Extracts a UTF16String list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, BLOB& val) = 0;
|
virtual bool extract(std::size_t pos, BLOB & val) = 0;
|
||||||
/// Extracts a BLOB. Returns false if null was received.
|
/// Extracts a BLOB. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, CLOB& val) = 0;
|
virtual bool extract(std::size_t pos, CLOB & val) = 0;
|
||||||
/// Extracts a CLOB. Returns false if null was received.
|
/// Extracts a CLOB. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<BLOB>& val);
|
virtual bool extract(std::size_t pos, std::vector<BLOB> & val);
|
||||||
/// Extracts a BLOB vector.
|
/// Extracts a BLOB vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<BLOB>& val);
|
virtual bool extract(std::size_t pos, std::deque<BLOB> & val);
|
||||||
/// Extracts a BLOB deque.
|
/// Extracts a BLOB deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<BLOB>& val);
|
virtual bool extract(std::size_t pos, std::list<BLOB> & val);
|
||||||
/// Extracts a BLOB list.
|
/// Extracts a BLOB list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<CLOB>& val);
|
virtual bool extract(std::size_t pos, std::vector<CLOB> & val);
|
||||||
/// Extracts a CLOB vector.
|
/// Extracts a CLOB vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<CLOB>& val);
|
virtual bool extract(std::size_t pos, std::deque<CLOB> & val);
|
||||||
/// Extracts a CLOB deque.
|
/// Extracts a CLOB deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<CLOB>& val);
|
virtual bool extract(std::size_t pos, std::list<CLOB> & val);
|
||||||
/// Extracts a CLOB list.
|
/// Extracts a CLOB list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, DateTime& val) = 0;
|
virtual bool extract(std::size_t pos, DateTime & val) = 0;
|
||||||
/// Extracts a DateTime. Returns false if null was received.
|
/// Extracts a DateTime. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<DateTime>& val);
|
virtual bool extract(std::size_t pos, std::vector<DateTime> & val);
|
||||||
/// Extracts a DateTime vector.
|
/// Extracts a DateTime vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<DateTime>& val);
|
virtual bool extract(std::size_t pos, std::deque<DateTime> & val);
|
||||||
/// Extracts a DateTime deque.
|
/// Extracts a DateTime deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<DateTime>& val);
|
virtual bool extract(std::size_t pos, std::list<DateTime> & val);
|
||||||
/// Extracts a DateTime list.
|
/// Extracts a DateTime list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, Date& val) = 0;
|
virtual bool extract(std::size_t pos, Date & val) = 0;
|
||||||
/// Extracts a Date. Returns false if null was received.
|
/// Extracts a Date. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<Date>& val);
|
virtual bool extract(std::size_t pos, std::vector<Date> & val);
|
||||||
/// Extracts a Date vector.
|
/// Extracts a Date vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<Date>& val);
|
virtual bool extract(std::size_t pos, std::deque<Date> & val);
|
||||||
/// Extracts a Date deque.
|
/// Extracts a Date deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<Date>& val);
|
virtual bool extract(std::size_t pos, std::list<Date> & val);
|
||||||
/// Extracts a Date list.
|
/// Extracts a Date list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, Time& val) = 0;
|
virtual bool extract(std::size_t pos, Time & val) = 0;
|
||||||
/// Extracts a Time. Returns false if null was received.
|
/// Extracts a Time. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<Time>& val);
|
virtual bool extract(std::size_t pos, std::vector<Time> & val);
|
||||||
/// Extracts a Time vector.
|
/// Extracts a Time vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<Time>& val);
|
virtual bool extract(std::size_t pos, std::deque<Time> & val);
|
||||||
/// Extracts a Time deque.
|
/// Extracts a Time deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<Time>& val);
|
virtual bool extract(std::size_t pos, std::list<Time> & val);
|
||||||
/// Extracts a Time list.
|
/// Extracts a Time list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, Any& val) = 0;
|
virtual bool extract(std::size_t pos, Any & val) = 0;
|
||||||
/// Extracts an Any. Returns false if null was received.
|
/// Extracts an Any. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<Any>& val);
|
virtual bool extract(std::size_t pos, std::vector<Any> & val);
|
||||||
/// Extracts an Any vector.
|
/// Extracts an Any vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<Any>& val);
|
virtual bool extract(std::size_t pos, std::deque<Any> & val);
|
||||||
/// Extracts an Any deque.
|
/// Extracts an Any deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<Any>& val);
|
virtual bool extract(std::size_t pos, std::list<Any> & val);
|
||||||
/// Extracts an Any list.
|
/// Extracts an Any list.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, Poco::Dynamic::Var& val) = 0;
|
virtual bool extract(std::size_t pos, Poco::Dynamic::Var & val) = 0;
|
||||||
/// Extracts a Var. Returns false if null was received.
|
/// Extracts a Var. Returns false if null was received.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::vector<Poco::Dynamic::Var>& val);
|
virtual bool extract(std::size_t pos, std::vector<Poco::Dynamic::Var> & val);
|
||||||
/// Extracts a Var vector.
|
/// Extracts a Var vector.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::deque<Poco::Dynamic::Var>& val);
|
virtual bool extract(std::size_t pos, std::deque<Poco::Dynamic::Var> & val);
|
||||||
/// Extracts a Var deque.
|
/// Extracts a Var deque.
|
||||||
|
|
||||||
virtual bool extract(std::size_t pos, std::list<Poco::Dynamic::Var>& val);
|
virtual bool extract(std::size_t pos, std::list<Poco::Dynamic::Var> & val);
|
||||||
/// Extracts a Var list.
|
/// Extracts a Var list.
|
||||||
|
|
||||||
virtual bool isNull(std::size_t col, std::size_t row = POCO_DATA_INVALID_ROW) = 0;
|
virtual bool isNull(std::size_t col, std::size_t row = POCO_DATA_INVALID_ROW) = 0;
|
||||||
/// Returns true if the value at [col,row] position is null.
|
/// Returns true if the value at [col,row] position is null.
|
||||||
|
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
/// Resets any information internally cached by the extractor.
|
/// Resets any information internally cached by the extractor.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// inlines
|
||||||
|
///
|
||||||
|
inline void AbstractExtractor::reset()
|
||||||
|
{
|
||||||
|
//default no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// inlines
|
|
||||||
///
|
|
||||||
inline void AbstractExtractor::reset()
|
|
||||||
{
|
|
||||||
//default no-op
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_AbstractExtractor_INCLUDED
|
#endif // Data_AbstractExtractor_INCLUDED
|
||||||
|
@ -18,54 +18,57 @@
|
|||||||
#define Data_AbstractPreparation_INCLUDED
|
#define Data_AbstractPreparation_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
|
||||||
#include "Poco/Data/AbstractPreparator.h"
|
|
||||||
#include "Poco/SharedPtr.h"
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include "Poco/Data/AbstractPreparator.h"
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
|
#include "Poco/SharedPtr.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API AbstractPreparation
|
|
||||||
/// Interface for calling the appropriate AbstractPreparator method
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
typedef SharedPtr<AbstractPreparation> Ptr;
|
|
||||||
typedef AbstractPreparator::Ptr PreparatorPtr;
|
|
||||||
|
|
||||||
AbstractPreparation(PreparatorPtr pPreparator);
|
|
||||||
/// Creates the AbstractPreparation.
|
|
||||||
|
|
||||||
virtual ~AbstractPreparation();
|
|
||||||
/// Destroys the AbstractPreparation.
|
|
||||||
|
|
||||||
virtual void prepare() = 0;
|
|
||||||
/// Prepares data.
|
|
||||||
|
|
||||||
protected:
|
|
||||||
AbstractPreparation();
|
|
||||||
AbstractPreparation(const AbstractPreparation&);
|
|
||||||
AbstractPreparation& operator = (const AbstractPreparation&);
|
|
||||||
|
|
||||||
PreparatorPtr preparation();
|
|
||||||
/// Returns the preparation object
|
|
||||||
|
|
||||||
PreparatorPtr _pPreparator;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline AbstractPreparation::PreparatorPtr AbstractPreparation::preparation()
|
|
||||||
{
|
{
|
||||||
return _pPreparator;
|
|
||||||
|
|
||||||
|
class Data_API AbstractPreparation
|
||||||
|
/// Interface for calling the appropriate AbstractPreparator method
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef SharedPtr<AbstractPreparation> Ptr;
|
||||||
|
typedef AbstractPreparator::Ptr PreparatorPtr;
|
||||||
|
|
||||||
|
AbstractPreparation(PreparatorPtr pPreparator);
|
||||||
|
/// Creates the AbstractPreparation.
|
||||||
|
|
||||||
|
virtual ~AbstractPreparation();
|
||||||
|
/// Destroys the AbstractPreparation.
|
||||||
|
|
||||||
|
virtual void prepare() = 0;
|
||||||
|
/// Prepares data.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AbstractPreparation();
|
||||||
|
AbstractPreparation(const AbstractPreparation &);
|
||||||
|
AbstractPreparation & operator=(const AbstractPreparation &);
|
||||||
|
|
||||||
|
PreparatorPtr preparation();
|
||||||
|
/// Returns the preparation object
|
||||||
|
|
||||||
|
PreparatorPtr _pPreparator;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline AbstractPreparation::PreparatorPtr AbstractPreparation::preparation()
|
||||||
|
{
|
||||||
|
return _pPreparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_AbstractPreparation_INCLUDED
|
#endif // Data_AbstractPreparation_INCLUDED
|
||||||
|
@ -18,371 +18,375 @@
|
|||||||
#define Data_AbstractPreparator_INCLUDED
|
#define Data_AbstractPreparator_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
#include <cstddef>
|
||||||
#include "Poco/RefCountedObject.h"
|
|
||||||
#include "Poco/Data/LOB.h"
|
|
||||||
#include "Poco/UTFString.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <cstddef>
|
#include <vector>
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
|
#include "Poco/Data/LOB.h"
|
||||||
|
#include "Poco/RefCountedObject.h"
|
||||||
|
#include "Poco/UTFString.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
class DateTime;
|
class DateTime;
|
||||||
class Any;
|
class Any;
|
||||||
|
|
||||||
namespace Dynamic {
|
namespace Dynamic
|
||||||
class Var;
|
{
|
||||||
|
class Var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace Data {
|
namespace Data
|
||||||
|
|
||||||
|
|
||||||
class Date;
|
|
||||||
class Time;
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API AbstractPreparator
|
|
||||||
/// Interface used for database preparation where we first have to register all data types
|
|
||||||
/// (and memory output locations) before extracting data, e.g. ODBC.
|
|
||||||
/// Extract works as two-phase extract: first we call prepare once, then extract n-times.
|
|
||||||
/// There are cases (bulk operations using std::vector storage) when extract is called only once.
|
|
||||||
/// The value passed to a prepare() call is not used by the prepare, serving only as an indication
|
|
||||||
/// of the data type being prepared, thus all values are passed as const references.
|
|
||||||
/// Implementing this interface is not mandatory for a connector. Connectors that only extract data
|
|
||||||
/// after SQL execution (e.g. SQLite) do not need this functionality at all.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
typedef SharedPtr<AbstractPreparator> Ptr;
|
|
||||||
|
|
||||||
AbstractPreparator(Poco::UInt32 length = 1u);
|
|
||||||
/// Creates the AbstractPreparator.
|
|
||||||
|
|
||||||
virtual ~AbstractPreparator();
|
class Date;
|
||||||
/// Destroys the AbstractPreparator.
|
class Time;
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const Poco::Int8&) = 0;
|
|
||||||
/// Prepares an Int8.
|
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<Poco::Int8>& val);
|
class Data_API AbstractPreparator
|
||||||
/// Prepares an Int8 vector.
|
/// Interface used for database preparation where we first have to register all data types
|
||||||
|
/// (and memory output locations) before extracting data, e.g. ODBC.
|
||||||
|
/// Extract works as two-phase extract: first we call prepare once, then extract n-times.
|
||||||
|
/// There are cases (bulk operations using std::vector storage) when extract is called only once.
|
||||||
|
/// The value passed to a prepare() call is not used by the prepare, serving only as an indication
|
||||||
|
/// of the data type being prepared, thus all values are passed as const references.
|
||||||
|
/// Implementing this interface is not mandatory for a connector. Connectors that only extract data
|
||||||
|
/// after SQL execution (e.g. SQLite) do not need this functionality at all.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef SharedPtr<AbstractPreparator> Ptr;
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<Poco::Int8>& val);
|
AbstractPreparator(Poco::UInt32 length = 1u);
|
||||||
/// Prepares an Int8 deque.
|
/// Creates the AbstractPreparator.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<Poco::Int8>& val);
|
virtual ~AbstractPreparator();
|
||||||
/// Prepares an Int8 list.
|
/// Destroys the AbstractPreparator.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const Poco::UInt8&) = 0;
|
virtual void prepare(std::size_t pos, const Poco::Int8 &) = 0;
|
||||||
/// Prepares an UInt8.
|
/// Prepares an Int8.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<Poco::UInt8>& val);
|
virtual void prepare(std::size_t pos, const std::vector<Poco::Int8> & val);
|
||||||
/// Prepares an UInt8 vector.
|
/// Prepares an Int8 vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<Poco::UInt8>& val);
|
virtual void prepare(std::size_t pos, const std::deque<Poco::Int8> & val);
|
||||||
/// Prepares an UInt8 deque.
|
/// Prepares an Int8 deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<Poco::UInt8>& val);
|
virtual void prepare(std::size_t pos, const std::list<Poco::Int8> & val);
|
||||||
/// Prepares an UInt8 list.
|
/// Prepares an Int8 list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const Poco::Int16&) = 0;
|
virtual void prepare(std::size_t pos, const Poco::UInt8 &) = 0;
|
||||||
/// Prepares an Int16.
|
/// Prepares an UInt8.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<Poco::Int16>& val);
|
virtual void prepare(std::size_t pos, const std::vector<Poco::UInt8> & val);
|
||||||
/// Prepares an Int16 vector.
|
/// Prepares an UInt8 vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<Poco::Int16>& val);
|
virtual void prepare(std::size_t pos, const std::deque<Poco::UInt8> & val);
|
||||||
/// Prepares an Int16 deque.
|
/// Prepares an UInt8 deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<Poco::Int16>& val);
|
virtual void prepare(std::size_t pos, const std::list<Poco::UInt8> & val);
|
||||||
/// Prepares an Int16 list.
|
/// Prepares an UInt8 list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const Poco::UInt16&) = 0;
|
virtual void prepare(std::size_t pos, const Poco::Int16 &) = 0;
|
||||||
/// Prepares an UInt16.
|
/// Prepares an Int16.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<Poco::UInt16>& val);
|
virtual void prepare(std::size_t pos, const std::vector<Poco::Int16> & val);
|
||||||
/// Prepares an UInt16 vector.
|
/// Prepares an Int16 vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<Poco::UInt16>& val);
|
virtual void prepare(std::size_t pos, const std::deque<Poco::Int16> & val);
|
||||||
/// Prepares an UInt16 deque.
|
/// Prepares an Int16 deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<Poco::UInt16>& val);
|
virtual void prepare(std::size_t pos, const std::list<Poco::Int16> & val);
|
||||||
/// Prepares an UInt16 list.
|
/// Prepares an Int16 list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const Poco::Int32&) = 0;
|
virtual void prepare(std::size_t pos, const Poco::UInt16 &) = 0;
|
||||||
/// Prepares an Int32.
|
/// Prepares an UInt16.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<Poco::Int32>& val);
|
virtual void prepare(std::size_t pos, const std::vector<Poco::UInt16> & val);
|
||||||
/// Prepares an Int32 vector.
|
/// Prepares an UInt16 vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<Poco::Int32>& val);
|
virtual void prepare(std::size_t pos, const std::deque<Poco::UInt16> & val);
|
||||||
/// Prepares an Int32 deque.
|
/// Prepares an UInt16 deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<Poco::Int32>& val);
|
virtual void prepare(std::size_t pos, const std::list<Poco::UInt16> & val);
|
||||||
/// Prepares an Int32 list.
|
/// Prepares an UInt16 list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const Poco::UInt32&) = 0;
|
virtual void prepare(std::size_t pos, const Poco::Int32 &) = 0;
|
||||||
/// Prepares an UInt32.
|
/// Prepares an Int32.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<Poco::UInt32>& val);
|
virtual void prepare(std::size_t pos, const std::vector<Poco::Int32> & val);
|
||||||
/// Prepares an UInt32 vector.
|
/// Prepares an Int32 vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<Poco::UInt32>& val);
|
virtual void prepare(std::size_t pos, const std::deque<Poco::Int32> & val);
|
||||||
/// Prepares an UInt32 deque.
|
/// Prepares an Int32 deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<Poco::UInt32>& val);
|
virtual void prepare(std::size_t pos, const std::list<Poco::Int32> & val);
|
||||||
/// Prepares an UInt32 list.
|
/// Prepares an Int32 list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const Poco::Int64&) = 0;
|
virtual void prepare(std::size_t pos, const Poco::UInt32 &) = 0;
|
||||||
/// Prepares an Int64.
|
/// Prepares an UInt32.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<Poco::Int64>& val);
|
virtual void prepare(std::size_t pos, const std::vector<Poco::UInt32> & val);
|
||||||
/// Prepares an Int64 vector.
|
/// Prepares an UInt32 vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<Poco::Int64>& val);
|
virtual void prepare(std::size_t pos, const std::deque<Poco::UInt32> & val);
|
||||||
/// Prepares an Int64 deque.
|
/// Prepares an UInt32 deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<Poco::Int64>& val);
|
virtual void prepare(std::size_t pos, const std::list<Poco::UInt32> & val);
|
||||||
/// Prepares an Int64 list.
|
/// Prepares an UInt32 list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const Poco::UInt64&) = 0;
|
virtual void prepare(std::size_t pos, const Poco::Int64 &) = 0;
|
||||||
/// Prepares an UInt64.
|
/// Prepares an Int64.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<Poco::UInt64>& val);
|
virtual void prepare(std::size_t pos, const std::vector<Poco::Int64> & val);
|
||||||
/// Prepares an UInt64 vector.
|
/// Prepares an Int64 vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<Poco::UInt64>& val);
|
virtual void prepare(std::size_t pos, const std::deque<Poco::Int64> & val);
|
||||||
/// Prepares an UInt64 deque.
|
/// Prepares an Int64 deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<Poco::UInt64>& val);
|
virtual void prepare(std::size_t pos, const std::list<Poco::Int64> & val);
|
||||||
/// Prepares an UInt64 list.
|
/// Prepares an Int64 list.
|
||||||
|
|
||||||
|
virtual void prepare(std::size_t pos, const Poco::UInt64 &) = 0;
|
||||||
|
/// Prepares an UInt64.
|
||||||
|
|
||||||
|
virtual void prepare(std::size_t pos, const std::vector<Poco::UInt64> & val);
|
||||||
|
/// Prepares an UInt64 vector.
|
||||||
|
|
||||||
|
virtual void prepare(std::size_t pos, const std::deque<Poco::UInt64> & val);
|
||||||
|
/// Prepares an UInt64 deque.
|
||||||
|
|
||||||
|
virtual void prepare(std::size_t pos, const std::list<Poco::UInt64> & val);
|
||||||
|
/// Prepares an UInt64 list.
|
||||||
|
|
||||||
#ifndef POCO_LONG_IS_64_BIT
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
virtual void prepare(std::size_t pos, const long&) = 0;
|
virtual void prepare(std::size_t pos, const long &) = 0;
|
||||||
/// Prepares a long.
|
/// Prepares a long.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const unsigned long&) = 0;
|
virtual void prepare(std::size_t pos, const unsigned long &) = 0;
|
||||||
/// Prepares an unsigned long.
|
/// Prepares an unsigned long.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<long>& val);
|
virtual void prepare(std::size_t pos, const std::vector<long> & val);
|
||||||
/// Prepares a long vector.
|
/// Prepares a long vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<long>& val);
|
virtual void prepare(std::size_t pos, const std::deque<long> & val);
|
||||||
/// Prepares a long deque.
|
/// Prepares a long deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<long>& val);
|
virtual void prepare(std::size_t pos, const std::list<long> & val);
|
||||||
/// Prepares a long list.
|
/// Prepares a long list.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const bool&) = 0;
|
virtual void prepare(std::size_t pos, const bool &) = 0;
|
||||||
/// Prepares a boolean.
|
/// Prepares a boolean.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<bool>& val);
|
virtual void prepare(std::size_t pos, const std::vector<bool> & val);
|
||||||
/// Prepares a boolean vector.
|
/// Prepares a boolean vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<bool>& val);
|
virtual void prepare(std::size_t pos, const std::deque<bool> & val);
|
||||||
/// Prepares a boolean deque.
|
/// Prepares a boolean deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<bool>& val);
|
virtual void prepare(std::size_t pos, const std::list<bool> & val);
|
||||||
/// Prepares a boolean list.
|
/// Prepares a boolean list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const float&) = 0;
|
virtual void prepare(std::size_t pos, const float &) = 0;
|
||||||
/// Prepares a float.
|
/// Prepares a float.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<float>& val);
|
virtual void prepare(std::size_t pos, const std::vector<float> & val);
|
||||||
/// Prepares a float vector.
|
/// Prepares a float vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<float>& val);
|
virtual void prepare(std::size_t pos, const std::deque<float> & val);
|
||||||
/// Prepares a float deque.
|
/// Prepares a float deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<float>& val);
|
virtual void prepare(std::size_t pos, const std::list<float> & val);
|
||||||
/// Prepares a float list.
|
/// Prepares a float list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const double&) = 0;
|
virtual void prepare(std::size_t pos, const double &) = 0;
|
||||||
/// Prepares a double.
|
/// Prepares a double.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<double>& val);
|
virtual void prepare(std::size_t pos, const std::vector<double> & val);
|
||||||
/// Prepares a double vector.
|
/// Prepares a double vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<double>& val);
|
virtual void prepare(std::size_t pos, const std::deque<double> & val);
|
||||||
/// Prepares a double deque.
|
/// Prepares a double deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<double>& val);
|
virtual void prepare(std::size_t pos, const std::list<double> & val);
|
||||||
/// Prepares a double list.
|
/// Prepares a double list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const char&) = 0;
|
virtual void prepare(std::size_t pos, const char &) = 0;
|
||||||
/// Prepares a single character.
|
/// Prepares a single character.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<char>& val);
|
virtual void prepare(std::size_t pos, const std::vector<char> & val);
|
||||||
/// Prepares a character vector.
|
/// Prepares a character vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<char>& val);
|
virtual void prepare(std::size_t pos, const std::deque<char> & val);
|
||||||
/// Prepares a character deque.
|
/// Prepares a character deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<char>& val);
|
virtual void prepare(std::size_t pos, const std::list<char> & val);
|
||||||
/// Prepares a character list.
|
/// Prepares a character list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::string&) = 0;
|
virtual void prepare(std::size_t pos, const std::string &) = 0;
|
||||||
/// Prepares a string.
|
/// Prepares a string.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<std::string>& val);
|
virtual void prepare(std::size_t pos, const std::vector<std::string> & val);
|
||||||
/// Prepares a string vector.
|
/// Prepares a string vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<std::string>& val);
|
virtual void prepare(std::size_t pos, const std::deque<std::string> & val);
|
||||||
/// Prepares a string deque.
|
/// Prepares a string deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<std::string>& val);
|
virtual void prepare(std::size_t pos, const std::list<std::string> & val);
|
||||||
/// Prepares a character list.
|
/// Prepares a character list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const UTF16String&);
|
virtual void prepare(std::size_t pos, const UTF16String &);
|
||||||
/// Prepares a UTF16String.
|
/// Prepares a UTF16String.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<UTF16String>& val);
|
virtual void prepare(std::size_t pos, const std::vector<UTF16String> & val);
|
||||||
/// Prepares a UTF16String vector.
|
/// Prepares a UTF16String vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<UTF16String>& val);
|
virtual void prepare(std::size_t pos, const std::deque<UTF16String> & val);
|
||||||
/// Prepares a UTF16String deque.
|
/// Prepares a UTF16String deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<UTF16String>& val);
|
virtual void prepare(std::size_t pos, const std::list<UTF16String> & val);
|
||||||
/// Prepares a UTF16String list.
|
/// Prepares a UTF16String list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const BLOB&) = 0;
|
virtual void prepare(std::size_t pos, const BLOB &) = 0;
|
||||||
/// Prepares a BLOB.
|
/// Prepares a BLOB.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const CLOB&) = 0;
|
virtual void prepare(std::size_t pos, const CLOB &) = 0;
|
||||||
/// Prepares a CLOB.
|
/// Prepares a CLOB.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<BLOB>& val);
|
virtual void prepare(std::size_t pos, const std::vector<BLOB> & val);
|
||||||
/// Prepares a BLOB vector.
|
/// Prepares a BLOB vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<BLOB>& val);
|
virtual void prepare(std::size_t pos, const std::deque<BLOB> & val);
|
||||||
/// Prepares a BLOB deque.
|
/// Prepares a BLOB deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<BLOB>& val);
|
virtual void prepare(std::size_t pos, const std::list<BLOB> & val);
|
||||||
/// Prepares a BLOB list.
|
/// Prepares a BLOB list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<CLOB>& val);
|
virtual void prepare(std::size_t pos, const std::vector<CLOB> & val);
|
||||||
/// Prepares a CLOB vector.
|
/// Prepares a CLOB vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<CLOB>& val);
|
virtual void prepare(std::size_t pos, const std::deque<CLOB> & val);
|
||||||
/// Prepares a CLOB deque.
|
/// Prepares a CLOB deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<CLOB>& val);
|
virtual void prepare(std::size_t pos, const std::list<CLOB> & val);
|
||||||
/// Prepares a CLOB list.
|
/// Prepares a CLOB list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const DateTime&) = 0;
|
virtual void prepare(std::size_t pos, const DateTime &) = 0;
|
||||||
/// Prepares a DateTime.
|
/// Prepares a DateTime.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<DateTime>& val);
|
virtual void prepare(std::size_t pos, const std::vector<DateTime> & val);
|
||||||
/// Prepares a DateTime vector.
|
/// Prepares a DateTime vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<DateTime>& val);
|
virtual void prepare(std::size_t pos, const std::deque<DateTime> & val);
|
||||||
/// Prepares a DateTime deque.
|
/// Prepares a DateTime deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<DateTime>& val);
|
virtual void prepare(std::size_t pos, const std::list<DateTime> & val);
|
||||||
/// Prepares a DateTime list.
|
/// Prepares a DateTime list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const Date&) = 0;
|
virtual void prepare(std::size_t pos, const Date &) = 0;
|
||||||
/// Prepares a Date.
|
/// Prepares a Date.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<Date>& val);
|
virtual void prepare(std::size_t pos, const std::vector<Date> & val);
|
||||||
/// Prepares a Date vector.
|
/// Prepares a Date vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<Date>& val);
|
virtual void prepare(std::size_t pos, const std::deque<Date> & val);
|
||||||
/// Prepares a Date deque.
|
/// Prepares a Date deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<Date>& val);
|
virtual void prepare(std::size_t pos, const std::list<Date> & val);
|
||||||
/// Prepares a Date list.
|
/// Prepares a Date list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const Time&) = 0;
|
virtual void prepare(std::size_t pos, const Time &) = 0;
|
||||||
/// Prepares a Time.
|
/// Prepares a Time.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<Time>& val);
|
virtual void prepare(std::size_t pos, const std::vector<Time> & val);
|
||||||
/// Prepares a Time vector.
|
/// Prepares a Time vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<Time>& val);
|
virtual void prepare(std::size_t pos, const std::deque<Time> & val);
|
||||||
/// Prepares a Time deque.
|
/// Prepares a Time deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<Time>& val);
|
|
||||||
/// Prepares a Time list.
|
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const Any&) = 0;
|
virtual void prepare(std::size_t pos, const std::list<Time> & val);
|
||||||
/// Prepares an Any.
|
/// Prepares a Time list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<Any>& val);
|
virtual void prepare(std::size_t pos, const Any &) = 0;
|
||||||
/// Prepares an Any vector.
|
/// Prepares an Any.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<Any>& val);
|
virtual void prepare(std::size_t pos, const std::vector<Any> & val);
|
||||||
/// Prepares an Any deque.
|
/// Prepares an Any vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<Any>& val);
|
virtual void prepare(std::size_t pos, const std::deque<Any> & val);
|
||||||
/// Prepares an Any list.
|
/// Prepares an Any deque.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const Poco::Dynamic::Var&) = 0;
|
virtual void prepare(std::size_t pos, const std::list<Any> & val);
|
||||||
/// Prepares a Var.
|
/// Prepares an Any list.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::vector<Poco::Dynamic::Var>& val);
|
virtual void prepare(std::size_t pos, const Poco::Dynamic::Var &) = 0;
|
||||||
/// Prepares a Var vector.
|
/// Prepares a Var.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::deque<Poco::Dynamic::Var>& val);
|
virtual void prepare(std::size_t pos, const std::vector<Poco::Dynamic::Var> & val);
|
||||||
/// Prepares a Var deque.
|
/// Prepares a Var vector.
|
||||||
|
|
||||||
virtual void prepare(std::size_t pos, const std::list<Poco::Dynamic::Var>& val);
|
virtual void prepare(std::size_t pos, const std::deque<Poco::Dynamic::Var> & val);
|
||||||
/// Prepares a Var list.
|
/// Prepares a Var deque.
|
||||||
|
|
||||||
void setLength(Poco::UInt32 length);
|
virtual void prepare(std::size_t pos, const std::list<Poco::Dynamic::Var> & val);
|
||||||
/// Sets the length of prepared data.
|
/// Prepares a Var list.
|
||||||
/// Needed only for data lengths greater than 1 (i.e. for
|
|
||||||
/// bulk operations).
|
|
||||||
|
|
||||||
Poco::UInt32 getLength() const;
|
void setLength(Poco::UInt32 length);
|
||||||
/// Returns the length of prepared data. Defaults to 1.
|
/// Sets the length of prepared data.
|
||||||
/// The length is greater than one for bulk operations.
|
/// Needed only for data lengths greater than 1 (i.e. for
|
||||||
|
/// bulk operations).
|
||||||
|
|
||||||
void setBulk(bool bulkPrep = true);
|
Poco::UInt32 getLength() const;
|
||||||
/// Sets bulk operation flag (always false at object creation time)
|
/// Returns the length of prepared data. Defaults to 1.
|
||||||
|
/// The length is greater than one for bulk operations.
|
||||||
|
|
||||||
bool isBulk() const;
|
void setBulk(bool bulkPrep = true);
|
||||||
/// Returns bulk operation flag.
|
/// Sets bulk operation flag (always false at object creation time)
|
||||||
|
|
||||||
private:
|
bool isBulk() const;
|
||||||
Poco::UInt32 _length;
|
/// Returns bulk operation flag.
|
||||||
bool _bulk;
|
|
||||||
};
|
private:
|
||||||
|
Poco::UInt32 _length;
|
||||||
|
bool _bulk;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// inlines
|
||||||
|
///
|
||||||
|
inline void AbstractPreparator::setLength(Poco::UInt32 length)
|
||||||
|
{
|
||||||
|
_length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Poco::UInt32 AbstractPreparator::getLength() const
|
||||||
|
{
|
||||||
|
return _length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void AbstractPreparator::setBulk(bool bulkPrep)
|
||||||
|
{
|
||||||
|
_bulk = bulkPrep;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool AbstractPreparator::isBulk() const
|
||||||
|
{
|
||||||
|
return _bulk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// inlines
|
|
||||||
///
|
|
||||||
inline void AbstractPreparator::setLength(Poco::UInt32 length)
|
|
||||||
{
|
|
||||||
_length = length;
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline Poco::UInt32 AbstractPreparator::getLength() const
|
|
||||||
{
|
|
||||||
return _length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void AbstractPreparator::setBulk(bool bulkPrep)
|
|
||||||
{
|
|
||||||
_bulk = bulkPrep;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool AbstractPreparator::isBulk() const
|
|
||||||
{
|
|
||||||
return _bulk;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_AbstractPreparator_INCLUDED
|
#endif // Data_AbstractPreparator_INCLUDED
|
||||||
|
@ -18,298 +18,295 @@
|
|||||||
#define Data_AbstractSessionImpl_INCLUDED
|
#define Data_AbstractSessionImpl_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
|
||||||
#include "Poco/Data/SessionImpl.h"
|
|
||||||
#include "Poco/Data/DataException.h"
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
|
#include "Poco/Data/DataException.h"
|
||||||
|
#include "Poco/Data/SessionImpl.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
{
|
||||||
|
namespace Data
|
||||||
|
|
||||||
template <class C>
|
|
||||||
class AbstractSessionImpl: public SessionImpl
|
|
||||||
/// A partial implementation of SessionImpl, providing
|
|
||||||
/// features and properties management.
|
|
||||||
///
|
|
||||||
/// To implement a certain feature or property, a subclass
|
|
||||||
/// must provide setter and getter methods and register
|
|
||||||
/// them with addFeature() or addProperty().
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
typedef void (C::*FeatureSetter)(const std::string&, bool);
|
|
||||||
/// The setter method for a feature.
|
|
||||||
|
|
||||||
typedef bool (C::*FeatureGetter)(const std::string&);
|
|
||||||
/// The getter method for a feature.
|
|
||||||
|
|
||||||
typedef void (C::*PropertySetter)(const std::string&, const Poco::Any&);
|
|
||||||
/// The setter method for a property.
|
|
||||||
|
|
||||||
typedef Poco::Any (C::*PropertyGetter)(const std::string&);
|
|
||||||
/// The getter method for a property.
|
|
||||||
|
|
||||||
AbstractSessionImpl(const std::string& connectionString,
|
|
||||||
std::size_t timeout = LOGIN_TIMEOUT_DEFAULT): SessionImpl(connectionString, timeout),
|
|
||||||
_storage(std::string("deque")),
|
|
||||||
_bulk(false),
|
|
||||||
_emptyStringIsNull(false),
|
|
||||||
_forceEmptyString(false)
|
|
||||||
/// Creates the AbstractSessionImpl.
|
|
||||||
///
|
|
||||||
/// Adds "storage" property and sets the default internal storage container
|
|
||||||
/// type to std::deque.
|
|
||||||
/// The storage is created by statements automatically whenever a query
|
|
||||||
/// returning results is executed but external storage is provided by the user.
|
|
||||||
/// Storage type can be reconfigured at runtime both globally (for the
|
|
||||||
/// duration of the session) and locally (for a single statement execution only).
|
|
||||||
/// See StatementImpl for details on how this property is used at runtime.
|
|
||||||
///
|
|
||||||
/// Adds "handle" property which, if set by the back end, returns native handle
|
|
||||||
/// for the back end DB.
|
|
||||||
///
|
|
||||||
/// Adds "bulk" feature and sets it to false.
|
|
||||||
/// Bulk feature determines whether the session is capable of bulk operations.
|
|
||||||
/// Connectors that are capable of it must set this feature prior to attempting
|
|
||||||
/// bulk operations.
|
|
||||||
///
|
|
||||||
/// Adds "emptyStringIsNull" feature and sets it to false. This feature should be
|
|
||||||
/// set to true in order to modify the behavior of the databases that distinguish
|
|
||||||
/// between zero-length character strings as nulls. Setting this feature to true
|
|
||||||
/// shall disregard any difference between empty character strings and nulls,
|
|
||||||
/// causing the framework to treat them the same (i.e. behave like Oracle).
|
|
||||||
///
|
|
||||||
/// Adds "forceEmptyString" feature and sets it to false. This feature should be set
|
|
||||||
/// to true in order to force the databases that do not distinguish empty strings from
|
|
||||||
/// nulls (e.g. Oracle) to always report empty string.
|
|
||||||
///
|
|
||||||
/// The "emptyStringIsNull" and "forceEmptyString" features are mutually exclusive.
|
|
||||||
/// While these features can not both be true at the same time, they can both be false,
|
|
||||||
/// resulting in default underlying database behavior.
|
|
||||||
///
|
|
||||||
{
|
|
||||||
addProperty("storage",
|
|
||||||
&AbstractSessionImpl<C>::setStorage,
|
|
||||||
&AbstractSessionImpl<C>::getStorage);
|
|
||||||
|
|
||||||
addProperty("handle",
|
|
||||||
&AbstractSessionImpl<C>::setHandle,
|
|
||||||
&AbstractSessionImpl<C>::getHandle);
|
|
||||||
|
|
||||||
addFeature("bulk",
|
|
||||||
&AbstractSessionImpl<C>::setBulk,
|
|
||||||
&AbstractSessionImpl<C>::getBulk);
|
|
||||||
|
|
||||||
addFeature("emptyStringIsNull",
|
|
||||||
&AbstractSessionImpl<C>::setEmptyStringIsNull,
|
|
||||||
&AbstractSessionImpl<C>::getEmptyStringIsNull);
|
|
||||||
|
|
||||||
addFeature("forceEmptyString",
|
|
||||||
&AbstractSessionImpl<C>::setForceEmptyString,
|
|
||||||
&AbstractSessionImpl<C>::getForceEmptyString);
|
|
||||||
}
|
|
||||||
|
|
||||||
~AbstractSessionImpl()
|
|
||||||
/// Destroys the AbstractSessionImpl.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFeature(const std::string& name, bool state)
|
|
||||||
/// Looks a feature up in the features map
|
|
||||||
/// and calls the feature's setter, if there is one.
|
|
||||||
{
|
|
||||||
typename FeatureMap::const_iterator it = _features.find(name);
|
|
||||||
if (it != _features.end())
|
|
||||||
{
|
|
||||||
if (it->second.setter)
|
|
||||||
(static_cast<C*>(this)->*it->second.setter)(name, state);
|
|
||||||
else
|
|
||||||
throw NotImplementedException("set", name);
|
|
||||||
}
|
|
||||||
else throw NotSupportedException(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getFeature(const std::string& name)
|
|
||||||
/// Looks a feature up in the features map
|
|
||||||
/// and calls the feature's getter, if there is one.
|
|
||||||
{
|
|
||||||
typename FeatureMap::const_iterator it = _features.find(name);
|
|
||||||
if (it != _features.end())
|
|
||||||
{
|
|
||||||
if (it->second.getter)
|
|
||||||
return (static_cast<C*>(this)->*it->second.getter)(name);
|
|
||||||
else
|
|
||||||
throw NotImplementedException("get", name);
|
|
||||||
}
|
|
||||||
else throw NotSupportedException(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setProperty(const std::string& name, const Poco::Any& value)
|
|
||||||
/// Looks a property up in the properties map
|
|
||||||
/// and calls the property's setter, if there is one.
|
|
||||||
{
|
|
||||||
typename PropertyMap::const_iterator it = _properties.find(name);
|
|
||||||
if (it != _properties.end())
|
|
||||||
{
|
|
||||||
if (it->second.setter)
|
|
||||||
(static_cast<C*>(this)->*it->second.setter)(name, value);
|
|
||||||
else
|
|
||||||
throw NotImplementedException("set", name);
|
|
||||||
}
|
|
||||||
else throw NotSupportedException(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
Poco::Any getProperty(const std::string& name)
|
|
||||||
/// Looks a property up in the properties map
|
|
||||||
/// and calls the property's getter, if there is one.
|
|
||||||
{
|
|
||||||
typename PropertyMap::const_iterator it = _properties.find(name);
|
|
||||||
if (it != _properties.end())
|
|
||||||
{
|
|
||||||
if (it->second.getter)
|
|
||||||
return (static_cast<C*>(this)->*it->second.getter)(name);
|
|
||||||
else
|
|
||||||
throw NotImplementedException("set", name);
|
|
||||||
}
|
|
||||||
else throw NotSupportedException(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setStorage(const std::string& value)
|
|
||||||
/// Sets the storage type.
|
|
||||||
{
|
|
||||||
_storage = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setStorage(const std::string& name, const Poco::Any& value)
|
|
||||||
/// Sets the storage type.
|
|
||||||
{
|
|
||||||
_storage = Poco::RefAnyCast<std::string>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Poco::Any getStorage(const std::string& name="")
|
|
||||||
/// Returns the storage type
|
|
||||||
{
|
|
||||||
return _storage;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setHandle(const std::string& name, const Poco::Any& handle)
|
|
||||||
/// Sets the native session handle.
|
|
||||||
{
|
|
||||||
_handle = handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
Poco::Any getHandle(const std::string& name="")
|
|
||||||
/// Returns the native session handle.
|
|
||||||
{
|
|
||||||
return _handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBulk(const std::string& name, bool bulk)
|
|
||||||
/// Sets the execution type.
|
|
||||||
{
|
|
||||||
_bulk = bulk;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getBulk(const std::string& name="")
|
|
||||||
/// Returns the execution type
|
|
||||||
{
|
|
||||||
return _bulk;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setEmptyStringIsNull(const std::string& name, bool emptyStringIsNull)
|
|
||||||
/// Sets the behavior regarding empty variable length strings.
|
|
||||||
/// Those are treated as NULL by Oracle and as empty string by
|
|
||||||
/// most other databases.
|
|
||||||
/// When this feature is true, empty strings are treated as NULL.
|
|
||||||
{
|
|
||||||
if (emptyStringIsNull && _forceEmptyString)
|
|
||||||
throw InvalidAccessException("Features mutually exclusive");
|
|
||||||
|
|
||||||
_emptyStringIsNull = emptyStringIsNull;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getEmptyStringIsNull(const std::string& name="")
|
|
||||||
/// Returns the setting for the behavior regarding empty variable
|
|
||||||
/// length strings. See setEmptyStringIsNull(const std::string&, bool)
|
|
||||||
/// and this class documentation for feature rationale and details.
|
|
||||||
{
|
|
||||||
return _emptyStringIsNull;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setForceEmptyString(const std::string& name, bool forceEmptyString)
|
|
||||||
/// Sets the behavior regarding empty variable length strings.
|
|
||||||
/// Those are treated as NULL by Oracle and as empty string by
|
|
||||||
/// most other databases.
|
|
||||||
/// When this feature is true, both empty strings and NULL values
|
|
||||||
/// are reported as empty strings.
|
|
||||||
{
|
|
||||||
if (forceEmptyString && _emptyStringIsNull)
|
|
||||||
throw InvalidAccessException("Features mutually exclusive");
|
|
||||||
|
|
||||||
_forceEmptyString = forceEmptyString;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getForceEmptyString(const std::string& name="")
|
|
||||||
/// Returns the setting for the behavior regarding empty variable
|
|
||||||
/// length strings. See setForceEmptyString(const std::string&, bool)
|
|
||||||
/// and this class documentation for feature rationale and details.
|
|
||||||
{
|
|
||||||
return _forceEmptyString;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void addFeature(const std::string& name, FeatureSetter setter, FeatureGetter getter)
|
|
||||||
/// Adds a feature to the map of supported features.
|
|
||||||
///
|
|
||||||
/// The setter or getter can be null, in case setting or getting a feature
|
|
||||||
/// is not supported.
|
|
||||||
{
|
|
||||||
Feature feature;
|
|
||||||
feature.setter = setter;
|
|
||||||
feature.getter = getter;
|
|
||||||
_features[name] = feature;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addProperty(const std::string& name, PropertySetter setter, PropertyGetter getter)
|
|
||||||
/// Adds a property to the map of supported properties.
|
|
||||||
///
|
|
||||||
/// The setter or getter can be null, in case setting or getting a property
|
|
||||||
/// is not supported.
|
|
||||||
{
|
|
||||||
Property property;
|
|
||||||
property.setter = setter;
|
|
||||||
property.getter = getter;
|
|
||||||
_properties[name] = property;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Feature
|
|
||||||
{
|
|
||||||
FeatureSetter setter;
|
|
||||||
FeatureGetter getter;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Property
|
|
||||||
{
|
|
||||||
PropertySetter setter;
|
|
||||||
PropertyGetter getter;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::map<std::string, Feature> FeatureMap;
|
|
||||||
typedef std::map<std::string, Property> PropertyMap;
|
|
||||||
|
|
||||||
FeatureMap _features;
|
|
||||||
PropertyMap _properties;
|
|
||||||
std::string _storage;
|
|
||||||
bool _bulk;
|
|
||||||
bool _emptyStringIsNull;
|
|
||||||
bool _forceEmptyString;
|
|
||||||
Poco::Any _handle;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
template <class C>
|
||||||
|
class AbstractSessionImpl : public SessionImpl
|
||||||
|
/// A partial implementation of SessionImpl, providing
|
||||||
|
/// features and properties management.
|
||||||
|
///
|
||||||
|
/// To implement a certain feature or property, a subclass
|
||||||
|
/// must provide setter and getter methods and register
|
||||||
|
/// them with addFeature() or addProperty().
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef void (C::*FeatureSetter)(const std::string &, bool);
|
||||||
|
/// The setter method for a feature.
|
||||||
|
|
||||||
|
typedef bool (C::*FeatureGetter)(const std::string &);
|
||||||
|
/// The getter method for a feature.
|
||||||
|
|
||||||
|
typedef void (C::*PropertySetter)(const std::string &, const Poco::Any &);
|
||||||
|
/// The setter method for a property.
|
||||||
|
|
||||||
|
typedef Poco::Any (C::*PropertyGetter)(const std::string &);
|
||||||
|
/// The getter method for a property.
|
||||||
|
|
||||||
|
AbstractSessionImpl(const std::string & connectionString, std::size_t timeout = LOGIN_TIMEOUT_DEFAULT)
|
||||||
|
: SessionImpl(connectionString, timeout)
|
||||||
|
, _storage(std::string("deque"))
|
||||||
|
, _bulk(false)
|
||||||
|
, _emptyStringIsNull(false)
|
||||||
|
, _forceEmptyString(false)
|
||||||
|
/// Creates the AbstractSessionImpl.
|
||||||
|
///
|
||||||
|
/// Adds "storage" property and sets the default internal storage container
|
||||||
|
/// type to std::deque.
|
||||||
|
/// The storage is created by statements automatically whenever a query
|
||||||
|
/// returning results is executed but external storage is provided by the user.
|
||||||
|
/// Storage type can be reconfigured at runtime both globally (for the
|
||||||
|
/// duration of the session) and locally (for a single statement execution only).
|
||||||
|
/// See StatementImpl for details on how this property is used at runtime.
|
||||||
|
///
|
||||||
|
/// Adds "handle" property which, if set by the back end, returns native handle
|
||||||
|
/// for the back end DB.
|
||||||
|
///
|
||||||
|
/// Adds "bulk" feature and sets it to false.
|
||||||
|
/// Bulk feature determines whether the session is capable of bulk operations.
|
||||||
|
/// Connectors that are capable of it must set this feature prior to attempting
|
||||||
|
/// bulk operations.
|
||||||
|
///
|
||||||
|
/// Adds "emptyStringIsNull" feature and sets it to false. This feature should be
|
||||||
|
/// set to true in order to modify the behavior of the databases that distinguish
|
||||||
|
/// between zero-length character strings as nulls. Setting this feature to true
|
||||||
|
/// shall disregard any difference between empty character strings and nulls,
|
||||||
|
/// causing the framework to treat them the same (i.e. behave like Oracle).
|
||||||
|
///
|
||||||
|
/// Adds "forceEmptyString" feature and sets it to false. This feature should be set
|
||||||
|
/// to true in order to force the databases that do not distinguish empty strings from
|
||||||
|
/// nulls (e.g. Oracle) to always report empty string.
|
||||||
|
///
|
||||||
|
/// The "emptyStringIsNull" and "forceEmptyString" features are mutually exclusive.
|
||||||
|
/// While these features can not both be true at the same time, they can both be false,
|
||||||
|
/// resulting in default underlying database behavior.
|
||||||
|
///
|
||||||
|
{
|
||||||
|
addProperty("storage", &AbstractSessionImpl<C>::setStorage, &AbstractSessionImpl<C>::getStorage);
|
||||||
|
|
||||||
|
addProperty("handle", &AbstractSessionImpl<C>::setHandle, &AbstractSessionImpl<C>::getHandle);
|
||||||
|
|
||||||
|
addFeature("bulk", &AbstractSessionImpl<C>::setBulk, &AbstractSessionImpl<C>::getBulk);
|
||||||
|
|
||||||
|
addFeature("emptyStringIsNull", &AbstractSessionImpl<C>::setEmptyStringIsNull, &AbstractSessionImpl<C>::getEmptyStringIsNull);
|
||||||
|
|
||||||
|
addFeature("forceEmptyString", &AbstractSessionImpl<C>::setForceEmptyString, &AbstractSessionImpl<C>::getForceEmptyString);
|
||||||
|
}
|
||||||
|
|
||||||
|
~AbstractSessionImpl()
|
||||||
|
/// Destroys the AbstractSessionImpl.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFeature(const std::string & name, bool state)
|
||||||
|
/// Looks a feature up in the features map
|
||||||
|
/// and calls the feature's setter, if there is one.
|
||||||
|
{
|
||||||
|
typename FeatureMap::const_iterator it = _features.find(name);
|
||||||
|
if (it != _features.end())
|
||||||
|
{
|
||||||
|
if (it->second.setter)
|
||||||
|
(static_cast<C *>(this)->*it->second.setter)(name, state);
|
||||||
|
else
|
||||||
|
throw NotImplementedException("set", name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw NotSupportedException(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getFeature(const std::string & name)
|
||||||
|
/// Looks a feature up in the features map
|
||||||
|
/// and calls the feature's getter, if there is one.
|
||||||
|
{
|
||||||
|
typename FeatureMap::const_iterator it = _features.find(name);
|
||||||
|
if (it != _features.end())
|
||||||
|
{
|
||||||
|
if (it->second.getter)
|
||||||
|
return (static_cast<C *>(this)->*it->second.getter)(name);
|
||||||
|
else
|
||||||
|
throw NotImplementedException("get", name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw NotSupportedException(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setProperty(const std::string & name, const Poco::Any & value)
|
||||||
|
/// Looks a property up in the properties map
|
||||||
|
/// and calls the property's setter, if there is one.
|
||||||
|
{
|
||||||
|
typename PropertyMap::const_iterator it = _properties.find(name);
|
||||||
|
if (it != _properties.end())
|
||||||
|
{
|
||||||
|
if (it->second.setter)
|
||||||
|
(static_cast<C *>(this)->*it->second.setter)(name, value);
|
||||||
|
else
|
||||||
|
throw NotImplementedException("set", name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw NotSupportedException(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Poco::Any getProperty(const std::string & name)
|
||||||
|
/// Looks a property up in the properties map
|
||||||
|
/// and calls the property's getter, if there is one.
|
||||||
|
{
|
||||||
|
typename PropertyMap::const_iterator it = _properties.find(name);
|
||||||
|
if (it != _properties.end())
|
||||||
|
{
|
||||||
|
if (it->second.getter)
|
||||||
|
return (static_cast<C *>(this)->*it->second.getter)(name);
|
||||||
|
else
|
||||||
|
throw NotImplementedException("set", name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw NotSupportedException(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setStorage(const std::string & value)
|
||||||
|
/// Sets the storage type.
|
||||||
|
{
|
||||||
|
_storage = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setStorage(const std::string & name, const Poco::Any & value)
|
||||||
|
/// Sets the storage type.
|
||||||
|
{
|
||||||
|
_storage = Poco::RefAnyCast<std::string>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Poco::Any getStorage(const std::string & name = "")
|
||||||
|
/// Returns the storage type
|
||||||
|
{
|
||||||
|
return _storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHandle(const std::string & name, const Poco::Any & handle)
|
||||||
|
/// Sets the native session handle.
|
||||||
|
{
|
||||||
|
_handle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
Poco::Any getHandle(const std::string & name = "")
|
||||||
|
/// Returns the native session handle.
|
||||||
|
{
|
||||||
|
return _handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBulk(const std::string & name, bool bulk)
|
||||||
|
/// Sets the execution type.
|
||||||
|
{
|
||||||
|
_bulk = bulk;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getBulk(const std::string & name = "")
|
||||||
|
/// Returns the execution type
|
||||||
|
{
|
||||||
|
return _bulk;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEmptyStringIsNull(const std::string & name, bool emptyStringIsNull)
|
||||||
|
/// Sets the behavior regarding empty variable length strings.
|
||||||
|
/// Those are treated as NULL by Oracle and as empty string by
|
||||||
|
/// most other databases.
|
||||||
|
/// When this feature is true, empty strings are treated as NULL.
|
||||||
|
{
|
||||||
|
if (emptyStringIsNull && _forceEmptyString)
|
||||||
|
throw InvalidAccessException("Features mutually exclusive");
|
||||||
|
|
||||||
|
_emptyStringIsNull = emptyStringIsNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getEmptyStringIsNull(const std::string & name = "")
|
||||||
|
/// Returns the setting for the behavior regarding empty variable
|
||||||
|
/// length strings. See setEmptyStringIsNull(const std::string&, bool)
|
||||||
|
/// and this class documentation for feature rationale and details.
|
||||||
|
{
|
||||||
|
return _emptyStringIsNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setForceEmptyString(const std::string & name, bool forceEmptyString)
|
||||||
|
/// Sets the behavior regarding empty variable length strings.
|
||||||
|
/// Those are treated as NULL by Oracle and as empty string by
|
||||||
|
/// most other databases.
|
||||||
|
/// When this feature is true, both empty strings and NULL values
|
||||||
|
/// are reported as empty strings.
|
||||||
|
{
|
||||||
|
if (forceEmptyString && _emptyStringIsNull)
|
||||||
|
throw InvalidAccessException("Features mutually exclusive");
|
||||||
|
|
||||||
|
_forceEmptyString = forceEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getForceEmptyString(const std::string & name = "")
|
||||||
|
/// Returns the setting for the behavior regarding empty variable
|
||||||
|
/// length strings. See setForceEmptyString(const std::string&, bool)
|
||||||
|
/// and this class documentation for feature rationale and details.
|
||||||
|
{
|
||||||
|
return _forceEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void addFeature(const std::string & name, FeatureSetter setter, FeatureGetter getter)
|
||||||
|
/// Adds a feature to the map of supported features.
|
||||||
|
///
|
||||||
|
/// The setter or getter can be null, in case setting or getting a feature
|
||||||
|
/// is not supported.
|
||||||
|
{
|
||||||
|
Feature feature;
|
||||||
|
feature.setter = setter;
|
||||||
|
feature.getter = getter;
|
||||||
|
_features[name] = feature;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addProperty(const std::string & name, PropertySetter setter, PropertyGetter getter)
|
||||||
|
/// Adds a property to the map of supported properties.
|
||||||
|
///
|
||||||
|
/// The setter or getter can be null, in case setting or getting a property
|
||||||
|
/// is not supported.
|
||||||
|
{
|
||||||
|
Property property;
|
||||||
|
property.setter = setter;
|
||||||
|
property.getter = getter;
|
||||||
|
_properties[name] = property;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Feature
|
||||||
|
{
|
||||||
|
FeatureSetter setter;
|
||||||
|
FeatureGetter getter;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Property
|
||||||
|
{
|
||||||
|
PropertySetter setter;
|
||||||
|
PropertyGetter getter;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<std::string, Feature> FeatureMap;
|
||||||
|
typedef std::map<std::string, Property> PropertyMap;
|
||||||
|
|
||||||
|
FeatureMap _features;
|
||||||
|
PropertyMap _properties;
|
||||||
|
std::string _storage;
|
||||||
|
bool _bulk;
|
||||||
|
bool _emptyStringIsNull;
|
||||||
|
bool _forceEmptyString;
|
||||||
|
Poco::Any _handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_AbstractSessionImpl_INCLUDED
|
#endif // Data_AbstractSessionImpl_INCLUDED
|
||||||
|
@ -21,202 +21,206 @@
|
|||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/Session.h"
|
#include "Poco/Data/Session.h"
|
||||||
#include "Poco/DateTime.h"
|
#include "Poco/DateTime.h"
|
||||||
#include "Poco/Timespan.h"
|
|
||||||
#include "Poco/Dynamic/Var.h"
|
#include "Poco/Dynamic/Var.h"
|
||||||
#include "Poco/SharedPtr.h"
|
#include "Poco/SharedPtr.h"
|
||||||
|
#include "Poco/Timespan.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API ArchiveStrategy
|
|
||||||
/// The ArchiveStrategy is used by SQLChannel to archive log rows.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
static const std::string DEFAULT_ARCHIVE_DESTINATION;
|
|
||||||
|
|
||||||
ArchiveStrategy(const std::string& connector,
|
|
||||||
const std::string& connect,
|
|
||||||
const std::string& source,
|
|
||||||
const std::string& destination = DEFAULT_ARCHIVE_DESTINATION);
|
|
||||||
/// Creates archive strategy.
|
|
||||||
|
|
||||||
virtual ~ArchiveStrategy();
|
|
||||||
/// Destroys archive strategy.
|
|
||||||
|
|
||||||
void open();
|
|
||||||
/// Opens the session.
|
|
||||||
|
|
||||||
virtual void archive() = 0;
|
|
||||||
/// Archives the rows.
|
|
||||||
|
|
||||||
const std::string& getSource() const;
|
|
||||||
/// Returns the name of the source table containing rows to be archived.
|
|
||||||
|
|
||||||
void setSource(const std::string& source);
|
|
||||||
/// Sets the name of the source table.
|
|
||||||
|
|
||||||
const std::string& getDestination() const;
|
|
||||||
/// Returns the name of the destination table for rows to be archived.
|
|
||||||
|
|
||||||
void setDestination(const std::string& destination);
|
|
||||||
/// Sets the name of the destination table.
|
|
||||||
|
|
||||||
virtual const std::string& getThreshold() const = 0;
|
|
||||||
/// Returns the archive threshold.
|
|
||||||
|
|
||||||
virtual void setThreshold(const std::string& threshold) = 0;
|
|
||||||
/// Sets the archive threshold.
|
|
||||||
|
|
||||||
protected:
|
|
||||||
typedef Poco::SharedPtr<Session> SessionPtr;
|
|
||||||
typedef Poco::SharedPtr<Statement> StatementPtr;
|
|
||||||
|
|
||||||
Session& session();
|
|
||||||
|
|
||||||
void setCopyStatement();
|
|
||||||
void setDeleteStatement();
|
|
||||||
void setCountStatement();
|
|
||||||
|
|
||||||
Statement& getCopyStatement();
|
|
||||||
Statement& getDeleteStatement();
|
|
||||||
Statement& getCountStatement();
|
|
||||||
private:
|
|
||||||
|
|
||||||
ArchiveStrategy();
|
|
||||||
ArchiveStrategy(const ArchiveStrategy&);
|
|
||||||
ArchiveStrategy& operator = (const ArchiveStrategy&);
|
|
||||||
|
|
||||||
std::string _connector;
|
|
||||||
std::string _connect;
|
|
||||||
SessionPtr _pSession;
|
|
||||||
StatementPtr _pCopyStatement;
|
|
||||||
StatementPtr _pDeleteStatement;
|
|
||||||
StatementPtr _pCountStatement;
|
|
||||||
std::string _source;
|
|
||||||
std::string _destination;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
|
|
||||||
inline const std::string& ArchiveStrategy::getSource() const
|
|
||||||
{
|
{
|
||||||
return _source;
|
|
||||||
|
|
||||||
|
class Data_API ArchiveStrategy
|
||||||
|
/// The ArchiveStrategy is used by SQLChannel to archive log rows.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const std::string DEFAULT_ARCHIVE_DESTINATION;
|
||||||
|
|
||||||
|
ArchiveStrategy(
|
||||||
|
const std::string & connector,
|
||||||
|
const std::string & connect,
|
||||||
|
const std::string & source,
|
||||||
|
const std::string & destination = DEFAULT_ARCHIVE_DESTINATION);
|
||||||
|
/// Creates archive strategy.
|
||||||
|
|
||||||
|
virtual ~ArchiveStrategy();
|
||||||
|
/// Destroys archive strategy.
|
||||||
|
|
||||||
|
void open();
|
||||||
|
/// Opens the session.
|
||||||
|
|
||||||
|
virtual void archive() = 0;
|
||||||
|
/// Archives the rows.
|
||||||
|
|
||||||
|
const std::string & getSource() const;
|
||||||
|
/// Returns the name of the source table containing rows to be archived.
|
||||||
|
|
||||||
|
void setSource(const std::string & source);
|
||||||
|
/// Sets the name of the source table.
|
||||||
|
|
||||||
|
const std::string & getDestination() const;
|
||||||
|
/// Returns the name of the destination table for rows to be archived.
|
||||||
|
|
||||||
|
void setDestination(const std::string & destination);
|
||||||
|
/// Sets the name of the destination table.
|
||||||
|
|
||||||
|
virtual const std::string & getThreshold() const = 0;
|
||||||
|
/// Returns the archive threshold.
|
||||||
|
|
||||||
|
virtual void setThreshold(const std::string & threshold) = 0;
|
||||||
|
/// Sets the archive threshold.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typedef Poco::SharedPtr<Session> SessionPtr;
|
||||||
|
typedef Poco::SharedPtr<Statement> StatementPtr;
|
||||||
|
|
||||||
|
Session & session();
|
||||||
|
|
||||||
|
void setCopyStatement();
|
||||||
|
void setDeleteStatement();
|
||||||
|
void setCountStatement();
|
||||||
|
|
||||||
|
Statement & getCopyStatement();
|
||||||
|
Statement & getDeleteStatement();
|
||||||
|
Statement & getCountStatement();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ArchiveStrategy();
|
||||||
|
ArchiveStrategy(const ArchiveStrategy &);
|
||||||
|
ArchiveStrategy & operator=(const ArchiveStrategy &);
|
||||||
|
|
||||||
|
std::string _connector;
|
||||||
|
std::string _connect;
|
||||||
|
SessionPtr _pSession;
|
||||||
|
StatementPtr _pCopyStatement;
|
||||||
|
StatementPtr _pDeleteStatement;
|
||||||
|
StatementPtr _pCountStatement;
|
||||||
|
std::string _source;
|
||||||
|
std::string _destination;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
|
||||||
|
inline const std::string & ArchiveStrategy::getSource() const
|
||||||
|
{
|
||||||
|
return _source;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void ArchiveStrategy::setSource(const std::string & source)
|
||||||
|
{
|
||||||
|
_source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void ArchiveStrategy::setDestination(const std::string & destination)
|
||||||
|
{
|
||||||
|
_destination = destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const std::string & ArchiveStrategy::getDestination() const
|
||||||
|
{
|
||||||
|
return _destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Session & ArchiveStrategy::session()
|
||||||
|
{
|
||||||
|
return *_pSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void ArchiveStrategy::setCopyStatement()
|
||||||
|
{
|
||||||
|
_pCopyStatement = new Statement(*_pSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void ArchiveStrategy::setDeleteStatement()
|
||||||
|
{
|
||||||
|
_pDeleteStatement = new Statement(*_pSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void ArchiveStrategy::setCountStatement()
|
||||||
|
{
|
||||||
|
_pCountStatement = new Statement(*_pSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Statement & ArchiveStrategy::getCopyStatement()
|
||||||
|
{
|
||||||
|
return *_pCopyStatement;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Statement & ArchiveStrategy::getDeleteStatement()
|
||||||
|
{
|
||||||
|
return *_pDeleteStatement;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Statement & ArchiveStrategy::getCountStatement()
|
||||||
|
{
|
||||||
|
return *_pCountStatement;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ArchiveByAgeStrategy
|
||||||
|
//
|
||||||
|
class Data_API ArchiveByAgeStrategy : public ArchiveStrategy
|
||||||
|
/// Archives rows scheduled for archiving.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ArchiveByAgeStrategy(
|
||||||
|
const std::string & connector,
|
||||||
|
const std::string & connect,
|
||||||
|
const std::string & sourceTable,
|
||||||
|
const std::string & destinationTable = DEFAULT_ARCHIVE_DESTINATION);
|
||||||
|
|
||||||
|
~ArchiveByAgeStrategy();
|
||||||
|
|
||||||
|
void archive();
|
||||||
|
|
||||||
|
const std::string & getThreshold() const;
|
||||||
|
/// Returns the archive threshold.
|
||||||
|
|
||||||
|
void setThreshold(const std::string & threshold);
|
||||||
|
/// Sets the archive threshold.
|
||||||
|
|
||||||
|
private:
|
||||||
|
ArchiveByAgeStrategy();
|
||||||
|
ArchiveByAgeStrategy(const ArchiveByAgeStrategy &);
|
||||||
|
ArchiveByAgeStrategy & operator=(const ArchiveByAgeStrategy &);
|
||||||
|
|
||||||
|
void initStatements();
|
||||||
|
|
||||||
|
Timespan _maxAge;
|
||||||
|
std::string _ageString;
|
||||||
|
DateTime _archiveDateTime;
|
||||||
|
Poco::Dynamic::Var _archiveCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
|
||||||
|
inline const std::string & ArchiveByAgeStrategy::getThreshold() const
|
||||||
|
{
|
||||||
|
return _ageString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline void ArchiveStrategy::setSource(const std::string& source)
|
|
||||||
{
|
|
||||||
_source = source;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void ArchiveStrategy::setDestination(const std::string& destination)
|
|
||||||
{
|
|
||||||
_destination = destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& ArchiveStrategy::getDestination() const
|
|
||||||
{
|
|
||||||
return _destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Session& ArchiveStrategy::session()
|
|
||||||
{
|
|
||||||
return *_pSession;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void ArchiveStrategy::setCopyStatement()
|
|
||||||
{
|
|
||||||
_pCopyStatement = new Statement(*_pSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void ArchiveStrategy::setDeleteStatement()
|
|
||||||
{
|
|
||||||
_pDeleteStatement = new Statement(*_pSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void ArchiveStrategy::setCountStatement()
|
|
||||||
{
|
|
||||||
_pCountStatement = new Statement(*_pSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Statement& ArchiveStrategy::getCopyStatement()
|
|
||||||
{
|
|
||||||
return *_pCopyStatement;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Statement& ArchiveStrategy::getDeleteStatement()
|
|
||||||
{
|
|
||||||
return *_pDeleteStatement;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Statement& ArchiveStrategy::getCountStatement()
|
|
||||||
{
|
|
||||||
return *_pCountStatement;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// ArchiveByAgeStrategy
|
|
||||||
//
|
|
||||||
class Data_API ArchiveByAgeStrategy: public ArchiveStrategy
|
|
||||||
/// Archives rows scheduled for archiving.
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ArchiveByAgeStrategy(const std::string& connector,
|
|
||||||
const std::string& connect,
|
|
||||||
const std::string& sourceTable,
|
|
||||||
const std::string& destinationTable = DEFAULT_ARCHIVE_DESTINATION);
|
|
||||||
|
|
||||||
~ArchiveByAgeStrategy();
|
|
||||||
|
|
||||||
void archive();
|
|
||||||
|
|
||||||
const std::string& getThreshold() const;
|
|
||||||
/// Returns the archive threshold.
|
|
||||||
|
|
||||||
void setThreshold(const std::string& threshold);
|
|
||||||
/// Sets the archive threshold.
|
|
||||||
|
|
||||||
private:
|
|
||||||
ArchiveByAgeStrategy();
|
|
||||||
ArchiveByAgeStrategy(const ArchiveByAgeStrategy&);
|
|
||||||
ArchiveByAgeStrategy& operator = (const ArchiveByAgeStrategy&);
|
|
||||||
|
|
||||||
void initStatements();
|
|
||||||
|
|
||||||
Timespan _maxAge;
|
|
||||||
std::string _ageString;
|
|
||||||
DateTime _archiveDateTime;
|
|
||||||
Poco::Dynamic::Var _archiveCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
|
|
||||||
inline const std::string& ArchiveByAgeStrategy::getThreshold() const
|
|
||||||
{
|
|
||||||
return _ageString;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_ArchiveStrategy_INCLUDED
|
#endif // Data_ArchiveStrategy_INCLUDED
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef Data_AutoTransaction_INCLUDED
|
#ifndef Data_AutoTransaction_INCLUDED
|
||||||
#define Data_AutoTransaction_INCLUDED
|
#define Data_AutoTransaction_INCLUDED
|
||||||
|
|
||||||
@ -22,14 +21,17 @@
|
|||||||
#include "Poco/Data/Transaction.h"
|
#include "Poco/Data/Transaction.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
{
|
||||||
|
namespace Data
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
typedef Transaction AutoTransaction;
|
typedef Transaction AutoTransaction;
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_AutoTransaction_INCLUDED
|
#endif // Data_AutoTransaction_INCLUDED
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,79 +18,83 @@
|
|||||||
#define Data_Bulk_INCLUDED
|
#define Data_Bulk_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Void.h"
|
|
||||||
#include "Poco/Data/Limit.h"
|
#include "Poco/Data/Limit.h"
|
||||||
|
#include "Poco/Void.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API Bulk
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
Bulk(const Limit& limit);
|
|
||||||
/// Creates the Bulk.
|
|
||||||
|
|
||||||
Bulk(Poco::UInt32 value);
|
|
||||||
/// Creates the Bulk.
|
|
||||||
|
|
||||||
~Bulk();
|
|
||||||
/// Destroys the bulk.
|
|
||||||
|
|
||||||
const Limit& limit() const;
|
|
||||||
/// Returns the limit associated with this bulk object.
|
|
||||||
|
|
||||||
Poco::UInt32 size() const;
|
|
||||||
/// Returns the value of the limit associated with
|
|
||||||
/// this bulk object.
|
|
||||||
|
|
||||||
private:
|
|
||||||
Bulk();
|
|
||||||
|
|
||||||
Limit _limit;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// inlines
|
|
||||||
///
|
|
||||||
inline const Limit& Bulk::limit() const
|
|
||||||
{
|
|
||||||
return _limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Poco::UInt32 Bulk::size() const
|
|
||||||
{
|
|
||||||
return _limit.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace Keywords {
|
|
||||||
|
|
||||||
|
|
||||||
inline Bulk bulk(const Limit& limit = Limit(Limit::LIMIT_UNLIMITED, false, false))
|
|
||||||
/// Convenience function for creation of bulk.
|
|
||||||
{
|
{
|
||||||
return Bulk(limit);
|
|
||||||
|
|
||||||
|
class Data_API Bulk
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Bulk(const Limit & limit);
|
||||||
|
/// Creates the Bulk.
|
||||||
|
|
||||||
|
Bulk(Poco::UInt32 value);
|
||||||
|
/// Creates the Bulk.
|
||||||
|
|
||||||
|
~Bulk();
|
||||||
|
/// Destroys the bulk.
|
||||||
|
|
||||||
|
const Limit & limit() const;
|
||||||
|
/// Returns the limit associated with this bulk object.
|
||||||
|
|
||||||
|
Poco::UInt32 size() const;
|
||||||
|
/// Returns the value of the limit associated with
|
||||||
|
/// this bulk object.
|
||||||
|
|
||||||
|
private:
|
||||||
|
Bulk();
|
||||||
|
|
||||||
|
Limit _limit;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// inlines
|
||||||
|
///
|
||||||
|
inline const Limit & Bulk::limit() const
|
||||||
|
{
|
||||||
|
return _limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Poco::UInt32 Bulk::size() const
|
||||||
|
{
|
||||||
|
return _limit.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace Keywords
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
inline Bulk bulk(const Limit & limit = Limit(Limit::LIMIT_UNLIMITED, false, false))
|
||||||
|
/// Convenience function for creation of bulk.
|
||||||
|
{
|
||||||
|
return Bulk(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void bulk(Void)
|
||||||
|
/// Dummy bulk function. Used for bulk binding creation
|
||||||
|
/// (see BulkBinding) and bulk extraction signalling to Statement.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Keywords
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (*BulkFnType)(Void);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline void bulk(Void)
|
|
||||||
/// Dummy bulk function. Used for bulk binding creation
|
|
||||||
/// (see BulkBinding) and bulk extraction signalling to Statement.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Keywords
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (*BulkFnType)(Void);
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_Bulk_INCLUDED
|
#endif // Data_Bulk_INCLUDED
|
||||||
|
@ -18,131 +18,124 @@
|
|||||||
#define Data_BulkBinding_INCLUDED
|
#define Data_BulkBinding_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
#include <cstddef>
|
||||||
#include "Poco/Data/AbstractBinding.h"
|
|
||||||
#include "Poco/Data/DataException.h"
|
|
||||||
#include "Poco/Data/TypeHandler.h"
|
|
||||||
#include "Poco/Data/Bulk.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <cstddef>
|
#include <vector>
|
||||||
|
#include "Poco/Data/AbstractBinding.h"
|
||||||
|
#include "Poco/Data/Bulk.h"
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
|
#include "Poco/Data/DataException.h"
|
||||||
|
#include "Poco/Data/TypeHandler.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
class BulkBinding: public AbstractBinding
|
|
||||||
/// A BulkBinding maps a value to a column.
|
|
||||||
/// Bulk binding support is provided only for std::vector.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
BulkBinding(const T& val, Poco::UInt32 bulkSize, const std::string& name = "", Direction direction = PD_IN):
|
|
||||||
AbstractBinding(name, direction, bulkSize),
|
|
||||||
_val(val),
|
|
||||||
_bound(false)
|
|
||||||
/// Creates the BulkBinding.
|
|
||||||
{
|
|
||||||
if (0 == _val.size())
|
|
||||||
throw BindingException("Zero size containers not allowed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
~BulkBinding()
|
|
||||||
/// Destroys the BulkBinding.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t numOfColumnsHandled() const
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t numOfRowsHandled() const
|
|
||||||
{
|
|
||||||
return _val.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool canBind() const
|
|
||||||
{
|
|
||||||
return !_bound;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bind(std::size_t pos)
|
|
||||||
{
|
|
||||||
poco_assert_dbg(!getBinder().isNull());
|
|
||||||
TypeHandler<T>::bind(pos, _val, getBinder(), getDirection());
|
|
||||||
_bound = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset ()
|
|
||||||
{
|
|
||||||
_bound = false;
|
|
||||||
getBinder()->reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const T& _val;
|
|
||||||
bool _bound;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
namespace Keywords {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
AbstractBinding::Ptr use(const std::vector<T>& t, BulkFnType, const std::string& name = "")
|
|
||||||
/// Convenience function for a more compact BulkBinding creation for std::vector.
|
|
||||||
{
|
{
|
||||||
return new BulkBinding<std::vector<T> >(t, static_cast<Poco::UInt32>(t.size()), name);
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class BulkBinding : public AbstractBinding
|
||||||
|
/// A BulkBinding maps a value to a column.
|
||||||
|
/// Bulk binding support is provided only for std::vector.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BulkBinding(const T & val, Poco::UInt32 bulkSize, const std::string & name = "", Direction direction = PD_IN)
|
||||||
|
: AbstractBinding(name, direction, bulkSize), _val(val), _bound(false)
|
||||||
|
/// Creates the BulkBinding.
|
||||||
|
{
|
||||||
|
if (0 == _val.size())
|
||||||
|
throw BindingException("Zero size containers not allowed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
~BulkBinding()
|
||||||
|
/// Destroys the BulkBinding.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t numOfColumnsHandled() const { return 1; }
|
||||||
|
|
||||||
|
std::size_t numOfRowsHandled() const { return _val.size(); }
|
||||||
|
|
||||||
|
bool canBind() const { return !_bound; }
|
||||||
|
|
||||||
|
void bind(std::size_t pos)
|
||||||
|
{
|
||||||
|
poco_assert_dbg(!getBinder().isNull());
|
||||||
|
TypeHandler<T>::bind(pos, _val, getBinder(), getDirection());
|
||||||
|
_bound = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
_bound = false;
|
||||||
|
getBinder()->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const T & _val;
|
||||||
|
bool _bound;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace Keywords
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AbstractBinding::Ptr use(const std::vector<T> & t, BulkFnType, const std::string & name = "")
|
||||||
|
/// Convenience function for a more compact BulkBinding creation for std::vector.
|
||||||
|
{
|
||||||
|
return new BulkBinding<std::vector<T>>(t, static_cast<Poco::UInt32>(t.size()), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AbstractBinding::Ptr in(const std::vector<T> & t, BulkFnType, const std::string & name = "")
|
||||||
|
/// Convenience function for a more compact BulkBinding creation for std::vector.
|
||||||
|
{
|
||||||
|
return new BulkBinding<std::vector<T>>(t, static_cast<Poco::UInt32>(t.size()), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AbstractBinding::Ptr use(const std::deque<T> & t, BulkFnType, const std::string & name = "")
|
||||||
|
/// Convenience function for a more compact BulkBinding creation for std::deque.
|
||||||
|
{
|
||||||
|
return new BulkBinding<std::deque<T>>(t, static_cast<Poco::UInt32>(t.size()), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AbstractBinding::Ptr in(const std::deque<T> & t, BulkFnType, const std::string & name = "")
|
||||||
|
/// Convenience function for a more compact BulkBinding creation for std::deque.
|
||||||
|
{
|
||||||
|
return new BulkBinding<std::deque<T>>(t, static_cast<Poco::UInt32>(t.size()), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AbstractBinding::Ptr use(const std::list<T> & t, BulkFnType, const std::string & name = "")
|
||||||
|
/// Convenience function for a more compact BulkBinding creation for std::list.
|
||||||
|
{
|
||||||
|
return new BulkBinding<std::list<T>>(t, static_cast<Poco::UInt32>(t.size()), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AbstractBinding::Ptr in(const std::list<T> & t, BulkFnType, const std::string & name = "")
|
||||||
|
/// Convenience function for a more compact BulkBinding creation for std::list.
|
||||||
|
{
|
||||||
|
return new BulkBinding<std::list<T>>(t, static_cast<Poco::UInt32>(t.size()), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Keywords
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
AbstractBinding::Ptr in(const std::vector<T>& t, BulkFnType, const std::string& name = "")
|
|
||||||
/// Convenience function for a more compact BulkBinding creation for std::vector.
|
|
||||||
{
|
|
||||||
return new BulkBinding<std::vector<T> >(t, static_cast<Poco::UInt32>(t.size()), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
AbstractBinding::Ptr use(const std::deque<T>& t, BulkFnType, const std::string& name = "")
|
|
||||||
/// Convenience function for a more compact BulkBinding creation for std::deque.
|
|
||||||
{
|
|
||||||
return new BulkBinding<std::deque<T> >(t, static_cast<Poco::UInt32>(t.size()), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
AbstractBinding::Ptr in(const std::deque<T>& t, BulkFnType, const std::string& name = "")
|
|
||||||
/// Convenience function for a more compact BulkBinding creation for std::deque.
|
|
||||||
{
|
|
||||||
return new BulkBinding<std::deque<T> >(t, static_cast<Poco::UInt32>(t.size()), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
AbstractBinding::Ptr use(const std::list<T>& t, BulkFnType, const std::string& name = "")
|
|
||||||
/// Convenience function for a more compact BulkBinding creation for std::list.
|
|
||||||
{
|
|
||||||
return new BulkBinding<std::list<T> >(t, static_cast<Poco::UInt32>(t.size()), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
AbstractBinding::Ptr in(const std::list<T>& t, BulkFnType, const std::string& name = "")
|
|
||||||
/// Convenience function for a more compact BulkBinding creation for std::list.
|
|
||||||
{
|
|
||||||
return new BulkBinding<std::list<T> >(t, static_cast<Poco::UInt32>(t.size()), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Keywords
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_BulkBinding_INCLUDED
|
#endif // Data_BulkBinding_INCLUDED
|
||||||
|
@ -18,259 +18,236 @@
|
|||||||
#define Data_BulkExtraction_INCLUDED
|
#define Data_BulkExtraction_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
#include <vector>
|
||||||
#include "Poco/Data/AbstractExtraction.h"
|
#include "Poco/Data/AbstractExtraction.h"
|
||||||
#include "Poco/Data/Bulk.h"
|
#include "Poco/Data/Bulk.h"
|
||||||
|
#include "Poco/Data/Column.h"
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
|
#include "Poco/Data/Position.h"
|
||||||
#include "Poco/Data/Preparation.h"
|
#include "Poco/Data/Preparation.h"
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
template <class C>
|
|
||||||
class BulkExtraction: public AbstractExtraction
|
|
||||||
/// Specialization for bulk extraction of values from a query result set.
|
|
||||||
/// Bulk extraction support is provided only for following STL containers:
|
|
||||||
/// - std::vector
|
|
||||||
/// - std::deque
|
|
||||||
/// - std::list
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
typedef C ValType;
|
|
||||||
typedef typename C::value_type CValType;
|
|
||||||
typedef SharedPtr<ValType> ValPtr;
|
|
||||||
typedef BulkExtraction<ValType> Type;
|
|
||||||
typedef SharedPtr<Type> Ptr;
|
|
||||||
|
|
||||||
BulkExtraction(C& result, Poco::UInt32 limit, const Position& pos = Position(0)):
|
|
||||||
AbstractExtraction(limit, pos.value(), true),
|
|
||||||
_rResult(result),
|
|
||||||
_default()
|
|
||||||
{
|
|
||||||
if (static_cast<Poco::UInt32>(result.size()) != limit)
|
|
||||||
result.resize(limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
BulkExtraction(C& result, const CValType& def, Poco::UInt32 limit, const Position& pos = Position(0)):
|
|
||||||
AbstractExtraction(limit, pos.value(), true),
|
|
||||||
_rResult(result),
|
|
||||||
_default(def)
|
|
||||||
{
|
|
||||||
if (static_cast<Poco::UInt32>(result.size()) != limit)
|
|
||||||
result.resize(limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~BulkExtraction()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t numOfColumnsHandled() const
|
|
||||||
{
|
|
||||||
return TypeHandler<C>::size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t numOfRowsHandled() const
|
|
||||||
{
|
|
||||||
return _rResult.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t numOfRowsAllowed() const
|
|
||||||
{
|
|
||||||
return getLimit();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isNull(std::size_t row) const
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return _nulls.at(row);
|
|
||||||
}
|
|
||||||
catch (std::out_of_range& ex)
|
|
||||||
{
|
|
||||||
throw RangeException(ex.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t extract(std::size_t col)
|
|
||||||
{
|
|
||||||
AbstractExtractor::Ptr pExt = getExtractor();
|
|
||||||
TypeHandler<C>::extract(col, _rResult, _default, pExt);
|
|
||||||
typename C::iterator it = _rResult.begin();
|
|
||||||
typename C::iterator end = _rResult.end();
|
|
||||||
for (int row = 0; it !=end; ++it, ++row)
|
|
||||||
{
|
|
||||||
_nulls.push_back(isValueNull(*it, pExt->isNull(col, row)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return _rResult.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void reset()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractPreparation::Ptr createPreparation(AbstractPreparator::Ptr& pPrep, std::size_t col)
|
|
||||||
{
|
|
||||||
Poco::UInt32 limit = getLimit();
|
|
||||||
if (limit != _rResult.size()) _rResult.resize(limit);
|
|
||||||
pPrep->setLength(limit);
|
|
||||||
pPrep->setBulk(true);
|
|
||||||
return new Preparation<C>(pPrep, col, _rResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const C& result() const
|
|
||||||
{
|
|
||||||
return _rResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
C& _rResult;
|
|
||||||
CValType _default;
|
|
||||||
std::deque<bool> _nulls;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <class C>
|
|
||||||
class InternalBulkExtraction: public BulkExtraction<C>
|
|
||||||
/// Container Data Type specialization extension for extraction of values from a query result set.
|
|
||||||
///
|
|
||||||
/// This class is intended for PocoData internal use - it is used by StatementImpl
|
|
||||||
/// to automatically create internal BulkExtraction in cases when statement returns data and no external storage
|
|
||||||
/// was supplied. It is later used by RecordSet to retrieve the fetched data after statement execution.
|
|
||||||
/// It takes ownership of the Column pointer supplied as constructor argument. Column object, in turn
|
|
||||||
/// owns the data container pointer.
|
|
||||||
///
|
|
||||||
/// InternalBulkExtraction objects can not be copied or assigned.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
typedef C ValType;
|
|
||||||
typedef typename C::value_type CValType;
|
|
||||||
typedef SharedPtr<ValType> ValPtr;
|
|
||||||
typedef InternalBulkExtraction<ValType> Type;
|
|
||||||
typedef SharedPtr<Type> Ptr;
|
|
||||||
|
|
||||||
InternalBulkExtraction(C& result,
|
|
||||||
Column<C>* pColumn,
|
|
||||||
Poco::UInt32 limit,
|
|
||||||
const Position& pos = Position(0)):
|
|
||||||
BulkExtraction<C>(result, CValType(), limit, pos),
|
|
||||||
_pColumn(pColumn)
|
|
||||||
/// Creates InternalBulkExtraction.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~InternalBulkExtraction()
|
|
||||||
/// Destroys InternalBulkExtraction.
|
|
||||||
{
|
|
||||||
delete _pColumn;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
{
|
|
||||||
_pColumn->reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
const CValType& value(int index) const
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return BulkExtraction<C>::result().at(index);
|
|
||||||
}
|
|
||||||
catch (std::out_of_range& ex)
|
|
||||||
{
|
|
||||||
throw RangeException(ex.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isNull(std::size_t row) const
|
|
||||||
{
|
|
||||||
return BulkExtraction<C>::isNull(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Column<C>& column() const
|
|
||||||
{
|
|
||||||
return *_pColumn;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
InternalBulkExtraction();
|
|
||||||
InternalBulkExtraction(const InternalBulkExtraction&);
|
|
||||||
InternalBulkExtraction& operator = (const InternalBulkExtraction&);
|
|
||||||
|
|
||||||
Column<C>* _pColumn;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
namespace Keywords {
|
template <class C>
|
||||||
|
class BulkExtraction : public AbstractExtraction
|
||||||
|
/// Specialization for bulk extraction of values from a query result set.
|
||||||
|
/// Bulk extraction support is provided only for following STL containers:
|
||||||
|
/// - std::vector
|
||||||
|
/// - std::deque
|
||||||
|
/// - std::list
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef C ValType;
|
||||||
|
typedef typename C::value_type CValType;
|
||||||
|
typedef SharedPtr<ValType> ValPtr;
|
||||||
|
typedef BulkExtraction<ValType> Type;
|
||||||
|
typedef SharedPtr<Type> Ptr;
|
||||||
|
|
||||||
|
BulkExtraction(C & result, Poco::UInt32 limit, const Position & pos = Position(0))
|
||||||
|
: AbstractExtraction(limit, pos.value(), true), _rResult(result), _default()
|
||||||
|
{
|
||||||
|
if (static_cast<Poco::UInt32>(result.size()) != limit)
|
||||||
|
result.resize(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
BulkExtraction(C & result, const CValType & def, Poco::UInt32 limit, const Position & pos = Position(0))
|
||||||
|
: AbstractExtraction(limit, pos.value(), true), _rResult(result), _default(def)
|
||||||
|
{
|
||||||
|
if (static_cast<Poco::UInt32>(result.size()) != limit)
|
||||||
|
result.resize(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~BulkExtraction() { }
|
||||||
|
|
||||||
|
std::size_t numOfColumnsHandled() const { return TypeHandler<C>::size(); }
|
||||||
|
|
||||||
|
std::size_t numOfRowsHandled() const { return _rResult.size(); }
|
||||||
|
|
||||||
|
std::size_t numOfRowsAllowed() const { return getLimit(); }
|
||||||
|
|
||||||
|
bool isNull(std::size_t row) const
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _nulls.at(row);
|
||||||
|
}
|
||||||
|
catch (std::out_of_range & ex)
|
||||||
|
{
|
||||||
|
throw RangeException(ex.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t extract(std::size_t col)
|
||||||
|
{
|
||||||
|
AbstractExtractor::Ptr pExt = getExtractor();
|
||||||
|
TypeHandler<C>::extract(col, _rResult, _default, pExt);
|
||||||
|
typename C::iterator it = _rResult.begin();
|
||||||
|
typename C::iterator end = _rResult.end();
|
||||||
|
for (int row = 0; it != end; ++it, ++row)
|
||||||
|
{
|
||||||
|
_nulls.push_back(isValueNull(*it, pExt->isNull(col, row)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return _rResult.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void reset() { }
|
||||||
|
|
||||||
|
AbstractPreparation::Ptr createPreparation(AbstractPreparator::Ptr & pPrep, std::size_t col)
|
||||||
|
{
|
||||||
|
Poco::UInt32 limit = getLimit();
|
||||||
|
if (limit != _rResult.size())
|
||||||
|
_rResult.resize(limit);
|
||||||
|
pPrep->setLength(limit);
|
||||||
|
pPrep->setBulk(true);
|
||||||
|
return new Preparation<C>(pPrep, col, _rResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const C & result() const { return _rResult; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
C & _rResult;
|
||||||
|
CValType _default;
|
||||||
|
std::deque<bool> _nulls;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class C>
|
||||||
|
class InternalBulkExtraction : public BulkExtraction<C>
|
||||||
|
/// Container Data Type specialization extension for extraction of values from a query result set.
|
||||||
|
///
|
||||||
|
/// This class is intended for PocoData internal use - it is used by StatementImpl
|
||||||
|
/// to automatically create internal BulkExtraction in cases when statement returns data and no external storage
|
||||||
|
/// was supplied. It is later used by RecordSet to retrieve the fetched data after statement execution.
|
||||||
|
/// It takes ownership of the Column pointer supplied as constructor argument. Column object, in turn
|
||||||
|
/// owns the data container pointer.
|
||||||
|
///
|
||||||
|
/// InternalBulkExtraction objects can not be copied or assigned.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef C ValType;
|
||||||
|
typedef typename C::value_type CValType;
|
||||||
|
typedef SharedPtr<ValType> ValPtr;
|
||||||
|
typedef InternalBulkExtraction<ValType> Type;
|
||||||
|
typedef SharedPtr<Type> Ptr;
|
||||||
|
|
||||||
|
InternalBulkExtraction(C & result, Column<C> * pColumn, Poco::UInt32 limit, const Position & pos = Position(0))
|
||||||
|
: BulkExtraction<C>(result, CValType(), limit, pos), _pColumn(pColumn)
|
||||||
|
/// Creates InternalBulkExtraction.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~InternalBulkExtraction()
|
||||||
|
/// Destroys InternalBulkExtraction.
|
||||||
|
{
|
||||||
|
delete _pColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() { _pColumn->reset(); }
|
||||||
|
|
||||||
|
const CValType & value(int index) const
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return BulkExtraction<C>::result().at(index);
|
||||||
|
}
|
||||||
|
catch (std::out_of_range & ex)
|
||||||
|
{
|
||||||
|
throw RangeException(ex.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNull(std::size_t row) const { return BulkExtraction<C>::isNull(row); }
|
||||||
|
|
||||||
|
const Column<C> & column() const { return *_pColumn; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
InternalBulkExtraction();
|
||||||
|
InternalBulkExtraction(const InternalBulkExtraction &);
|
||||||
|
InternalBulkExtraction & operator=(const InternalBulkExtraction &);
|
||||||
|
|
||||||
|
Column<C> * _pColumn;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace Keywords
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AbstractExtraction::Ptr into(std::vector<T> & t, const Bulk & bulk, const Position & pos = Position(0))
|
||||||
|
/// Convenience function to allow for a more compact creation of an extraction object
|
||||||
|
/// with std::vector bulk extraction support.
|
||||||
|
{
|
||||||
|
return new BulkExtraction<std::vector<T>>(t, bulk.size(), pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AbstractExtraction::Ptr into(std::vector<T> & t, BulkFnType, const Position & pos = Position(0))
|
||||||
|
/// Convenience function to allow for a more compact creation of an extraction object
|
||||||
|
/// with std::vector bulk extraction support.
|
||||||
|
{
|
||||||
|
Poco::UInt32 size = static_cast<Poco::UInt32>(t.size());
|
||||||
|
if (0 == size)
|
||||||
|
throw InvalidArgumentException("Zero length not allowed.");
|
||||||
|
return new BulkExtraction<std::vector<T>>(t, size, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AbstractExtraction::Ptr into(std::deque<T> & t, const Bulk & bulk, const Position & pos = Position(0))
|
||||||
|
/// Convenience function to allow for a more compact creation of an extraction object
|
||||||
|
/// with std::deque bulk extraction support.
|
||||||
|
{
|
||||||
|
return new BulkExtraction<std::deque<T>>(t, bulk.size(), pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AbstractExtraction::Ptr into(std::deque<T> & t, BulkFnType, const Position & pos = Position(0))
|
||||||
|
/// Convenience function to allow for a more compact creation of an extraction object
|
||||||
|
/// with std::deque bulk extraction support.
|
||||||
|
{
|
||||||
|
Poco::UInt32 size = static_cast<Poco::UInt32>(t.size());
|
||||||
|
if (0 == size)
|
||||||
|
throw InvalidArgumentException("Zero length not allowed.");
|
||||||
|
return new BulkExtraction<std::deque<T>>(t, size, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AbstractExtraction::Ptr into(std::list<T> & t, const Bulk & bulk, const Position & pos = Position(0))
|
||||||
|
/// Convenience function to allow for a more compact creation of an extraction object
|
||||||
|
/// with std::list bulk extraction support.
|
||||||
|
{
|
||||||
|
return new BulkExtraction<std::list<T>>(t, bulk.size(), pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AbstractExtraction::Ptr into(std::list<T> & t, BulkFnType, const Position & pos = Position(0))
|
||||||
|
/// Convenience function to allow for a more compact creation of an extraction object
|
||||||
|
/// with std::list bulk extraction support.
|
||||||
|
{
|
||||||
|
Poco::UInt32 size = static_cast<Poco::UInt32>(t.size());
|
||||||
|
if (0 == size)
|
||||||
|
throw InvalidArgumentException("Zero length not allowed.");
|
||||||
|
return new BulkExtraction<std::list<T>>(t, size, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Keywords
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
AbstractExtraction::Ptr into(std::vector<T>& t, const Bulk& bulk, const Position& pos = Position(0))
|
|
||||||
/// Convenience function to allow for a more compact creation of an extraction object
|
|
||||||
/// with std::vector bulk extraction support.
|
|
||||||
{
|
|
||||||
return new BulkExtraction<std::vector<T> >(t, bulk.size(), pos);
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
AbstractExtraction::Ptr into(std::vector<T>& t, BulkFnType, const Position& pos = Position(0))
|
|
||||||
/// Convenience function to allow for a more compact creation of an extraction object
|
|
||||||
/// with std::vector bulk extraction support.
|
|
||||||
{
|
|
||||||
Poco::UInt32 size = static_cast<Poco::UInt32>(t.size());
|
|
||||||
if (0 == size) throw InvalidArgumentException("Zero length not allowed.");
|
|
||||||
return new BulkExtraction<std::vector<T> >(t, size, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
AbstractExtraction::Ptr into(std::deque<T>& t, const Bulk& bulk, const Position& pos = Position(0))
|
|
||||||
/// Convenience function to allow for a more compact creation of an extraction object
|
|
||||||
/// with std::deque bulk extraction support.
|
|
||||||
{
|
|
||||||
return new BulkExtraction<std::deque<T> >(t, bulk.size(), pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
AbstractExtraction::Ptr into(std::deque<T>& t, BulkFnType, const Position& pos = Position(0))
|
|
||||||
/// Convenience function to allow for a more compact creation of an extraction object
|
|
||||||
/// with std::deque bulk extraction support.
|
|
||||||
{
|
|
||||||
Poco::UInt32 size = static_cast<Poco::UInt32>(t.size());
|
|
||||||
if (0 == size) throw InvalidArgumentException("Zero length not allowed.");
|
|
||||||
return new BulkExtraction<std::deque<T> >(t, size, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
AbstractExtraction::Ptr into(std::list<T>& t, const Bulk& bulk, const Position& pos = Position(0))
|
|
||||||
/// Convenience function to allow for a more compact creation of an extraction object
|
|
||||||
/// with std::list bulk extraction support.
|
|
||||||
{
|
|
||||||
return new BulkExtraction<std::list<T> >(t, bulk.size(), pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
AbstractExtraction::Ptr into(std::list<T>& t, BulkFnType, const Position& pos = Position(0))
|
|
||||||
/// Convenience function to allow for a more compact creation of an extraction object
|
|
||||||
/// with std::list bulk extraction support.
|
|
||||||
{
|
|
||||||
Poco::UInt32 size = static_cast<Poco::UInt32>(t.size());
|
|
||||||
if (0 == size) throw InvalidArgumentException("Zero length not allowed.");
|
|
||||||
return new BulkExtraction<std::list<T> >(t, size, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Keywords
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_BulkExtraction_INCLUDED
|
#endif // Data_BulkExtraction_INCLUDED
|
||||||
|
@ -18,473 +18,465 @@
|
|||||||
#define Data_Column_INCLUDED
|
#define Data_Column_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/MetaColumn.h"
|
#include "Poco/Data/MetaColumn.h"
|
||||||
#include "Poco/SharedPtr.h"
|
|
||||||
#include "Poco/RefCountedObject.h"
|
#include "Poco/RefCountedObject.h"
|
||||||
#include <vector>
|
#include "Poco/SharedPtr.h"
|
||||||
#include <list>
|
|
||||||
#include <deque>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
template <class C>
|
|
||||||
class Column
|
|
||||||
/// Column class is column data container.
|
|
||||||
/// Data (a pointer to underlying STL container) is assigned to the class
|
|
||||||
/// at construction time. Construction with null pointer is not allowed.
|
|
||||||
/// This class owns the data assigned to it and deletes the storage on destruction.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
typedef C Container;
|
|
||||||
typedef Poco::SharedPtr<C> ContainerPtr;
|
|
||||||
typedef typename C::const_iterator Iterator;
|
|
||||||
typedef typename C::const_reverse_iterator RIterator;
|
|
||||||
typedef typename C::size_type Size;
|
|
||||||
typedef typename C::value_type Type;
|
|
||||||
|
|
||||||
Column(const MetaColumn& metaColumn, Container* pData):
|
|
||||||
_metaColumn(metaColumn),
|
|
||||||
_pData(pData)
|
|
||||||
/// Creates the Column.
|
|
||||||
{
|
|
||||||
if (!_pData)
|
|
||||||
throw NullPointerException("Container pointer must point to valid storage.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Column(const Column& col):
|
|
||||||
_metaColumn(col._metaColumn),
|
|
||||||
_pData(col._pData)
|
|
||||||
/// Creates the Column.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~Column()
|
|
||||||
/// Destroys the Column.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Column& operator = (const Column& col)
|
|
||||||
/// Assignment operator.
|
|
||||||
{
|
|
||||||
Column tmp(col);
|
|
||||||
swap(tmp);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(Column& other)
|
|
||||||
/// Swaps the column with another one.
|
|
||||||
{
|
|
||||||
using std::swap;
|
|
||||||
swap(_metaColumn, other._metaColumn);
|
|
||||||
swap(_pData, other._pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
Container& data()
|
|
||||||
/// Returns reference to contained data.
|
|
||||||
{
|
|
||||||
return *_pData;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Type& value(std::size_t row) const
|
|
||||||
/// Returns the field value in specified row.
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return _pData->at(row);
|
|
||||||
}
|
|
||||||
catch (std::out_of_range& ex)
|
|
||||||
{
|
|
||||||
throw RangeException(ex.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Type& operator [] (std::size_t row) const
|
|
||||||
/// Returns the field value in specified row.
|
|
||||||
{
|
|
||||||
return value(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
Size rowCount() const
|
|
||||||
/// Returns number of rows.
|
|
||||||
{
|
|
||||||
return _pData->size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
/// Clears and shrinks the storage.
|
|
||||||
{
|
|
||||||
Container().swap(*_pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& name() const
|
|
||||||
/// Returns column name.
|
|
||||||
{
|
|
||||||
return _metaColumn.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t length() const
|
|
||||||
/// Returns column maximum length.
|
|
||||||
{
|
|
||||||
return _metaColumn.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t precision() const
|
|
||||||
/// Returns column precision.
|
|
||||||
/// Valid for floating point fields only (zero for other data types).
|
|
||||||
{
|
|
||||||
return _metaColumn.precision();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t position() const
|
|
||||||
/// Returns column position.
|
|
||||||
{
|
|
||||||
return _metaColumn.position();
|
|
||||||
}
|
|
||||||
|
|
||||||
MetaColumn::ColumnDataType type() const
|
|
||||||
/// Returns column type.
|
|
||||||
{
|
|
||||||
return _metaColumn.type();
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator begin() const
|
|
||||||
/// Returns iterator pointing to the beginning of data storage vector.
|
|
||||||
{
|
|
||||||
return _pData->begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator end() const
|
|
||||||
/// Returns iterator pointing to the end of data storage vector.
|
|
||||||
{
|
|
||||||
return _pData->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Column();
|
|
||||||
|
|
||||||
MetaColumn _metaColumn;
|
|
||||||
ContainerPtr _pData;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class Column<std::vector<bool> >
|
|
||||||
/// The std::vector<bool> specialization for the Column class.
|
|
||||||
///
|
|
||||||
/// This specialization is necessary due to the nature of std::vector<bool>.
|
|
||||||
/// For details, see the standard library implementation of vector<bool>
|
|
||||||
/// or
|
|
||||||
/// S. Meyers: "Effective STL" (Copyright Addison-Wesley 2001),
|
|
||||||
/// Item 18: "Avoid using vector<bool>."
|
|
||||||
///
|
|
||||||
/// The workaround employed here is using deque<bool> as an
|
|
||||||
/// internal "companion" container kept in sync with the vector<bool>
|
|
||||||
/// column data.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
typedef std::vector<bool> Container;
|
|
||||||
typedef Poco::SharedPtr<Container> ContainerPtr;
|
|
||||||
typedef Container::const_iterator Iterator;
|
|
||||||
typedef Container::const_reverse_iterator RIterator;
|
|
||||||
typedef Container::size_type Size;
|
|
||||||
|
|
||||||
Column(const MetaColumn& metaColumn, Container* pData):
|
|
||||||
_metaColumn(metaColumn),
|
|
||||||
_pData(pData)
|
|
||||||
/// Creates the Column.
|
|
||||||
{
|
|
||||||
poco_check_ptr (_pData);
|
|
||||||
_deque.assign(_pData->begin(), _pData->end());
|
|
||||||
}
|
|
||||||
|
|
||||||
Column(const Column& col):
|
|
||||||
_metaColumn(col._metaColumn),
|
|
||||||
_pData(col._pData)
|
|
||||||
/// Creates the Column.
|
|
||||||
{
|
|
||||||
_deque.assign(_pData->begin(), _pData->end());
|
|
||||||
}
|
|
||||||
|
|
||||||
~Column()
|
|
||||||
/// Destroys the Column.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Column& operator = (const Column& col)
|
|
||||||
/// Assignment operator.
|
|
||||||
{
|
|
||||||
Column tmp(col);
|
|
||||||
swap(tmp);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(Column& other)
|
|
||||||
/// Swaps the column with another one.
|
|
||||||
{
|
|
||||||
using std::swap;
|
|
||||||
swap(_metaColumn, other._metaColumn);
|
|
||||||
swap(_pData, other._pData);
|
|
||||||
swap(_deque, other._deque);
|
|
||||||
}
|
|
||||||
|
|
||||||
Container& data()
|
|
||||||
/// Returns reference to contained data.
|
|
||||||
{
|
|
||||||
return *_pData;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool& value(std::size_t row) const
|
|
||||||
/// Returns the field value in specified row.
|
|
||||||
{
|
|
||||||
if (_deque.size() < _pData->size())
|
|
||||||
_deque.resize(_pData->size());
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return _deque.at(row) = _pData->at(row);
|
|
||||||
}
|
|
||||||
catch (std::out_of_range& ex)
|
|
||||||
{
|
|
||||||
throw RangeException(ex.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool& operator [] (std::size_t row) const
|
|
||||||
/// Returns the field value in specified row.
|
|
||||||
{
|
|
||||||
return value(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
Size rowCount() const
|
|
||||||
/// Returns number of rows.
|
|
||||||
{
|
|
||||||
return _pData->size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
/// Clears and shrinks the storage.
|
|
||||||
{
|
|
||||||
Container().swap(*_pData);
|
|
||||||
_deque.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& name() const
|
|
||||||
/// Returns column name.
|
|
||||||
{
|
|
||||||
return _metaColumn.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t length() const
|
|
||||||
/// Returns column maximum length.
|
|
||||||
{
|
|
||||||
return _metaColumn.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t precision() const
|
|
||||||
/// Returns column precision.
|
|
||||||
/// Valid for floating point fields only (zero for other data types).
|
|
||||||
{
|
|
||||||
return _metaColumn.precision();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t position() const
|
|
||||||
/// Returns column position.
|
|
||||||
{
|
|
||||||
return _metaColumn.position();
|
|
||||||
}
|
|
||||||
|
|
||||||
MetaColumn::ColumnDataType type() const
|
|
||||||
/// Returns column type.
|
|
||||||
{
|
|
||||||
return _metaColumn.type();
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator begin() const
|
|
||||||
/// Returns iterator pointing to the beginning of data storage vector.
|
|
||||||
{
|
|
||||||
return _pData->begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator end() const
|
|
||||||
/// Returns iterator pointing to the end of data storage vector.
|
|
||||||
{
|
|
||||||
return _pData->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Column();
|
|
||||||
|
|
||||||
MetaColumn _metaColumn;
|
|
||||||
ContainerPtr _pData;
|
|
||||||
mutable std::deque<bool> _deque;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class C>
|
||||||
class Column<std::list<T> >
|
class Column
|
||||||
/// Column specialization for std::list
|
/// Column class is column data container.
|
||||||
{
|
/// Data (a pointer to underlying STL container) is assigned to the class
|
||||||
public:
|
/// at construction time. Construction with null pointer is not allowed.
|
||||||
typedef std::list<T> Container;
|
/// This class owns the data assigned to it and deletes the storage on destruction.
|
||||||
typedef Poco::SharedPtr<Container> ContainerPtr;
|
{
|
||||||
typedef typename Container::const_iterator Iterator;
|
public:
|
||||||
typedef typename Container::const_reverse_iterator RIterator;
|
typedef C Container;
|
||||||
typedef typename Container::size_type Size;
|
typedef Poco::SharedPtr<C> ContainerPtr;
|
||||||
|
typedef typename C::const_iterator Iterator;
|
||||||
|
typedef typename C::const_reverse_iterator RIterator;
|
||||||
|
typedef typename C::size_type Size;
|
||||||
|
typedef typename C::value_type Type;
|
||||||
|
|
||||||
Column(const MetaColumn& metaColumn, std::list<T>* pData):
|
Column(const MetaColumn & metaColumn, Container * pData) : _metaColumn(metaColumn), _pData(pData)
|
||||||
_metaColumn(metaColumn),
|
/// Creates the Column.
|
||||||
_pData(pData)
|
{
|
||||||
/// Creates the Column.
|
if (!_pData)
|
||||||
{
|
throw NullPointerException("Container pointer must point to valid storage.");
|
||||||
poco_check_ptr (_pData);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Column(const Column& col):
|
Column(const Column & col) : _metaColumn(col._metaColumn), _pData(col._pData)
|
||||||
_metaColumn(col._metaColumn),
|
/// Creates the Column.
|
||||||
_pData(col._pData)
|
{
|
||||||
/// Creates the Column.
|
}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~Column()
|
~Column()
|
||||||
/// Destroys the Column.
|
/// Destroys the Column.
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Column& operator = (const Column& col)
|
Column & operator=(const Column & col)
|
||||||
/// Assignment operator.
|
/// Assignment operator.
|
||||||
{
|
{
|
||||||
Column tmp(col);
|
Column tmp(col);
|
||||||
swap(tmp);
|
swap(tmp);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(Column& other)
|
void swap(Column & other)
|
||||||
/// Swaps the column with another one.
|
/// Swaps the column with another one.
|
||||||
{
|
{
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(_metaColumn, other._metaColumn);
|
swap(_metaColumn, other._metaColumn);
|
||||||
swap(_pData, other._pData);
|
swap(_pData, other._pData);
|
||||||
}
|
}
|
||||||
|
|
||||||
Container& data()
|
Container & data()
|
||||||
/// Returns reference to contained data.
|
/// Returns reference to contained data.
|
||||||
{
|
{
|
||||||
return *_pData;
|
return *_pData;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& value(std::size_t row) const
|
const Type & value(std::size_t row) const
|
||||||
/// Returns the field value in specified row.
|
/// Returns the field value in specified row.
|
||||||
/// This is the std::list specialization and std::list
|
{
|
||||||
/// is not the optimal solution for cases where random
|
try
|
||||||
/// access is needed.
|
{
|
||||||
/// However, to allow for compatibility with other
|
return _pData->at(row);
|
||||||
/// containers, this functionality is provided here.
|
}
|
||||||
/// To alleviate the problem, an effort is made
|
catch (std::out_of_range & ex)
|
||||||
/// to start iteration from beginning or end,
|
{
|
||||||
/// depending on the position requested.
|
throw RangeException(ex.what());
|
||||||
{
|
}
|
||||||
if (row <= (std::size_t) (_pData->size() / 2))
|
}
|
||||||
{
|
|
||||||
Iterator it = _pData->begin();
|
|
||||||
Iterator end = _pData->end();
|
|
||||||
for (int i = 0; it != end; ++it, ++i)
|
|
||||||
if (i == row) return *it;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
row = _pData->size() - row;
|
|
||||||
RIterator it = _pData->rbegin();
|
|
||||||
RIterator end = _pData->rend();
|
|
||||||
for (int i = 1; it != end; ++it, ++i)
|
|
||||||
if (i == row) return *it;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw RangeException("Invalid row number.");
|
const Type & operator[](std::size_t row) const
|
||||||
}
|
/// Returns the field value in specified row.
|
||||||
|
{
|
||||||
|
return value(row);
|
||||||
|
}
|
||||||
|
|
||||||
const T& operator [] (std::size_t row) const
|
Size rowCount() const
|
||||||
/// Returns the field value in specified row.
|
/// Returns number of rows.
|
||||||
{
|
{
|
||||||
return value(row);
|
return _pData->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
Size rowCount() const
|
void reset()
|
||||||
/// Returns number of rows.
|
/// Clears and shrinks the storage.
|
||||||
{
|
{
|
||||||
return _pData->size();
|
Container().swap(*_pData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
const std::string & name() const
|
||||||
/// Clears the storage.
|
/// Returns column name.
|
||||||
{
|
{
|
||||||
_pData->clear();
|
return _metaColumn.name();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& name() const
|
std::size_t length() const
|
||||||
/// Returns column name.
|
/// Returns column maximum length.
|
||||||
{
|
{
|
||||||
return _metaColumn.name();
|
return _metaColumn.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t length() const
|
std::size_t precision() const
|
||||||
/// Returns column maximum length.
|
/// Returns column precision.
|
||||||
{
|
/// Valid for floating point fields only (zero for other data types).
|
||||||
return _metaColumn.length();
|
{
|
||||||
}
|
return _metaColumn.precision();
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t precision() const
|
std::size_t position() const
|
||||||
/// Returns column precision.
|
/// Returns column position.
|
||||||
/// Valid for floating point fields only (zero for other data types).
|
{
|
||||||
{
|
return _metaColumn.position();
|
||||||
return _metaColumn.precision();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t position() const
|
MetaColumn::ColumnDataType type() const
|
||||||
/// Returns column position.
|
/// Returns column type.
|
||||||
{
|
{
|
||||||
return _metaColumn.position();
|
return _metaColumn.type();
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaColumn::ColumnDataType type() const
|
Iterator begin() const
|
||||||
/// Returns column type.
|
/// Returns iterator pointing to the beginning of data storage vector.
|
||||||
{
|
{
|
||||||
return _metaColumn.type();
|
return _pData->begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator begin() const
|
Iterator end() const
|
||||||
/// Returns iterator pointing to the beginning of data storage vector.
|
/// Returns iterator pointing to the end of data storage vector.
|
||||||
{
|
{
|
||||||
return _pData->begin();
|
return _pData->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator end() const
|
private:
|
||||||
/// Returns iterator pointing to the end of data storage vector.
|
Column();
|
||||||
{
|
|
||||||
return _pData->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
MetaColumn _metaColumn;
|
||||||
Column();
|
ContainerPtr _pData;
|
||||||
|
};
|
||||||
MetaColumn _metaColumn;
|
|
||||||
ContainerPtr _pData;
|
|
||||||
};
|
template <>
|
||||||
|
class Column<std::vector<bool>>
|
||||||
|
/// The std::vector<bool> specialization for the Column class.
|
||||||
|
///
|
||||||
|
/// This specialization is necessary due to the nature of std::vector<bool>.
|
||||||
|
/// For details, see the standard library implementation of vector<bool>
|
||||||
|
/// or
|
||||||
|
/// S. Meyers: "Effective STL" (Copyright Addison-Wesley 2001),
|
||||||
|
/// Item 18: "Avoid using vector<bool>."
|
||||||
|
///
|
||||||
|
/// The workaround employed here is using deque<bool> as an
|
||||||
|
/// internal "companion" container kept in sync with the vector<bool>
|
||||||
|
/// column data.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::vector<bool> Container;
|
||||||
|
typedef Poco::SharedPtr<Container> ContainerPtr;
|
||||||
|
typedef Container::const_iterator Iterator;
|
||||||
|
typedef Container::const_reverse_iterator RIterator;
|
||||||
|
typedef Container::size_type Size;
|
||||||
|
|
||||||
|
Column(const MetaColumn & metaColumn, Container * pData) : _metaColumn(metaColumn), _pData(pData)
|
||||||
|
/// Creates the Column.
|
||||||
|
{
|
||||||
|
poco_check_ptr(_pData);
|
||||||
|
_deque.assign(_pData->begin(), _pData->end());
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(const Column & col) : _metaColumn(col._metaColumn), _pData(col._pData)
|
||||||
|
/// Creates the Column.
|
||||||
|
{
|
||||||
|
_deque.assign(_pData->begin(), _pData->end());
|
||||||
|
}
|
||||||
|
|
||||||
|
~Column()
|
||||||
|
/// Destroys the Column.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Column & operator=(const Column & col)
|
||||||
|
/// Assignment operator.
|
||||||
|
{
|
||||||
|
Column tmp(col);
|
||||||
|
swap(tmp);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(Column & other)
|
||||||
|
/// Swaps the column with another one.
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(_metaColumn, other._metaColumn);
|
||||||
|
swap(_pData, other._pData);
|
||||||
|
swap(_deque, other._deque);
|
||||||
|
}
|
||||||
|
|
||||||
|
Container & data()
|
||||||
|
/// Returns reference to contained data.
|
||||||
|
{
|
||||||
|
return *_pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool & value(std::size_t row) const
|
||||||
|
/// Returns the field value in specified row.
|
||||||
|
{
|
||||||
|
if (_deque.size() < _pData->size())
|
||||||
|
_deque.resize(_pData->size());
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _deque.at(row) = _pData->at(row);
|
||||||
|
}
|
||||||
|
catch (std::out_of_range & ex)
|
||||||
|
{
|
||||||
|
throw RangeException(ex.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool & operator[](std::size_t row) const
|
||||||
|
/// Returns the field value in specified row.
|
||||||
|
{
|
||||||
|
return value(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
Size rowCount() const
|
||||||
|
/// Returns number of rows.
|
||||||
|
{
|
||||||
|
return _pData->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
/// Clears and shrinks the storage.
|
||||||
|
{
|
||||||
|
Container().swap(*_pData);
|
||||||
|
_deque.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string & name() const
|
||||||
|
/// Returns column name.
|
||||||
|
{
|
||||||
|
return _metaColumn.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t length() const
|
||||||
|
/// Returns column maximum length.
|
||||||
|
{
|
||||||
|
return _metaColumn.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t precision() const
|
||||||
|
/// Returns column precision.
|
||||||
|
/// Valid for floating point fields only (zero for other data types).
|
||||||
|
{
|
||||||
|
return _metaColumn.precision();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t position() const
|
||||||
|
/// Returns column position.
|
||||||
|
{
|
||||||
|
return _metaColumn.position();
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaColumn::ColumnDataType type() const
|
||||||
|
/// Returns column type.
|
||||||
|
{
|
||||||
|
return _metaColumn.type();
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator begin() const
|
||||||
|
/// Returns iterator pointing to the beginning of data storage vector.
|
||||||
|
{
|
||||||
|
return _pData->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator end() const
|
||||||
|
/// Returns iterator pointing to the end of data storage vector.
|
||||||
|
{
|
||||||
|
return _pData->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Column();
|
||||||
|
|
||||||
|
MetaColumn _metaColumn;
|
||||||
|
ContainerPtr _pData;
|
||||||
|
mutable std::deque<bool> _deque;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Column<std::list<T>>
|
||||||
|
/// Column specialization for std::list
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::list<T> Container;
|
||||||
|
typedef Poco::SharedPtr<Container> ContainerPtr;
|
||||||
|
typedef typename Container::const_iterator Iterator;
|
||||||
|
typedef typename Container::const_reverse_iterator RIterator;
|
||||||
|
typedef typename Container::size_type Size;
|
||||||
|
|
||||||
|
Column(const MetaColumn & metaColumn, std::list<T> * pData) : _metaColumn(metaColumn), _pData(pData)
|
||||||
|
/// Creates the Column.
|
||||||
|
{
|
||||||
|
poco_check_ptr(_pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(const Column & col) : _metaColumn(col._metaColumn), _pData(col._pData)
|
||||||
|
/// Creates the Column.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Column()
|
||||||
|
/// Destroys the Column.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Column & operator=(const Column & col)
|
||||||
|
/// Assignment operator.
|
||||||
|
{
|
||||||
|
Column tmp(col);
|
||||||
|
swap(tmp);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(Column & other)
|
||||||
|
/// Swaps the column with another one.
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(_metaColumn, other._metaColumn);
|
||||||
|
swap(_pData, other._pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
Container & data()
|
||||||
|
/// Returns reference to contained data.
|
||||||
|
{
|
||||||
|
return *_pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T & value(std::size_t row) const
|
||||||
|
/// Returns the field value in specified row.
|
||||||
|
/// This is the std::list specialization and std::list
|
||||||
|
/// is not the optimal solution for cases where random
|
||||||
|
/// access is needed.
|
||||||
|
/// However, to allow for compatibility with other
|
||||||
|
/// containers, this functionality is provided here.
|
||||||
|
/// To alleviate the problem, an effort is made
|
||||||
|
/// to start iteration from beginning or end,
|
||||||
|
/// depending on the position requested.
|
||||||
|
{
|
||||||
|
if (row <= (std::size_t)(_pData->size() / 2))
|
||||||
|
{
|
||||||
|
Iterator it = _pData->begin();
|
||||||
|
Iterator end = _pData->end();
|
||||||
|
for (int i = 0; it != end; ++it, ++i)
|
||||||
|
if (i == row)
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
row = _pData->size() - row;
|
||||||
|
RIterator it = _pData->rbegin();
|
||||||
|
RIterator end = _pData->rend();
|
||||||
|
for (int i = 1; it != end; ++it, ++i)
|
||||||
|
if (i == row)
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw RangeException("Invalid row number.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const T & operator[](std::size_t row) const
|
||||||
|
/// Returns the field value in specified row.
|
||||||
|
{
|
||||||
|
return value(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
Size rowCount() const
|
||||||
|
/// Returns number of rows.
|
||||||
|
{
|
||||||
|
return _pData->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
/// Clears the storage.
|
||||||
|
{
|
||||||
|
_pData->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string & name() const
|
||||||
|
/// Returns column name.
|
||||||
|
{
|
||||||
|
return _metaColumn.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t length() const
|
||||||
|
/// Returns column maximum length.
|
||||||
|
{
|
||||||
|
return _metaColumn.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t precision() const
|
||||||
|
/// Returns column precision.
|
||||||
|
/// Valid for floating point fields only (zero for other data types).
|
||||||
|
{
|
||||||
|
return _metaColumn.precision();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t position() const
|
||||||
|
/// Returns column position.
|
||||||
|
{
|
||||||
|
return _metaColumn.position();
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaColumn::ColumnDataType type() const
|
||||||
|
/// Returns column type.
|
||||||
|
{
|
||||||
|
return _metaColumn.type();
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator begin() const
|
||||||
|
/// Returns iterator pointing to the beginning of data storage vector.
|
||||||
|
{
|
||||||
|
return _pData->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator end() const
|
||||||
|
/// Returns iterator pointing to the end of data storage vector.
|
||||||
|
{
|
||||||
|
return _pData->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Column();
|
||||||
|
|
||||||
|
MetaColumn _metaColumn;
|
||||||
|
ContainerPtr _pData;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename C>
|
||||||
|
inline void swap(Column<C> & c1, Column<C> & c2)
|
||||||
|
{
|
||||||
|
c1.swap(c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename C>
|
|
||||||
inline void swap(Column<C>& c1, Column<C>& c2)
|
|
||||||
{
|
|
||||||
c1.swap(c2);
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_Column_INCLUDED
|
#endif // Data_Column_INCLUDED
|
||||||
|
|
||||||
|
@ -18,39 +18,42 @@
|
|||||||
#define Data_Connector_INCLUDED
|
#define Data_Connector_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/AutoPtr.h"
|
||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/SessionImpl.h"
|
#include "Poco/Data/SessionImpl.h"
|
||||||
#include "Poco/AutoPtr.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
{
|
||||||
|
namespace Data
|
||||||
|
|
||||||
class Data_API Connector
|
|
||||||
/// A Connector creates SessionImpl objects.
|
|
||||||
///
|
|
||||||
/// Every connector library (like the SQLite or the ODBC connector)
|
|
||||||
/// provides a subclass of this class, an instance of which is
|
|
||||||
/// registered with the SessionFactory.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
Connector();
|
|
||||||
/// Creates the Connector.
|
|
||||||
|
|
||||||
virtual ~Connector();
|
|
||||||
/// Destroys the Connector.
|
|
||||||
|
|
||||||
virtual const std::string& name() const = 0;
|
|
||||||
/// Returns the name associated with this connector.
|
|
||||||
|
|
||||||
virtual Poco::AutoPtr<SessionImpl> createSession(const std::string& connectionString,
|
|
||||||
std::size_t timeout = SessionImpl::LOGIN_TIMEOUT_DEFAULT) = 0;
|
|
||||||
/// Create a SessionImpl object and initialize it with the given connectionString.
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
class Data_API Connector
|
||||||
|
/// A Connector creates SessionImpl objects.
|
||||||
|
///
|
||||||
|
/// Every connector library (like the SQLite or the ODBC connector)
|
||||||
|
/// provides a subclass of this class, an instance of which is
|
||||||
|
/// registered with the SessionFactory.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Connector();
|
||||||
|
/// Creates the Connector.
|
||||||
|
|
||||||
|
virtual ~Connector();
|
||||||
|
/// Destroys the Connector.
|
||||||
|
|
||||||
|
virtual const std::string & name() const = 0;
|
||||||
|
/// Returns the name associated with this connector.
|
||||||
|
|
||||||
|
virtual Poco::AutoPtr<SessionImpl>
|
||||||
|
createSession(const std::string & connectionString, std::size_t timeout = SessionImpl::LOGIN_TIMEOUT_DEFAULT) = 0;
|
||||||
|
/// Create a SessionImpl object and initialize it with the given connectionString.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_Connector_INCLUDED
|
#endif // Data_Connector_INCLUDED
|
||||||
|
@ -19,18 +19,21 @@
|
|||||||
|
|
||||||
|
|
||||||
#undef max
|
#undef max
|
||||||
#include <limits>
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
{
|
||||||
|
namespace Data
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
static const std::size_t POCO_DATA_INVALID_ROW = std::numeric_limits<std::size_t>::max();
|
static const std::size_t POCO_DATA_INVALID_ROW = std::numeric_limits<std::size_t>::max();
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_Constants_INCLUDED
|
#endif // Data_Constants_INCLUDED
|
||||||
|
@ -32,20 +32,20 @@
|
|||||||
// defined with this macro as being exported.
|
// defined with this macro as being exported.
|
||||||
//
|
//
|
||||||
#if defined(_WIN32) && defined(POCO_DLL)
|
#if defined(_WIN32) && defined(POCO_DLL)
|
||||||
#if defined(Data_EXPORTS)
|
# if defined(Data_EXPORTS)
|
||||||
#define Data_API __declspec(dllexport)
|
# define Data_API __declspec(dllexport)
|
||||||
#else
|
# else
|
||||||
#define Data_API __declspec(dllimport)
|
# define Data_API __declspec(dllimport)
|
||||||
#endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(Data_API)
|
#if !defined(Data_API)
|
||||||
#if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined (__GNUC__) && (__GNUC__ >= 4)
|
# if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined(__GNUC__) && (__GNUC__ >= 4)
|
||||||
#define Data_API __attribute__ ((visibility ("default")))
|
# define Data_API __attribute__((visibility("default")))
|
||||||
#else
|
# else
|
||||||
#define Data_API
|
# define Data_API
|
||||||
#endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -53,9 +53,9 @@
|
|||||||
// Automatically link Data library.
|
// Automatically link Data library.
|
||||||
//
|
//
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(Data_EXPORTS)
|
# if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(Data_EXPORTS)
|
||||||
#pragma comment(lib, "PocoData" POCO_LIB_SUFFIX)
|
# pragma comment(lib, "PocoData" POCO_LIB_SUFFIX)
|
||||||
#endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,29 +22,32 @@
|
|||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
{
|
||||||
|
namespace Data
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, DataException, Poco::IOException)
|
POCO_DECLARE_EXCEPTION(Data_API, DataException, Poco::IOException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, RowDataMissingException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, RowDataMissingException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, UnknownDataBaseException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, UnknownDataBaseException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, UnknownTypeException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, UnknownTypeException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, ExecutionException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, ExecutionException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, BindingException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, BindingException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, ExtractException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, ExtractException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, LimitException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, LimitException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, NotSupportedException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, NotSupportedException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, SessionUnavailableException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, SessionUnavailableException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, SessionPoolExhaustedException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, SessionPoolExhaustedException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, SessionPoolExistsException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, SessionPoolExistsException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, NoDataException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, NoDataException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, LengthExceededException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, LengthExceededException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, ConnectionFailedException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, ConnectionFailedException, DataException)
|
||||||
POCO_DECLARE_EXCEPTION(Data_API, NotConnectedException, DataException)
|
POCO_DECLARE_EXCEPTION(Data_API, NotConnectedException, DataException)
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_DataException_INCLUDED
|
#endif // Data_DataException_INCLUDED
|
||||||
|
@ -23,135 +23,137 @@
|
|||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
|
{
|
||||||
|
|
||||||
class DateTime;
|
class DateTime;
|
||||||
|
|
||||||
namespace Dynamic {
|
namespace Dynamic
|
||||||
|
{
|
||||||
|
|
||||||
class Var;
|
class Var;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Data {
|
namespace Data
|
||||||
|
|
||||||
|
|
||||||
class Time;
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API Date
|
|
||||||
/// Date class wraps a DateTime and exposes date related interface.
|
|
||||||
/// The purpose of this class is binding/extraction support for date fields.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
Date();
|
|
||||||
/// Creates the Date
|
|
||||||
|
|
||||||
Date(int year, int month, int day);
|
|
||||||
/// Creates the Date
|
|
||||||
|
|
||||||
Date(const DateTime& dt);
|
|
||||||
/// Creates the Date from DateTime
|
|
||||||
|
|
||||||
~Date();
|
|
||||||
/// Destroys the Date.
|
|
||||||
|
|
||||||
int year() const;
|
|
||||||
/// Returns the year.
|
|
||||||
|
|
||||||
int month() const;
|
|
||||||
/// Returns the month.
|
|
||||||
|
|
||||||
int day() const;
|
|
||||||
/// Returns the day.
|
|
||||||
|
|
||||||
void assign(int year, int month, int day);
|
|
||||||
/// Assigns date.
|
|
||||||
|
|
||||||
Date& operator = (const Date& d);
|
|
||||||
/// Assignment operator for Date.
|
|
||||||
|
|
||||||
Date& operator = (const DateTime& dt);
|
|
||||||
/// Assignment operator for DateTime.
|
|
||||||
|
|
||||||
Date& operator = (const Poco::Dynamic::Var& var);
|
|
||||||
/// Assignment operator for Var.
|
|
||||||
|
|
||||||
bool operator == (const Date& date) const;
|
|
||||||
/// Equality operator.
|
|
||||||
|
|
||||||
bool operator != (const Date& date) const;
|
|
||||||
/// Inequality operator.
|
|
||||||
|
|
||||||
bool operator < (const Date& date) const;
|
|
||||||
/// Less then operator.
|
|
||||||
|
|
||||||
bool operator > (const Date& date) const;
|
|
||||||
/// Greater then operator.
|
|
||||||
|
|
||||||
private:
|
|
||||||
int _year;
|
|
||||||
int _month;
|
|
||||||
int _day;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
class Time;
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline int Date::year() const
|
class Data_API Date
|
||||||
{
|
/// Date class wraps a DateTime and exposes date related interface.
|
||||||
return _year;
|
/// The purpose of this class is binding/extraction support for date fields.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Date();
|
||||||
|
/// Creates the Date
|
||||||
|
|
||||||
|
Date(int year, int month, int day);
|
||||||
|
/// Creates the Date
|
||||||
|
|
||||||
|
Date(const DateTime & dt);
|
||||||
|
/// Creates the Date from DateTime
|
||||||
|
|
||||||
|
~Date();
|
||||||
|
/// Destroys the Date.
|
||||||
|
|
||||||
|
int year() const;
|
||||||
|
/// Returns the year.
|
||||||
|
|
||||||
|
int month() const;
|
||||||
|
/// Returns the month.
|
||||||
|
|
||||||
|
int day() const;
|
||||||
|
/// Returns the day.
|
||||||
|
|
||||||
|
void assign(int year, int month, int day);
|
||||||
|
/// Assigns date.
|
||||||
|
|
||||||
|
Date & operator=(const Date & d);
|
||||||
|
/// Assignment operator for Date.
|
||||||
|
|
||||||
|
Date & operator=(const DateTime & dt);
|
||||||
|
/// Assignment operator for DateTime.
|
||||||
|
|
||||||
|
Date & operator=(const Poco::Dynamic::Var & var);
|
||||||
|
/// Assignment operator for Var.
|
||||||
|
|
||||||
|
bool operator==(const Date & date) const;
|
||||||
|
/// Equality operator.
|
||||||
|
|
||||||
|
bool operator!=(const Date & date) const;
|
||||||
|
/// Inequality operator.
|
||||||
|
|
||||||
|
bool operator<(const Date & date) const;
|
||||||
|
/// Less then operator.
|
||||||
|
|
||||||
|
bool operator>(const Date & date) const;
|
||||||
|
/// Greater then operator.
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _year;
|
||||||
|
int _month;
|
||||||
|
int _day;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline int Date::year() const
|
||||||
|
{
|
||||||
|
return _year;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int Date::month() const
|
||||||
|
{
|
||||||
|
return _month;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int Date::day() const
|
||||||
|
{
|
||||||
|
return _day;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Date & Date::operator=(const Date & d)
|
||||||
|
{
|
||||||
|
assign(d.year(), d.month(), d.day());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Date & Date::operator=(const DateTime & dt)
|
||||||
|
{
|
||||||
|
assign(dt.year(), dt.month(), dt.day());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Date::operator==(const Date & date) const
|
||||||
|
{
|
||||||
|
return _year == date.year() && _month == date.month() && _day == date.day();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Date::operator!=(const Date & date) const
|
||||||
|
{
|
||||||
|
return !(*this == date);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Date::operator>(const Date & date) const
|
||||||
|
{
|
||||||
|
return !(*this == date) && !(*this < date);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline int Date::month() const
|
|
||||||
{
|
|
||||||
return _month;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline int Date::day() const
|
|
||||||
{
|
|
||||||
return _day;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Date& Date::operator = (const Date& d)
|
|
||||||
{
|
|
||||||
assign(d.year(), d.month(), d.day());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Date& Date::operator = (const DateTime& dt)
|
|
||||||
{
|
|
||||||
assign(dt.year(), dt.month(), dt.day());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Date::operator == (const Date& date) const
|
|
||||||
{
|
|
||||||
return _year == date.year() &&
|
|
||||||
_month == date.month() &&
|
|
||||||
_day == date.day();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Date::operator != (const Date& date) const
|
|
||||||
{
|
|
||||||
return !(*this == date);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Date::operator > (const Date& date) const
|
|
||||||
{
|
|
||||||
return !(*this == date) && !(*this < date);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -159,67 +161,51 @@ inline bool Date::operator > (const Date& date) const
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Dynamic {
|
{
|
||||||
|
namespace Dynamic
|
||||||
|
|
||||||
template <>
|
|
||||||
class VarHolderImpl<Poco::Data::Date>: public VarHolder
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
VarHolderImpl(const Poco::Data::Date& val): _val(val)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~VarHolderImpl()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::type_info& type() const
|
|
||||||
{
|
|
||||||
return typeid(Poco::Data::Date);
|
|
||||||
}
|
|
||||||
|
|
||||||
void convert(Poco::Timestamp& val) const
|
|
||||||
{
|
|
||||||
DateTime dt;
|
|
||||||
dt.assign(_val.year(), _val.month(), _val.day());
|
|
||||||
val = dt.timestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
void convert(Poco::DateTime& val) const
|
|
||||||
{
|
|
||||||
val.assign(_val.year(), _val.month(), _val.day());
|
|
||||||
}
|
|
||||||
|
|
||||||
void convert(Poco::LocalDateTime& val) const
|
|
||||||
{
|
|
||||||
val.assign(_val.year(), _val.month(), _val.day());
|
|
||||||
}
|
|
||||||
|
|
||||||
void convert(std::string& val) const
|
|
||||||
{
|
|
||||||
DateTime dt(_val.year(), _val.month(), _val.day());
|
|
||||||
val = DateTimeFormatter::format(dt, "%Y/%m/%d");
|
|
||||||
}
|
|
||||||
|
|
||||||
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
|
||||||
{
|
|
||||||
return cloneHolder(pVarHolder, _val);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Poco::Data::Date& value() const
|
|
||||||
{
|
|
||||||
return _val;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
VarHolderImpl();
|
|
||||||
Poco::Data::Date _val;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Dynamic
|
template <>
|
||||||
|
class VarHolderImpl<Poco::Data::Date> : public VarHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VarHolderImpl(const Poco::Data::Date & val) : _val(val) { }
|
||||||
|
|
||||||
|
~VarHolderImpl() { }
|
||||||
|
|
||||||
|
const std::type_info & type() const { return typeid(Poco::Data::Date); }
|
||||||
|
|
||||||
|
void convert(Poco::Timestamp & val) const
|
||||||
|
{
|
||||||
|
DateTime dt;
|
||||||
|
dt.assign(_val.year(), _val.month(), _val.day());
|
||||||
|
val = dt.timestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void convert(Poco::DateTime & val) const { val.assign(_val.year(), _val.month(), _val.day()); }
|
||||||
|
|
||||||
|
void convert(Poco::LocalDateTime & val) const { val.assign(_val.year(), _val.month(), _val.day()); }
|
||||||
|
|
||||||
|
void convert(std::string & val) const
|
||||||
|
{
|
||||||
|
DateTime dt(_val.year(), _val.month(), _val.day());
|
||||||
|
val = DateTimeFormatter::format(dt, "%Y/%m/%d");
|
||||||
|
}
|
||||||
|
|
||||||
|
VarHolder * clone(Placeholder<VarHolder> * pVarHolder = 0) const { return cloneHolder(pVarHolder, _val); }
|
||||||
|
|
||||||
|
const Poco::Data::Date & value() const { return _val; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
VarHolderImpl();
|
||||||
|
Poco::Data::Date _val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Dynamic
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_Date_INCLUDED
|
#endif // Data_Date_INCLUDED
|
||||||
|
@ -24,24 +24,32 @@
|
|||||||
#include "Poco/Dynamic/Var.h"
|
#include "Poco/Dynamic/Var.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
{
|
||||||
|
namespace Data
|
||||||
|
{
|
||||||
|
|
||||||
class Date;
|
class Date;
|
||||||
class Time;
|
class Time;
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Dynamic {
|
{
|
||||||
|
namespace Dynamic
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
template <> Data_API Var::operator Poco::Data::Date () const;
|
template <>
|
||||||
template <> Data_API Var::operator Poco::Data::Time () const;
|
Data_API Var::operator Poco::Data::Date() const;
|
||||||
|
template <>
|
||||||
|
Data_API Var::operator Poco::Data::Time() const;
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Dynamic
|
}
|
||||||
|
} // namespace Poco::Dynamic
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_DynamicDateTime_INCLUDED
|
#endif // Data_DynamicDateTime_INCLUDED
|
||||||
|
@ -23,23 +23,32 @@
|
|||||||
#include "Poco/Dynamic/Var.h"
|
#include "Poco/Dynamic/Var.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
{
|
||||||
|
namespace Data
|
||||||
|
{
|
||||||
|
|
||||||
template <typename T> class LOB;
|
template <typename T>
|
||||||
typedef LOB<unsigned char> BLOB;
|
class LOB;
|
||||||
typedef LOB<char> CLOB;
|
typedef LOB<unsigned char> BLOB;
|
||||||
|
typedef LOB<char> CLOB;
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Dynamic {
|
{
|
||||||
|
namespace Dynamic
|
||||||
|
{
|
||||||
|
|
||||||
template <> Data_API Var::operator Poco::Data::CLOB () const;
|
template <>
|
||||||
template <> Data_API Var::operator Poco::Data::BLOB () const;
|
Data_API Var::operator Poco::Data::CLOB() const;
|
||||||
|
template <>
|
||||||
|
Data_API Var::operator Poco::Data::BLOB() const;
|
||||||
|
|
||||||
} } // namespace Poco::Dynamic
|
}
|
||||||
|
} // namespace Poco::Dynamic
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_DynamicLOB_INCLUDED
|
#endif // Data_DynamicLOB_INCLUDED
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,203 +18,196 @@
|
|||||||
#define Data_LOB_INCLUDED
|
#define Data_LOB_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/SharedPtr.h"
|
|
||||||
#include "Poco/Dynamic/VarHolder.h"
|
#include "Poco/Dynamic/VarHolder.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include <vector>
|
#include "Poco/SharedPtr.h"
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class LOB
|
|
||||||
/// Representation of a Large OBject.
|
|
||||||
///
|
|
||||||
/// A LOB can hold arbitrary data.
|
|
||||||
/// The maximum size depends on the underlying database.
|
|
||||||
///
|
|
||||||
/// The LOBInputStream and LOBOutputStream classes provide
|
|
||||||
/// a convenient way to access the data in a LOB.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
typedef typename std::vector<T>::const_iterator Iterator;
|
|
||||||
typedef T ValueType;
|
|
||||||
typedef typename std::vector<T> Container;
|
|
||||||
typedef Poco::SharedPtr<Container> ContentPtr;
|
|
||||||
|
|
||||||
LOB(): _pContent(new std::vector<T>())
|
|
||||||
/// Creates an empty LOB.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
LOB(const std::vector<T>& content):
|
|
||||||
_pContent(new std::vector<T>(content))
|
|
||||||
/// Creates the LOB, content is deep-copied.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
LOB(const T* const pContent, std::size_t size):
|
|
||||||
_pContent(new std::vector<T>(pContent, pContent + size))
|
|
||||||
/// Creates the LOB by deep-copying pContent.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
LOB(const std::basic_string<T>& content):
|
|
||||||
_pContent(new std::vector<T>(content.begin(), content.end()))
|
|
||||||
/// Creates a LOB from a string.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
LOB(const LOB& other): _pContent(other._pContent)
|
|
||||||
/// Creates a LOB by copying another one.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~LOB()
|
|
||||||
/// Destroys the LOB.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
LOB& operator = (const LOB& other)
|
|
||||||
/// Assignment operator.
|
|
||||||
{
|
|
||||||
LOB tmp(other);
|
|
||||||
swap(tmp);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator == (const LOB& other) const
|
|
||||||
/// Compares for equality LOB by value.
|
|
||||||
{
|
|
||||||
return *_pContent == *other._pContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator != (const LOB& other) const
|
|
||||||
/// Compares for inequality LOB by value.
|
|
||||||
{
|
|
||||||
return *_pContent != *other._pContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(LOB& other)
|
|
||||||
/// Swaps the LOB with another one.
|
|
||||||
{
|
|
||||||
using std::swap;
|
|
||||||
swap(_pContent, other._pContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<T>& content() const
|
|
||||||
/// Returns the content.
|
|
||||||
{
|
|
||||||
return *_pContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
const T* rawContent() const
|
|
||||||
/// Returns the raw content.
|
|
||||||
///
|
|
||||||
/// If the LOB is empty, returns NULL.
|
|
||||||
{
|
|
||||||
if (_pContent->empty())
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return &(*_pContent)[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
void assignVal(std::size_t count, const T& val)
|
|
||||||
/// Assigns raw content to internal storage.
|
|
||||||
{
|
|
||||||
ContentPtr tmp = new Container(count, val);
|
|
||||||
_pContent.swap(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void assignRaw(const T* ptr, std::size_t count)
|
|
||||||
/// Assigns raw content to internal storage.
|
|
||||||
{
|
|
||||||
poco_assert_dbg (ptr);
|
|
||||||
LOB tmp(ptr, count);
|
|
||||||
swap(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void appendRaw(const T* pChar, std::size_t count)
|
|
||||||
/// Assigns raw content to internal storage.
|
|
||||||
{
|
|
||||||
poco_assert_dbg (pChar);
|
|
||||||
_pContent->insert(_pContent->end(), pChar, pChar+count);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear(bool doCompact = false)
|
|
||||||
/// Clears the content of the blob.
|
|
||||||
/// If doCompact is true, trims the excess capacity.
|
|
||||||
{
|
|
||||||
_pContent->clear();
|
|
||||||
if (doCompact) compact();
|
|
||||||
}
|
|
||||||
|
|
||||||
void compact()
|
|
||||||
/// Trims the internal storage excess capacity.
|
|
||||||
{
|
|
||||||
std::vector<T>(*_pContent).swap(*_pContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator begin() const
|
|
||||||
{
|
|
||||||
return _pContent->begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator end() const
|
|
||||||
{
|
|
||||||
return _pContent->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t size() const
|
|
||||||
/// Returns the size of the LOB in bytes.
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(_pContent->size());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ContentPtr _pContent;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef LOB<unsigned char> BLOB;
|
|
||||||
typedef LOB<char> CLOB;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void swap(LOB<T>& b1, LOB<T>& b2)
|
|
||||||
{
|
{
|
||||||
b1.swap(b2);
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class LOB
|
||||||
|
/// Representation of a Large OBject.
|
||||||
|
///
|
||||||
|
/// A LOB can hold arbitrary data.
|
||||||
|
/// The maximum size depends on the underlying database.
|
||||||
|
///
|
||||||
|
/// The LOBInputStream and LOBOutputStream classes provide
|
||||||
|
/// a convenient way to access the data in a LOB.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename std::vector<T>::const_iterator Iterator;
|
||||||
|
typedef T ValueType;
|
||||||
|
typedef typename std::vector<T> Container;
|
||||||
|
typedef Poco::SharedPtr<Container> ContentPtr;
|
||||||
|
|
||||||
|
LOB() : _pContent(new std::vector<T>())
|
||||||
|
/// Creates an empty LOB.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LOB(const std::vector<T> & content) : _pContent(new std::vector<T>(content))
|
||||||
|
/// Creates the LOB, content is deep-copied.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LOB(const T * const pContent, std::size_t size) : _pContent(new std::vector<T>(pContent, pContent + size))
|
||||||
|
/// Creates the LOB by deep-copying pContent.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LOB(const std::basic_string<T> & content) : _pContent(new std::vector<T>(content.begin(), content.end()))
|
||||||
|
/// Creates a LOB from a string.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LOB(const LOB & other) : _pContent(other._pContent)
|
||||||
|
/// Creates a LOB by copying another one.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~LOB()
|
||||||
|
/// Destroys the LOB.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LOB & operator=(const LOB & other)
|
||||||
|
/// Assignment operator.
|
||||||
|
{
|
||||||
|
LOB tmp(other);
|
||||||
|
swap(tmp);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const LOB & other) const
|
||||||
|
/// Compares for equality LOB by value.
|
||||||
|
{
|
||||||
|
return *_pContent == *other._pContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const LOB & other) const
|
||||||
|
/// Compares for inequality LOB by value.
|
||||||
|
{
|
||||||
|
return *_pContent != *other._pContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(LOB & other)
|
||||||
|
/// Swaps the LOB with another one.
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(_pContent, other._pContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<T> & content() const
|
||||||
|
/// Returns the content.
|
||||||
|
{
|
||||||
|
return *_pContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T * rawContent() const
|
||||||
|
/// Returns the raw content.
|
||||||
|
///
|
||||||
|
/// If the LOB is empty, returns NULL.
|
||||||
|
{
|
||||||
|
if (_pContent->empty())
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return &(*_pContent)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void assignVal(std::size_t count, const T & val)
|
||||||
|
/// Assigns raw content to internal storage.
|
||||||
|
{
|
||||||
|
ContentPtr tmp = new Container(count, val);
|
||||||
|
_pContent.swap(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assignRaw(const T * ptr, std::size_t count)
|
||||||
|
/// Assigns raw content to internal storage.
|
||||||
|
{
|
||||||
|
poco_assert_dbg(ptr);
|
||||||
|
LOB tmp(ptr, count);
|
||||||
|
swap(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendRaw(const T * pChar, std::size_t count)
|
||||||
|
/// Assigns raw content to internal storage.
|
||||||
|
{
|
||||||
|
poco_assert_dbg(pChar);
|
||||||
|
_pContent->insert(_pContent->end(), pChar, pChar + count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear(bool doCompact = false)
|
||||||
|
/// Clears the content of the blob.
|
||||||
|
/// If doCompact is true, trims the excess capacity.
|
||||||
|
{
|
||||||
|
_pContent->clear();
|
||||||
|
if (doCompact)
|
||||||
|
compact();
|
||||||
|
}
|
||||||
|
|
||||||
|
void compact()
|
||||||
|
/// Trims the internal storage excess capacity.
|
||||||
|
{
|
||||||
|
std::vector<T>(*_pContent).swap(*_pContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator begin() const { return _pContent->begin(); }
|
||||||
|
|
||||||
|
Iterator end() const { return _pContent->end(); }
|
||||||
|
|
||||||
|
std::size_t size() const
|
||||||
|
/// Returns the size of the LOB in bytes.
|
||||||
|
{
|
||||||
|
return static_cast<std::size_t>(_pContent->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ContentPtr _pContent;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef LOB<unsigned char> BLOB;
|
||||||
|
typedef LOB<char> CLOB;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void swap(LOB<T> & b1, LOB<T> & b2)
|
||||||
|
{
|
||||||
|
b1.swap(b2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
template<>
|
template <>
|
||||||
inline void swap<Poco::Data::BLOB>(Poco::Data::BLOB& b1,
|
inline void swap<Poco::Data::BLOB>(Poco::Data::BLOB & b1, Poco::Data::BLOB & b2)
|
||||||
Poco::Data::BLOB& b2)
|
/// Full template specalization of std:::swap for BLOB
|
||||||
/// Full template specalization of std:::swap for BLOB
|
{
|
||||||
{
|
b1.swap(b2);
|
||||||
b1.swap(b2);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
inline void swap<Poco::Data::CLOB>(Poco::Data::CLOB& c1,
|
inline void swap<Poco::Data::CLOB>(Poco::Data::CLOB & c1, Poco::Data::CLOB & c2)
|
||||||
Poco::Data::CLOB& c2)
|
/// Full template specalization of std:::swap for CLOB
|
||||||
/// Full template specalization of std:::swap for CLOB
|
{
|
||||||
{
|
c1.swap(c2);
|
||||||
c1.swap(c2);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -223,87 +216,58 @@ namespace std
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Dynamic {
|
|
||||||
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class VarHolderImpl<Poco::Data::BLOB>: public VarHolder
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Dynamic
|
||||||
VarHolderImpl(const Poco::Data::BLOB& val): _val(val)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~VarHolderImpl()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::type_info& type() const
|
|
||||||
{
|
|
||||||
return typeid(Poco::Data::BLOB);
|
|
||||||
}
|
|
||||||
|
|
||||||
void convert(std::string& val) const
|
|
||||||
{
|
|
||||||
val.assign(_val.begin(), _val.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
|
||||||
{
|
|
||||||
return cloneHolder(pVarHolder, _val);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Poco::Data::BLOB& value() const
|
|
||||||
{
|
|
||||||
return _val;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
VarHolderImpl();
|
|
||||||
Poco::Data::BLOB _val;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class VarHolderImpl<Poco::Data::CLOB>: public VarHolder
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
VarHolderImpl(const Poco::Data::CLOB& val): _val(val)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~VarHolderImpl()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::type_info& type() const
|
|
||||||
{
|
|
||||||
return typeid(Poco::Data::CLOB);
|
|
||||||
}
|
|
||||||
|
|
||||||
void convert(std::string& val) const
|
|
||||||
{
|
|
||||||
val.assign(_val.begin(), _val.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
|
||||||
{
|
|
||||||
return cloneHolder(pVarHolder, _val);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Poco::Data::CLOB& value() const
|
|
||||||
{
|
|
||||||
return _val;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
VarHolderImpl();
|
|
||||||
Poco::Data::CLOB _val;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Dynamic
|
template <>
|
||||||
|
class VarHolderImpl<Poco::Data::BLOB> : public VarHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VarHolderImpl(const Poco::Data::BLOB & val) : _val(val) { }
|
||||||
|
|
||||||
|
~VarHolderImpl() { }
|
||||||
|
|
||||||
|
const std::type_info & type() const { return typeid(Poco::Data::BLOB); }
|
||||||
|
|
||||||
|
void convert(std::string & val) const { val.assign(_val.begin(), _val.end()); }
|
||||||
|
|
||||||
|
VarHolder * clone(Placeholder<VarHolder> * pVarHolder = 0) const { return cloneHolder(pVarHolder, _val); }
|
||||||
|
|
||||||
|
const Poco::Data::BLOB & value() const { return _val; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
VarHolderImpl();
|
||||||
|
Poco::Data::BLOB _val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class VarHolderImpl<Poco::Data::CLOB> : public VarHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VarHolderImpl(const Poco::Data::CLOB & val) : _val(val) { }
|
||||||
|
|
||||||
|
~VarHolderImpl() { }
|
||||||
|
|
||||||
|
const std::type_info & type() const { return typeid(Poco::Data::CLOB); }
|
||||||
|
|
||||||
|
void convert(std::string & val) const { val.assign(_val.begin(), _val.end()); }
|
||||||
|
|
||||||
|
VarHolder * clone(Placeholder<VarHolder> * pVarHolder = 0) const { return cloneHolder(pVarHolder, _val); }
|
||||||
|
|
||||||
|
const Poco::Data::CLOB & value() const { return _val; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
VarHolderImpl();
|
||||||
|
Poco::Data::CLOB _val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Dynamic
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_LOB_INCLUDED
|
#endif // Data_LOB_INCLUDED
|
||||||
|
@ -18,133 +18,132 @@
|
|||||||
#define Data_LOBStream_INCLUDED
|
#define Data_LOBStream_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Foundation.h"
|
|
||||||
#include "Poco/UnbufferedStreamBuf.h"
|
|
||||||
#include "Poco/Data/LOB.h"
|
|
||||||
#include <istream>
|
#include <istream>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include "Poco/Data/LOB.h"
|
||||||
|
#include "Poco/Foundation.h"
|
||||||
|
#include "Poco/UnbufferedStreamBuf.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class LOBStreamBuf: public BasicUnbufferedStreamBuf<T, std::char_traits<T> >
|
|
||||||
/// This is the streambuf class used for reading from and writing to a LOB.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
LOBStreamBuf(LOB<T>& lob): _lob(lob), _it(_lob.begin())
|
|
||||||
/// Creates LOBStreamBuf.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
~LOBStreamBuf()
|
|
||||||
/// Destroys LOBStreamBuf.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
typedef std::char_traits<T> TraitsType;
|
|
||||||
typedef BasicUnbufferedStreamBuf<T, TraitsType> BaseType;
|
|
||||||
|
|
||||||
typename BaseType::int_type readFromDevice()
|
|
||||||
{
|
|
||||||
if (_it != _lob.end())
|
|
||||||
return BaseType::charToInt(*_it++);
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
typename BaseType::int_type writeToDevice(T c)
|
|
||||||
{
|
|
||||||
_lob.appendRaw(&c, 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
LOB<T>& _lob;
|
|
||||||
typename LOB<T>::Iterator _it;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class LOBIOS: public virtual std::ios
|
|
||||||
/// The base class for LOBInputStream and
|
|
||||||
/// LOBOutputStream.
|
|
||||||
///
|
|
||||||
/// This class is needed to ensure the correct initialization
|
|
||||||
/// order of the stream buffer and base classes.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
LOBIOS(LOB<T>& lob, openmode mode): _buf(lob)
|
|
||||||
/// Creates the LOBIOS with the given LOB.
|
|
||||||
{
|
|
||||||
poco_ios_init(&_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
~LOBIOS()
|
|
||||||
/// Destroys the LOBIOS.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
LOBStreamBuf<T>* rdbuf()
|
|
||||||
/// Returns a pointer to the internal LOBStreamBuf.
|
|
||||||
{
|
|
||||||
return &_buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
LOBStreamBuf<T> _buf;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class LOBOutputStream: public LOBIOS<T>, public std::basic_ostream<T, std::char_traits<T> >
|
class LOBStreamBuf : public BasicUnbufferedStreamBuf<T, std::char_traits<T>>
|
||||||
/// An output stream for writing to a LOB.
|
/// This is the streambuf class used for reading from and writing to a LOB.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LOBOutputStream(LOB<T>& lob):
|
LOBStreamBuf(LOB<T> & lob) : _lob(lob), _it(_lob.begin())
|
||||||
LOBIOS<T>(lob, std::ios::out),
|
/// Creates LOBStreamBuf.
|
||||||
std::ostream(LOBIOS<T>::rdbuf())
|
{
|
||||||
/// Creates the LOBOutputStream with the given LOB.
|
}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~LOBOutputStream()
|
|
||||||
/// Destroys the LOBOutputStream.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
~LOBStreamBuf()
|
||||||
class LOBInputStream: public LOBIOS<T>, public std::basic_istream<T, std::char_traits<T> >
|
/// Destroys LOBStreamBuf.
|
||||||
/// An input stream for reading from a LOB.
|
{
|
||||||
{
|
}
|
||||||
public:
|
|
||||||
LOBInputStream(LOB<T>& lob):
|
|
||||||
LOBIOS<T>(lob, std::ios::in),
|
|
||||||
std::istream(LOBIOS<T>::rdbuf())
|
|
||||||
/// Creates the LOBInputStream with the given LOB.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~LOBInputStream()
|
protected:
|
||||||
/// Destroys the LOBInputStream.
|
typedef std::char_traits<T> TraitsType;
|
||||||
{
|
typedef BasicUnbufferedStreamBuf<T, TraitsType> BaseType;
|
||||||
}
|
|
||||||
};
|
typename BaseType::int_type readFromDevice()
|
||||||
|
{
|
||||||
|
if (_it != _lob.end())
|
||||||
|
return BaseType::charToInt(*_it++);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
typename BaseType::int_type writeToDevice(T c)
|
||||||
|
{
|
||||||
|
_lob.appendRaw(&c, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
LOB<T> & _lob;
|
||||||
|
typename LOB<T>::Iterator _it;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef LOBOutputStream<unsigned char> BLOBOutputStream;
|
template <typename T>
|
||||||
typedef LOBOutputStream<char> CLOBOutputStream;
|
class LOBIOS : public virtual std::ios
|
||||||
|
/// The base class for LOBInputStream and
|
||||||
|
/// LOBOutputStream.
|
||||||
|
///
|
||||||
|
/// This class is needed to ensure the correct initialization
|
||||||
|
/// order of the stream buffer and base classes.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LOBIOS(LOB<T> & lob, openmode mode) : _buf(lob)
|
||||||
|
/// Creates the LOBIOS with the given LOB.
|
||||||
|
{
|
||||||
|
poco_ios_init(&_buf);
|
||||||
|
}
|
||||||
|
|
||||||
typedef LOBInputStream<unsigned char> BLOBInputStream;
|
~LOBIOS()
|
||||||
typedef LOBInputStream<char> CLOBInputStream;
|
/// Destroys the LOBIOS.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
LOBStreamBuf<T> * rdbuf()
|
||||||
|
/// Returns a pointer to the internal LOBStreamBuf.
|
||||||
|
{
|
||||||
|
return &_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LOBStreamBuf<T> _buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class LOBOutputStream : public LOBIOS<T>, public std::basic_ostream<T, std::char_traits<T>>
|
||||||
|
/// An output stream for writing to a LOB.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LOBOutputStream(LOB<T> & lob) : LOBIOS<T>(lob, std::ios::out), std::ostream(LOBIOS<T>::rdbuf())
|
||||||
|
/// Creates the LOBOutputStream with the given LOB.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~LOBOutputStream()
|
||||||
|
/// Destroys the LOBOutputStream.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class LOBInputStream : public LOBIOS<T>, public std::basic_istream<T, std::char_traits<T>>
|
||||||
|
/// An input stream for reading from a LOB.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LOBInputStream(LOB<T> & lob) : LOBIOS<T>(lob, std::ios::in), std::istream(LOBIOS<T>::rdbuf())
|
||||||
|
/// Creates the LOBInputStream with the given LOB.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~LOBInputStream()
|
||||||
|
/// Destroys the LOBInputStream.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef LOBOutputStream<unsigned char> BLOBOutputStream;
|
||||||
|
typedef LOBOutputStream<char> CLOBOutputStream;
|
||||||
|
|
||||||
|
typedef LOBInputStream<unsigned char> BLOBInputStream;
|
||||||
|
typedef LOBInputStream<char> CLOBInputStream;
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_LOBStream_INCLUDED
|
#endif // Data_LOBStream_INCLUDED
|
||||||
|
@ -21,93 +21,92 @@
|
|||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API Limit
|
|
||||||
/// Limit stores information how many rows a query should return.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
typedef Poco::UInt32 SizeT;
|
|
||||||
|
|
||||||
enum Type
|
|
||||||
{
|
|
||||||
LIMIT_UNLIMITED = ~((SizeT) 0)
|
|
||||||
};
|
|
||||||
|
|
||||||
Limit(SizeT value, bool hardLimit = false, bool isLowerLimit = false);
|
|
||||||
/// Creates the Limit.
|
|
||||||
///
|
|
||||||
/// Value contains the upper row hint, if hardLimit is set to true, the limit acts as a hard
|
|
||||||
/// border, ie. every query must return exactly value rows, returning more than value objects will throw an exception!
|
|
||||||
/// LowerLimits always act as hard-limits!
|
|
||||||
///
|
|
||||||
/// A value of LIMIT_UNLIMITED disables the limit.
|
|
||||||
|
|
||||||
~Limit();
|
|
||||||
/// Destroys the Limit.
|
|
||||||
|
|
||||||
SizeT value() const;
|
|
||||||
/// Returns the value of the limit
|
|
||||||
|
|
||||||
bool isHardLimit() const;
|
|
||||||
/// Returns true if the limit is a hard limit.
|
|
||||||
|
|
||||||
bool isLowerLimit() const;
|
|
||||||
/// Returns true if the limit is a lower limit, otherwise it is an upperLimit
|
|
||||||
|
|
||||||
bool operator == (const Limit& other) const;
|
|
||||||
/// Equality operator.
|
|
||||||
|
|
||||||
bool operator != (const Limit& other) const;
|
|
||||||
/// Inequality operator.
|
|
||||||
|
|
||||||
private:
|
|
||||||
SizeT _value;
|
|
||||||
bool _hardLimit;
|
|
||||||
bool _isLowerLimit;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline Poco::UInt32 Limit::value() const
|
|
||||||
{
|
{
|
||||||
return _value;
|
|
||||||
|
|
||||||
|
class Data_API Limit
|
||||||
|
/// Limit stores information how many rows a query should return.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Poco::UInt32 SizeT;
|
||||||
|
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
LIMIT_UNLIMITED = ~((SizeT)0)
|
||||||
|
};
|
||||||
|
|
||||||
|
Limit(SizeT value, bool hardLimit = false, bool isLowerLimit = false);
|
||||||
|
/// Creates the Limit.
|
||||||
|
///
|
||||||
|
/// Value contains the upper row hint, if hardLimit is set to true, the limit acts as a hard
|
||||||
|
/// border, ie. every query must return exactly value rows, returning more than value objects will throw an exception!
|
||||||
|
/// LowerLimits always act as hard-limits!
|
||||||
|
///
|
||||||
|
/// A value of LIMIT_UNLIMITED disables the limit.
|
||||||
|
|
||||||
|
~Limit();
|
||||||
|
/// Destroys the Limit.
|
||||||
|
|
||||||
|
SizeT value() const;
|
||||||
|
/// Returns the value of the limit
|
||||||
|
|
||||||
|
bool isHardLimit() const;
|
||||||
|
/// Returns true if the limit is a hard limit.
|
||||||
|
|
||||||
|
bool isLowerLimit() const;
|
||||||
|
/// Returns true if the limit is a lower limit, otherwise it is an upperLimit
|
||||||
|
|
||||||
|
bool operator==(const Limit & other) const;
|
||||||
|
/// Equality operator.
|
||||||
|
|
||||||
|
bool operator!=(const Limit & other) const;
|
||||||
|
/// Inequality operator.
|
||||||
|
|
||||||
|
private:
|
||||||
|
SizeT _value;
|
||||||
|
bool _hardLimit;
|
||||||
|
bool _isLowerLimit;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline Poco::UInt32 Limit::value() const
|
||||||
|
{
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Limit::isHardLimit() const
|
||||||
|
{
|
||||||
|
return _hardLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Limit::isLowerLimit() const
|
||||||
|
{
|
||||||
|
return _isLowerLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Limit::operator==(const Limit & other) const
|
||||||
|
{
|
||||||
|
return other._value == _value && other._hardLimit == _hardLimit && other._isLowerLimit == _isLowerLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Limit::operator!=(const Limit & other) const
|
||||||
|
{
|
||||||
|
return other._value != _value || other._hardLimit != _hardLimit || other._isLowerLimit != _isLowerLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline bool Limit::isHardLimit() const
|
|
||||||
{
|
|
||||||
return _hardLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Limit::isLowerLimit() const
|
|
||||||
{
|
|
||||||
return _isLowerLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Limit::operator == (const Limit& other) const
|
|
||||||
{
|
|
||||||
return other._value == _value &&
|
|
||||||
other._hardLimit == _hardLimit &&
|
|
||||||
other._isLowerLimit == _isLowerLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Limit::operator != (const Limit& other) const
|
|
||||||
{
|
|
||||||
return other._value != _value ||
|
|
||||||
other._hardLimit != _hardLimit ||
|
|
||||||
other._isLowerLimit != _isLowerLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_Limit_INCLUDED
|
#endif // Data_Limit_INCLUDED
|
||||||
|
@ -18,171 +18,175 @@
|
|||||||
#define Data_MetaColumn_INCLUDED
|
#define Data_MetaColumn_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API MetaColumn
|
|
||||||
/// MetaColumn class contains column metadata information.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
enum ColumnDataType
|
|
||||||
{
|
|
||||||
FDT_BOOL,
|
|
||||||
FDT_INT8,
|
|
||||||
FDT_UINT8,
|
|
||||||
FDT_INT16,
|
|
||||||
FDT_UINT16,
|
|
||||||
FDT_INT32,
|
|
||||||
FDT_UINT32,
|
|
||||||
FDT_INT64,
|
|
||||||
FDT_UINT64,
|
|
||||||
FDT_FLOAT,
|
|
||||||
FDT_DOUBLE,
|
|
||||||
FDT_STRING,
|
|
||||||
FDT_WSTRING,
|
|
||||||
FDT_BLOB,
|
|
||||||
FDT_CLOB,
|
|
||||||
FDT_DATE,
|
|
||||||
FDT_TIME,
|
|
||||||
FDT_TIMESTAMP,
|
|
||||||
FDT_UNKNOWN
|
|
||||||
};
|
|
||||||
|
|
||||||
MetaColumn();
|
|
||||||
/// Creates the MetaColumn.
|
|
||||||
|
|
||||||
explicit MetaColumn(std::size_t position,
|
|
||||||
const std::string& name = "",
|
|
||||||
ColumnDataType type = FDT_UNKNOWN,
|
|
||||||
std::size_t length = 0,
|
|
||||||
std::size_t precision = 0,
|
|
||||||
bool nullable = false);
|
|
||||||
/// Creates the MetaColumn.
|
|
||||||
|
|
||||||
virtual ~MetaColumn();
|
|
||||||
/// Destroys the MetaColumn.
|
|
||||||
|
|
||||||
const std::string& name() const;
|
|
||||||
/// Returns column name.
|
|
||||||
|
|
||||||
std::size_t length() const;
|
|
||||||
/// Returns column maximum length.
|
|
||||||
|
|
||||||
std::size_t precision() const;
|
|
||||||
/// Returns column precision.
|
|
||||||
/// Valid for floating point fields only
|
|
||||||
/// (zero for other data types).
|
|
||||||
|
|
||||||
std::size_t position() const;
|
|
||||||
/// Returns column position.
|
|
||||||
|
|
||||||
ColumnDataType type() const;
|
|
||||||
/// Returns column type.
|
|
||||||
|
|
||||||
bool isNullable() const;
|
|
||||||
/// Returns true if column allows null values, false otherwise.
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void setName(const std::string& name);
|
|
||||||
/// Sets the column name.
|
|
||||||
|
|
||||||
void setLength(std::size_t length);
|
|
||||||
/// Sets the column length.
|
|
||||||
|
|
||||||
void setPrecision(std::size_t precision);
|
|
||||||
/// Sets the column precision.
|
|
||||||
|
|
||||||
void setType(ColumnDataType type);
|
|
||||||
/// Sets the column data type.
|
|
||||||
|
|
||||||
void setNullable(bool nullable);
|
|
||||||
/// Sets the column nullability.
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string _name;
|
|
||||||
std::size_t _length;
|
|
||||||
std::size_t _precision;
|
|
||||||
std::size_t _position;
|
|
||||||
ColumnDataType _type;
|
|
||||||
bool _nullable;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// inlines
|
|
||||||
///
|
|
||||||
inline const std::string& MetaColumn::name() const
|
|
||||||
{
|
{
|
||||||
return _name;
|
|
||||||
|
|
||||||
|
class Data_API MetaColumn
|
||||||
|
/// MetaColumn class contains column metadata information.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum ColumnDataType
|
||||||
|
{
|
||||||
|
FDT_BOOL,
|
||||||
|
FDT_INT8,
|
||||||
|
FDT_UINT8,
|
||||||
|
FDT_INT16,
|
||||||
|
FDT_UINT16,
|
||||||
|
FDT_INT32,
|
||||||
|
FDT_UINT32,
|
||||||
|
FDT_INT64,
|
||||||
|
FDT_UINT64,
|
||||||
|
FDT_FLOAT,
|
||||||
|
FDT_DOUBLE,
|
||||||
|
FDT_STRING,
|
||||||
|
FDT_WSTRING,
|
||||||
|
FDT_BLOB,
|
||||||
|
FDT_CLOB,
|
||||||
|
FDT_DATE,
|
||||||
|
FDT_TIME,
|
||||||
|
FDT_TIMESTAMP,
|
||||||
|
FDT_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
MetaColumn();
|
||||||
|
/// Creates the MetaColumn.
|
||||||
|
|
||||||
|
explicit MetaColumn(
|
||||||
|
std::size_t position,
|
||||||
|
const std::string & name = "",
|
||||||
|
ColumnDataType type = FDT_UNKNOWN,
|
||||||
|
std::size_t length = 0,
|
||||||
|
std::size_t precision = 0,
|
||||||
|
bool nullable = false);
|
||||||
|
/// Creates the MetaColumn.
|
||||||
|
|
||||||
|
virtual ~MetaColumn();
|
||||||
|
/// Destroys the MetaColumn.
|
||||||
|
|
||||||
|
const std::string & name() const;
|
||||||
|
/// Returns column name.
|
||||||
|
|
||||||
|
std::size_t length() const;
|
||||||
|
/// Returns column maximum length.
|
||||||
|
|
||||||
|
std::size_t precision() const;
|
||||||
|
/// Returns column precision.
|
||||||
|
/// Valid for floating point fields only
|
||||||
|
/// (zero for other data types).
|
||||||
|
|
||||||
|
std::size_t position() const;
|
||||||
|
/// Returns column position.
|
||||||
|
|
||||||
|
ColumnDataType type() const;
|
||||||
|
/// Returns column type.
|
||||||
|
|
||||||
|
bool isNullable() const;
|
||||||
|
/// Returns true if column allows null values, false otherwise.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setName(const std::string & name);
|
||||||
|
/// Sets the column name.
|
||||||
|
|
||||||
|
void setLength(std::size_t length);
|
||||||
|
/// Sets the column length.
|
||||||
|
|
||||||
|
void setPrecision(std::size_t precision);
|
||||||
|
/// Sets the column precision.
|
||||||
|
|
||||||
|
void setType(ColumnDataType type);
|
||||||
|
/// Sets the column data type.
|
||||||
|
|
||||||
|
void setNullable(bool nullable);
|
||||||
|
/// Sets the column nullability.
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string _name;
|
||||||
|
std::size_t _length;
|
||||||
|
std::size_t _precision;
|
||||||
|
std::size_t _position;
|
||||||
|
ColumnDataType _type;
|
||||||
|
bool _nullable;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// inlines
|
||||||
|
///
|
||||||
|
inline const std::string & MetaColumn::name() const
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::size_t MetaColumn::length() const
|
||||||
|
{
|
||||||
|
return _length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::size_t MetaColumn::precision() const
|
||||||
|
{
|
||||||
|
return _precision;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::size_t MetaColumn::position() const
|
||||||
|
{
|
||||||
|
return _position;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline MetaColumn::ColumnDataType MetaColumn::type() const
|
||||||
|
{
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool MetaColumn::isNullable() const
|
||||||
|
{
|
||||||
|
return _nullable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void MetaColumn::setName(const std::string & name)
|
||||||
|
{
|
||||||
|
_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void MetaColumn::setLength(std::size_t length)
|
||||||
|
{
|
||||||
|
_length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void MetaColumn::setPrecision(std::size_t precision)
|
||||||
|
{
|
||||||
|
_precision = precision;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void MetaColumn::setType(ColumnDataType type)
|
||||||
|
{
|
||||||
|
_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void MetaColumn::setNullable(bool nullable)
|
||||||
|
{
|
||||||
|
_nullable = nullable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline std::size_t MetaColumn::length() const
|
|
||||||
{
|
|
||||||
return _length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::size_t MetaColumn::precision() const
|
|
||||||
{
|
|
||||||
return _precision;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::size_t MetaColumn::position() const
|
|
||||||
{
|
|
||||||
return _position;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline MetaColumn::ColumnDataType MetaColumn::type() const
|
|
||||||
{
|
|
||||||
return _type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool MetaColumn::isNullable() const
|
|
||||||
{
|
|
||||||
return _nullable;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void MetaColumn::setName(const std::string& name)
|
|
||||||
{
|
|
||||||
_name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void MetaColumn::setLength(std::size_t length)
|
|
||||||
{
|
|
||||||
_length = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void MetaColumn::setPrecision(std::size_t precision)
|
|
||||||
{
|
|
||||||
_precision = precision;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void MetaColumn::setType(ColumnDataType type)
|
|
||||||
{
|
|
||||||
_type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void MetaColumn::setNullable(bool nullable)
|
|
||||||
{
|
|
||||||
_nullable = nullable;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_MetaColumn_INCLUDED
|
#endif // Data_MetaColumn_INCLUDED
|
||||||
|
@ -18,82 +18,85 @@
|
|||||||
#define Data_PooledSessionHolder_INCLUDED
|
#define Data_PooledSessionHolder_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/AutoPtr.h"
|
||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/SessionImpl.h"
|
#include "Poco/Data/SessionImpl.h"
|
||||||
#include "Poco/AutoPtr.h"
|
|
||||||
#include "Poco/Timestamp.h"
|
|
||||||
#include "Poco/Mutex.h"
|
#include "Poco/Mutex.h"
|
||||||
|
#include "Poco/Timestamp.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class SessionPool;
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API PooledSessionHolder: public Poco::RefCountedObject
|
|
||||||
/// This class is used by SessionPool to manage SessionImpl objects.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
PooledSessionHolder(SessionPool& owner, SessionImpl* pSessionImpl);
|
|
||||||
/// Creates the PooledSessionHolder.
|
|
||||||
|
|
||||||
~PooledSessionHolder();
|
|
||||||
/// Destroys the PooledSessionHolder.
|
|
||||||
|
|
||||||
SessionImpl* session();
|
|
||||||
/// Returns a pointer to the SessionImpl.
|
|
||||||
|
|
||||||
SessionPool& owner();
|
|
||||||
/// Returns a reference to the SessionHolder's owner.
|
|
||||||
|
|
||||||
void access();
|
|
||||||
/// Updates the last access timestamp.
|
|
||||||
|
|
||||||
int idle() const;
|
|
||||||
/// Returns the number of seconds the session has not been used.
|
|
||||||
|
|
||||||
private:
|
|
||||||
SessionPool& _owner;
|
|
||||||
Poco::AutoPtr<SessionImpl> _pImpl;
|
|
||||||
Poco::Timestamp _lastUsed;
|
|
||||||
mutable Poco::FastMutex _mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline SessionImpl* PooledSessionHolder::session()
|
|
||||||
{
|
{
|
||||||
return _pImpl;
|
|
||||||
|
|
||||||
|
class SessionPool;
|
||||||
|
|
||||||
|
|
||||||
|
class Data_API PooledSessionHolder : public Poco::RefCountedObject
|
||||||
|
/// This class is used by SessionPool to manage SessionImpl objects.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PooledSessionHolder(SessionPool & owner, SessionImpl * pSessionImpl);
|
||||||
|
/// Creates the PooledSessionHolder.
|
||||||
|
|
||||||
|
~PooledSessionHolder();
|
||||||
|
/// Destroys the PooledSessionHolder.
|
||||||
|
|
||||||
|
SessionImpl * session();
|
||||||
|
/// Returns a pointer to the SessionImpl.
|
||||||
|
|
||||||
|
SessionPool & owner();
|
||||||
|
/// Returns a reference to the SessionHolder's owner.
|
||||||
|
|
||||||
|
void access();
|
||||||
|
/// Updates the last access timestamp.
|
||||||
|
|
||||||
|
int idle() const;
|
||||||
|
/// Returns the number of seconds the session has not been used.
|
||||||
|
|
||||||
|
private:
|
||||||
|
SessionPool & _owner;
|
||||||
|
Poco::AutoPtr<SessionImpl> _pImpl;
|
||||||
|
Poco::Timestamp _lastUsed;
|
||||||
|
mutable Poco::FastMutex _mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline SessionImpl * PooledSessionHolder::session()
|
||||||
|
{
|
||||||
|
return _pImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline SessionPool & PooledSessionHolder::owner()
|
||||||
|
{
|
||||||
|
return _owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void PooledSessionHolder::access()
|
||||||
|
{
|
||||||
|
Poco::FastMutex::ScopedLock lock(_mutex);
|
||||||
|
|
||||||
|
_lastUsed.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int PooledSessionHolder::idle() const
|
||||||
|
{
|
||||||
|
Poco::FastMutex::ScopedLock lock(_mutex);
|
||||||
|
|
||||||
|
return (int)(_lastUsed.elapsed() / Poco::Timestamp::resolution());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline SessionPool& PooledSessionHolder::owner()
|
|
||||||
{
|
|
||||||
return _owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void PooledSessionHolder::access()
|
|
||||||
{
|
|
||||||
Poco::FastMutex::ScopedLock lock(_mutex);
|
|
||||||
|
|
||||||
_lastUsed.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline int PooledSessionHolder::idle() const
|
|
||||||
{
|
|
||||||
Poco::FastMutex::ScopedLock lock(_mutex);
|
|
||||||
|
|
||||||
return (int) (_lastUsed.elapsed()/Poco::Timestamp::resolution());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_PooledSessionHolder_INCLUDED
|
#endif // Data_PooledSessionHolder_INCLUDED
|
||||||
|
@ -18,80 +18,83 @@
|
|||||||
#define Data_PooledSessionImpl_INCLUDED
|
#define Data_PooledSessionImpl_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
|
||||||
#include "Poco/Data/SessionImpl.h"
|
|
||||||
#include "Poco/Data/PooledSessionHolder.h"
|
|
||||||
#include "Poco/AutoPtr.h"
|
#include "Poco/AutoPtr.h"
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
|
#include "Poco/Data/PooledSessionHolder.h"
|
||||||
|
#include "Poco/Data/SessionImpl.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class SessionPool;
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API PooledSessionImpl: public SessionImpl
|
|
||||||
/// PooledSessionImpl is a decorator created by
|
|
||||||
/// SessionPool that adds session pool
|
|
||||||
/// management to SessionImpl objects.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
PooledSessionImpl(PooledSessionHolder* pHolder);
|
|
||||||
/// Creates the PooledSessionImpl.
|
|
||||||
|
|
||||||
~PooledSessionImpl();
|
|
||||||
/// Destroys the PooledSessionImpl.
|
|
||||||
|
|
||||||
// SessionImpl
|
|
||||||
StatementImpl* createStatementImpl();
|
|
||||||
void begin();
|
|
||||||
void commit();
|
|
||||||
void rollback();
|
|
||||||
void open(const std::string& connect = "");
|
|
||||||
void close();
|
|
||||||
bool isConnected();
|
|
||||||
void setConnectionTimeout(std::size_t timeout);
|
|
||||||
std::size_t getConnectionTimeout();
|
|
||||||
bool canTransact();
|
|
||||||
bool isTransaction();
|
|
||||||
void setTransactionIsolation(Poco::UInt32);
|
|
||||||
Poco::UInt32 getTransactionIsolation();
|
|
||||||
bool hasTransactionIsolation(Poco::UInt32);
|
|
||||||
bool isTransactionIsolation(Poco::UInt32);
|
|
||||||
const std::string& connectorName() const;
|
|
||||||
void setFeature(const std::string& name, bool state);
|
|
||||||
bool getFeature(const std::string& name);
|
|
||||||
void setProperty(const std::string& name, const Poco::Any& value);
|
|
||||||
Poco::Any getProperty(const std::string& name);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
SessionImpl* access() const;
|
|
||||||
/// Updates the last access timestamp,
|
|
||||||
/// verifies validity of the session
|
|
||||||
/// and returns the session if it is valid.
|
|
||||||
///
|
|
||||||
/// Throws an SessionUnavailableException if the
|
|
||||||
/// session is no longer valid.
|
|
||||||
|
|
||||||
SessionImpl* impl() const;
|
|
||||||
/// Returns a pointer to the SessionImpl.
|
|
||||||
|
|
||||||
private:
|
|
||||||
mutable Poco::AutoPtr<PooledSessionHolder> _pHolder;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline SessionImpl* PooledSessionImpl::impl() const
|
|
||||||
{
|
{
|
||||||
return _pHolder->session();
|
|
||||||
|
|
||||||
|
class SessionPool;
|
||||||
|
|
||||||
|
|
||||||
|
class Data_API PooledSessionImpl : public SessionImpl
|
||||||
|
/// PooledSessionImpl is a decorator created by
|
||||||
|
/// SessionPool that adds session pool
|
||||||
|
/// management to SessionImpl objects.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PooledSessionImpl(PooledSessionHolder * pHolder);
|
||||||
|
/// Creates the PooledSessionImpl.
|
||||||
|
|
||||||
|
~PooledSessionImpl();
|
||||||
|
/// Destroys the PooledSessionImpl.
|
||||||
|
|
||||||
|
// SessionImpl
|
||||||
|
StatementImpl * createStatementImpl();
|
||||||
|
void begin();
|
||||||
|
void commit();
|
||||||
|
void rollback();
|
||||||
|
void open(const std::string & connect = "");
|
||||||
|
void close();
|
||||||
|
bool isConnected();
|
||||||
|
void setConnectionTimeout(std::size_t timeout);
|
||||||
|
std::size_t getConnectionTimeout();
|
||||||
|
bool canTransact();
|
||||||
|
bool isTransaction();
|
||||||
|
void setTransactionIsolation(Poco::UInt32);
|
||||||
|
Poco::UInt32 getTransactionIsolation();
|
||||||
|
bool hasTransactionIsolation(Poco::UInt32);
|
||||||
|
bool isTransactionIsolation(Poco::UInt32);
|
||||||
|
const std::string & connectorName() const;
|
||||||
|
void setFeature(const std::string & name, bool state);
|
||||||
|
bool getFeature(const std::string & name);
|
||||||
|
void setProperty(const std::string & name, const Poco::Any & value);
|
||||||
|
Poco::Any getProperty(const std::string & name);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SessionImpl * access() const;
|
||||||
|
/// Updates the last access timestamp,
|
||||||
|
/// verifies validity of the session
|
||||||
|
/// and returns the session if it is valid.
|
||||||
|
///
|
||||||
|
/// Throws an SessionUnavailableException if the
|
||||||
|
/// session is no longer valid.
|
||||||
|
|
||||||
|
SessionImpl * impl() const;
|
||||||
|
/// Returns a pointer to the SessionImpl.
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable Poco::AutoPtr<PooledSessionHolder> _pHolder;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline SessionImpl * PooledSessionImpl::impl() const
|
||||||
|
{
|
||||||
|
return _pHolder->session();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_PooledSessionImpl_INCLUDED
|
#endif // Data_PooledSessionImpl_INCLUDED
|
||||||
|
@ -21,55 +21,59 @@
|
|||||||
#include "Poco/Data/Limit.h"
|
#include "Poco/Data/Limit.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API Position
|
|
||||||
/// Utility class wrapping unsigned integer. Used to
|
|
||||||
/// indicate the recordset position in batch SQL statements.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
Position(Poco::UInt32 value);
|
|
||||||
/// Creates the Position.
|
|
||||||
|
|
||||||
~Position();
|
|
||||||
/// Destroys the Position.
|
|
||||||
|
|
||||||
Poco::UInt32 value() const;
|
|
||||||
/// Returns the position value.
|
|
||||||
|
|
||||||
private:
|
|
||||||
Position();
|
|
||||||
|
|
||||||
Poco::UInt32 _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// inlines
|
|
||||||
///
|
|
||||||
inline Poco::UInt32 Position::value() const
|
|
||||||
{
|
|
||||||
return _value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace Keywords {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline Position from(const T& value)
|
|
||||||
/// Convenience function for creation of position.
|
|
||||||
{
|
{
|
||||||
return Position(value);
|
|
||||||
|
|
||||||
|
class Data_API Position
|
||||||
|
/// Utility class wrapping unsigned integer. Used to
|
||||||
|
/// indicate the recordset position in batch SQL statements.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Position(Poco::UInt32 value);
|
||||||
|
/// Creates the Position.
|
||||||
|
|
||||||
|
~Position();
|
||||||
|
/// Destroys the Position.
|
||||||
|
|
||||||
|
Poco::UInt32 value() const;
|
||||||
|
/// Returns the position value.
|
||||||
|
|
||||||
|
private:
|
||||||
|
Position();
|
||||||
|
|
||||||
|
Poco::UInt32 _value;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// inlines
|
||||||
|
///
|
||||||
|
inline Poco::UInt32 Position::value() const
|
||||||
|
{
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace Keywords
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline Position from(const T & value)
|
||||||
|
/// Convenience function for creation of position.
|
||||||
|
{
|
||||||
|
return Position(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Keywords
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
} // namespace Keywords
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_Position_INCLUDED
|
#endif // Data_Position_INCLUDED
|
||||||
|
@ -18,144 +18,139 @@
|
|||||||
#define Data_Preparation_INCLUDED
|
#define Data_Preparation_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
|
||||||
#include "Poco/Data/AbstractPreparation.h"
|
|
||||||
#include "Poco/Data/TypeHandler.h"
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "Poco/Data/AbstractPreparation.h"
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
|
#include "Poco/Data/TypeHandler.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class Preparation: public AbstractPreparation
|
|
||||||
/// Class for calling the appropriate AbstractPreparator method.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
Preparation(AbstractPreparator::Ptr& pPreparator, std::size_t pos, T& val):
|
|
||||||
AbstractPreparation(pPreparator),
|
|
||||||
_pos(pos),
|
|
||||||
_val(val)
|
|
||||||
/// Creates the Preparation.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~Preparation()
|
|
||||||
/// Destroys the Preparation.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void prepare()
|
|
||||||
/// Prepares data.
|
|
||||||
{
|
|
||||||
TypeHandler<T>::prepare(_pos, _val, preparation());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::size_t _pos;
|
|
||||||
T& _val;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class Preparation<std::vector<T> >: public AbstractPreparation
|
|
||||||
/// Preparation specialization for std::vector.
|
|
||||||
/// This specialization is needed for bulk operations to enforce
|
|
||||||
/// the whole vector preparation, rather than only individual contained values.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
Preparation(AbstractPreparator::Ptr pPreparator, std::size_t pos, std::vector<T>& val = std::vector<T>()):
|
|
||||||
AbstractPreparation(pPreparator),
|
|
||||||
_pos(pos),
|
|
||||||
_val(val)
|
|
||||||
/// Creates the Preparation.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~Preparation()
|
|
||||||
/// Destroys the Preparation.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void prepare()
|
|
||||||
/// Prepares data.
|
|
||||||
{
|
|
||||||
TypeHandler<std::vector<T> >::prepare(_pos, _val, preparation());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::size_t _pos;
|
|
||||||
std::vector<T>& _val;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
class Preparation<std::deque<T> >: public AbstractPreparation
|
class Preparation : public AbstractPreparation
|
||||||
/// Preparation specialization for std::deque.
|
/// Class for calling the appropriate AbstractPreparator method.
|
||||||
/// This specialization is needed for bulk operations to enforce
|
{
|
||||||
/// the whole deque preparation, rather than only individual contained values.
|
public:
|
||||||
{
|
Preparation(AbstractPreparator::Ptr & pPreparator, std::size_t pos, T & val)
|
||||||
public:
|
: AbstractPreparation(pPreparator), _pos(pos), _val(val)
|
||||||
Preparation(AbstractPreparator::Ptr pPreparator, std::size_t pos, std::deque<T>& val = std::deque<T>()):
|
/// Creates the Preparation.
|
||||||
AbstractPreparation(pPreparator),
|
{
|
||||||
_pos(pos),
|
}
|
||||||
_val(val)
|
|
||||||
/// Creates the Preparation.
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~Preparation()
|
~Preparation()
|
||||||
/// Destroys the Preparation.
|
/// Destroys the Preparation.
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare()
|
void prepare()
|
||||||
/// Prepares data.
|
/// Prepares data.
|
||||||
{
|
{
|
||||||
TypeHandler<std::deque<T> >::prepare(_pos, _val, preparation());
|
TypeHandler<T>::prepare(_pos, _val, preparation());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::size_t _pos;
|
std::size_t _pos;
|
||||||
std::deque<T>& _val;
|
T & _val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
class Preparation<std::list<T> >: public AbstractPreparation
|
class Preparation<std::vector<T>> : public AbstractPreparation
|
||||||
/// Preparation specialization for std::list.
|
/// Preparation specialization for std::vector.
|
||||||
/// This specialization is needed for bulk operations to enforce
|
/// This specialization is needed for bulk operations to enforce
|
||||||
/// the whole list preparation, rather than only individual contained values.
|
/// the whole vector preparation, rather than only individual contained values.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Preparation(AbstractPreparator::Ptr pPreparator, std::size_t pos, std::list<T>& val = std::list<T>()):
|
Preparation(AbstractPreparator::Ptr pPreparator, std::size_t pos, std::vector<T> & val = std::vector<T>())
|
||||||
AbstractPreparation(pPreparator),
|
: AbstractPreparation(pPreparator), _pos(pos), _val(val)
|
||||||
_pos(pos),
|
/// Creates the Preparation.
|
||||||
_val(val)
|
{
|
||||||
/// Creates the Preparation.
|
}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~Preparation()
|
~Preparation()
|
||||||
/// Destroys the Preparation.
|
/// Destroys the Preparation.
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare()
|
void prepare()
|
||||||
/// Prepares data.
|
/// Prepares data.
|
||||||
{
|
{
|
||||||
TypeHandler<std::list<T> >::prepare(_pos, _val, preparation());
|
TypeHandler<std::vector<T>>::prepare(_pos, _val, preparation());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::size_t _pos;
|
std::size_t _pos;
|
||||||
std::list<T>& _val;
|
std::vector<T> & _val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
template <typename T>
|
||||||
|
class Preparation<std::deque<T>> : public AbstractPreparation
|
||||||
|
/// Preparation specialization for std::deque.
|
||||||
|
/// This specialization is needed for bulk operations to enforce
|
||||||
|
/// the whole deque preparation, rather than only individual contained values.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Preparation(AbstractPreparator::Ptr pPreparator, std::size_t pos, std::deque<T> & val = std::deque<T>())
|
||||||
|
: AbstractPreparation(pPreparator), _pos(pos), _val(val)
|
||||||
|
/// Creates the Preparation.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Preparation()
|
||||||
|
/// Destroys the Preparation.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepare()
|
||||||
|
/// Prepares data.
|
||||||
|
{
|
||||||
|
TypeHandler<std::deque<T>>::prepare(_pos, _val, preparation());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t _pos;
|
||||||
|
std::deque<T> & _val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Preparation<std::list<T>> : public AbstractPreparation
|
||||||
|
/// Preparation specialization for std::list.
|
||||||
|
/// This specialization is needed for bulk operations to enforce
|
||||||
|
/// the whole list preparation, rather than only individual contained values.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Preparation(AbstractPreparator::Ptr pPreparator, std::size_t pos, std::list<T> & val = std::list<T>())
|
||||||
|
: AbstractPreparation(pPreparator), _pos(pos), _val(val)
|
||||||
|
/// Creates the Preparation.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Preparation()
|
||||||
|
/// Destroys the Preparation.
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepare()
|
||||||
|
/// Prepares data.
|
||||||
|
{
|
||||||
|
TypeHandler<std::list<T>>::prepare(_pos, _val, preparation());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t _pos;
|
||||||
|
std::list<T> & _val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_Preparation_INCLUDED
|
#endif // Data_Preparation_INCLUDED
|
||||||
|
@ -22,83 +22,87 @@
|
|||||||
#include "Poco/Data/Limit.h"
|
#include "Poco/Data/Limit.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API Range
|
|
||||||
/// Range stores information how many rows a query should return.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
Range(Limit::SizeT lowValue, Limit::SizeT upValue, bool hardLimit);
|
|
||||||
/// Creates the Range. lowValue must be smaller equal than upValue
|
|
||||||
|
|
||||||
~Range();
|
|
||||||
/// Destroys the Limit.
|
|
||||||
|
|
||||||
const Limit& lower() const;
|
|
||||||
/// Returns the lower limit
|
|
||||||
|
|
||||||
const Limit& upper() const;
|
|
||||||
/// Returns the upper limit
|
|
||||||
|
|
||||||
private:
|
|
||||||
Limit _lower;
|
|
||||||
Limit _upper;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline const Limit& Range::lower() const
|
|
||||||
{
|
{
|
||||||
return _lower;
|
|
||||||
|
|
||||||
|
class Data_API Range
|
||||||
|
/// Range stores information how many rows a query should return.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Range(Limit::SizeT lowValue, Limit::SizeT upValue, bool hardLimit);
|
||||||
|
/// Creates the Range. lowValue must be smaller equal than upValue
|
||||||
|
|
||||||
|
~Range();
|
||||||
|
/// Destroys the Limit.
|
||||||
|
|
||||||
|
const Limit & lower() const;
|
||||||
|
/// Returns the lower limit
|
||||||
|
|
||||||
|
const Limit & upper() const;
|
||||||
|
/// Returns the upper limit
|
||||||
|
|
||||||
|
private:
|
||||||
|
Limit _lower;
|
||||||
|
Limit _upper;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline const Limit & Range::lower() const
|
||||||
|
{
|
||||||
|
return _lower;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const Limit & Range::upper() const
|
||||||
|
{
|
||||||
|
return _upper;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace Keywords
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Limit limit(T lim, bool hard = false)
|
||||||
|
/// Creates an upperLimit
|
||||||
|
{
|
||||||
|
return Limit(static_cast<Limit::SizeT>(lim), hard, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Limit upperLimit(T lim, bool hard = false)
|
||||||
|
{
|
||||||
|
return limit(lim, hard);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Limit lowerLimit(T lim)
|
||||||
|
{
|
||||||
|
return Limit(static_cast<Limit::SizeT>(lim), true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Range range(T low, T upp, bool hard = false)
|
||||||
|
{
|
||||||
|
return Range(static_cast<Limit::SizeT>(low), static_cast<Limit::SizeT>(upp), hard);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Keywords
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline const Limit& Range::upper() const
|
|
||||||
{
|
|
||||||
return _upper;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace Keywords {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Limit limit(T lim, bool hard = false)
|
|
||||||
/// Creates an upperLimit
|
|
||||||
{
|
|
||||||
return Limit(static_cast<Limit::SizeT>(lim), hard, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Limit upperLimit(T lim, bool hard = false)
|
|
||||||
{
|
|
||||||
return limit(lim, hard);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Limit lowerLimit(T lim)
|
|
||||||
{
|
|
||||||
return Limit(static_cast<Limit::SizeT>(lim), true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Range range(T low, T upp, bool hard = false)
|
|
||||||
{
|
|
||||||
return Range(static_cast<Limit::SizeT>(low), static_cast<Limit::SizeT>(upp), hard);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Keywords
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_Range_INCLUDED
|
#endif // Data_Range_INCLUDED
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,295 +18,297 @@
|
|||||||
#define Data_Row_INCLUDED
|
#define Data_Row_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/RowFormatter.h"
|
#include "Poco/Data/RowFormatter.h"
|
||||||
#include "Poco/Dynamic/Var.h"
|
#include "Poco/Dynamic/Var.h"
|
||||||
#include "Poco/Tuple.h"
|
|
||||||
#include "Poco/SharedPtr.h"
|
#include "Poco/SharedPtr.h"
|
||||||
#include <vector>
|
#include "Poco/Tuple.h"
|
||||||
#include <string>
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class RecordSet;
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API Row
|
|
||||||
/// Row class provides a data type for RecordSet iteration purposes.
|
|
||||||
/// Dereferencing a RowIterator returns Row.
|
|
||||||
/// Rows are sortable. The sortability is maintained at all times (i.e. there
|
|
||||||
/// is always at least one column specified as a sorting criteria) .
|
|
||||||
/// The default and minimal sorting criteria is the first field (position 0).
|
|
||||||
/// The default sorting criteria can be replaced with any other field by
|
|
||||||
/// calling replaceSortField() member function.
|
|
||||||
/// Additional fields can be added to sorting criteria, in which case the
|
|
||||||
/// field precedence corresponds to addition order (i.e. later added fields
|
|
||||||
/// have lower sorting precedence).
|
|
||||||
/// These features make Row suitable for use with standard sorted
|
|
||||||
/// containers and algorithms. The main constraint is that all the rows from
|
|
||||||
/// a set that is being sorted must have the same sorting criteria (i.e., the same
|
|
||||||
/// set of fields must be in sorting criteria in the same order). Since rows don't
|
|
||||||
/// know about each other, it is the programmer's responsibility to ensure this
|
|
||||||
/// constraint is satisfied.
|
|
||||||
/// Field names are a shared pointer to a vector of strings. For efficiency sake,
|
|
||||||
/// a constructor taking a shared pointer to names vector argument is provided.
|
|
||||||
/// The stream operator is provided for Row data type as a free-standing function.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
typedef RowFormatter::NameVec NameVec;
|
|
||||||
typedef RowFormatter::NameVecPtr NameVecPtr;
|
|
||||||
typedef RowFormatter::ValueVec ValueVec;
|
|
||||||
|
|
||||||
enum ComparisonType
|
|
||||||
{
|
|
||||||
COMPARE_AS_EMPTY,
|
|
||||||
COMPARE_AS_INTEGER,
|
|
||||||
COMPARE_AS_FLOAT,
|
|
||||||
COMPARE_AS_STRING
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef Tuple<std::size_t, ComparisonType> SortTuple;
|
|
||||||
typedef std::vector<SortTuple> SortMap;
|
|
||||||
/// The type for map holding fields used for sorting criteria.
|
|
||||||
/// Fields are added sequentially and have precedence that
|
|
||||||
/// corresponds to field adding sequence order (rather than field's
|
|
||||||
/// position in the row).
|
|
||||||
/// This requirement rules out use of std::map due to its sorted nature.
|
|
||||||
typedef SharedPtr<SortMap> SortMapPtr;
|
|
||||||
|
|
||||||
Row();
|
|
||||||
/// Creates the Row.
|
|
||||||
|
|
||||||
Row(NameVecPtr pNames,
|
|
||||||
const RowFormatter::Ptr& pFormatter = 0);
|
|
||||||
/// Creates the Row.
|
|
||||||
|
|
||||||
Row(NameVecPtr pNames,
|
|
||||||
const SortMapPtr& pSortMap,
|
|
||||||
const RowFormatter::Ptr& pFormatter = 0);
|
|
||||||
/// Creates the Row.
|
|
||||||
|
|
||||||
~Row();
|
|
||||||
/// Destroys the Row.
|
|
||||||
|
|
||||||
Poco::Dynamic::Var& get(std::size_t col);
|
|
||||||
/// Returns the reference to data value at column location.
|
|
||||||
|
|
||||||
Poco::Dynamic::Var& operator [] (std::size_t col);
|
|
||||||
/// Returns the reference to data value at column location.
|
|
||||||
|
|
||||||
Poco::Dynamic::Var& operator [] (const std::string& name);
|
|
||||||
/// Returns the reference to data value at named column location.
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void append(const std::string& name, const T& val)
|
|
||||||
/// Appends the value to the row.
|
|
||||||
{
|
|
||||||
if (!_pNames) _pNames = new NameVec;
|
|
||||||
_values.push_back(val);
|
|
||||||
_pNames->push_back(name);
|
|
||||||
if (1 == _values.size()) addSortField(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void set(std::size_t pos, const T& val)
|
|
||||||
/// Assigns the value to the row.
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_values.at(pos) = val;
|
|
||||||
}
|
|
||||||
catch (std::out_of_range&)
|
|
||||||
{
|
|
||||||
throw RangeException("Invalid column number.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void set(const std::string& name, const T& val)
|
|
||||||
/// Assigns the value to the row.
|
|
||||||
{
|
|
||||||
NameVec::iterator it = _pNames->begin();
|
|
||||||
NameVec::iterator end = _pNames->end();
|
|
||||||
for (int i = 0; it != end; ++it, ++i)
|
|
||||||
{
|
|
||||||
if (*it == name)
|
|
||||||
return set(i, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
os << "Column with name " << name << " not found.";
|
|
||||||
throw NotFoundException(os.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t fieldCount() const;
|
|
||||||
/// Returns the number of fields in this row.
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
/// Resets the row by clearing all field names and values.
|
|
||||||
|
|
||||||
void separator(const std::string& sep);
|
|
||||||
/// Sets the separator.
|
|
||||||
|
|
||||||
void addSortField(std::size_t pos);
|
|
||||||
/// Adds the field used for sorting.
|
|
||||||
|
|
||||||
void addSortField(const std::string& name);
|
|
||||||
/// Adds the field used for sorting.
|
|
||||||
|
|
||||||
void removeSortField(std::size_t pos);
|
|
||||||
/// Removes the field used for sorting.
|
|
||||||
|
|
||||||
void removeSortField(const std::string& name);
|
|
||||||
/// Removes the field used for sorting.
|
|
||||||
|
|
||||||
void replaceSortField(std::size_t oldPos, std::size_t newPos);
|
|
||||||
/// Replaces the field used for sorting.
|
|
||||||
|
|
||||||
void replaceSortField(const std::string& oldName, const std::string& newName);
|
|
||||||
/// Replaces the field used for sorting.
|
|
||||||
|
|
||||||
void resetSort();
|
|
||||||
/// Resets the sorting criteria to field 0 only.
|
|
||||||
|
|
||||||
const std::string& namesToString() const;
|
|
||||||
/// Converts the column names to string.
|
|
||||||
|
|
||||||
void formatNames() const;
|
|
||||||
/// Formats the column names.
|
|
||||||
|
|
||||||
const std::string& valuesToString() const;
|
|
||||||
/// Converts the row values to string and returns the formatted string.
|
|
||||||
|
|
||||||
void formatValues() const;
|
|
||||||
/// Formats the row values.
|
|
||||||
|
|
||||||
bool operator == (const Row& other) const;
|
|
||||||
/// Equality operator.
|
|
||||||
|
|
||||||
bool operator != (const Row& other) const;
|
|
||||||
/// Inequality operator.
|
|
||||||
|
|
||||||
bool operator < (const Row& other) const;
|
|
||||||
/// Less-than operator.
|
|
||||||
|
|
||||||
const NameVecPtr names() const;
|
|
||||||
/// Returns the shared pointer to names vector.
|
|
||||||
|
|
||||||
const ValueVec& values() const;
|
|
||||||
/// Returns the const reference to values vector.
|
|
||||||
|
|
||||||
void setFormatter(const RowFormatter::Ptr& pFormatter = 0);
|
|
||||||
/// Sets the formatter for this row and takes the
|
|
||||||
/// shared ownership of it.
|
|
||||||
|
|
||||||
const RowFormatter& getFormatter() const;
|
|
||||||
/// Returns the reference to the formatter.
|
|
||||||
|
|
||||||
void setSortMap(const SortMapPtr& pSortMap = 0);
|
|
||||||
/// Adds the sorting fields entry and takes the
|
|
||||||
/// shared ownership of it.
|
|
||||||
|
|
||||||
const SortMapPtr& getSortMap() const;
|
|
||||||
/// Returns the reference to the sorting fields.
|
|
||||||
|
|
||||||
private:
|
|
||||||
void init(const SortMapPtr& pSortMap, const RowFormatter::Ptr& pFormatter);
|
|
||||||
|
|
||||||
ValueVec& values();
|
|
||||||
/// Returns the reference to values vector.
|
|
||||||
|
|
||||||
std::size_t getPosition(const std::string& name);
|
|
||||||
bool isEqualSize(const Row& other) const;
|
|
||||||
bool isEqualType(const Row& other) const;
|
|
||||||
|
|
||||||
NameVecPtr _pNames;
|
|
||||||
ValueVec _values;
|
|
||||||
SortMapPtr _pSortMap;
|
|
||||||
mutable RowFormatter::Ptr _pFormatter;
|
|
||||||
mutable std::string _nameStr;
|
|
||||||
mutable std::string _valueStr;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Data_API std::ostream& operator << (std::ostream &os, const Row& row);
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// inlines
|
|
||||||
///
|
|
||||||
inline std::size_t Row::fieldCount() const
|
|
||||||
{
|
{
|
||||||
return static_cast<std::size_t>(_values.size());
|
|
||||||
|
|
||||||
|
class RecordSet;
|
||||||
|
|
||||||
|
|
||||||
|
class Data_API Row
|
||||||
|
/// Row class provides a data type for RecordSet iteration purposes.
|
||||||
|
/// Dereferencing a RowIterator returns Row.
|
||||||
|
/// Rows are sortable. The sortability is maintained at all times (i.e. there
|
||||||
|
/// is always at least one column specified as a sorting criteria) .
|
||||||
|
/// The default and minimal sorting criteria is the first field (position 0).
|
||||||
|
/// The default sorting criteria can be replaced with any other field by
|
||||||
|
/// calling replaceSortField() member function.
|
||||||
|
/// Additional fields can be added to sorting criteria, in which case the
|
||||||
|
/// field precedence corresponds to addition order (i.e. later added fields
|
||||||
|
/// have lower sorting precedence).
|
||||||
|
/// These features make Row suitable for use with standard sorted
|
||||||
|
/// containers and algorithms. The main constraint is that all the rows from
|
||||||
|
/// a set that is being sorted must have the same sorting criteria (i.e., the same
|
||||||
|
/// set of fields must be in sorting criteria in the same order). Since rows don't
|
||||||
|
/// know about each other, it is the programmer's responsibility to ensure this
|
||||||
|
/// constraint is satisfied.
|
||||||
|
/// Field names are a shared pointer to a vector of strings. For efficiency sake,
|
||||||
|
/// a constructor taking a shared pointer to names vector argument is provided.
|
||||||
|
/// The stream operator is provided for Row data type as a free-standing function.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef RowFormatter::NameVec NameVec;
|
||||||
|
typedef RowFormatter::NameVecPtr NameVecPtr;
|
||||||
|
typedef RowFormatter::ValueVec ValueVec;
|
||||||
|
|
||||||
|
enum ComparisonType
|
||||||
|
{
|
||||||
|
COMPARE_AS_EMPTY,
|
||||||
|
COMPARE_AS_INTEGER,
|
||||||
|
COMPARE_AS_FLOAT,
|
||||||
|
COMPARE_AS_STRING
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Tuple<std::size_t, ComparisonType> SortTuple;
|
||||||
|
typedef std::vector<SortTuple> SortMap;
|
||||||
|
/// The type for map holding fields used for sorting criteria.
|
||||||
|
/// Fields are added sequentially and have precedence that
|
||||||
|
/// corresponds to field adding sequence order (rather than field's
|
||||||
|
/// position in the row).
|
||||||
|
/// This requirement rules out use of std::map due to its sorted nature.
|
||||||
|
typedef SharedPtr<SortMap> SortMapPtr;
|
||||||
|
|
||||||
|
Row();
|
||||||
|
/// Creates the Row.
|
||||||
|
|
||||||
|
Row(NameVecPtr pNames, const RowFormatter::Ptr & pFormatter = 0);
|
||||||
|
/// Creates the Row.
|
||||||
|
|
||||||
|
Row(NameVecPtr pNames, const SortMapPtr & pSortMap, const RowFormatter::Ptr & pFormatter = 0);
|
||||||
|
/// Creates the Row.
|
||||||
|
|
||||||
|
~Row();
|
||||||
|
/// Destroys the Row.
|
||||||
|
|
||||||
|
Poco::Dynamic::Var & get(std::size_t col);
|
||||||
|
/// Returns the reference to data value at column location.
|
||||||
|
|
||||||
|
Poco::Dynamic::Var & operator[](std::size_t col);
|
||||||
|
/// Returns the reference to data value at column location.
|
||||||
|
|
||||||
|
Poco::Dynamic::Var & operator[](const std::string & name);
|
||||||
|
/// Returns the reference to data value at named column location.
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void append(const std::string & name, const T & val)
|
||||||
|
/// Appends the value to the row.
|
||||||
|
{
|
||||||
|
if (!_pNames)
|
||||||
|
_pNames = new NameVec;
|
||||||
|
_values.push_back(val);
|
||||||
|
_pNames->push_back(name);
|
||||||
|
if (1 == _values.size())
|
||||||
|
addSortField(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void set(std::size_t pos, const T & val)
|
||||||
|
/// Assigns the value to the row.
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_values.at(pos) = val;
|
||||||
|
}
|
||||||
|
catch (std::out_of_range &)
|
||||||
|
{
|
||||||
|
throw RangeException("Invalid column number.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void set(const std::string & name, const T & val)
|
||||||
|
/// Assigns the value to the row.
|
||||||
|
{
|
||||||
|
NameVec::iterator it = _pNames->begin();
|
||||||
|
NameVec::iterator end = _pNames->end();
|
||||||
|
for (int i = 0; it != end; ++it, ++i)
|
||||||
|
{
|
||||||
|
if (*it == name)
|
||||||
|
return set(i, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Column with name " << name << " not found.";
|
||||||
|
throw NotFoundException(os.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t fieldCount() const;
|
||||||
|
/// Returns the number of fields in this row.
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
/// Resets the row by clearing all field names and values.
|
||||||
|
|
||||||
|
void separator(const std::string & sep);
|
||||||
|
/// Sets the separator.
|
||||||
|
|
||||||
|
void addSortField(std::size_t pos);
|
||||||
|
/// Adds the field used for sorting.
|
||||||
|
|
||||||
|
void addSortField(const std::string & name);
|
||||||
|
/// Adds the field used for sorting.
|
||||||
|
|
||||||
|
void removeSortField(std::size_t pos);
|
||||||
|
/// Removes the field used for sorting.
|
||||||
|
|
||||||
|
void removeSortField(const std::string & name);
|
||||||
|
/// Removes the field used for sorting.
|
||||||
|
|
||||||
|
void replaceSortField(std::size_t oldPos, std::size_t newPos);
|
||||||
|
/// Replaces the field used for sorting.
|
||||||
|
|
||||||
|
void replaceSortField(const std::string & oldName, const std::string & newName);
|
||||||
|
/// Replaces the field used for sorting.
|
||||||
|
|
||||||
|
void resetSort();
|
||||||
|
/// Resets the sorting criteria to field 0 only.
|
||||||
|
|
||||||
|
const std::string & namesToString() const;
|
||||||
|
/// Converts the column names to string.
|
||||||
|
|
||||||
|
void formatNames() const;
|
||||||
|
/// Formats the column names.
|
||||||
|
|
||||||
|
const std::string & valuesToString() const;
|
||||||
|
/// Converts the row values to string and returns the formatted string.
|
||||||
|
|
||||||
|
void formatValues() const;
|
||||||
|
/// Formats the row values.
|
||||||
|
|
||||||
|
bool operator==(const Row & other) const;
|
||||||
|
/// Equality operator.
|
||||||
|
|
||||||
|
bool operator!=(const Row & other) const;
|
||||||
|
/// Inequality operator.
|
||||||
|
|
||||||
|
bool operator<(const Row & other) const;
|
||||||
|
/// Less-than operator.
|
||||||
|
|
||||||
|
const NameVecPtr names() const;
|
||||||
|
/// Returns the shared pointer to names vector.
|
||||||
|
|
||||||
|
const ValueVec & values() const;
|
||||||
|
/// Returns the const reference to values vector.
|
||||||
|
|
||||||
|
void setFormatter(const RowFormatter::Ptr & pFormatter = 0);
|
||||||
|
/// Sets the formatter for this row and takes the
|
||||||
|
/// shared ownership of it.
|
||||||
|
|
||||||
|
const RowFormatter & getFormatter() const;
|
||||||
|
/// Returns the reference to the formatter.
|
||||||
|
|
||||||
|
void setSortMap(const SortMapPtr & pSortMap = 0);
|
||||||
|
/// Adds the sorting fields entry and takes the
|
||||||
|
/// shared ownership of it.
|
||||||
|
|
||||||
|
const SortMapPtr & getSortMap() const;
|
||||||
|
/// Returns the reference to the sorting fields.
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init(const SortMapPtr & pSortMap, const RowFormatter::Ptr & pFormatter);
|
||||||
|
|
||||||
|
ValueVec & values();
|
||||||
|
/// Returns the reference to values vector.
|
||||||
|
|
||||||
|
std::size_t getPosition(const std::string & name);
|
||||||
|
bool isEqualSize(const Row & other) const;
|
||||||
|
bool isEqualType(const Row & other) const;
|
||||||
|
|
||||||
|
NameVecPtr _pNames;
|
||||||
|
ValueVec _values;
|
||||||
|
SortMapPtr _pSortMap;
|
||||||
|
mutable RowFormatter::Ptr _pFormatter;
|
||||||
|
mutable std::string _nameStr;
|
||||||
|
mutable std::string _valueStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Data_API std::ostream & operator<<(std::ostream & os, const Row & row);
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// inlines
|
||||||
|
///
|
||||||
|
inline std::size_t Row::fieldCount() const
|
||||||
|
{
|
||||||
|
return static_cast<std::size_t>(_values.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Row::reset()
|
||||||
|
{
|
||||||
|
_pNames->clear();
|
||||||
|
_values.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const Row::NameVecPtr Row::names() const
|
||||||
|
{
|
||||||
|
return _pNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const Row::ValueVec & Row::values() const
|
||||||
|
{
|
||||||
|
return _values;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Row::ValueVec & Row::values()
|
||||||
|
{
|
||||||
|
return _values;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Poco::Dynamic::Var & Row::operator[](std::size_t col)
|
||||||
|
{
|
||||||
|
return get(col);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Poco::Dynamic::Var & Row::operator[](const std::string & name)
|
||||||
|
{
|
||||||
|
return get(getPosition(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const RowFormatter & Row::getFormatter() const
|
||||||
|
{
|
||||||
|
return *_pFormatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const Row::SortMapPtr & Row::getSortMap() const
|
||||||
|
{
|
||||||
|
return _pSortMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const std::string & Row::valuesToString() const
|
||||||
|
{
|
||||||
|
return _pFormatter->formatValues(values(), _valueStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Row::formatValues() const
|
||||||
|
{
|
||||||
|
return _pFormatter->formatValues(values());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline void Row::reset()
|
|
||||||
{
|
|
||||||
_pNames->clear();
|
|
||||||
_values.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const Row::NameVecPtr Row::names() const
|
|
||||||
{
|
|
||||||
return _pNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const Row::ValueVec& Row::values() const
|
|
||||||
{
|
|
||||||
return _values;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Row::ValueVec& Row::values()
|
|
||||||
{
|
|
||||||
return _values;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Poco::Dynamic::Var& Row::operator [] (std::size_t col)
|
|
||||||
{
|
|
||||||
return get(col);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Poco::Dynamic::Var& Row::operator [] (const std::string& name)
|
|
||||||
{
|
|
||||||
return get(getPosition(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const RowFormatter& Row::getFormatter() const
|
|
||||||
{
|
|
||||||
return *_pFormatter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const Row::SortMapPtr& Row::getSortMap() const
|
|
||||||
{
|
|
||||||
return _pSortMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& Row::valuesToString() const
|
|
||||||
{
|
|
||||||
return _pFormatter->formatValues(values(), _valueStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Row::formatValues() const
|
|
||||||
{
|
|
||||||
return _pFormatter->formatValues(values());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_Row_INCLUDED
|
#endif // Data_Row_INCLUDED
|
||||||
|
@ -18,259 +18,258 @@
|
|||||||
#define Data_RowFilter_INCLUDED
|
#define Data_RowFilter_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
|
#include "Poco/AutoPtr.h"
|
||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Dynamic/Var.h"
|
#include "Poco/Dynamic/Var.h"
|
||||||
#include "Poco/Tuple.h"
|
|
||||||
#include "Poco/String.h"
|
|
||||||
#include "Poco/RefCountedObject.h"
|
#include "Poco/RefCountedObject.h"
|
||||||
#include "Poco/AutoPtr.h"
|
#include "Poco/String.h"
|
||||||
#include <map>
|
#include "Poco/Tuple.h"
|
||||||
#include <list>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class RecordSet;
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API RowFilter: public RefCountedObject
|
|
||||||
/// RowFilter class provides row filtering functionality.
|
|
||||||
/// A filter contains a set of criteria (field name, value and
|
|
||||||
/// logical operation) for row filtering.
|
|
||||||
/// Additionally, a row filter contains a map of pointers to other
|
|
||||||
/// filters with related logical operations between filters.
|
|
||||||
/// RowFilter is typically added to recordset in order to filter
|
|
||||||
/// its content. Since the recordset own iteration is dependent upon
|
|
||||||
/// filtering, whenever the filtering criteria is changed,
|
|
||||||
/// the filter automatically notifies all associated recordsets
|
|
||||||
/// by rewinding them to the first position.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
enum Comparison
|
|
||||||
{
|
|
||||||
VALUE_LESS_THAN,
|
|
||||||
VALUE_LESS_THAN_OR_EQUAL,
|
|
||||||
VALUE_EQUAL,
|
|
||||||
VALUE_GREATER_THAN,
|
|
||||||
VALUE_GREATER_THAN_OR_EQUAL,
|
|
||||||
VALUE_NOT_EQUAL,
|
|
||||||
VALUE_IS_NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
enum LogicOperator
|
|
||||||
{
|
|
||||||
OP_AND,
|
|
||||||
OP_OR,
|
|
||||||
OP_NOT
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef bool (*CompT)(const Poco::Dynamic::Var&, const Poco::Dynamic::Var&);
|
|
||||||
typedef AutoPtr<RowFilter> Ptr;
|
|
||||||
typedef std::map<std::string, Comparison> Comparisons;
|
|
||||||
typedef Tuple<Poco::Dynamic::Var, Comparison, LogicOperator> ComparisonEntry;
|
|
||||||
typedef std::multimap<std::string, ComparisonEntry> ComparisonMap;
|
|
||||||
typedef std::map<AutoPtr<RowFilter>, LogicOperator> FilterMap;
|
|
||||||
|
|
||||||
RowFilter(RecordSet* pRecordSet);
|
|
||||||
/// Creates the top-level RowFilter and associates it with the recordset.
|
|
||||||
|
|
||||||
RowFilter(Ptr pParent, LogicOperator op = OP_OR);
|
|
||||||
/// Creates child RowFilter and associates it with the parent filter.
|
|
||||||
|
|
||||||
~RowFilter();
|
|
||||||
/// Destroys the RowFilter.
|
|
||||||
|
|
||||||
void addFilter(Ptr pFilter, LogicOperator comparison);
|
|
||||||
/// Appends another filter to this one.
|
|
||||||
|
|
||||||
void removeFilter(Ptr pFilter);
|
|
||||||
/// Removes filter from this filter.
|
|
||||||
|
|
||||||
bool has(Ptr pFilter) const;
|
|
||||||
/// Returns true if this filter is parent of pFilter;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void add(const std::string& name, Comparison comparison, const T& value, LogicOperator op = OP_OR)
|
|
||||||
/// Adds value to the filter.
|
|
||||||
{
|
|
||||||
rewindRecordSet();
|
|
||||||
_comparisonMap.insert(ComparisonMap::value_type(toUpper(name),
|
|
||||||
ComparisonEntry(value, comparison, op)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void add(const std::string& name, const std::string& comp, const T& value, LogicOperator op = OP_OR)
|
|
||||||
/// Adds value to the filter.
|
|
||||||
{
|
|
||||||
add(name, getComparison(comp), value, op);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void addAnd(const std::string& name, const std::string& comp, const T& value)
|
|
||||||
/// Adds logically AND-ed value to the filter.
|
|
||||||
{
|
|
||||||
add(name, getComparison(comp), value, OP_AND);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void addOr(const std::string& name, const std::string& comp, const T& value)
|
|
||||||
/// Adds logically OR-ed value to the filter.
|
|
||||||
{
|
|
||||||
add(name, getComparison(comp), value, OP_OR);
|
|
||||||
}
|
|
||||||
|
|
||||||
int remove(const std::string& name);
|
|
||||||
/// Removes named comparisons from the filter.
|
|
||||||
/// All comparisons with specified name are removed.
|
|
||||||
/// Returns the number of comparisons removed.
|
|
||||||
|
|
||||||
void toggleNot();
|
|
||||||
/// Togless the NOT operator for this filter;
|
|
||||||
|
|
||||||
bool isNot() const;
|
|
||||||
/// Returns true if filter is NOT-ed, false otherwise.
|
|
||||||
|
|
||||||
bool isEmpty() const;
|
|
||||||
/// Returns true if there is not filtering criteria specified.
|
|
||||||
|
|
||||||
bool isAllowed(std::size_t row) const;
|
|
||||||
/// Returns true if name and value are allowed.
|
|
||||||
|
|
||||||
bool exists(const std::string& name) const;
|
|
||||||
/// Returns true if name is known to this row filter.
|
|
||||||
|
|
||||||
private:
|
|
||||||
RowFilter();
|
|
||||||
RowFilter(const RowFilter&);
|
|
||||||
RowFilter& operator=(const RowFilter&);
|
|
||||||
|
|
||||||
void init();
|
|
||||||
|
|
||||||
static bool equal(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2);
|
|
||||||
static bool notEqual(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2);
|
|
||||||
static bool less(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2);
|
|
||||||
static bool greater(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2);
|
|
||||||
static bool lessOrEqual(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2);
|
|
||||||
static bool greaterOrEqual(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2);
|
|
||||||
static bool logicalAnd(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2);
|
|
||||||
static bool logicalOr(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2);
|
|
||||||
static bool isNull(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var&);
|
|
||||||
|
|
||||||
static void doCompare(Poco::Dynamic::Var& ret,
|
|
||||||
Poco::Dynamic::Var& val,
|
|
||||||
CompT comp,
|
|
||||||
const ComparisonEntry& ce);
|
|
||||||
|
|
||||||
RecordSet& recordSet() const;
|
|
||||||
|
|
||||||
Comparison getComparison(const std::string& comp) const;
|
|
||||||
|
|
||||||
void rewindRecordSet();
|
|
||||||
|
|
||||||
Comparisons _comparisons;
|
|
||||||
ComparisonMap _comparisonMap;
|
|
||||||
mutable RecordSet* _pRecordSet;
|
|
||||||
Ptr _pParent;
|
|
||||||
FilterMap _filterMap;
|
|
||||||
bool _not;
|
|
||||||
|
|
||||||
friend class RecordSet;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// inlines
|
|
||||||
///
|
|
||||||
|
|
||||||
|
|
||||||
inline bool RowFilter::has(Ptr pFilter) const
|
|
||||||
{
|
{
|
||||||
return _filterMap.find(pFilter) != _filterMap.end();
|
|
||||||
|
|
||||||
|
class RecordSet;
|
||||||
|
|
||||||
|
|
||||||
|
class Data_API RowFilter : public RefCountedObject
|
||||||
|
/// RowFilter class provides row filtering functionality.
|
||||||
|
/// A filter contains a set of criteria (field name, value and
|
||||||
|
/// logical operation) for row filtering.
|
||||||
|
/// Additionally, a row filter contains a map of pointers to other
|
||||||
|
/// filters with related logical operations between filters.
|
||||||
|
/// RowFilter is typically added to recordset in order to filter
|
||||||
|
/// its content. Since the recordset own iteration is dependent upon
|
||||||
|
/// filtering, whenever the filtering criteria is changed,
|
||||||
|
/// the filter automatically notifies all associated recordsets
|
||||||
|
/// by rewinding them to the first position.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Comparison
|
||||||
|
{
|
||||||
|
VALUE_LESS_THAN,
|
||||||
|
VALUE_LESS_THAN_OR_EQUAL,
|
||||||
|
VALUE_EQUAL,
|
||||||
|
VALUE_GREATER_THAN,
|
||||||
|
VALUE_GREATER_THAN_OR_EQUAL,
|
||||||
|
VALUE_NOT_EQUAL,
|
||||||
|
VALUE_IS_NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LogicOperator
|
||||||
|
{
|
||||||
|
OP_AND,
|
||||||
|
OP_OR,
|
||||||
|
OP_NOT
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef bool (*CompT)(const Poco::Dynamic::Var &, const Poco::Dynamic::Var &);
|
||||||
|
typedef AutoPtr<RowFilter> Ptr;
|
||||||
|
typedef std::map<std::string, Comparison> Comparisons;
|
||||||
|
typedef Tuple<Poco::Dynamic::Var, Comparison, LogicOperator> ComparisonEntry;
|
||||||
|
typedef std::multimap<std::string, ComparisonEntry> ComparisonMap;
|
||||||
|
typedef std::map<AutoPtr<RowFilter>, LogicOperator> FilterMap;
|
||||||
|
|
||||||
|
RowFilter(RecordSet * pRecordSet);
|
||||||
|
/// Creates the top-level RowFilter and associates it with the recordset.
|
||||||
|
|
||||||
|
RowFilter(Ptr pParent, LogicOperator op = OP_OR);
|
||||||
|
/// Creates child RowFilter and associates it with the parent filter.
|
||||||
|
|
||||||
|
~RowFilter();
|
||||||
|
/// Destroys the RowFilter.
|
||||||
|
|
||||||
|
void addFilter(Ptr pFilter, LogicOperator comparison);
|
||||||
|
/// Appends another filter to this one.
|
||||||
|
|
||||||
|
void removeFilter(Ptr pFilter);
|
||||||
|
/// Removes filter from this filter.
|
||||||
|
|
||||||
|
bool has(Ptr pFilter) const;
|
||||||
|
/// Returns true if this filter is parent of pFilter;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void add(const std::string & name, Comparison comparison, const T & value, LogicOperator op = OP_OR)
|
||||||
|
/// Adds value to the filter.
|
||||||
|
{
|
||||||
|
rewindRecordSet();
|
||||||
|
_comparisonMap.insert(ComparisonMap::value_type(toUpper(name), ComparisonEntry(value, comparison, op)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void add(const std::string & name, const std::string & comp, const T & value, LogicOperator op = OP_OR)
|
||||||
|
/// Adds value to the filter.
|
||||||
|
{
|
||||||
|
add(name, getComparison(comp), value, op);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void addAnd(const std::string & name, const std::string & comp, const T & value)
|
||||||
|
/// Adds logically AND-ed value to the filter.
|
||||||
|
{
|
||||||
|
add(name, getComparison(comp), value, OP_AND);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void addOr(const std::string & name, const std::string & comp, const T & value)
|
||||||
|
/// Adds logically OR-ed value to the filter.
|
||||||
|
{
|
||||||
|
add(name, getComparison(comp), value, OP_OR);
|
||||||
|
}
|
||||||
|
|
||||||
|
int remove(const std::string & name);
|
||||||
|
/// Removes named comparisons from the filter.
|
||||||
|
/// All comparisons with specified name are removed.
|
||||||
|
/// Returns the number of comparisons removed.
|
||||||
|
|
||||||
|
void toggleNot();
|
||||||
|
/// Togless the NOT operator for this filter;
|
||||||
|
|
||||||
|
bool isNot() const;
|
||||||
|
/// Returns true if filter is NOT-ed, false otherwise.
|
||||||
|
|
||||||
|
bool isEmpty() const;
|
||||||
|
/// Returns true if there is not filtering criteria specified.
|
||||||
|
|
||||||
|
bool isAllowed(std::size_t row) const;
|
||||||
|
/// Returns true if name and value are allowed.
|
||||||
|
|
||||||
|
bool exists(const std::string & name) const;
|
||||||
|
/// Returns true if name is known to this row filter.
|
||||||
|
|
||||||
|
private:
|
||||||
|
RowFilter();
|
||||||
|
RowFilter(const RowFilter &);
|
||||||
|
RowFilter & operator=(const RowFilter &);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
static bool equal(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2);
|
||||||
|
static bool notEqual(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2);
|
||||||
|
static bool less(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2);
|
||||||
|
static bool greater(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2);
|
||||||
|
static bool lessOrEqual(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2);
|
||||||
|
static bool greaterOrEqual(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2);
|
||||||
|
static bool logicalAnd(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2);
|
||||||
|
static bool logicalOr(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2);
|
||||||
|
static bool isNull(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var &);
|
||||||
|
|
||||||
|
static void doCompare(Poco::Dynamic::Var & ret, Poco::Dynamic::Var & val, CompT comp, const ComparisonEntry & ce);
|
||||||
|
|
||||||
|
RecordSet & recordSet() const;
|
||||||
|
|
||||||
|
Comparison getComparison(const std::string & comp) const;
|
||||||
|
|
||||||
|
void rewindRecordSet();
|
||||||
|
|
||||||
|
Comparisons _comparisons;
|
||||||
|
ComparisonMap _comparisonMap;
|
||||||
|
mutable RecordSet * _pRecordSet;
|
||||||
|
Ptr _pParent;
|
||||||
|
FilterMap _filterMap;
|
||||||
|
bool _not;
|
||||||
|
|
||||||
|
friend class RecordSet;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// inlines
|
||||||
|
///
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::has(Ptr pFilter) const
|
||||||
|
{
|
||||||
|
return _filterMap.find(pFilter) != _filterMap.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::isEmpty() const
|
||||||
|
{
|
||||||
|
return _comparisonMap.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::exists(const std::string & name) const
|
||||||
|
{
|
||||||
|
return _comparisonMap.find(name) != _comparisonMap.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void RowFilter::toggleNot()
|
||||||
|
{
|
||||||
|
_not = !_not;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::isNot() const
|
||||||
|
{
|
||||||
|
return _not;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::equal(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2)
|
||||||
|
{
|
||||||
|
return p1 == p2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::notEqual(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2)
|
||||||
|
{
|
||||||
|
return p1 != p2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::less(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2)
|
||||||
|
{
|
||||||
|
return p1 < p2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::greater(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2)
|
||||||
|
{
|
||||||
|
return p1 > p2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::lessOrEqual(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2)
|
||||||
|
{
|
||||||
|
return p1 <= p2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::greaterOrEqual(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2)
|
||||||
|
{
|
||||||
|
return p1 >= p2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::logicalAnd(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2)
|
||||||
|
{
|
||||||
|
return p1 && p2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::logicalOr(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var & p2)
|
||||||
|
{
|
||||||
|
return p1 || p2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowFilter::isNull(const Poco::Dynamic::Var & p1, const Poco::Dynamic::Var &)
|
||||||
|
{
|
||||||
|
return p1.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline bool RowFilter::isEmpty() const
|
|
||||||
{
|
|
||||||
return _comparisonMap.size() == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool RowFilter::exists(const std::string& name) const
|
|
||||||
{
|
|
||||||
return _comparisonMap.find(name) != _comparisonMap.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void RowFilter::toggleNot()
|
|
||||||
{
|
|
||||||
_not = !_not;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool RowFilter::isNot() const
|
|
||||||
{
|
|
||||||
return _not;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool RowFilter::equal(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2)
|
|
||||||
{
|
|
||||||
return p1 == p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool RowFilter::notEqual(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2)
|
|
||||||
{
|
|
||||||
return p1 != p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool RowFilter::less(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2)
|
|
||||||
{
|
|
||||||
return p1 < p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool RowFilter::greater(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2)
|
|
||||||
{
|
|
||||||
return p1 > p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool RowFilter::lessOrEqual(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2)
|
|
||||||
{
|
|
||||||
return p1 <= p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool RowFilter::greaterOrEqual(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2)
|
|
||||||
{
|
|
||||||
return p1 >= p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool RowFilter::logicalAnd(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2)
|
|
||||||
{
|
|
||||||
return p1 && p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool RowFilter::logicalOr(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var& p2)
|
|
||||||
{
|
|
||||||
return p1 || p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool RowFilter::isNull(const Poco::Dynamic::Var& p1, const Poco::Dynamic::Var&)
|
|
||||||
{
|
|
||||||
return p1.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_RowFilter_INCLUDED
|
#endif // Data_RowFilter_INCLUDED
|
||||||
|
@ -18,214 +18,214 @@
|
|||||||
#define Data_RowFormatter_INCLUDED
|
#define Data_RowFormatter_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
|
||||||
#include "Poco/SharedPtr.h"
|
|
||||||
#include "Poco/RefCountedObject.h"
|
|
||||||
#include "Poco/Dynamic/Var.h"
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
|
#include "Poco/Dynamic/Var.h"
|
||||||
|
#include "Poco/RefCountedObject.h"
|
||||||
|
#include "Poco/SharedPtr.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API RowFormatter
|
|
||||||
/// Row formatter is an abstract class providing definition for row formatting functionality.
|
|
||||||
/// For custom formatting strategies, inherit from this class and override formatNames()
|
|
||||||
/// and formatValues() member functions.
|
|
||||||
///
|
|
||||||
/// Row formatter can be either passed to the RecordSet at construction time,
|
|
||||||
/// like in the following example:
|
|
||||||
///
|
|
||||||
/// RecordSet rs(session. "SELECT * FROM Table", new MyRowFormater);
|
|
||||||
///
|
|
||||||
/// or it can be supplied to the statement as in the following example:
|
|
||||||
///
|
|
||||||
/// MyRowFormatter rf
|
|
||||||
/// session << "SELECT * FROM Table", format(rf);
|
|
||||||
///
|
|
||||||
/// If no formatter is externally supplied to the statement, the SimpleRowFormatter is used.
|
|
||||||
/// Statement always has the ownership of the row formatter and shares
|
|
||||||
/// it with rows through RecordSet.
|
|
||||||
///
|
|
||||||
/// To accommodate for various formatting needs, a formatter can operate in two modes:
|
|
||||||
///
|
|
||||||
/// - progressive: formatted individual row strings are gemerated and returned from each
|
|
||||||
/// call to formatValues;
|
|
||||||
/// std::string& formatNames(const NameVecPtr, std::string&) and
|
|
||||||
/// std::string& formatValues(const ValueVec&, std::string&) member calls should be
|
|
||||||
/// used in this case; this is the default mode
|
|
||||||
///
|
|
||||||
/// - bulk: formatted resulting string is accumulated internally and obtained at
|
|
||||||
/// the end of iteration via toString() member function;
|
|
||||||
/// void formatNames(const NameVecPtr) and
|
|
||||||
/// void formatValues(const ValueVec&) member calls should be used in this case
|
|
||||||
///
|
|
||||||
/// When formatter is used in conjunction with Row/RecordSet, the formatting members corresponding
|
|
||||||
/// to the formatter mode are expected to be implemented. If a call is propagated to this parent
|
|
||||||
/// class, the functions do nothing or silently return empty string respectively.
|
|
||||||
///
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
typedef SharedPtr<RowFormatter> Ptr;
|
|
||||||
typedef std::vector<std::string> NameVec;
|
|
||||||
typedef SharedPtr<std::vector<std::string> > NameVecPtr;
|
|
||||||
typedef std::vector<Poco::Dynamic::Var> ValueVec;
|
|
||||||
|
|
||||||
static const int INVALID_ROW_COUNT = -1;
|
|
||||||
|
|
||||||
enum Mode
|
|
||||||
{
|
|
||||||
FORMAT_PROGRESSIVE,
|
|
||||||
FORMAT_BULK
|
|
||||||
};
|
|
||||||
|
|
||||||
RowFormatter(const std::string& prefix = "",
|
|
||||||
const std::string& postfix = "",
|
|
||||||
Mode mode = FORMAT_PROGRESSIVE);
|
|
||||||
/// Creates the RowFormatter and sets the prefix and postfix to specified values.
|
|
||||||
|
|
||||||
virtual ~RowFormatter();
|
|
||||||
/// Destroys the RowFormatter.
|
|
||||||
|
|
||||||
virtual std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames);
|
|
||||||
/// Should be implemented to format the row fields names and return the formatted string.
|
|
||||||
/// The default implementation clears the names string and returns it.
|
|
||||||
|
|
||||||
virtual void formatNames(const NameVecPtr pNames);
|
|
||||||
/// Should be implemented to format the row fields names.
|
|
||||||
/// The default implementation does nothing.
|
|
||||||
|
|
||||||
virtual std::string& formatValues(const ValueVec& vals, std::string& formattedValues);
|
|
||||||
/// Should be implemented to format the row fields values and return the formatted string.
|
|
||||||
/// The default implementation clears the values string and returns it.
|
|
||||||
|
|
||||||
virtual void formatValues(const ValueVec& vals);
|
|
||||||
/// Should be implemented to format the row fields values.
|
|
||||||
/// The default implementation does nothing.
|
|
||||||
|
|
||||||
virtual const std::string& toString();
|
|
||||||
/// Throws NotImplementedException. Formatters operating in bulk mode should
|
|
||||||
/// implement this member function to return valid pointer to the formatted result.
|
|
||||||
|
|
||||||
virtual int rowCount() const;
|
|
||||||
/// Returns INVALID_ROW_COUNT. Must be implemented by inheriting classes
|
|
||||||
/// which maintain count of processed rows.
|
|
||||||
|
|
||||||
int getTotalRowCount() const;
|
|
||||||
/// Returns zero. Must be implemented by inheriting classes.
|
|
||||||
/// Typically, total row count shall be set up front through
|
|
||||||
/// setTotalRowCount() call.
|
|
||||||
|
|
||||||
void setTotalRowCount(int count);
|
|
||||||
/// Sets total row count.
|
|
||||||
|
|
||||||
virtual const std::string& prefix() const;
|
|
||||||
/// Returns prefix string;
|
|
||||||
|
|
||||||
virtual const std::string& postfix() const;
|
|
||||||
/// Returns postfix string;
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
/// Resets the formatter by setting prefix and postfix
|
|
||||||
/// to empty strings and row count to INVALID_ROW_COUNT.
|
|
||||||
|
|
||||||
Mode getMode() const;
|
|
||||||
/// Returns the formatter mo
|
|
||||||
|
|
||||||
void setMode(Mode mode);
|
|
||||||
/// Sets the fromatter mode.
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void setPrefix(const std::string& prefix);
|
|
||||||
/// Sets the prefix for the formatter.
|
|
||||||
|
|
||||||
void setPostfix(const std::string& postfix);
|
|
||||||
/// Sets the postfix for the formatter
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
mutable std::string _prefix;
|
|
||||||
mutable std::string _postfix;
|
|
||||||
Mode _mode;
|
|
||||||
int _totalRowCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// inlines
|
|
||||||
///
|
|
||||||
inline int RowFormatter::rowCount() const
|
|
||||||
{
|
{
|
||||||
return INVALID_ROW_COUNT;
|
|
||||||
|
|
||||||
|
class Data_API RowFormatter
|
||||||
|
/// Row formatter is an abstract class providing definition for row formatting functionality.
|
||||||
|
/// For custom formatting strategies, inherit from this class and override formatNames()
|
||||||
|
/// and formatValues() member functions.
|
||||||
|
///
|
||||||
|
/// Row formatter can be either passed to the RecordSet at construction time,
|
||||||
|
/// like in the following example:
|
||||||
|
///
|
||||||
|
/// RecordSet rs(session. "SELECT * FROM Table", new MyRowFormater);
|
||||||
|
///
|
||||||
|
/// or it can be supplied to the statement as in the following example:
|
||||||
|
///
|
||||||
|
/// MyRowFormatter rf
|
||||||
|
/// session << "SELECT * FROM Table", format(rf);
|
||||||
|
///
|
||||||
|
/// If no formatter is externally supplied to the statement, the SimpleRowFormatter is used.
|
||||||
|
/// Statement always has the ownership of the row formatter and shares
|
||||||
|
/// it with rows through RecordSet.
|
||||||
|
///
|
||||||
|
/// To accommodate for various formatting needs, a formatter can operate in two modes:
|
||||||
|
///
|
||||||
|
/// - progressive: formatted individual row strings are gemerated and returned from each
|
||||||
|
/// call to formatValues;
|
||||||
|
/// std::string& formatNames(const NameVecPtr, std::string&) and
|
||||||
|
/// std::string& formatValues(const ValueVec&, std::string&) member calls should be
|
||||||
|
/// used in this case; this is the default mode
|
||||||
|
///
|
||||||
|
/// - bulk: formatted resulting string is accumulated internally and obtained at
|
||||||
|
/// the end of iteration via toString() member function;
|
||||||
|
/// void formatNames(const NameVecPtr) and
|
||||||
|
/// void formatValues(const ValueVec&) member calls should be used in this case
|
||||||
|
///
|
||||||
|
/// When formatter is used in conjunction with Row/RecordSet, the formatting members corresponding
|
||||||
|
/// to the formatter mode are expected to be implemented. If a call is propagated to this parent
|
||||||
|
/// class, the functions do nothing or silently return empty string respectively.
|
||||||
|
///
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef SharedPtr<RowFormatter> Ptr;
|
||||||
|
typedef std::vector<std::string> NameVec;
|
||||||
|
typedef SharedPtr<std::vector<std::string>> NameVecPtr;
|
||||||
|
typedef std::vector<Poco::Dynamic::Var> ValueVec;
|
||||||
|
|
||||||
|
static const int INVALID_ROW_COUNT = -1;
|
||||||
|
|
||||||
|
enum Mode
|
||||||
|
{
|
||||||
|
FORMAT_PROGRESSIVE,
|
||||||
|
FORMAT_BULK
|
||||||
|
};
|
||||||
|
|
||||||
|
RowFormatter(const std::string & prefix = "", const std::string & postfix = "", Mode mode = FORMAT_PROGRESSIVE);
|
||||||
|
/// Creates the RowFormatter and sets the prefix and postfix to specified values.
|
||||||
|
|
||||||
|
virtual ~RowFormatter();
|
||||||
|
/// Destroys the RowFormatter.
|
||||||
|
|
||||||
|
virtual std::string & formatNames(const NameVecPtr pNames, std::string & formattedNames);
|
||||||
|
/// Should be implemented to format the row fields names and return the formatted string.
|
||||||
|
/// The default implementation clears the names string and returns it.
|
||||||
|
|
||||||
|
virtual void formatNames(const NameVecPtr pNames);
|
||||||
|
/// Should be implemented to format the row fields names.
|
||||||
|
/// The default implementation does nothing.
|
||||||
|
|
||||||
|
virtual std::string & formatValues(const ValueVec & vals, std::string & formattedValues);
|
||||||
|
/// Should be implemented to format the row fields values and return the formatted string.
|
||||||
|
/// The default implementation clears the values string and returns it.
|
||||||
|
|
||||||
|
virtual void formatValues(const ValueVec & vals);
|
||||||
|
/// Should be implemented to format the row fields values.
|
||||||
|
/// The default implementation does nothing.
|
||||||
|
|
||||||
|
virtual const std::string & toString();
|
||||||
|
/// Throws NotImplementedException. Formatters operating in bulk mode should
|
||||||
|
/// implement this member function to return valid pointer to the formatted result.
|
||||||
|
|
||||||
|
virtual int rowCount() const;
|
||||||
|
/// Returns INVALID_ROW_COUNT. Must be implemented by inheriting classes
|
||||||
|
/// which maintain count of processed rows.
|
||||||
|
|
||||||
|
int getTotalRowCount() const;
|
||||||
|
/// Returns zero. Must be implemented by inheriting classes.
|
||||||
|
/// Typically, total row count shall be set up front through
|
||||||
|
/// setTotalRowCount() call.
|
||||||
|
|
||||||
|
void setTotalRowCount(int count);
|
||||||
|
/// Sets total row count.
|
||||||
|
|
||||||
|
virtual const std::string & prefix() const;
|
||||||
|
/// Returns prefix string;
|
||||||
|
|
||||||
|
virtual const std::string & postfix() const;
|
||||||
|
/// Returns postfix string;
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
/// Resets the formatter by setting prefix and postfix
|
||||||
|
/// to empty strings and row count to INVALID_ROW_COUNT.
|
||||||
|
|
||||||
|
Mode getMode() const;
|
||||||
|
/// Returns the formatter mo
|
||||||
|
|
||||||
|
void setMode(Mode mode);
|
||||||
|
/// Sets the fromatter mode.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setPrefix(const std::string & prefix);
|
||||||
|
/// Sets the prefix for the formatter.
|
||||||
|
|
||||||
|
void setPostfix(const std::string & postfix);
|
||||||
|
/// Sets the postfix for the formatter
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable std::string _prefix;
|
||||||
|
mutable std::string _postfix;
|
||||||
|
Mode _mode;
|
||||||
|
int _totalRowCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// inlines
|
||||||
|
///
|
||||||
|
inline int RowFormatter::rowCount() const
|
||||||
|
{
|
||||||
|
return INVALID_ROW_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int RowFormatter::getTotalRowCount() const
|
||||||
|
{
|
||||||
|
return _totalRowCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void RowFormatter::setTotalRowCount(int count)
|
||||||
|
{
|
||||||
|
_totalRowCount = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void RowFormatter::setPrefix(const std::string & prefix)
|
||||||
|
{
|
||||||
|
_prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void RowFormatter::setPostfix(const std::string & postfix)
|
||||||
|
{
|
||||||
|
_postfix = postfix;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const std::string & RowFormatter::prefix() const
|
||||||
|
{
|
||||||
|
return _prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const std::string & RowFormatter::postfix() const
|
||||||
|
{
|
||||||
|
return _postfix;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline RowFormatter::Mode RowFormatter::getMode() const
|
||||||
|
{
|
||||||
|
return _mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void RowFormatter::setMode(Mode mode)
|
||||||
|
{
|
||||||
|
_mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace Keywords
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline RowFormatter::Ptr format(const T & formatter)
|
||||||
|
/// Utility function used to pass formatter to the statement.
|
||||||
|
{
|
||||||
|
return new T(formatter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Keywords
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline int RowFormatter::getTotalRowCount() const
|
|
||||||
{
|
|
||||||
return _totalRowCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void RowFormatter::setTotalRowCount(int count)
|
|
||||||
{
|
|
||||||
_totalRowCount = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void RowFormatter::setPrefix(const std::string& prefix)
|
|
||||||
{
|
|
||||||
_prefix = prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void RowFormatter::setPostfix(const std::string& postfix)
|
|
||||||
{
|
|
||||||
_postfix = postfix;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& RowFormatter::prefix() const
|
|
||||||
{
|
|
||||||
return _prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& RowFormatter::postfix() const
|
|
||||||
{
|
|
||||||
return _postfix;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline RowFormatter::Mode RowFormatter::getMode() const
|
|
||||||
{
|
|
||||||
return _mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void RowFormatter::setMode(Mode mode)
|
|
||||||
{
|
|
||||||
_mode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace Keywords {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline RowFormatter::Ptr format(const T& formatter)
|
|
||||||
/// Utility function used to pass formatter to the statement.
|
|
||||||
{
|
|
||||||
return new T(formatter);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Keywords
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_RowFormatter_INCLUDED
|
#endif // Data_RowFormatter_INCLUDED
|
||||||
|
@ -18,132 +18,134 @@
|
|||||||
#define Data_RowIterator_INCLUDED
|
#define Data_RowIterator_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/Row.h"
|
#include "Poco/Data/Row.h"
|
||||||
#include "Poco/Dynamic/Var.h"
|
#include "Poco/Dynamic/Var.h"
|
||||||
#include <iterator>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class RecordSet;
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API RowIterator
|
|
||||||
/// RowIterator class.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
typedef std::bidirectional_iterator_tag iterator_category;
|
|
||||||
typedef Row value_type;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
typedef Row* pointer;
|
|
||||||
typedef Row& reference;
|
|
||||||
|
|
||||||
static const std::size_t POSITION_END;
|
|
||||||
/// End position indicator.
|
|
||||||
|
|
||||||
RowIterator(RecordSet* pRecordSet, bool positionEnd);
|
|
||||||
/// Creates the RowIterator and positions it at the end of
|
|
||||||
/// the recordset if positionEnd is true. Otherwise, it is
|
|
||||||
/// positioned at the beginning.
|
|
||||||
|
|
||||||
RowIterator(const RowIterator& other);
|
|
||||||
/// Creates a copy of other RowIterator.
|
|
||||||
|
|
||||||
~RowIterator();
|
|
||||||
/// Destroys the RowIterator.
|
|
||||||
|
|
||||||
RowIterator& operator = (const RowIterator& other);
|
|
||||||
/// Assigns the other RowIterator.
|
|
||||||
|
|
||||||
bool operator == (const RowIterator& other) const;
|
|
||||||
/// Equality operator.
|
|
||||||
|
|
||||||
bool operator != (const RowIterator& other) const;
|
|
||||||
/// Inequality operator.
|
|
||||||
|
|
||||||
Row& operator * () const;
|
|
||||||
/// Returns reference to the current row.
|
|
||||||
|
|
||||||
Row* operator -> () const;
|
|
||||||
/// Returns pointer to the current row.
|
|
||||||
|
|
||||||
const RowIterator& operator ++ () const;
|
|
||||||
/// Advances by one position and returns current position.
|
|
||||||
|
|
||||||
RowIterator operator ++ (int) const;
|
|
||||||
/// Advances by one position and returns copy of the iterator with
|
|
||||||
/// previous current position.
|
|
||||||
|
|
||||||
const RowIterator& operator -- () const;
|
|
||||||
/// Goes back by one position and returns copy of the iterator with
|
|
||||||
/// previous current position.
|
|
||||||
|
|
||||||
RowIterator operator -- (int) const;
|
|
||||||
/// Goes back by one position and returns previous current position.
|
|
||||||
|
|
||||||
RowIterator operator + (std::size_t diff) const;
|
|
||||||
/// Returns a copy the RowIterator advanced by diff positions.
|
|
||||||
|
|
||||||
RowIterator operator - (std::size_t diff) const;
|
|
||||||
/// Returns a copy the RowIterator backed by diff positions.
|
|
||||||
/// Throws RangeException if diff is larger than current position.
|
|
||||||
|
|
||||||
void swap(RowIterator& other);
|
|
||||||
/// Swaps the RowIterator with another one.
|
|
||||||
|
|
||||||
private:
|
|
||||||
RowIterator();
|
|
||||||
|
|
||||||
void increment() const;
|
|
||||||
/// Increments the iterator position by one.
|
|
||||||
/// Throws RangeException if position is out of range.
|
|
||||||
|
|
||||||
void decrement() const;
|
|
||||||
/// Decrements the iterator position by one.
|
|
||||||
/// Throws RangeException if position is out of range.
|
|
||||||
|
|
||||||
void setPosition(std::size_t pos) const;
|
|
||||||
/// Sets the iterator position.
|
|
||||||
/// Throws RangeException if position is out of range.
|
|
||||||
|
|
||||||
RecordSet* _pRecordSet;
|
|
||||||
mutable std::size_t _position;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// inlines
|
|
||||||
///
|
|
||||||
|
|
||||||
|
|
||||||
inline bool RowIterator::operator == (const RowIterator& other) const
|
|
||||||
{
|
{
|
||||||
return _pRecordSet == other._pRecordSet && _position == other._position;
|
|
||||||
|
|
||||||
|
class RecordSet;
|
||||||
|
|
||||||
|
|
||||||
|
class Data_API RowIterator
|
||||||
|
/// RowIterator class.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::bidirectional_iterator_tag iterator_category;
|
||||||
|
typedef Row value_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
typedef Row * pointer;
|
||||||
|
typedef Row & reference;
|
||||||
|
|
||||||
|
static const std::size_t POSITION_END;
|
||||||
|
/// End position indicator.
|
||||||
|
|
||||||
|
RowIterator(RecordSet * pRecordSet, bool positionEnd);
|
||||||
|
/// Creates the RowIterator and positions it at the end of
|
||||||
|
/// the recordset if positionEnd is true. Otherwise, it is
|
||||||
|
/// positioned at the beginning.
|
||||||
|
|
||||||
|
RowIterator(const RowIterator & other);
|
||||||
|
/// Creates a copy of other RowIterator.
|
||||||
|
|
||||||
|
~RowIterator();
|
||||||
|
/// Destroys the RowIterator.
|
||||||
|
|
||||||
|
RowIterator & operator=(const RowIterator & other);
|
||||||
|
/// Assigns the other RowIterator.
|
||||||
|
|
||||||
|
bool operator==(const RowIterator & other) const;
|
||||||
|
/// Equality operator.
|
||||||
|
|
||||||
|
bool operator!=(const RowIterator & other) const;
|
||||||
|
/// Inequality operator.
|
||||||
|
|
||||||
|
Row & operator*() const;
|
||||||
|
/// Returns reference to the current row.
|
||||||
|
|
||||||
|
Row * operator->() const;
|
||||||
|
/// Returns pointer to the current row.
|
||||||
|
|
||||||
|
const RowIterator & operator++() const;
|
||||||
|
/// Advances by one position and returns current position.
|
||||||
|
|
||||||
|
RowIterator operator++(int) const;
|
||||||
|
/// Advances by one position and returns copy of the iterator with
|
||||||
|
/// previous current position.
|
||||||
|
|
||||||
|
const RowIterator & operator--() const;
|
||||||
|
/// Goes back by one position and returns copy of the iterator with
|
||||||
|
/// previous current position.
|
||||||
|
|
||||||
|
RowIterator operator--(int) const;
|
||||||
|
/// Goes back by one position and returns previous current position.
|
||||||
|
|
||||||
|
RowIterator operator+(std::size_t diff) const;
|
||||||
|
/// Returns a copy the RowIterator advanced by diff positions.
|
||||||
|
|
||||||
|
RowIterator operator-(std::size_t diff) const;
|
||||||
|
/// Returns a copy the RowIterator backed by diff positions.
|
||||||
|
/// Throws RangeException if diff is larger than current position.
|
||||||
|
|
||||||
|
void swap(RowIterator & other);
|
||||||
|
/// Swaps the RowIterator with another one.
|
||||||
|
|
||||||
|
private:
|
||||||
|
RowIterator();
|
||||||
|
|
||||||
|
void increment() const;
|
||||||
|
/// Increments the iterator position by one.
|
||||||
|
/// Throws RangeException if position is out of range.
|
||||||
|
|
||||||
|
void decrement() const;
|
||||||
|
/// Decrements the iterator position by one.
|
||||||
|
/// Throws RangeException if position is out of range.
|
||||||
|
|
||||||
|
void setPosition(std::size_t pos) const;
|
||||||
|
/// Sets the iterator position.
|
||||||
|
/// Throws RangeException if position is out of range.
|
||||||
|
|
||||||
|
RecordSet * _pRecordSet;
|
||||||
|
mutable std::size_t _position;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// inlines
|
||||||
|
///
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowIterator::operator==(const RowIterator & other) const
|
||||||
|
{
|
||||||
|
return _pRecordSet == other._pRecordSet && _position == other._position;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RowIterator::operator!=(const RowIterator & other) const
|
||||||
|
{
|
||||||
|
return _pRecordSet != other._pRecordSet || _position != other._position;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline bool RowIterator::operator != (const RowIterator& other) const
|
|
||||||
{
|
|
||||||
return _pRecordSet != other._pRecordSet || _position != other._position;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
template<>
|
template <>
|
||||||
inline void swap<Poco::Data::RowIterator>(Poco::Data::RowIterator& s1,
|
inline void swap<Poco::Data::RowIterator>(Poco::Data::RowIterator & s1, Poco::Data::RowIterator & s2)
|
||||||
Poco::Data::RowIterator& s2)
|
/// Full template specalization of std:::swap for RowIterator
|
||||||
/// Full template specalization of std:::swap for RowIterator
|
{
|
||||||
{
|
s1.swap(s2);
|
||||||
s1.swap(s2);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,200 +18,199 @@
|
|||||||
#define Data_SQLChannel_INCLUDED
|
#define Data_SQLChannel_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
#include "Poco/AutoPtr.h"
|
||||||
|
#include "Poco/Channel.h"
|
||||||
|
#include "Poco/Data/ArchiveStrategy.h"
|
||||||
#include "Poco/Data/Connector.h"
|
#include "Poco/Data/Connector.h"
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/Session.h"
|
#include "Poco/Data/Session.h"
|
||||||
#include "Poco/Data/Statement.h"
|
#include "Poco/Data/Statement.h"
|
||||||
#include "Poco/Data/ArchiveStrategy.h"
|
|
||||||
#include "Poco/Channel.h"
|
|
||||||
#include "Poco/Message.h"
|
#include "Poco/Message.h"
|
||||||
#include "Poco/AutoPtr.h"
|
|
||||||
#include "Poco/String.h"
|
#include "Poco/String.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API SQLChannel: public Poco::Channel
|
|
||||||
/// This Channel implements logging to a SQL database.
|
|
||||||
/// The channel is dependent on the schema. The DDL for
|
|
||||||
/// table creation (subject to target DDL dialect dependent
|
|
||||||
/// modifications) is:
|
|
||||||
///
|
|
||||||
/// "CREATE TABLE T_POCO_LOG (Source VARCHAR,
|
|
||||||
/// Name VARCHAR,
|
|
||||||
/// ProcessId INTEGER,
|
|
||||||
/// Thread VARCHAR,
|
|
||||||
/// ThreadId INTEGER,
|
|
||||||
/// Priority INTEGER,
|
|
||||||
/// Text VARCHAR,
|
|
||||||
/// DateTime DATE)"
|
|
||||||
///
|
|
||||||
/// The table name is configurable through "table" property.
|
|
||||||
/// Other than DateTime filed name used for optiona time-based archiving purposes, currently the
|
|
||||||
/// field names are not mandated. However, it is recommended to use names as specified above.
|
|
||||||
///
|
|
||||||
/// To provide as non-intrusive operation as possible, the log entries are cached and
|
|
||||||
/// inserted into the target database asynchronously by default . The blocking, however, will occur
|
|
||||||
/// before the next entry insertion with default timeout of 1 second. The default settings can be
|
|
||||||
/// overridden (see async, timeout and throw properties for details).
|
|
||||||
/// If throw property is false, insertion timeouts are ignored, otherwise a TimeoutException is thrown.
|
|
||||||
/// To force insertion of every entry, set timeout to 0. This setting, however, introduces
|
|
||||||
/// a risk of long blocking periods in case of remote server communication delays.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
SQLChannel();
|
|
||||||
/// Creates SQLChannel.
|
|
||||||
|
|
||||||
SQLChannel(const std::string& connector,
|
|
||||||
const std::string& connect,
|
|
||||||
const std::string& name = "-");
|
|
||||||
/// Creates a SQLChannel with the given connector, connect string, timeout, table and name.
|
|
||||||
/// The connector must be already registered.
|
|
||||||
|
|
||||||
void open();
|
|
||||||
/// Opens the SQLChannel.
|
|
||||||
|
|
||||||
void close();
|
|
||||||
/// Closes the SQLChannel.
|
|
||||||
|
|
||||||
void log(const Message& msg);
|
|
||||||
/// Sends the message's text to the syslog service.
|
|
||||||
|
|
||||||
void setProperty(const std::string& name, const std::string& value);
|
|
||||||
/// Sets the property with the given value.
|
|
||||||
///
|
|
||||||
/// The following properties are supported:
|
|
||||||
/// * name: The name used to identify the source of log messages.
|
|
||||||
/// Defaults to "-".
|
|
||||||
///
|
|
||||||
/// * target: The target data storage type ("SQLite", "ODBC", ...).
|
|
||||||
///
|
|
||||||
/// * connector: The target data storage connector name.
|
|
||||||
///
|
|
||||||
/// * connect: The target data storage connection string.
|
|
||||||
///
|
|
||||||
/// * table: Destination log table name. Defaults to "T_POCO_LOG".
|
|
||||||
/// Table must exist in the target database.
|
|
||||||
///
|
|
||||||
/// * keep: Max row age for the log table. To disable archiving,
|
|
||||||
/// set this property to empty string or "forever".
|
|
||||||
///
|
|
||||||
/// * archive: Archive table name. Defaults to "T_POCO_LOG_ARCHIVE".
|
|
||||||
/// Table must exist in the target database. To disable archiving,
|
|
||||||
/// set this property to empty string.
|
|
||||||
///
|
|
||||||
/// * async: Indicates asynchronous execution. When executing asynchronously,
|
|
||||||
/// messages are sent to the target using asynchronous execution.
|
|
||||||
/// However, prior to the next message being processed and sent to
|
|
||||||
/// the target, the previous operation must have been either completed
|
|
||||||
/// or timed out (see timeout and throw properties for details on
|
|
||||||
/// how abnormal conditos are handled).
|
|
||||||
///
|
|
||||||
/// * timeout: Timeout (ms) to wait for previous log operation completion.
|
|
||||||
/// Values "0" and "" mean no timeout. Only valid when logging
|
|
||||||
/// is asynchronous, otherwise ignored.
|
|
||||||
///
|
|
||||||
/// * throw: Boolean value indicating whether to throw in case of timeout.
|
|
||||||
/// Setting this property to false may result in log entries being lost.
|
|
||||||
/// True values are (case insensitive) "true", "t", "yes", "y".
|
|
||||||
/// Anything else yields false.
|
|
||||||
|
|
||||||
std::string getProperty(const std::string& name) const;
|
|
||||||
/// Returns the value of the property with the given name.
|
|
||||||
|
|
||||||
std::size_t wait();
|
|
||||||
/// Waits for the completion of the previous operation and returns
|
|
||||||
/// the result. If channel is in synchronous mode, returns 0 immediately.
|
|
||||||
|
|
||||||
static void registerChannel();
|
|
||||||
/// Registers the channel with the global LoggingFactory.
|
|
||||||
|
|
||||||
static const std::string PROP_CONNECT;
|
|
||||||
static const std::string PROP_CONNECTOR;
|
|
||||||
static const std::string PROP_NAME;
|
|
||||||
static const std::string PROP_TABLE;
|
|
||||||
static const std::string PROP_ARCHIVE_TABLE;
|
|
||||||
static const std::string PROP_MAX_AGE;
|
|
||||||
static const std::string PROP_ASYNC;
|
|
||||||
static const std::string PROP_TIMEOUT;
|
|
||||||
static const std::string PROP_THROW;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
~SQLChannel();
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef Poco::SharedPtr<Session> SessionPtr;
|
|
||||||
typedef Poco::SharedPtr<Statement> StatementPtr;
|
|
||||||
typedef Poco::Message::Priority Priority;
|
|
||||||
typedef Poco::SharedPtr<ArchiveStrategy> StrategyPtr;
|
|
||||||
|
|
||||||
void initLogStatement();
|
|
||||||
/// Initiallizes the log statement.
|
|
||||||
|
|
||||||
void initArchiveStatements();
|
|
||||||
/// Initiallizes the archive statement.
|
|
||||||
|
|
||||||
void logAsync(const Message& msg);
|
|
||||||
/// Waits for previous operation completion and
|
|
||||||
/// calls logSync(). If the previous operation times out,
|
|
||||||
/// and _throw is true, TimeoutException is thrown, otherwise
|
|
||||||
/// the timeout is ignored and log entry is lost.
|
|
||||||
|
|
||||||
void logSync(const Message& msg);
|
|
||||||
/// Inserts the message in the target database.
|
|
||||||
|
|
||||||
bool isTrue(const std::string& value) const;
|
|
||||||
/// Returns true is value is "true", "t", "yes" or "y".
|
|
||||||
/// Case insensitive.
|
|
||||||
|
|
||||||
std::string _connector;
|
|
||||||
std::string _connect;
|
|
||||||
SessionPtr _pSession;
|
|
||||||
StatementPtr _pLogStatement;
|
|
||||||
std::string _name;
|
|
||||||
std::string _table;
|
|
||||||
int _timeout;
|
|
||||||
bool _throw;
|
|
||||||
bool _async;
|
|
||||||
|
|
||||||
// members for log entry cache (needed for async mode)
|
|
||||||
std::string _source;
|
|
||||||
long _pid;
|
|
||||||
std::string _thread;
|
|
||||||
long _tid;
|
|
||||||
int _priority;
|
|
||||||
std::string _text;
|
|
||||||
DateTime _dateTime;
|
|
||||||
|
|
||||||
StrategyPtr _pArchiveStrategy;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
|
|
||||||
inline std::size_t SQLChannel::wait()
|
|
||||||
{
|
{
|
||||||
if (_async && _pLogStatement)
|
|
||||||
return _pLogStatement->wait(_timeout);
|
|
||||||
|
class Data_API SQLChannel : public Poco::Channel
|
||||||
return 0;
|
/// This Channel implements logging to a SQL database.
|
||||||
|
/// The channel is dependent on the schema. The DDL for
|
||||||
|
/// table creation (subject to target DDL dialect dependent
|
||||||
|
/// modifications) is:
|
||||||
|
///
|
||||||
|
/// "CREATE TABLE T_POCO_LOG (Source VARCHAR,
|
||||||
|
/// Name VARCHAR,
|
||||||
|
/// ProcessId INTEGER,
|
||||||
|
/// Thread VARCHAR,
|
||||||
|
/// ThreadId INTEGER,
|
||||||
|
/// Priority INTEGER,
|
||||||
|
/// Text VARCHAR,
|
||||||
|
/// DateTime DATE)"
|
||||||
|
///
|
||||||
|
/// The table name is configurable through "table" property.
|
||||||
|
/// Other than DateTime filed name used for optiona time-based archiving purposes, currently the
|
||||||
|
/// field names are not mandated. However, it is recommended to use names as specified above.
|
||||||
|
///
|
||||||
|
/// To provide as non-intrusive operation as possible, the log entries are cached and
|
||||||
|
/// inserted into the target database asynchronously by default . The blocking, however, will occur
|
||||||
|
/// before the next entry insertion with default timeout of 1 second. The default settings can be
|
||||||
|
/// overridden (see async, timeout and throw properties for details).
|
||||||
|
/// If throw property is false, insertion timeouts are ignored, otherwise a TimeoutException is thrown.
|
||||||
|
/// To force insertion of every entry, set timeout to 0. This setting, however, introduces
|
||||||
|
/// a risk of long blocking periods in case of remote server communication delays.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SQLChannel();
|
||||||
|
/// Creates SQLChannel.
|
||||||
|
|
||||||
|
SQLChannel(const std::string & connector, const std::string & connect, const std::string & name = "-");
|
||||||
|
/// Creates a SQLChannel with the given connector, connect string, timeout, table and name.
|
||||||
|
/// The connector must be already registered.
|
||||||
|
|
||||||
|
void open();
|
||||||
|
/// Opens the SQLChannel.
|
||||||
|
|
||||||
|
void close();
|
||||||
|
/// Closes the SQLChannel.
|
||||||
|
|
||||||
|
void log(const Message & msg);
|
||||||
|
/// Sends the message's text to the syslog service.
|
||||||
|
|
||||||
|
void setProperty(const std::string & name, const std::string & value);
|
||||||
|
/// Sets the property with the given value.
|
||||||
|
///
|
||||||
|
/// The following properties are supported:
|
||||||
|
/// * name: The name used to identify the source of log messages.
|
||||||
|
/// Defaults to "-".
|
||||||
|
///
|
||||||
|
/// * target: The target data storage type ("SQLite", "ODBC", ...).
|
||||||
|
///
|
||||||
|
/// * connector: The target data storage connector name.
|
||||||
|
///
|
||||||
|
/// * connect: The target data storage connection string.
|
||||||
|
///
|
||||||
|
/// * table: Destination log table name. Defaults to "T_POCO_LOG".
|
||||||
|
/// Table must exist in the target database.
|
||||||
|
///
|
||||||
|
/// * keep: Max row age for the log table. To disable archiving,
|
||||||
|
/// set this property to empty string or "forever".
|
||||||
|
///
|
||||||
|
/// * archive: Archive table name. Defaults to "T_POCO_LOG_ARCHIVE".
|
||||||
|
/// Table must exist in the target database. To disable archiving,
|
||||||
|
/// set this property to empty string.
|
||||||
|
///
|
||||||
|
/// * async: Indicates asynchronous execution. When executing asynchronously,
|
||||||
|
/// messages are sent to the target using asynchronous execution.
|
||||||
|
/// However, prior to the next message being processed and sent to
|
||||||
|
/// the target, the previous operation must have been either completed
|
||||||
|
/// or timed out (see timeout and throw properties for details on
|
||||||
|
/// how abnormal conditos are handled).
|
||||||
|
///
|
||||||
|
/// * timeout: Timeout (ms) to wait for previous log operation completion.
|
||||||
|
/// Values "0" and "" mean no timeout. Only valid when logging
|
||||||
|
/// is asynchronous, otherwise ignored.
|
||||||
|
///
|
||||||
|
/// * throw: Boolean value indicating whether to throw in case of timeout.
|
||||||
|
/// Setting this property to false may result in log entries being lost.
|
||||||
|
/// True values are (case insensitive) "true", "t", "yes", "y".
|
||||||
|
/// Anything else yields false.
|
||||||
|
|
||||||
|
std::string getProperty(const std::string & name) const;
|
||||||
|
/// Returns the value of the property with the given name.
|
||||||
|
|
||||||
|
std::size_t wait();
|
||||||
|
/// Waits for the completion of the previous operation and returns
|
||||||
|
/// the result. If channel is in synchronous mode, returns 0 immediately.
|
||||||
|
|
||||||
|
static void registerChannel();
|
||||||
|
/// Registers the channel with the global LoggingFactory.
|
||||||
|
|
||||||
|
static const std::string PROP_CONNECT;
|
||||||
|
static const std::string PROP_CONNECTOR;
|
||||||
|
static const std::string PROP_NAME;
|
||||||
|
static const std::string PROP_TABLE;
|
||||||
|
static const std::string PROP_ARCHIVE_TABLE;
|
||||||
|
static const std::string PROP_MAX_AGE;
|
||||||
|
static const std::string PROP_ASYNC;
|
||||||
|
static const std::string PROP_TIMEOUT;
|
||||||
|
static const std::string PROP_THROW;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
~SQLChannel();
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef Poco::SharedPtr<Session> SessionPtr;
|
||||||
|
typedef Poco::SharedPtr<Statement> StatementPtr;
|
||||||
|
typedef Poco::Message::Priority Priority;
|
||||||
|
typedef Poco::SharedPtr<ArchiveStrategy> StrategyPtr;
|
||||||
|
|
||||||
|
void initLogStatement();
|
||||||
|
/// Initiallizes the log statement.
|
||||||
|
|
||||||
|
void initArchiveStatements();
|
||||||
|
/// Initiallizes the archive statement.
|
||||||
|
|
||||||
|
void logAsync(const Message & msg);
|
||||||
|
/// Waits for previous operation completion and
|
||||||
|
/// calls logSync(). If the previous operation times out,
|
||||||
|
/// and _throw is true, TimeoutException is thrown, otherwise
|
||||||
|
/// the timeout is ignored and log entry is lost.
|
||||||
|
|
||||||
|
void logSync(const Message & msg);
|
||||||
|
/// Inserts the message in the target database.
|
||||||
|
|
||||||
|
bool isTrue(const std::string & value) const;
|
||||||
|
/// Returns true is value is "true", "t", "yes" or "y".
|
||||||
|
/// Case insensitive.
|
||||||
|
|
||||||
|
std::string _connector;
|
||||||
|
std::string _connect;
|
||||||
|
SessionPtr _pSession;
|
||||||
|
StatementPtr _pLogStatement;
|
||||||
|
std::string _name;
|
||||||
|
std::string _table;
|
||||||
|
int _timeout;
|
||||||
|
bool _throw;
|
||||||
|
bool _async;
|
||||||
|
|
||||||
|
// members for log entry cache (needed for async mode)
|
||||||
|
std::string _source;
|
||||||
|
long _pid;
|
||||||
|
std::string _thread;
|
||||||
|
long _tid;
|
||||||
|
int _priority;
|
||||||
|
std::string _text;
|
||||||
|
DateTime _dateTime;
|
||||||
|
|
||||||
|
StrategyPtr _pArchiveStrategy;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
|
||||||
|
inline std::size_t SQLChannel::wait()
|
||||||
|
{
|
||||||
|
if (_async && _pLogStatement)
|
||||||
|
return _pLogStatement->wait(_timeout);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool SQLChannel::isTrue(const std::string & value) const
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(0 == icompare(value, "true")) || (0 == icompare(value, "t")) || (0 == icompare(value, "yes")) || (0 == icompare(value, "y")));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline bool SQLChannel::isTrue(const std::string& value) const
|
|
||||||
{
|
|
||||||
return ((0 == icompare(value, "true")) ||
|
|
||||||
(0 == icompare(value, "t")) ||
|
|
||||||
(0 == icompare(value, "yes")) ||
|
|
||||||
(0 == icompare(value, "y")));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_SQLChannel_INCLUDED
|
#endif // Data_SQLChannel_INCLUDED
|
||||||
|
@ -18,476 +18,473 @@
|
|||||||
#define Data_Session_INCLUDED
|
#define Data_Session_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include "Poco/Any.h"
|
||||||
|
#include "Poco/AutoPtr.h"
|
||||||
|
#include "Poco/Data/Binding.h"
|
||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/SessionImpl.h"
|
#include "Poco/Data/SessionImpl.h"
|
||||||
#include "Poco/Data/Statement.h"
|
#include "Poco/Data/Statement.h"
|
||||||
#include "Poco/Data/StatementCreator.h"
|
#include "Poco/Data/StatementCreator.h"
|
||||||
#include "Poco/Data/Binding.h"
|
|
||||||
#include "Poco/AutoPtr.h"
|
|
||||||
#include "Poco/Any.h"
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class StatementImpl;
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API Session
|
|
||||||
/// A Session holds a connection to a Database and creates Statement objects.
|
|
||||||
///
|
|
||||||
/// Sessions are always created via the SessionFactory:
|
|
||||||
///
|
|
||||||
/// Session ses(SessionFactory::instance().create(connectorKey, connectionString));
|
|
||||||
///
|
|
||||||
/// where the first param presents the type of session one wants to create (e.g., for SQLite one would choose "SQLite",
|
|
||||||
/// for ODBC the key is "ODBC") and the second param is the connection string that the session implementation
|
|
||||||
/// requires to connect to the database. The format of the connection string is specific to the actual connector.
|
|
||||||
///
|
|
||||||
/// A simpler form to create the session is to pass the connector key and connection string directly to
|
|
||||||
/// the Session constructor.
|
|
||||||
///
|
|
||||||
/// A concrete example to open an SQLite database stored in the file "dummy.db" would be
|
|
||||||
///
|
|
||||||
/// Session ses("SQLite", "dummy.db");
|
|
||||||
///
|
|
||||||
/// Via a Session one can create two different types of statements. First, statements that should only be executed once and immediately, and
|
|
||||||
/// second, statements that should be executed multiple times, using a separate execute() call.
|
|
||||||
/// The simple one is immediate execution:
|
|
||||||
///
|
|
||||||
/// ses << "CREATE TABLE Dummy (data INTEGER(10))", now;
|
|
||||||
///
|
|
||||||
/// The now at the end of the statement is required, otherwise the statement
|
|
||||||
/// would not be executed.
|
|
||||||
///
|
|
||||||
/// If one wants to reuse a Statement (and avoid the overhead of repeatedly parsing an SQL statement)
|
|
||||||
/// one uses an explicit Statement object and its execute() method:
|
|
||||||
///
|
|
||||||
/// int i = 0;
|
|
||||||
/// Statement stmt = (ses << "INSERT INTO Dummy VALUES(:data)", use(i));
|
|
||||||
///
|
|
||||||
/// for (i = 0; i < 100; ++i)
|
|
||||||
/// {
|
|
||||||
/// stmt.execute();
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// The above example assigns the variable i to the ":data" placeholder in the SQL query. The query is parsed and compiled exactly
|
|
||||||
/// once, but executed 100 times. At the end the values 0 to 99 will be present in the Table "DUMMY".
|
|
||||||
///
|
|
||||||
/// A faster implementation of the above code will simply create a vector of int
|
|
||||||
/// and use the vector as parameter to the use clause (you could also use set or multiset instead):
|
|
||||||
///
|
|
||||||
/// std::vector<int> data;
|
|
||||||
/// for (int i = 0; i < 100; ++i)
|
|
||||||
/// {
|
|
||||||
/// data.push_back(i);
|
|
||||||
/// }
|
|
||||||
/// ses << "INSERT INTO Dummy VALUES(:data)", use(data);
|
|
||||||
///
|
|
||||||
/// NEVER try to bind to an empty collection. This will give a BindingException at run-time!
|
|
||||||
///
|
|
||||||
/// Retrieving data from a database works similar, you could use simple data types, vectors, sets or multiset as your targets:
|
|
||||||
///
|
|
||||||
/// std::set<int> retData;
|
|
||||||
/// ses << "SELECT * FROM Dummy", into(retData));
|
|
||||||
///
|
|
||||||
/// Due to the blocking nature of the above call it is possible to partition the data retrieval into chunks by setting a limit to
|
|
||||||
/// the maximum number of rows retrieved from the database:
|
|
||||||
///
|
|
||||||
/// std::set<int> retData;
|
|
||||||
/// Statement stmt = (ses << "SELECT * FROM Dummy", into(retData), limit(50));
|
|
||||||
/// while (!stmt.done())
|
|
||||||
/// {
|
|
||||||
/// stmt.execute();
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// The "into" keyword is used to inform the statement where output results should be placed. The limit value ensures
|
|
||||||
/// that during each run at most 50 rows are retrieved. Assuming Dummy contains 100 rows, retData will contain 50
|
|
||||||
/// elements after the first run and 100 after the second run, i.e.
|
|
||||||
/// the collection is not cleared between consecutive runs. After the second execute stmt.done() will return true.
|
|
||||||
///
|
|
||||||
/// A prepared Statement will behave exactly the same but a further call to execute() will simply reset the Statement,
|
|
||||||
/// execute it again and append more data to the result set.
|
|
||||||
///
|
|
||||||
/// Note that it is possible to append several "bind" or "into" clauses to the statement. Theoretically, one could also have several
|
|
||||||
/// limit clauses but only the last one that was added will be effective.
|
|
||||||
/// Also several preconditions must be met concerning binds and intos.
|
|
||||||
/// Take the following example:
|
|
||||||
///
|
|
||||||
/// ses << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))";
|
|
||||||
/// std::vector<std::string> nameVec; // [...] add some elements
|
|
||||||
/// std::vector<int> ageVec; // [...] add some elements
|
|
||||||
/// ses << "INSERT INTO Person (LastName, Age) VALUES(:ln, :age)", use(nameVec), use(ageVec);
|
|
||||||
///
|
|
||||||
/// The size of all use parameters MUST be the same, otherwise an exception is thrown. Furthermore,
|
|
||||||
/// the amount of use clauses must match the number of wildcards in the query (to be more precise:
|
|
||||||
/// each binding has a numberOfColumnsHandled() value which defaults to 1. The sum of all these values
|
|
||||||
/// must match the wildcard count in the query.
|
|
||||||
/// However, this is only important if you have written your own TypeHandler specializations.
|
|
||||||
/// If you plan to map complex object types to tables see the TypeHandler documentation.
|
|
||||||
/// For now, we simply assume we have written one TypeHandler for Person objects. Instead of having n different vectors,
|
|
||||||
/// we have one collection:
|
|
||||||
///
|
|
||||||
/// std::vector<Person> people; // [...] add some elements
|
|
||||||
/// ses << "INSERT INTO Person (LastName, FirstName, Age) VALUES(:ln, :fn, :age)", use(people);
|
|
||||||
///
|
|
||||||
/// which will insert all Person objects from the people vector to the database (and again, you can use set, multiset too,
|
|
||||||
/// even map and multimap if Person provides an operator() which returns the key for the map).
|
|
||||||
/// The same works for a SELECT statement with "into" clauses:
|
|
||||||
///
|
|
||||||
/// std::vector<Person> people;
|
|
||||||
/// ses << "SELECT * FROM PERSON", into(people);
|
|
||||||
///
|
|
||||||
/// Mixing constants or variables with manipulators is allowed provided there are corresponding placeholders for the constants provided in
|
|
||||||
/// the SQL string, such as in following example:
|
|
||||||
///
|
|
||||||
/// std::vector<Person> people;
|
|
||||||
/// ses << "SELECT * FROM %s", into(people), "PERSON";
|
|
||||||
///
|
|
||||||
/// Formatting only kicks in if there are values to be injected into the SQL string, otherwise it is skipped.
|
|
||||||
/// If the formatting will occur and the percent sign is part of the query itself, it can be passed to the query by entering it twice (%%).
|
|
||||||
/// However, if no formatting is used, one percent sign is sufficient as the string will be passed unaltered.
|
|
||||||
/// For complete list of supported data types with their respective specifications, see the documentation for format in Foundation.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
static const std::size_t LOGIN_TIMEOUT_DEFAULT = SessionImpl::LOGIN_TIMEOUT_DEFAULT;
|
|
||||||
static const Poco::UInt32 TRANSACTION_READ_UNCOMMITTED = 0x00000001L;
|
|
||||||
static const Poco::UInt32 TRANSACTION_READ_COMMITTED = 0x00000002L;
|
|
||||||
static const Poco::UInt32 TRANSACTION_REPEATABLE_READ = 0x00000004L;
|
|
||||||
static const Poco::UInt32 TRANSACTION_SERIALIZABLE = 0x00000008L;
|
|
||||||
|
|
||||||
Session(Poco::AutoPtr<SessionImpl> ptrImpl);
|
|
||||||
/// Creates the Session.
|
|
||||||
|
|
||||||
Session(const std::string& connector,
|
|
||||||
const std::string& connectionString,
|
|
||||||
std::size_t timeout = LOGIN_TIMEOUT_DEFAULT);
|
|
||||||
/// Creates a new session, using the given connector (which must have
|
|
||||||
/// been registered), and connectionString.
|
|
||||||
|
|
||||||
Session(const std::string& connection,
|
|
||||||
std::size_t timeout = LOGIN_TIMEOUT_DEFAULT);
|
|
||||||
/// Creates a new session, using the given connection (must be in
|
|
||||||
/// "connection:///connectionString" format).
|
|
||||||
|
|
||||||
Session(const Session&);
|
|
||||||
/// Creates a session by copying another one.
|
|
||||||
|
|
||||||
Session& operator = (const Session&);
|
|
||||||
/// Assignment operator.
|
|
||||||
|
|
||||||
~Session();
|
|
||||||
/// Destroys the Session.
|
|
||||||
|
|
||||||
void swap(Session& other);
|
|
||||||
/// Swaps the session with another one.
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Statement operator << (const T& t)
|
|
||||||
/// Creates a Statement with the given data as SQLContent
|
|
||||||
{
|
|
||||||
return _statementCreator << t;
|
|
||||||
}
|
|
||||||
|
|
||||||
StatementImpl* createStatementImpl();
|
|
||||||
/// Creates a StatementImpl.
|
|
||||||
|
|
||||||
void open(const std::string& connect = "");
|
|
||||||
/// Opens the session using the supplied string.
|
|
||||||
/// Can also be used with default empty string to
|
|
||||||
/// reconnect a disconnected session.
|
|
||||||
/// If the connection is not established,
|
|
||||||
/// a ConnectionFailedException is thrown.
|
|
||||||
/// Zero timeout means indefinite
|
|
||||||
|
|
||||||
void close();
|
|
||||||
/// Closes the session.
|
|
||||||
|
|
||||||
bool isConnected();
|
|
||||||
/// Returns true iff session is connected, false otherwise.
|
|
||||||
|
|
||||||
void reconnect();
|
|
||||||
/// Closes the session and opens it.
|
|
||||||
|
|
||||||
void setLoginTimeout(std::size_t timeout);
|
|
||||||
/// Sets the session login timeout value.
|
|
||||||
|
|
||||||
std::size_t getLoginTimeout() const;
|
|
||||||
/// Returns the session login timeout value.
|
|
||||||
|
|
||||||
void setConnectionTimeout(std::size_t timeout);
|
|
||||||
/// Sets the session connection timeout value.
|
|
||||||
|
|
||||||
std::size_t getConnectionTimeout();
|
|
||||||
/// Returns the session connection timeout value.
|
|
||||||
|
|
||||||
void begin();
|
|
||||||
/// Starts a transaction.
|
|
||||||
|
|
||||||
void commit();
|
|
||||||
/// Commits and ends a transaction.
|
|
||||||
|
|
||||||
void rollback();
|
|
||||||
/// Rolls back and ends a transaction.
|
|
||||||
|
|
||||||
bool canTransact();
|
|
||||||
/// Returns true if session has transaction capabilities.
|
|
||||||
|
|
||||||
bool isTransaction();
|
|
||||||
/// Returns true iff a transaction is in progress, false otherwise.
|
|
||||||
|
|
||||||
void setTransactionIsolation(Poco::UInt32);
|
|
||||||
/// Sets the transaction isolation level.
|
|
||||||
|
|
||||||
Poco::UInt32 getTransactionIsolation();
|
|
||||||
/// Returns the transaction isolation level.
|
|
||||||
|
|
||||||
bool hasTransactionIsolation(Poco::UInt32 ti);
|
|
||||||
/// Returns true iff the transaction isolation level corresponding
|
|
||||||
/// to the supplied bitmask is supported.
|
|
||||||
|
|
||||||
bool isTransactionIsolation(Poco::UInt32 ti);
|
|
||||||
/// Returns true iff the transaction isolation level corresponds
|
|
||||||
/// to the supplied bitmask.
|
|
||||||
|
|
||||||
std::string connector() const;
|
|
||||||
/// Returns the connector name for this session.
|
|
||||||
|
|
||||||
std::string uri() const;
|
|
||||||
/// Returns the URI for this session.
|
|
||||||
|
|
||||||
static std::string uri(const std::string& connector,
|
|
||||||
const std::string& connectionString);
|
|
||||||
/// Utility function that teturns the URI formatted from supplied
|
|
||||||
/// arguments as "connector:///connectionString".
|
|
||||||
|
|
||||||
void setFeature(const std::string& name, bool state);
|
|
||||||
/// Set the state of a feature.
|
|
||||||
///
|
|
||||||
/// Features are a generic extension mechanism for session implementations.
|
|
||||||
/// and are defined by the underlying SessionImpl instance.
|
|
||||||
///
|
|
||||||
/// Throws a NotSupportedException if the requested feature is
|
|
||||||
/// not supported by the underlying implementation.
|
|
||||||
|
|
||||||
bool getFeature(const std::string& name) const;
|
|
||||||
/// Look up the state of a feature.
|
|
||||||
///
|
|
||||||
/// Features are a generic extension mechanism for session implementations.
|
|
||||||
/// and are defined by the underlying SessionImpl instance.
|
|
||||||
///
|
|
||||||
/// Throws a NotSupportedException if the requested feature is
|
|
||||||
/// not supported by the underlying implementation.
|
|
||||||
|
|
||||||
void setProperty(const std::string& name, const Poco::Any& value);
|
|
||||||
/// Set the value of a property.
|
|
||||||
///
|
|
||||||
/// Properties are a generic extension mechanism for session implementations.
|
|
||||||
/// and are defined by the underlying SessionImpl instance.
|
|
||||||
///
|
|
||||||
/// Throws a NotSupportedException if the requested property is
|
|
||||||
/// not supported by the underlying implementation.
|
|
||||||
|
|
||||||
Poco::Any getProperty(const std::string& name) const;
|
|
||||||
/// Look up the value of a property.
|
|
||||||
///
|
|
||||||
/// Properties are a generic extension mechanism for session implementations.
|
|
||||||
/// and are defined by the underlying SessionImpl instance.
|
|
||||||
///
|
|
||||||
/// Throws a NotSupportedException if the requested property is
|
|
||||||
/// not supported by the underlying implementation.
|
|
||||||
|
|
||||||
SessionImpl* impl();
|
|
||||||
/// Returns a pointer to the underlying SessionImpl.
|
|
||||||
|
|
||||||
private:
|
|
||||||
Session();
|
|
||||||
|
|
||||||
Poco::AutoPtr<SessionImpl> _pImpl;
|
|
||||||
StatementCreator _statementCreator;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline StatementImpl* Session::createStatementImpl()
|
|
||||||
{
|
{
|
||||||
return _pImpl->createStatementImpl();
|
|
||||||
|
|
||||||
|
class StatementImpl;
|
||||||
|
|
||||||
|
|
||||||
|
class Data_API Session
|
||||||
|
/// A Session holds a connection to a Database and creates Statement objects.
|
||||||
|
///
|
||||||
|
/// Sessions are always created via the SessionFactory:
|
||||||
|
///
|
||||||
|
/// Session ses(SessionFactory::instance().create(connectorKey, connectionString));
|
||||||
|
///
|
||||||
|
/// where the first param presents the type of session one wants to create (e.g., for SQLite one would choose "SQLite",
|
||||||
|
/// for ODBC the key is "ODBC") and the second param is the connection string that the session implementation
|
||||||
|
/// requires to connect to the database. The format of the connection string is specific to the actual connector.
|
||||||
|
///
|
||||||
|
/// A simpler form to create the session is to pass the connector key and connection string directly to
|
||||||
|
/// the Session constructor.
|
||||||
|
///
|
||||||
|
/// A concrete example to open an SQLite database stored in the file "dummy.db" would be
|
||||||
|
///
|
||||||
|
/// Session ses("SQLite", "dummy.db");
|
||||||
|
///
|
||||||
|
/// Via a Session one can create two different types of statements. First, statements that should only be executed once and immediately, and
|
||||||
|
/// second, statements that should be executed multiple times, using a separate execute() call.
|
||||||
|
/// The simple one is immediate execution:
|
||||||
|
///
|
||||||
|
/// ses << "CREATE TABLE Dummy (data INTEGER(10))", now;
|
||||||
|
///
|
||||||
|
/// The now at the end of the statement is required, otherwise the statement
|
||||||
|
/// would not be executed.
|
||||||
|
///
|
||||||
|
/// If one wants to reuse a Statement (and avoid the overhead of repeatedly parsing an SQL statement)
|
||||||
|
/// one uses an explicit Statement object and its execute() method:
|
||||||
|
///
|
||||||
|
/// int i = 0;
|
||||||
|
/// Statement stmt = (ses << "INSERT INTO Dummy VALUES(:data)", use(i));
|
||||||
|
///
|
||||||
|
/// for (i = 0; i < 100; ++i)
|
||||||
|
/// {
|
||||||
|
/// stmt.execute();
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// The above example assigns the variable i to the ":data" placeholder in the SQL query. The query is parsed and compiled exactly
|
||||||
|
/// once, but executed 100 times. At the end the values 0 to 99 will be present in the Table "DUMMY".
|
||||||
|
///
|
||||||
|
/// A faster implementation of the above code will simply create a vector of int
|
||||||
|
/// and use the vector as parameter to the use clause (you could also use set or multiset instead):
|
||||||
|
///
|
||||||
|
/// std::vector<int> data;
|
||||||
|
/// for (int i = 0; i < 100; ++i)
|
||||||
|
/// {
|
||||||
|
/// data.push_back(i);
|
||||||
|
/// }
|
||||||
|
/// ses << "INSERT INTO Dummy VALUES(:data)", use(data);
|
||||||
|
///
|
||||||
|
/// NEVER try to bind to an empty collection. This will give a BindingException at run-time!
|
||||||
|
///
|
||||||
|
/// Retrieving data from a database works similar, you could use simple data types, vectors, sets or multiset as your targets:
|
||||||
|
///
|
||||||
|
/// std::set<int> retData;
|
||||||
|
/// ses << "SELECT * FROM Dummy", into(retData));
|
||||||
|
///
|
||||||
|
/// Due to the blocking nature of the above call it is possible to partition the data retrieval into chunks by setting a limit to
|
||||||
|
/// the maximum number of rows retrieved from the database:
|
||||||
|
///
|
||||||
|
/// std::set<int> retData;
|
||||||
|
/// Statement stmt = (ses << "SELECT * FROM Dummy", into(retData), limit(50));
|
||||||
|
/// while (!stmt.done())
|
||||||
|
/// {
|
||||||
|
/// stmt.execute();
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// The "into" keyword is used to inform the statement where output results should be placed. The limit value ensures
|
||||||
|
/// that during each run at most 50 rows are retrieved. Assuming Dummy contains 100 rows, retData will contain 50
|
||||||
|
/// elements after the first run and 100 after the second run, i.e.
|
||||||
|
/// the collection is not cleared between consecutive runs. After the second execute stmt.done() will return true.
|
||||||
|
///
|
||||||
|
/// A prepared Statement will behave exactly the same but a further call to execute() will simply reset the Statement,
|
||||||
|
/// execute it again and append more data to the result set.
|
||||||
|
///
|
||||||
|
/// Note that it is possible to append several "bind" or "into" clauses to the statement. Theoretically, one could also have several
|
||||||
|
/// limit clauses but only the last one that was added will be effective.
|
||||||
|
/// Also several preconditions must be met concerning binds and intos.
|
||||||
|
/// Take the following example:
|
||||||
|
///
|
||||||
|
/// ses << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3))";
|
||||||
|
/// std::vector<std::string> nameVec; // [...] add some elements
|
||||||
|
/// std::vector<int> ageVec; // [...] add some elements
|
||||||
|
/// ses << "INSERT INTO Person (LastName, Age) VALUES(:ln, :age)", use(nameVec), use(ageVec);
|
||||||
|
///
|
||||||
|
/// The size of all use parameters MUST be the same, otherwise an exception is thrown. Furthermore,
|
||||||
|
/// the amount of use clauses must match the number of wildcards in the query (to be more precise:
|
||||||
|
/// each binding has a numberOfColumnsHandled() value which defaults to 1. The sum of all these values
|
||||||
|
/// must match the wildcard count in the query.
|
||||||
|
/// However, this is only important if you have written your own TypeHandler specializations.
|
||||||
|
/// If you plan to map complex object types to tables see the TypeHandler documentation.
|
||||||
|
/// For now, we simply assume we have written one TypeHandler for Person objects. Instead of having n different vectors,
|
||||||
|
/// we have one collection:
|
||||||
|
///
|
||||||
|
/// std::vector<Person> people; // [...] add some elements
|
||||||
|
/// ses << "INSERT INTO Person (LastName, FirstName, Age) VALUES(:ln, :fn, :age)", use(people);
|
||||||
|
///
|
||||||
|
/// which will insert all Person objects from the people vector to the database (and again, you can use set, multiset too,
|
||||||
|
/// even map and multimap if Person provides an operator() which returns the key for the map).
|
||||||
|
/// The same works for a SELECT statement with "into" clauses:
|
||||||
|
///
|
||||||
|
/// std::vector<Person> people;
|
||||||
|
/// ses << "SELECT * FROM PERSON", into(people);
|
||||||
|
///
|
||||||
|
/// Mixing constants or variables with manipulators is allowed provided there are corresponding placeholders for the constants provided in
|
||||||
|
/// the SQL string, such as in following example:
|
||||||
|
///
|
||||||
|
/// std::vector<Person> people;
|
||||||
|
/// ses << "SELECT * FROM %s", into(people), "PERSON";
|
||||||
|
///
|
||||||
|
/// Formatting only kicks in if there are values to be injected into the SQL string, otherwise it is skipped.
|
||||||
|
/// If the formatting will occur and the percent sign is part of the query itself, it can be passed to the query by entering it twice (%%).
|
||||||
|
/// However, if no formatting is used, one percent sign is sufficient as the string will be passed unaltered.
|
||||||
|
/// For complete list of supported data types with their respective specifications, see the documentation for format in Foundation.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const std::size_t LOGIN_TIMEOUT_DEFAULT = SessionImpl::LOGIN_TIMEOUT_DEFAULT;
|
||||||
|
static const Poco::UInt32 TRANSACTION_READ_UNCOMMITTED = 0x00000001L;
|
||||||
|
static const Poco::UInt32 TRANSACTION_READ_COMMITTED = 0x00000002L;
|
||||||
|
static const Poco::UInt32 TRANSACTION_REPEATABLE_READ = 0x00000004L;
|
||||||
|
static const Poco::UInt32 TRANSACTION_SERIALIZABLE = 0x00000008L;
|
||||||
|
|
||||||
|
Session(Poco::AutoPtr<SessionImpl> ptrImpl);
|
||||||
|
/// Creates the Session.
|
||||||
|
|
||||||
|
Session(const std::string & connector, const std::string & connectionString, std::size_t timeout = LOGIN_TIMEOUT_DEFAULT);
|
||||||
|
/// Creates a new session, using the given connector (which must have
|
||||||
|
/// been registered), and connectionString.
|
||||||
|
|
||||||
|
Session(const std::string & connection, std::size_t timeout = LOGIN_TIMEOUT_DEFAULT);
|
||||||
|
/// Creates a new session, using the given connection (must be in
|
||||||
|
/// "connection:///connectionString" format).
|
||||||
|
|
||||||
|
Session(const Session &);
|
||||||
|
/// Creates a session by copying another one.
|
||||||
|
|
||||||
|
Session & operator=(const Session &);
|
||||||
|
/// Assignment operator.
|
||||||
|
|
||||||
|
~Session();
|
||||||
|
/// Destroys the Session.
|
||||||
|
|
||||||
|
void swap(Session & other);
|
||||||
|
/// Swaps the session with another one.
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Statement operator<<(const T & t)
|
||||||
|
/// Creates a Statement with the given data as SQLContent
|
||||||
|
{
|
||||||
|
return _statementCreator << t;
|
||||||
|
}
|
||||||
|
|
||||||
|
StatementImpl * createStatementImpl();
|
||||||
|
/// Creates a StatementImpl.
|
||||||
|
|
||||||
|
void open(const std::string & connect = "");
|
||||||
|
/// Opens the session using the supplied string.
|
||||||
|
/// Can also be used with default empty string to
|
||||||
|
/// reconnect a disconnected session.
|
||||||
|
/// If the connection is not established,
|
||||||
|
/// a ConnectionFailedException is thrown.
|
||||||
|
/// Zero timeout means indefinite
|
||||||
|
|
||||||
|
void close();
|
||||||
|
/// Closes the session.
|
||||||
|
|
||||||
|
bool isConnected();
|
||||||
|
/// Returns true iff session is connected, false otherwise.
|
||||||
|
|
||||||
|
void reconnect();
|
||||||
|
/// Closes the session and opens it.
|
||||||
|
|
||||||
|
void setLoginTimeout(std::size_t timeout);
|
||||||
|
/// Sets the session login timeout value.
|
||||||
|
|
||||||
|
std::size_t getLoginTimeout() const;
|
||||||
|
/// Returns the session login timeout value.
|
||||||
|
|
||||||
|
void setConnectionTimeout(std::size_t timeout);
|
||||||
|
/// Sets the session connection timeout value.
|
||||||
|
|
||||||
|
std::size_t getConnectionTimeout();
|
||||||
|
/// Returns the session connection timeout value.
|
||||||
|
|
||||||
|
void begin();
|
||||||
|
/// Starts a transaction.
|
||||||
|
|
||||||
|
void commit();
|
||||||
|
/// Commits and ends a transaction.
|
||||||
|
|
||||||
|
void rollback();
|
||||||
|
/// Rolls back and ends a transaction.
|
||||||
|
|
||||||
|
bool canTransact();
|
||||||
|
/// Returns true if session has transaction capabilities.
|
||||||
|
|
||||||
|
bool isTransaction();
|
||||||
|
/// Returns true iff a transaction is in progress, false otherwise.
|
||||||
|
|
||||||
|
void setTransactionIsolation(Poco::UInt32);
|
||||||
|
/// Sets the transaction isolation level.
|
||||||
|
|
||||||
|
Poco::UInt32 getTransactionIsolation();
|
||||||
|
/// Returns the transaction isolation level.
|
||||||
|
|
||||||
|
bool hasTransactionIsolation(Poco::UInt32 ti);
|
||||||
|
/// Returns true iff the transaction isolation level corresponding
|
||||||
|
/// to the supplied bitmask is supported.
|
||||||
|
|
||||||
|
bool isTransactionIsolation(Poco::UInt32 ti);
|
||||||
|
/// Returns true iff the transaction isolation level corresponds
|
||||||
|
/// to the supplied bitmask.
|
||||||
|
|
||||||
|
std::string connector() const;
|
||||||
|
/// Returns the connector name for this session.
|
||||||
|
|
||||||
|
std::string uri() const;
|
||||||
|
/// Returns the URI for this session.
|
||||||
|
|
||||||
|
static std::string uri(const std::string & connector, const std::string & connectionString);
|
||||||
|
/// Utility function that teturns the URI formatted from supplied
|
||||||
|
/// arguments as "connector:///connectionString".
|
||||||
|
|
||||||
|
void setFeature(const std::string & name, bool state);
|
||||||
|
/// Set the state of a feature.
|
||||||
|
///
|
||||||
|
/// Features are a generic extension mechanism for session implementations.
|
||||||
|
/// and are defined by the underlying SessionImpl instance.
|
||||||
|
///
|
||||||
|
/// Throws a NotSupportedException if the requested feature is
|
||||||
|
/// not supported by the underlying implementation.
|
||||||
|
|
||||||
|
bool getFeature(const std::string & name) const;
|
||||||
|
/// Look up the state of a feature.
|
||||||
|
///
|
||||||
|
/// Features are a generic extension mechanism for session implementations.
|
||||||
|
/// and are defined by the underlying SessionImpl instance.
|
||||||
|
///
|
||||||
|
/// Throws a NotSupportedException if the requested feature is
|
||||||
|
/// not supported by the underlying implementation.
|
||||||
|
|
||||||
|
void setProperty(const std::string & name, const Poco::Any & value);
|
||||||
|
/// Set the value of a property.
|
||||||
|
///
|
||||||
|
/// Properties are a generic extension mechanism for session implementations.
|
||||||
|
/// and are defined by the underlying SessionImpl instance.
|
||||||
|
///
|
||||||
|
/// Throws a NotSupportedException if the requested property is
|
||||||
|
/// not supported by the underlying implementation.
|
||||||
|
|
||||||
|
Poco::Any getProperty(const std::string & name) const;
|
||||||
|
/// Look up the value of a property.
|
||||||
|
///
|
||||||
|
/// Properties are a generic extension mechanism for session implementations.
|
||||||
|
/// and are defined by the underlying SessionImpl instance.
|
||||||
|
///
|
||||||
|
/// Throws a NotSupportedException if the requested property is
|
||||||
|
/// not supported by the underlying implementation.
|
||||||
|
|
||||||
|
SessionImpl * impl();
|
||||||
|
/// Returns a pointer to the underlying SessionImpl.
|
||||||
|
|
||||||
|
private:
|
||||||
|
Session();
|
||||||
|
|
||||||
|
Poco::AutoPtr<SessionImpl> _pImpl;
|
||||||
|
StatementCreator _statementCreator;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline StatementImpl * Session::createStatementImpl()
|
||||||
|
{
|
||||||
|
return _pImpl->createStatementImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Session::open(const std::string & connect)
|
||||||
|
{
|
||||||
|
_pImpl->open(connect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Session::close()
|
||||||
|
{
|
||||||
|
_pImpl->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Session::isConnected()
|
||||||
|
{
|
||||||
|
return _pImpl->isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Session::reconnect()
|
||||||
|
{
|
||||||
|
_pImpl->reconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Session::setLoginTimeout(std::size_t timeout)
|
||||||
|
{
|
||||||
|
_pImpl->setLoginTimeout(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::size_t Session::getLoginTimeout() const
|
||||||
|
{
|
||||||
|
return _pImpl->getLoginTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Session::setConnectionTimeout(std::size_t timeout)
|
||||||
|
{
|
||||||
|
_pImpl->setConnectionTimeout(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::size_t Session::getConnectionTimeout()
|
||||||
|
{
|
||||||
|
return _pImpl->getConnectionTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Session::begin()
|
||||||
|
{
|
||||||
|
return _pImpl->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Session::commit()
|
||||||
|
{
|
||||||
|
return _pImpl->commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Session::rollback()
|
||||||
|
{
|
||||||
|
return _pImpl->rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Session::canTransact()
|
||||||
|
{
|
||||||
|
return _pImpl->canTransact();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Session::isTransaction()
|
||||||
|
{
|
||||||
|
return _pImpl->isTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Session::setTransactionIsolation(Poco::UInt32 ti)
|
||||||
|
{
|
||||||
|
_pImpl->setTransactionIsolation(ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Poco::UInt32 Session::getTransactionIsolation()
|
||||||
|
{
|
||||||
|
return _pImpl->getTransactionIsolation();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Session::hasTransactionIsolation(Poco::UInt32 ti)
|
||||||
|
{
|
||||||
|
return _pImpl->hasTransactionIsolation(ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Session::isTransactionIsolation(Poco::UInt32 ti)
|
||||||
|
{
|
||||||
|
return _pImpl->isTransactionIsolation(ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::string Session::connector() const
|
||||||
|
{
|
||||||
|
return _pImpl->connectorName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::string Session::uri(const std::string & connector, const std::string & connectionString)
|
||||||
|
{
|
||||||
|
return SessionImpl::uri(connector, connectionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::string Session::uri() const
|
||||||
|
{
|
||||||
|
return _pImpl->uri();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Session::setFeature(const std::string & name, bool state)
|
||||||
|
{
|
||||||
|
_pImpl->setFeature(name, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Session::getFeature(const std::string & name) const
|
||||||
|
{
|
||||||
|
return const_cast<SessionImpl *>(_pImpl.get())->getFeature(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Session::setProperty(const std::string & name, const Poco::Any & value)
|
||||||
|
{
|
||||||
|
_pImpl->setProperty(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Poco::Any Session::getProperty(const std::string & name) const
|
||||||
|
{
|
||||||
|
return const_cast<SessionImpl *>(_pImpl.get())->getProperty(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline SessionImpl * Session::impl()
|
||||||
|
{
|
||||||
|
return _pImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void swap(Session & s1, Session & s2)
|
||||||
|
{
|
||||||
|
s1.swap(s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline void Session::open(const std::string& connect)
|
|
||||||
{
|
|
||||||
_pImpl->open(connect);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Session::close()
|
|
||||||
{
|
|
||||||
_pImpl->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Session::isConnected()
|
|
||||||
{
|
|
||||||
return _pImpl->isConnected();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Session::reconnect()
|
|
||||||
{
|
|
||||||
_pImpl->reconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Session::setLoginTimeout(std::size_t timeout)
|
|
||||||
{
|
|
||||||
_pImpl->setLoginTimeout(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::size_t Session::getLoginTimeout() const
|
|
||||||
{
|
|
||||||
return _pImpl->getLoginTimeout();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Session::setConnectionTimeout(std::size_t timeout)
|
|
||||||
{
|
|
||||||
_pImpl->setConnectionTimeout(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::size_t Session::getConnectionTimeout()
|
|
||||||
{
|
|
||||||
return _pImpl->getConnectionTimeout();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Session::begin()
|
|
||||||
{
|
|
||||||
return _pImpl->begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Session::commit()
|
|
||||||
{
|
|
||||||
return _pImpl->commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Session::rollback()
|
|
||||||
{
|
|
||||||
return _pImpl->rollback();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Session::canTransact()
|
|
||||||
{
|
|
||||||
return _pImpl->canTransact();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Session::isTransaction()
|
|
||||||
{
|
|
||||||
return _pImpl->isTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Session::setTransactionIsolation(Poco::UInt32 ti)
|
|
||||||
{
|
|
||||||
_pImpl->setTransactionIsolation(ti);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Poco::UInt32 Session::getTransactionIsolation()
|
|
||||||
{
|
|
||||||
return _pImpl->getTransactionIsolation();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Session::hasTransactionIsolation(Poco::UInt32 ti)
|
|
||||||
{
|
|
||||||
return _pImpl->hasTransactionIsolation(ti);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Session::isTransactionIsolation(Poco::UInt32 ti)
|
|
||||||
{
|
|
||||||
return _pImpl->isTransactionIsolation(ti);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::string Session::connector() const
|
|
||||||
{
|
|
||||||
return _pImpl->connectorName();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::string Session::uri(const std::string& connector,
|
|
||||||
const std::string& connectionString)
|
|
||||||
{
|
|
||||||
return SessionImpl::uri(connector, connectionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::string Session::uri() const
|
|
||||||
{
|
|
||||||
return _pImpl->uri();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Session::setFeature(const std::string& name, bool state)
|
|
||||||
{
|
|
||||||
_pImpl->setFeature(name, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Session::getFeature(const std::string& name) const
|
|
||||||
{
|
|
||||||
return const_cast<SessionImpl*>(_pImpl.get())->getFeature(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Session::setProperty(const std::string& name, const Poco::Any& value)
|
|
||||||
{
|
|
||||||
_pImpl->setProperty(name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Poco::Any Session::getProperty(const std::string& name) const
|
|
||||||
{
|
|
||||||
return const_cast<SessionImpl*>(_pImpl.get())->getProperty(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline SessionImpl* Session::impl()
|
|
||||||
{
|
|
||||||
return _pImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void swap(Session& s1, Session& s2)
|
|
||||||
{
|
|
||||||
s1.swap(s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
template<>
|
template <>
|
||||||
inline void swap<Poco::Data::Session>(Poco::Data::Session& s1,
|
inline void swap<Poco::Data::Session>(Poco::Data::Session & s1, Poco::Data::Session & s2)
|
||||||
Poco::Data::Session& s2)
|
/// Full template specalization of std:::swap for Session
|
||||||
/// Full template specalization of std:::swap for Session
|
{
|
||||||
{
|
s1.swap(s2);
|
||||||
s1.swap(s2);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,82 +18,81 @@
|
|||||||
#define Data_SessionFactory_INCLUDED
|
#define Data_SessionFactory_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Data/Data.h"
|
#include <map>
|
||||||
#include "Poco/Data/Connector.h"
|
#include "Poco/Data/Connector.h"
|
||||||
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/Session.h"
|
#include "Poco/Data/Session.h"
|
||||||
#include "Poco/Mutex.h"
|
#include "Poco/Mutex.h"
|
||||||
#include "Poco/SharedPtr.h"
|
#include "Poco/SharedPtr.h"
|
||||||
#include "Poco/String.h"
|
#include "Poco/String.h"
|
||||||
#include <map>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
{
|
||||||
|
namespace Data
|
||||||
|
|
||||||
class Data_API SessionFactory
|
|
||||||
/// A SessionFactory is a singleton class that stores Connectors and allows to
|
|
||||||
/// create Sessions of the required type:
|
|
||||||
///
|
|
||||||
/// Session ses(SessionFactory::instance().create(connector, connectionString));
|
|
||||||
///
|
|
||||||
/// where the first param presents the type of session one wants to create (e.g. for SQLite one would choose "SQLite")
|
|
||||||
/// and the second param is the connection string that the connector requires to connect to the database.
|
|
||||||
///
|
|
||||||
/// A concrete example to open an SQLite database stored in the file "dummy.db" would be
|
|
||||||
///
|
|
||||||
/// Session ses(SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db"));
|
|
||||||
///
|
|
||||||
/// An even simpler way to create a session is to use the two argument constructor of Session, which
|
|
||||||
/// automatically invokes the SessionFactory:
|
|
||||||
///
|
|
||||||
/// Session ses("SQLite", "dummy.db");
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
|
|
||||||
static SessionFactory& instance();
|
|
||||||
/// returns the static instance of the singleton.
|
|
||||||
|
|
||||||
void add(Connector* pIn);
|
|
||||||
/// Registers a Connector under its key at the factory. If a registration for that
|
|
||||||
/// key is already active, the first registration will be kept, only its reference count will be increased.
|
|
||||||
/// Always takes ownership of parameter pIn.
|
|
||||||
|
|
||||||
void remove(const std::string& key);
|
|
||||||
/// Lowers the reference count for the Connector registered under that key. If the count reaches zero,
|
|
||||||
/// the object is removed.
|
|
||||||
|
|
||||||
Session create(const std::string& key,
|
|
||||||
const std::string& connectionString,
|
|
||||||
std::size_t timeout = Session::LOGIN_TIMEOUT_DEFAULT);
|
|
||||||
/// Creates a Session for the given key with the connectionString. Throws an Poco:Data::UnknownDataBaseException
|
|
||||||
/// if no Connector is registered for that key.
|
|
||||||
|
|
||||||
Session create(const std::string& uri,
|
|
||||||
std::size_t timeout = Session::LOGIN_TIMEOUT_DEFAULT);
|
|
||||||
/// Creates a Session for the given URI (must be in key:///connectionString format).
|
|
||||||
/// Throws a Poco:Data::UnknownDataBaseException if no Connector is registered for the key.
|
|
||||||
|
|
||||||
private:
|
|
||||||
SessionFactory();
|
|
||||||
~SessionFactory();
|
|
||||||
SessionFactory(const SessionFactory&);
|
|
||||||
SessionFactory& operator = (const SessionFactory&);
|
|
||||||
|
|
||||||
struct SessionInfo
|
|
||||||
{
|
|
||||||
int cnt;
|
|
||||||
Poco::SharedPtr<Connector> ptrSI;
|
|
||||||
SessionInfo(Connector* pSI);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::map<std::string, SessionInfo, Poco::CILess> Connectors;
|
|
||||||
Connectors _connectors;
|
|
||||||
Poco::FastMutex _mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
class Data_API SessionFactory
|
||||||
|
/// A SessionFactory is a singleton class that stores Connectors and allows to
|
||||||
|
/// create Sessions of the required type:
|
||||||
|
///
|
||||||
|
/// Session ses(SessionFactory::instance().create(connector, connectionString));
|
||||||
|
///
|
||||||
|
/// where the first param presents the type of session one wants to create (e.g. for SQLite one would choose "SQLite")
|
||||||
|
/// and the second param is the connection string that the connector requires to connect to the database.
|
||||||
|
///
|
||||||
|
/// A concrete example to open an SQLite database stored in the file "dummy.db" would be
|
||||||
|
///
|
||||||
|
/// Session ses(SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db"));
|
||||||
|
///
|
||||||
|
/// An even simpler way to create a session is to use the two argument constructor of Session, which
|
||||||
|
/// automatically invokes the SessionFactory:
|
||||||
|
///
|
||||||
|
/// Session ses("SQLite", "dummy.db");
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static SessionFactory & instance();
|
||||||
|
/// returns the static instance of the singleton.
|
||||||
|
|
||||||
|
void add(Connector * pIn);
|
||||||
|
/// Registers a Connector under its key at the factory. If a registration for that
|
||||||
|
/// key is already active, the first registration will be kept, only its reference count will be increased.
|
||||||
|
/// Always takes ownership of parameter pIn.
|
||||||
|
|
||||||
|
void remove(const std::string & key);
|
||||||
|
/// Lowers the reference count for the Connector registered under that key. If the count reaches zero,
|
||||||
|
/// the object is removed.
|
||||||
|
|
||||||
|
Session create(const std::string & key, const std::string & connectionString, std::size_t timeout = Session::LOGIN_TIMEOUT_DEFAULT);
|
||||||
|
/// Creates a Session for the given key with the connectionString. Throws an Poco:Data::UnknownDataBaseException
|
||||||
|
/// if no Connector is registered for that key.
|
||||||
|
|
||||||
|
Session create(const std::string & uri, std::size_t timeout = Session::LOGIN_TIMEOUT_DEFAULT);
|
||||||
|
/// Creates a Session for the given URI (must be in key:///connectionString format).
|
||||||
|
/// Throws a Poco:Data::UnknownDataBaseException if no Connector is registered for the key.
|
||||||
|
|
||||||
|
private:
|
||||||
|
SessionFactory();
|
||||||
|
~SessionFactory();
|
||||||
|
SessionFactory(const SessionFactory &);
|
||||||
|
SessionFactory & operator=(const SessionFactory &);
|
||||||
|
|
||||||
|
struct SessionInfo
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
Poco::SharedPtr<Connector> ptrSI;
|
||||||
|
SessionInfo(Connector * pSI);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<std::string, SessionInfo, Poco::CILess> Connectors;
|
||||||
|
Connectors _connectors;
|
||||||
|
Poco::FastMutex _mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_SessionFactory_INCLUDED
|
#endif // Data_SessionFactory_INCLUDED
|
||||||
|
@ -18,204 +18,205 @@
|
|||||||
#define Data_SessionImpl_INCLUDED
|
#define Data_SessionImpl_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Any.h"
|
||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
|
#include "Poco/Format.h"
|
||||||
#include "Poco/RefCountedObject.h"
|
#include "Poco/RefCountedObject.h"
|
||||||
#include "Poco/String.h"
|
#include "Poco/String.h"
|
||||||
#include "Poco/Format.h"
|
|
||||||
#include "Poco/Any.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class StatementImpl;
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API SessionImpl: public Poco::RefCountedObject
|
|
||||||
/// Interface for Session functionality that subclasses must extend.
|
|
||||||
/// SessionImpl objects are noncopyable.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
static const std::size_t LOGIN_TIMEOUT_INFINITE = 0;
|
|
||||||
/// Infinite connection/login timeout.
|
|
||||||
|
|
||||||
static const std::size_t LOGIN_TIMEOUT_DEFAULT = 60;
|
|
||||||
/// Default connection/login timeout in seconds.
|
|
||||||
|
|
||||||
static const std::size_t CONNECTION_TIMEOUT_INFINITE = 0;
|
|
||||||
/// Infinite connection/login timeout.
|
|
||||||
|
|
||||||
static const std::size_t CONNECTION_TIMEOUT_DEFAULT = CONNECTION_TIMEOUT_INFINITE;
|
|
||||||
/// Default connection/login timeout in seconds.
|
|
||||||
|
|
||||||
SessionImpl(const std::string& connectionString,
|
|
||||||
std::size_t timeout = LOGIN_TIMEOUT_DEFAULT);
|
|
||||||
/// Creates the SessionImpl.
|
|
||||||
|
|
||||||
virtual ~SessionImpl();
|
|
||||||
/// Destroys the SessionImpl.
|
|
||||||
|
|
||||||
virtual StatementImpl* createStatementImpl() = 0;
|
|
||||||
/// Creates a StatementImpl.
|
|
||||||
|
|
||||||
virtual void open(const std::string& connectionString = "") = 0;
|
|
||||||
/// Opens the session using the supplied string.
|
|
||||||
/// Can also be used with default empty string to reconnect
|
|
||||||
/// a disconnected session.
|
|
||||||
/// If the connection is not established within requested timeout
|
|
||||||
/// (specified in seconds), a ConnectionFailedException is thrown.
|
|
||||||
/// Zero timeout means indefinite
|
|
||||||
|
|
||||||
virtual void close() = 0;
|
|
||||||
/// Closes the connection.
|
|
||||||
|
|
||||||
virtual bool isConnected() = 0;
|
|
||||||
/// Returns true if session is connected, false otherwise.
|
|
||||||
|
|
||||||
void setLoginTimeout(std::size_t timeout);
|
|
||||||
/// Sets the session login timeout value.
|
|
||||||
|
|
||||||
std::size_t getLoginTimeout() const;
|
|
||||||
/// Returns the session login timeout value.
|
|
||||||
|
|
||||||
virtual void setConnectionTimeout(std::size_t timeout) = 0;
|
|
||||||
/// Sets the session connection timeout value.
|
|
||||||
|
|
||||||
virtual std::size_t getConnectionTimeout() = 0;
|
|
||||||
/// Returns the session connection timeout value.
|
|
||||||
|
|
||||||
void reconnect();
|
|
||||||
/// Closes the connection and opens it again.
|
|
||||||
|
|
||||||
virtual void begin() = 0;
|
|
||||||
/// Starts a transaction.
|
|
||||||
|
|
||||||
virtual void commit() = 0;
|
|
||||||
/// Commits and ends a transaction.
|
|
||||||
|
|
||||||
virtual void rollback() = 0;
|
|
||||||
/// Aborts a transaction.
|
|
||||||
|
|
||||||
virtual bool canTransact() = 0;
|
|
||||||
/// Returns true if session has transaction capabilities.
|
|
||||||
|
|
||||||
virtual bool isTransaction() = 0;
|
|
||||||
/// Returns true iff a transaction is a transaction is in progress, false otherwise.
|
|
||||||
|
|
||||||
virtual void setTransactionIsolation(Poco::UInt32) = 0;
|
|
||||||
/// Sets the transaction isolation level.
|
|
||||||
|
|
||||||
virtual Poco::UInt32 getTransactionIsolation() = 0;
|
|
||||||
/// Returns the transaction isolation level.
|
|
||||||
|
|
||||||
virtual bool hasTransactionIsolation(Poco::UInt32) = 0;
|
|
||||||
/// Returns true iff the transaction isolation level corresponding
|
|
||||||
/// to the supplied bitmask is supported.
|
|
||||||
|
|
||||||
virtual bool isTransactionIsolation(Poco::UInt32) = 0;
|
|
||||||
/// Returns true iff the transaction isolation level corresponds
|
|
||||||
/// to the supplied bitmask.
|
|
||||||
|
|
||||||
virtual const std::string& connectorName() const = 0;
|
|
||||||
/// Returns the name of the connector.
|
|
||||||
|
|
||||||
const std::string& connectionString() const;
|
|
||||||
/// Returns the connection string.
|
|
||||||
|
|
||||||
static std::string uri(const std::string& connector, const std::string& connectionString);
|
|
||||||
/// Returns formatted URI.
|
|
||||||
|
|
||||||
std::string uri() const;
|
|
||||||
/// Returns the URI for this session.
|
|
||||||
|
|
||||||
virtual void setFeature(const std::string& name, bool state) = 0;
|
|
||||||
/// Set the state of a feature.
|
|
||||||
///
|
|
||||||
/// Features are a generic extension mechanism for session implementations.
|
|
||||||
/// and are defined by the underlying SessionImpl instance.
|
|
||||||
///
|
|
||||||
/// Throws a NotSupportedException if the requested feature is
|
|
||||||
/// not supported by the underlying implementation.
|
|
||||||
|
|
||||||
virtual bool getFeature(const std::string& name) = 0;
|
|
||||||
/// Look up the state of a feature.
|
|
||||||
///
|
|
||||||
/// Features are a generic extension mechanism for session implementations.
|
|
||||||
/// and are defined by the underlying SessionImpl instance.
|
|
||||||
///
|
|
||||||
/// Throws a NotSupportedException if the requested feature is
|
|
||||||
/// not supported by the underlying implementation.
|
|
||||||
|
|
||||||
virtual void setProperty(const std::string& name, const Poco::Any& value) = 0;
|
|
||||||
/// Set the value of a property.
|
|
||||||
///
|
|
||||||
/// Properties are a generic extension mechanism for session implementations.
|
|
||||||
/// and are defined by the underlying SessionImpl instance.
|
|
||||||
///
|
|
||||||
/// Throws a NotSupportedException if the requested property is
|
|
||||||
/// not supported by the underlying implementation.
|
|
||||||
|
|
||||||
virtual Poco::Any getProperty(const std::string& name) = 0;
|
|
||||||
/// Look up the value of a property.
|
|
||||||
///
|
|
||||||
/// Properties are a generic extension mechanism for session implementations.
|
|
||||||
/// and are defined by the underlying SessionImpl instance.
|
|
||||||
///
|
|
||||||
/// Throws a NotSupportedException if the requested property is
|
|
||||||
/// not supported by the underlying implementation.
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void setConnectionString(const std::string& connectionString);
|
|
||||||
/// Sets the connection string. Should only be called on
|
|
||||||
/// disconnetced sessions. Throws InvalidAccessException when called on
|
|
||||||
/// a connected session.
|
|
||||||
|
|
||||||
private:
|
|
||||||
SessionImpl();
|
|
||||||
SessionImpl(const SessionImpl&);
|
|
||||||
SessionImpl& operator = (const SessionImpl&);
|
|
||||||
|
|
||||||
std::string _connectionString;
|
|
||||||
std::size_t _loginTimeout;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline const std::string& SessionImpl::connectionString() const
|
|
||||||
{
|
{
|
||||||
return _connectionString;
|
|
||||||
|
|
||||||
|
class StatementImpl;
|
||||||
|
|
||||||
|
|
||||||
|
class Data_API SessionImpl : public Poco::RefCountedObject
|
||||||
|
/// Interface for Session functionality that subclasses must extend.
|
||||||
|
/// SessionImpl objects are noncopyable.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const std::size_t LOGIN_TIMEOUT_INFINITE = 0;
|
||||||
|
/// Infinite connection/login timeout.
|
||||||
|
|
||||||
|
static const std::size_t LOGIN_TIMEOUT_DEFAULT = 60;
|
||||||
|
/// Default connection/login timeout in seconds.
|
||||||
|
|
||||||
|
static const std::size_t CONNECTION_TIMEOUT_INFINITE = 0;
|
||||||
|
/// Infinite connection/login timeout.
|
||||||
|
|
||||||
|
static const std::size_t CONNECTION_TIMEOUT_DEFAULT = CONNECTION_TIMEOUT_INFINITE;
|
||||||
|
/// Default connection/login timeout in seconds.
|
||||||
|
|
||||||
|
SessionImpl(const std::string & connectionString, std::size_t timeout = LOGIN_TIMEOUT_DEFAULT);
|
||||||
|
/// Creates the SessionImpl.
|
||||||
|
|
||||||
|
virtual ~SessionImpl();
|
||||||
|
/// Destroys the SessionImpl.
|
||||||
|
|
||||||
|
virtual StatementImpl * createStatementImpl() = 0;
|
||||||
|
/// Creates a StatementImpl.
|
||||||
|
|
||||||
|
virtual void open(const std::string & connectionString = "") = 0;
|
||||||
|
/// Opens the session using the supplied string.
|
||||||
|
/// Can also be used with default empty string to reconnect
|
||||||
|
/// a disconnected session.
|
||||||
|
/// If the connection is not established within requested timeout
|
||||||
|
/// (specified in seconds), a ConnectionFailedException is thrown.
|
||||||
|
/// Zero timeout means indefinite
|
||||||
|
|
||||||
|
virtual void close() = 0;
|
||||||
|
/// Closes the connection.
|
||||||
|
|
||||||
|
virtual bool isConnected() = 0;
|
||||||
|
/// Returns true if session is connected, false otherwise.
|
||||||
|
|
||||||
|
void setLoginTimeout(std::size_t timeout);
|
||||||
|
/// Sets the session login timeout value.
|
||||||
|
|
||||||
|
std::size_t getLoginTimeout() const;
|
||||||
|
/// Returns the session login timeout value.
|
||||||
|
|
||||||
|
virtual void setConnectionTimeout(std::size_t timeout) = 0;
|
||||||
|
/// Sets the session connection timeout value.
|
||||||
|
|
||||||
|
virtual std::size_t getConnectionTimeout() = 0;
|
||||||
|
/// Returns the session connection timeout value.
|
||||||
|
|
||||||
|
void reconnect();
|
||||||
|
/// Closes the connection and opens it again.
|
||||||
|
|
||||||
|
virtual void begin() = 0;
|
||||||
|
/// Starts a transaction.
|
||||||
|
|
||||||
|
virtual void commit() = 0;
|
||||||
|
/// Commits and ends a transaction.
|
||||||
|
|
||||||
|
virtual void rollback() = 0;
|
||||||
|
/// Aborts a transaction.
|
||||||
|
|
||||||
|
virtual bool canTransact() = 0;
|
||||||
|
/// Returns true if session has transaction capabilities.
|
||||||
|
|
||||||
|
virtual bool isTransaction() = 0;
|
||||||
|
/// Returns true iff a transaction is a transaction is in progress, false otherwise.
|
||||||
|
|
||||||
|
virtual void setTransactionIsolation(Poco::UInt32) = 0;
|
||||||
|
/// Sets the transaction isolation level.
|
||||||
|
|
||||||
|
virtual Poco::UInt32 getTransactionIsolation() = 0;
|
||||||
|
/// Returns the transaction isolation level.
|
||||||
|
|
||||||
|
virtual bool hasTransactionIsolation(Poco::UInt32) = 0;
|
||||||
|
/// Returns true iff the transaction isolation level corresponding
|
||||||
|
/// to the supplied bitmask is supported.
|
||||||
|
|
||||||
|
virtual bool isTransactionIsolation(Poco::UInt32) = 0;
|
||||||
|
/// Returns true iff the transaction isolation level corresponds
|
||||||
|
/// to the supplied bitmask.
|
||||||
|
|
||||||
|
virtual const std::string & connectorName() const = 0;
|
||||||
|
/// Returns the name of the connector.
|
||||||
|
|
||||||
|
const std::string & connectionString() const;
|
||||||
|
/// Returns the connection string.
|
||||||
|
|
||||||
|
static std::string uri(const std::string & connector, const std::string & connectionString);
|
||||||
|
/// Returns formatted URI.
|
||||||
|
|
||||||
|
std::string uri() const;
|
||||||
|
/// Returns the URI for this session.
|
||||||
|
|
||||||
|
virtual void setFeature(const std::string & name, bool state) = 0;
|
||||||
|
/// Set the state of a feature.
|
||||||
|
///
|
||||||
|
/// Features are a generic extension mechanism for session implementations.
|
||||||
|
/// and are defined by the underlying SessionImpl instance.
|
||||||
|
///
|
||||||
|
/// Throws a NotSupportedException if the requested feature is
|
||||||
|
/// not supported by the underlying implementation.
|
||||||
|
|
||||||
|
virtual bool getFeature(const std::string & name) = 0;
|
||||||
|
/// Look up the state of a feature.
|
||||||
|
///
|
||||||
|
/// Features are a generic extension mechanism for session implementations.
|
||||||
|
/// and are defined by the underlying SessionImpl instance.
|
||||||
|
///
|
||||||
|
/// Throws a NotSupportedException if the requested feature is
|
||||||
|
/// not supported by the underlying implementation.
|
||||||
|
|
||||||
|
virtual void setProperty(const std::string & name, const Poco::Any & value) = 0;
|
||||||
|
/// Set the value of a property.
|
||||||
|
///
|
||||||
|
/// Properties are a generic extension mechanism for session implementations.
|
||||||
|
/// and are defined by the underlying SessionImpl instance.
|
||||||
|
///
|
||||||
|
/// Throws a NotSupportedException if the requested property is
|
||||||
|
/// not supported by the underlying implementation.
|
||||||
|
|
||||||
|
virtual Poco::Any getProperty(const std::string & name) = 0;
|
||||||
|
/// Look up the value of a property.
|
||||||
|
///
|
||||||
|
/// Properties are a generic extension mechanism for session implementations.
|
||||||
|
/// and are defined by the underlying SessionImpl instance.
|
||||||
|
///
|
||||||
|
/// Throws a NotSupportedException if the requested property is
|
||||||
|
/// not supported by the underlying implementation.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setConnectionString(const std::string & connectionString);
|
||||||
|
/// Sets the connection string. Should only be called on
|
||||||
|
/// disconnetced sessions. Throws InvalidAccessException when called on
|
||||||
|
/// a connected session.
|
||||||
|
|
||||||
|
private:
|
||||||
|
SessionImpl();
|
||||||
|
SessionImpl(const SessionImpl &);
|
||||||
|
SessionImpl & operator=(const SessionImpl &);
|
||||||
|
|
||||||
|
std::string _connectionString;
|
||||||
|
std::size_t _loginTimeout;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline const std::string & SessionImpl::connectionString() const
|
||||||
|
{
|
||||||
|
return _connectionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void SessionImpl::setLoginTimeout(std::size_t timeout)
|
||||||
|
{
|
||||||
|
_loginTimeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::size_t SessionImpl::getLoginTimeout() const
|
||||||
|
{
|
||||||
|
return _loginTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::string SessionImpl::uri(const std::string & connector, const std::string & connectionString)
|
||||||
|
{
|
||||||
|
return format("%s:///%s", connector, connectionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::string SessionImpl::uri() const
|
||||||
|
{
|
||||||
|
return uri(connectorName(), connectionString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline void SessionImpl::setLoginTimeout(std::size_t timeout)
|
|
||||||
{
|
|
||||||
_loginTimeout = timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::size_t SessionImpl::getLoginTimeout() const
|
|
||||||
{
|
|
||||||
return _loginTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::string SessionImpl::uri(const std::string& connector,
|
|
||||||
const std::string& connectionString)
|
|
||||||
{
|
|
||||||
return format("%s:///%s", connector, connectionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::string SessionImpl::uri() const
|
|
||||||
{
|
|
||||||
return uri(connectorName(), connectionString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_SessionImpl_INCLUDED
|
#endif // Data_SessionImpl_INCLUDED
|
||||||
|
@ -18,216 +18,216 @@
|
|||||||
#define Data_SessionPool_INCLUDED
|
#define Data_SessionPool_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include "Poco/Any.h"
|
||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/PooledSessionHolder.h"
|
#include "Poco/Data/PooledSessionHolder.h"
|
||||||
#include "Poco/Data/PooledSessionImpl.h"
|
#include "Poco/Data/PooledSessionImpl.h"
|
||||||
#include "Poco/Data/Session.h"
|
#include "Poco/Data/Session.h"
|
||||||
#include "Poco/HashMap.h"
|
#include "Poco/HashMap.h"
|
||||||
#include "Poco/Any.h"
|
|
||||||
#include "Poco/Timer.h"
|
|
||||||
#include "Poco/Mutex.h"
|
#include "Poco/Mutex.h"
|
||||||
#include <list>
|
#include "Poco/Timer.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API SessionPool: public RefCountedObject
|
|
||||||
/// This class implements session pooling for POCO Data.
|
|
||||||
///
|
|
||||||
/// Creating a connection to a database is often a time consuming
|
|
||||||
/// operation. Therefore it makes sense to reuse a session object
|
|
||||||
/// once it is no longer needed.
|
|
||||||
///
|
|
||||||
/// A SessionPool manages a collection of SessionImpl objects
|
|
||||||
/// (decorated with a PooledSessionImpl).
|
|
||||||
///
|
|
||||||
/// When a SessionImpl object is requested, the SessionPool first
|
|
||||||
/// looks in its set of already initialized SessionImpl for an
|
|
||||||
/// available object. If one is found, it is returned to the
|
|
||||||
/// client and marked as "in-use". If no SessionImpl is available,
|
|
||||||
/// the SessionPool attempts to create a new one for the client.
|
|
||||||
/// To avoid excessive creation of SessionImpl objects, a limit
|
|
||||||
/// can be set on the maximum number of objects.
|
|
||||||
/// Sessions found not to be connected to the database are purged
|
|
||||||
/// from the pool whenever one of the following events occurs:
|
|
||||||
///
|
|
||||||
/// - JanitorTimer event
|
|
||||||
/// - get() request
|
|
||||||
/// - putBack() request
|
|
||||||
///
|
|
||||||
/// Not connected idle sessions can not exist.
|
|
||||||
///
|
|
||||||
/// Usage example:
|
|
||||||
///
|
|
||||||
/// SessionPool pool("ODBC", "...");
|
|
||||||
/// ...
|
|
||||||
/// Session sess(pool.get());
|
|
||||||
/// ...
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
SessionPool(const std::string& connector,
|
|
||||||
const std::string& connectionString,
|
|
||||||
int minSessions = 1,
|
|
||||||
int maxSessions = 32,
|
|
||||||
int idleTime = 60);
|
|
||||||
/// Creates the SessionPool for sessions with the given connector
|
|
||||||
/// and connectionString.
|
|
||||||
///
|
|
||||||
/// The pool allows for at most maxSessions sessions to be created.
|
|
||||||
/// If a session has been idle for more than idleTime seconds, and more than
|
|
||||||
/// minSessions sessions are in the pool, the session is automatically destroyed.
|
|
||||||
|
|
||||||
~SessionPool();
|
|
||||||
/// Destroys the SessionPool.
|
|
||||||
|
|
||||||
Session get();
|
|
||||||
/// Returns a Session.
|
|
||||||
///
|
|
||||||
/// If there are unused sessions available, one of the
|
|
||||||
/// unused sessions is recycled. Otherwise, a new session
|
|
||||||
/// is created.
|
|
||||||
///
|
|
||||||
/// If the maximum number of sessions for this pool has
|
|
||||||
/// already been created, a SessionPoolExhaustedException
|
|
||||||
/// is thrown.
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Session get(const std::string& name, const T& value)
|
|
||||||
/// Returns a Session with requested property set.
|
|
||||||
/// The property can be different from the default pool
|
|
||||||
/// value, in which case it is reset back to the pool
|
|
||||||
/// value when the session is reclaimed by the pool.
|
|
||||||
{
|
|
||||||
Session s = get();
|
|
||||||
_addPropertyMap.insert(AddPropertyMap::value_type(s.impl(),
|
|
||||||
std::make_pair(name, s.getProperty(name))));
|
|
||||||
s.setProperty(name, value);
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
Session get(const std::string& name, bool value);
|
|
||||||
/// Returns a Session with requested feature set.
|
|
||||||
/// The feature can be different from the default pool
|
|
||||||
/// value, in which case it is reset back to the pool
|
|
||||||
/// value when the session is reclaimed by the pool.
|
|
||||||
|
|
||||||
int capacity() const;
|
|
||||||
/// Returns the maximum number of sessions the SessionPool will manage.
|
|
||||||
|
|
||||||
int used() const;
|
|
||||||
/// Returns the number of sessions currently in use.
|
|
||||||
|
|
||||||
int idle() const;
|
|
||||||
/// Returns the number of idle sessions.
|
|
||||||
|
|
||||||
int dead();
|
|
||||||
/// Returns the number of not connected active sessions.
|
|
||||||
|
|
||||||
int allocated() const;
|
|
||||||
/// Returns the number of allocated sessions.
|
|
||||||
|
|
||||||
int available() const;
|
|
||||||
/// Returns the number of available (idle + remaining capacity) sessions.
|
|
||||||
|
|
||||||
std::string name() const;
|
|
||||||
/// Returns the name for this pool.
|
|
||||||
|
|
||||||
static std::string name(const std::string& connector,
|
|
||||||
const std::string& connectionString);
|
|
||||||
/// Returns the name formatted from supplied arguments as "connector:///connectionString".
|
|
||||||
|
|
||||||
void setFeature(const std::string& name, bool state);
|
|
||||||
/// Sets feature for all the sessions.
|
|
||||||
|
|
||||||
bool getFeature(const std::string& name);
|
|
||||||
/// Returns the requested feature.
|
|
||||||
|
|
||||||
void setProperty(const std::string& name, const Poco::Any& value);
|
|
||||||
/// Sets property for all sessions.
|
|
||||||
|
|
||||||
Poco::Any getProperty(const std::string& name);
|
|
||||||
/// Returns the requested property.
|
|
||||||
|
|
||||||
void shutdown();
|
|
||||||
/// Shuts down the session pool.
|
|
||||||
|
|
||||||
bool isActive() const;
|
|
||||||
/// Returns true if session pool is active (not shut down).
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void customizeSession(Session& session);
|
|
||||||
/// Can be overridden by subclass to perform custom initialization
|
|
||||||
/// of a newly created database session.
|
|
||||||
///
|
|
||||||
/// The default implementation does nothing.
|
|
||||||
|
|
||||||
typedef Poco::AutoPtr<PooledSessionHolder> PooledSessionHolderPtr;
|
|
||||||
typedef Poco::AutoPtr<PooledSessionImpl> PooledSessionImplPtr;
|
|
||||||
typedef std::list<PooledSessionHolderPtr> SessionList;
|
|
||||||
typedef Poco::HashMap<std::string, bool> FeatureMap;
|
|
||||||
typedef Poco::HashMap<std::string, Poco::Any> PropertyMap;
|
|
||||||
|
|
||||||
void purgeDeadSessions();
|
|
||||||
int deadImpl(SessionList& rSessions);
|
|
||||||
void applySettings(SessionImpl* pImpl);
|
|
||||||
void putBack(PooledSessionHolderPtr pHolder);
|
|
||||||
void onJanitorTimer(Poco::Timer&);
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef std::pair<std::string, Poco::Any> PropertyPair;
|
|
||||||
typedef std::pair<std::string, bool> FeaturePair;
|
|
||||||
typedef std::map<SessionImpl*, PropertyPair> AddPropertyMap;
|
|
||||||
typedef std::map<SessionImpl*, FeaturePair> AddFeatureMap;
|
|
||||||
|
|
||||||
SessionPool(const SessionPool&);
|
|
||||||
SessionPool& operator = (const SessionPool&);
|
|
||||||
|
|
||||||
void closeAll(SessionList& sessionList);
|
|
||||||
|
|
||||||
std::string _connector;
|
|
||||||
std::string _connectionString;
|
|
||||||
int _minSessions;
|
|
||||||
int _maxSessions;
|
|
||||||
int _idleTime;
|
|
||||||
int _nSessions;
|
|
||||||
SessionList _idleSessions;
|
|
||||||
SessionList _activeSessions;
|
|
||||||
Poco::Timer _janitorTimer;
|
|
||||||
FeatureMap _featureMap;
|
|
||||||
PropertyMap _propertyMap;
|
|
||||||
bool _shutdown;
|
|
||||||
AddPropertyMap _addPropertyMap;
|
|
||||||
AddFeatureMap _addFeatureMap;
|
|
||||||
mutable
|
|
||||||
Poco::Mutex _mutex;
|
|
||||||
|
|
||||||
friend class PooledSessionImpl;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
inline std::string SessionPool::name(const std::string& connector,
|
|
||||||
const std::string& connectionString)
|
|
||||||
{
|
{
|
||||||
return Session::uri(connector, connectionString);
|
|
||||||
|
|
||||||
|
class Data_API SessionPool : public RefCountedObject
|
||||||
|
/// This class implements session pooling for POCO Data.
|
||||||
|
///
|
||||||
|
/// Creating a connection to a database is often a time consuming
|
||||||
|
/// operation. Therefore it makes sense to reuse a session object
|
||||||
|
/// once it is no longer needed.
|
||||||
|
///
|
||||||
|
/// A SessionPool manages a collection of SessionImpl objects
|
||||||
|
/// (decorated with a PooledSessionImpl).
|
||||||
|
///
|
||||||
|
/// When a SessionImpl object is requested, the SessionPool first
|
||||||
|
/// looks in its set of already initialized SessionImpl for an
|
||||||
|
/// available object. If one is found, it is returned to the
|
||||||
|
/// client and marked as "in-use". If no SessionImpl is available,
|
||||||
|
/// the SessionPool attempts to create a new one for the client.
|
||||||
|
/// To avoid excessive creation of SessionImpl objects, a limit
|
||||||
|
/// can be set on the maximum number of objects.
|
||||||
|
/// Sessions found not to be connected to the database are purged
|
||||||
|
/// from the pool whenever one of the following events occurs:
|
||||||
|
///
|
||||||
|
/// - JanitorTimer event
|
||||||
|
/// - get() request
|
||||||
|
/// - putBack() request
|
||||||
|
///
|
||||||
|
/// Not connected idle sessions can not exist.
|
||||||
|
///
|
||||||
|
/// Usage example:
|
||||||
|
///
|
||||||
|
/// SessionPool pool("ODBC", "...");
|
||||||
|
/// ...
|
||||||
|
/// Session sess(pool.get());
|
||||||
|
/// ...
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SessionPool(
|
||||||
|
const std::string & connector,
|
||||||
|
const std::string & connectionString,
|
||||||
|
int minSessions = 1,
|
||||||
|
int maxSessions = 32,
|
||||||
|
int idleTime = 60);
|
||||||
|
/// Creates the SessionPool for sessions with the given connector
|
||||||
|
/// and connectionString.
|
||||||
|
///
|
||||||
|
/// The pool allows for at most maxSessions sessions to be created.
|
||||||
|
/// If a session has been idle for more than idleTime seconds, and more than
|
||||||
|
/// minSessions sessions are in the pool, the session is automatically destroyed.
|
||||||
|
|
||||||
|
~SessionPool();
|
||||||
|
/// Destroys the SessionPool.
|
||||||
|
|
||||||
|
Session get();
|
||||||
|
/// Returns a Session.
|
||||||
|
///
|
||||||
|
/// If there are unused sessions available, one of the
|
||||||
|
/// unused sessions is recycled. Otherwise, a new session
|
||||||
|
/// is created.
|
||||||
|
///
|
||||||
|
/// If the maximum number of sessions for this pool has
|
||||||
|
/// already been created, a SessionPoolExhaustedException
|
||||||
|
/// is thrown.
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Session get(const std::string & name, const T & value)
|
||||||
|
/// Returns a Session with requested property set.
|
||||||
|
/// The property can be different from the default pool
|
||||||
|
/// value, in which case it is reset back to the pool
|
||||||
|
/// value when the session is reclaimed by the pool.
|
||||||
|
{
|
||||||
|
Session s = get();
|
||||||
|
_addPropertyMap.insert(AddPropertyMap::value_type(s.impl(), std::make_pair(name, s.getProperty(name))));
|
||||||
|
s.setProperty(name, value);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
Session get(const std::string & name, bool value);
|
||||||
|
/// Returns a Session with requested feature set.
|
||||||
|
/// The feature can be different from the default pool
|
||||||
|
/// value, in which case it is reset back to the pool
|
||||||
|
/// value when the session is reclaimed by the pool.
|
||||||
|
|
||||||
|
int capacity() const;
|
||||||
|
/// Returns the maximum number of sessions the SessionPool will manage.
|
||||||
|
|
||||||
|
int used() const;
|
||||||
|
/// Returns the number of sessions currently in use.
|
||||||
|
|
||||||
|
int idle() const;
|
||||||
|
/// Returns the number of idle sessions.
|
||||||
|
|
||||||
|
int dead();
|
||||||
|
/// Returns the number of not connected active sessions.
|
||||||
|
|
||||||
|
int allocated() const;
|
||||||
|
/// Returns the number of allocated sessions.
|
||||||
|
|
||||||
|
int available() const;
|
||||||
|
/// Returns the number of available (idle + remaining capacity) sessions.
|
||||||
|
|
||||||
|
std::string name() const;
|
||||||
|
/// Returns the name for this pool.
|
||||||
|
|
||||||
|
static std::string name(const std::string & connector, const std::string & connectionString);
|
||||||
|
/// Returns the name formatted from supplied arguments as "connector:///connectionString".
|
||||||
|
|
||||||
|
void setFeature(const std::string & name, bool state);
|
||||||
|
/// Sets feature for all the sessions.
|
||||||
|
|
||||||
|
bool getFeature(const std::string & name);
|
||||||
|
/// Returns the requested feature.
|
||||||
|
|
||||||
|
void setProperty(const std::string & name, const Poco::Any & value);
|
||||||
|
/// Sets property for all sessions.
|
||||||
|
|
||||||
|
Poco::Any getProperty(const std::string & name);
|
||||||
|
/// Returns the requested property.
|
||||||
|
|
||||||
|
void shutdown();
|
||||||
|
/// Shuts down the session pool.
|
||||||
|
|
||||||
|
bool isActive() const;
|
||||||
|
/// Returns true if session pool is active (not shut down).
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void customizeSession(Session & session);
|
||||||
|
/// Can be overridden by subclass to perform custom initialization
|
||||||
|
/// of a newly created database session.
|
||||||
|
///
|
||||||
|
/// The default implementation does nothing.
|
||||||
|
|
||||||
|
typedef Poco::AutoPtr<PooledSessionHolder> PooledSessionHolderPtr;
|
||||||
|
typedef Poco::AutoPtr<PooledSessionImpl> PooledSessionImplPtr;
|
||||||
|
typedef std::list<PooledSessionHolderPtr> SessionList;
|
||||||
|
typedef Poco::HashMap<std::string, bool> FeatureMap;
|
||||||
|
typedef Poco::HashMap<std::string, Poco::Any> PropertyMap;
|
||||||
|
|
||||||
|
void purgeDeadSessions();
|
||||||
|
int deadImpl(SessionList & rSessions);
|
||||||
|
void applySettings(SessionImpl * pImpl);
|
||||||
|
void putBack(PooledSessionHolderPtr pHolder);
|
||||||
|
void onJanitorTimer(Poco::Timer &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::pair<std::string, Poco::Any> PropertyPair;
|
||||||
|
typedef std::pair<std::string, bool> FeaturePair;
|
||||||
|
typedef std::map<SessionImpl *, PropertyPair> AddPropertyMap;
|
||||||
|
typedef std::map<SessionImpl *, FeaturePair> AddFeatureMap;
|
||||||
|
|
||||||
|
SessionPool(const SessionPool &);
|
||||||
|
SessionPool & operator=(const SessionPool &);
|
||||||
|
|
||||||
|
void closeAll(SessionList & sessionList);
|
||||||
|
|
||||||
|
std::string _connector;
|
||||||
|
std::string _connectionString;
|
||||||
|
int _minSessions;
|
||||||
|
int _maxSessions;
|
||||||
|
int _idleTime;
|
||||||
|
int _nSessions;
|
||||||
|
SessionList _idleSessions;
|
||||||
|
SessionList _activeSessions;
|
||||||
|
Poco::Timer _janitorTimer;
|
||||||
|
FeatureMap _featureMap;
|
||||||
|
PropertyMap _propertyMap;
|
||||||
|
bool _shutdown;
|
||||||
|
AddPropertyMap _addPropertyMap;
|
||||||
|
AddFeatureMap _addFeatureMap;
|
||||||
|
mutable Poco::Mutex _mutex;
|
||||||
|
|
||||||
|
friend class PooledSessionImpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline std::string SessionPool::name(const std::string & connector, const std::string & connectionString)
|
||||||
|
{
|
||||||
|
return Session::uri(connector, connectionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::string SessionPool::name() const
|
||||||
|
{
|
||||||
|
return name(_connector, _connectionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool SessionPool::isActive() const
|
||||||
|
{
|
||||||
|
return !_shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline std::string SessionPool::name() const
|
|
||||||
{
|
|
||||||
return name(_connector, _connectionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool SessionPool::isActive() const
|
|
||||||
{
|
|
||||||
return !_shutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_SessionPool_INCLUDED
|
#endif // Data_SessionPool_INCLUDED
|
||||||
|
@ -21,94 +21,97 @@
|
|||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/Session.h"
|
#include "Poco/Data/Session.h"
|
||||||
#include "Poco/Data/SessionPool.h"
|
#include "Poco/Data/SessionPool.h"
|
||||||
#include "Poco/String.h"
|
|
||||||
#include "Poco/Mutex.h"
|
#include "Poco/Mutex.h"
|
||||||
|
#include "Poco/String.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API SessionPoolContainer
|
|
||||||
/// This class implements container of session pools.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
SessionPoolContainer();
|
|
||||||
/// Creates the SessionPoolContainer for sessions with the given session parameters.
|
|
||||||
|
|
||||||
~SessionPoolContainer();
|
|
||||||
/// Destroys the SessionPoolContainer.
|
|
||||||
|
|
||||||
void add(SessionPool* pPool);
|
|
||||||
/// Adds existing session pool to the container.
|
|
||||||
/// Throws SessionPoolExistsException if pool already exists.
|
|
||||||
|
|
||||||
Session add(const std::string& sessionKey,
|
|
||||||
const std::string& connectionString,
|
|
||||||
int minSessions = 1,
|
|
||||||
int maxSessions = 32,
|
|
||||||
int idleTime = 60);
|
|
||||||
/// Adds a new session pool to the container and returns a Session from
|
|
||||||
/// newly created pool. If pool already exists, request to add is silently
|
|
||||||
/// ignored and session is returned from the existing pool.
|
|
||||||
|
|
||||||
bool has(const std::string& name) const;
|
|
||||||
/// Returns true if the requested name exists, false otherwise.
|
|
||||||
|
|
||||||
bool isActive(const std::string& sessionKey,
|
|
||||||
const std::string& connectionString = "") const;
|
|
||||||
/// Returns true if the session is active (i.e. not shut down).
|
|
||||||
/// If connectionString is empty string, sessionKey must be a
|
|
||||||
/// fully qualified session name as registered with the pool
|
|
||||||
/// container.
|
|
||||||
|
|
||||||
Session get(const std::string& name);
|
|
||||||
/// Returns the requested Session.
|
|
||||||
/// Throws NotFoundException if session is not found.
|
|
||||||
|
|
||||||
SessionPool& getPool(const std::string& name);
|
|
||||||
/// Returns a SessionPool reference.
|
|
||||||
/// Throws NotFoundException if session is not found.
|
|
||||||
|
|
||||||
void remove(const std::string& name);
|
|
||||||
/// Removes a SessionPool.
|
|
||||||
|
|
||||||
int count() const;
|
|
||||||
/// Returns the number of session pols in the container.
|
|
||||||
|
|
||||||
void shutdown();
|
|
||||||
/// Shuts down all the held pools.
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef std::map<std::string, AutoPtr<SessionPool>, Poco::CILess> SessionPoolMap;
|
|
||||||
|
|
||||||
SessionPoolContainer(const SessionPoolContainer&);
|
|
||||||
SessionPoolContainer& operator = (const SessionPoolContainer&);
|
|
||||||
|
|
||||||
SessionPoolMap _sessionPools;
|
|
||||||
Poco::FastMutex _mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
inline bool SessionPoolContainer::has(const std::string& name) const
|
|
||||||
{
|
{
|
||||||
return _sessionPools.find(name) != _sessionPools.end();
|
|
||||||
|
|
||||||
|
class Data_API SessionPoolContainer
|
||||||
|
/// This class implements container of session pools.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SessionPoolContainer();
|
||||||
|
/// Creates the SessionPoolContainer for sessions with the given session parameters.
|
||||||
|
|
||||||
|
~SessionPoolContainer();
|
||||||
|
/// Destroys the SessionPoolContainer.
|
||||||
|
|
||||||
|
void add(SessionPool * pPool);
|
||||||
|
/// Adds existing session pool to the container.
|
||||||
|
/// Throws SessionPoolExistsException if pool already exists.
|
||||||
|
|
||||||
|
Session
|
||||||
|
add(const std::string & sessionKey,
|
||||||
|
const std::string & connectionString,
|
||||||
|
int minSessions = 1,
|
||||||
|
int maxSessions = 32,
|
||||||
|
int idleTime = 60);
|
||||||
|
/// Adds a new session pool to the container and returns a Session from
|
||||||
|
/// newly created pool. If pool already exists, request to add is silently
|
||||||
|
/// ignored and session is returned from the existing pool.
|
||||||
|
|
||||||
|
bool has(const std::string & name) const;
|
||||||
|
/// Returns true if the requested name exists, false otherwise.
|
||||||
|
|
||||||
|
bool isActive(const std::string & sessionKey, const std::string & connectionString = "") const;
|
||||||
|
/// Returns true if the session is active (i.e. not shut down).
|
||||||
|
/// If connectionString is empty string, sessionKey must be a
|
||||||
|
/// fully qualified session name as registered with the pool
|
||||||
|
/// container.
|
||||||
|
|
||||||
|
Session get(const std::string & name);
|
||||||
|
/// Returns the requested Session.
|
||||||
|
/// Throws NotFoundException if session is not found.
|
||||||
|
|
||||||
|
SessionPool & getPool(const std::string & name);
|
||||||
|
/// Returns a SessionPool reference.
|
||||||
|
/// Throws NotFoundException if session is not found.
|
||||||
|
|
||||||
|
void remove(const std::string & name);
|
||||||
|
/// Removes a SessionPool.
|
||||||
|
|
||||||
|
int count() const;
|
||||||
|
/// Returns the number of session pols in the container.
|
||||||
|
|
||||||
|
void shutdown();
|
||||||
|
/// Shuts down all the held pools.
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::map<std::string, AutoPtr<SessionPool>, Poco::CILess> SessionPoolMap;
|
||||||
|
|
||||||
|
SessionPoolContainer(const SessionPoolContainer &);
|
||||||
|
SessionPoolContainer & operator=(const SessionPoolContainer &);
|
||||||
|
|
||||||
|
SessionPoolMap _sessionPools;
|
||||||
|
Poco::FastMutex _mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline bool SessionPoolContainer::has(const std::string & name) const
|
||||||
|
{
|
||||||
|
return _sessionPools.find(name) != _sessionPools.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void SessionPoolContainer::remove(const std::string & name)
|
||||||
|
{
|
||||||
|
_sessionPools.erase(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int SessionPoolContainer::count() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(_sessionPools.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline void SessionPoolContainer::remove(const std::string& name)
|
|
||||||
{
|
|
||||||
_sessionPools.erase(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline int SessionPoolContainer::count() const
|
|
||||||
{
|
|
||||||
return static_cast<int>(_sessionPools.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_SessionPoolContainer_INCLUDED
|
#endif // Data_SessionPoolContainer_INCLUDED
|
||||||
|
@ -22,100 +22,102 @@
|
|||||||
#include "Poco/Data/RowFormatter.h"
|
#include "Poco/Data/RowFormatter.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API SimpleRowFormatter: public RowFormatter
|
|
||||||
/// A simple row formatting class.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
//typedef RowFormatter::NameVec NameVec;
|
|
||||||
//typedef RowFormatter::NameVecPtr NameVecPtr;
|
|
||||||
//typedef RowFormatter::ValueVec ValueVec;
|
|
||||||
|
|
||||||
static const int DEFAULT_COLUMN_WIDTH = 16;
|
|
||||||
static const int DEFAULT_SPACING = 1;
|
|
||||||
|
|
||||||
SimpleRowFormatter(std::streamsize columnWidth = DEFAULT_COLUMN_WIDTH, std::streamsize spacing = DEFAULT_SPACING);
|
|
||||||
/// Creates the SimpleRowFormatter and sets the column width to specified value.
|
|
||||||
|
|
||||||
SimpleRowFormatter(const SimpleRowFormatter& other);
|
|
||||||
/// Creates the copy of the supplied SimpleRowFormatter.
|
|
||||||
|
|
||||||
SimpleRowFormatter& operator = (const SimpleRowFormatter& row);
|
|
||||||
/// Assignment operator.
|
|
||||||
|
|
||||||
~SimpleRowFormatter();
|
|
||||||
/// Destroys the SimpleRowFormatter.
|
|
||||||
|
|
||||||
void swap(SimpleRowFormatter& other);
|
|
||||||
/// Swaps the row formatter with another one.
|
|
||||||
|
|
||||||
std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames);
|
|
||||||
/// Formats the row field names.
|
|
||||||
|
|
||||||
std::string& formatValues(const ValueVec& vals, std::string& formattedValues);
|
|
||||||
/// Formats the row values.
|
|
||||||
|
|
||||||
int rowCount() const;
|
|
||||||
/// Returns row count.
|
|
||||||
|
|
||||||
void setColumnWidth(std::streamsize width);
|
|
||||||
/// Sets the column width.
|
|
||||||
|
|
||||||
std::streamsize getColumnWidth() const;
|
|
||||||
/// Returns the column width.
|
|
||||||
|
|
||||||
std::streamsize getSpacing() const;
|
|
||||||
/// Returns the spacing.
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::streamsize _colWidth;
|
|
||||||
std::streamsize _spacing;
|
|
||||||
int _rowCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// inlines
|
|
||||||
///
|
|
||||||
inline int SimpleRowFormatter::rowCount() const
|
|
||||||
{
|
{
|
||||||
return _rowCount;
|
|
||||||
|
|
||||||
|
class Data_API SimpleRowFormatter : public RowFormatter
|
||||||
|
/// A simple row formatting class.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//typedef RowFormatter::NameVec NameVec;
|
||||||
|
//typedef RowFormatter::NameVecPtr NameVecPtr;
|
||||||
|
//typedef RowFormatter::ValueVec ValueVec;
|
||||||
|
|
||||||
|
static const int DEFAULT_COLUMN_WIDTH = 16;
|
||||||
|
static const int DEFAULT_SPACING = 1;
|
||||||
|
|
||||||
|
SimpleRowFormatter(std::streamsize columnWidth = DEFAULT_COLUMN_WIDTH, std::streamsize spacing = DEFAULT_SPACING);
|
||||||
|
/// Creates the SimpleRowFormatter and sets the column width to specified value.
|
||||||
|
|
||||||
|
SimpleRowFormatter(const SimpleRowFormatter & other);
|
||||||
|
/// Creates the copy of the supplied SimpleRowFormatter.
|
||||||
|
|
||||||
|
SimpleRowFormatter & operator=(const SimpleRowFormatter & row);
|
||||||
|
/// Assignment operator.
|
||||||
|
|
||||||
|
~SimpleRowFormatter();
|
||||||
|
/// Destroys the SimpleRowFormatter.
|
||||||
|
|
||||||
|
void swap(SimpleRowFormatter & other);
|
||||||
|
/// Swaps the row formatter with another one.
|
||||||
|
|
||||||
|
std::string & formatNames(const NameVecPtr pNames, std::string & formattedNames);
|
||||||
|
/// Formats the row field names.
|
||||||
|
|
||||||
|
std::string & formatValues(const ValueVec & vals, std::string & formattedValues);
|
||||||
|
/// Formats the row values.
|
||||||
|
|
||||||
|
int rowCount() const;
|
||||||
|
/// Returns row count.
|
||||||
|
|
||||||
|
void setColumnWidth(std::streamsize width);
|
||||||
|
/// Sets the column width.
|
||||||
|
|
||||||
|
std::streamsize getColumnWidth() const;
|
||||||
|
/// Returns the column width.
|
||||||
|
|
||||||
|
std::streamsize getSpacing() const;
|
||||||
|
/// Returns the spacing.
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::streamsize _colWidth;
|
||||||
|
std::streamsize _spacing;
|
||||||
|
int _rowCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// inlines
|
||||||
|
///
|
||||||
|
inline int SimpleRowFormatter::rowCount() const
|
||||||
|
{
|
||||||
|
return _rowCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void SimpleRowFormatter::setColumnWidth(std::streamsize columnWidth)
|
||||||
|
{
|
||||||
|
_colWidth = columnWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::streamsize SimpleRowFormatter::getColumnWidth() const
|
||||||
|
{
|
||||||
|
return _colWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::streamsize SimpleRowFormatter::getSpacing() const
|
||||||
|
{
|
||||||
|
return _spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline void SimpleRowFormatter::setColumnWidth(std::streamsize columnWidth)
|
|
||||||
{
|
|
||||||
_colWidth = columnWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::streamsize SimpleRowFormatter::getColumnWidth() const
|
|
||||||
{
|
|
||||||
return _colWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::streamsize SimpleRowFormatter::getSpacing() const
|
|
||||||
{
|
|
||||||
return _spacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
template<>
|
template <>
|
||||||
inline void swap<Poco::Data::SimpleRowFormatter>(Poco::Data::SimpleRowFormatter& s1,
|
inline void swap<Poco::Data::SimpleRowFormatter>(Poco::Data::SimpleRowFormatter & s1, Poco::Data::SimpleRowFormatter & s2)
|
||||||
Poco::Data::SimpleRowFormatter& s2)
|
/// Full template specalization of std:::swap for SimpleRowFormatter
|
||||||
/// Full template specalization of std:::swap for SimpleRowFormatter
|
{
|
||||||
{
|
s1.swap(s2);
|
||||||
s1.swap(s2);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,56 +18,59 @@
|
|||||||
#define Data_StatementCreator_INCLUDED
|
#define Data_StatementCreator_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/AutoPtr.h"
|
||||||
#include "Poco/Data/Data.h"
|
#include "Poco/Data/Data.h"
|
||||||
#include "Poco/Data/SessionImpl.h"
|
#include "Poco/Data/SessionImpl.h"
|
||||||
#include "Poco/Data/Statement.h"
|
#include "Poco/Data/Statement.h"
|
||||||
#include "Poco/AutoPtr.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
{
|
||||||
|
namespace Data
|
||||||
|
|
||||||
class Data_API StatementCreator
|
|
||||||
/// A StatementCreator creates Statements.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
StatementCreator();
|
|
||||||
/// Creates an uninitialized StatementCreator.
|
|
||||||
|
|
||||||
StatementCreator(Poco::AutoPtr<SessionImpl> ptrImpl);
|
|
||||||
/// Creates a StatementCreator.
|
|
||||||
|
|
||||||
StatementCreator(const StatementCreator& other);
|
|
||||||
/// Creates a StatementCreator by copying another one.
|
|
||||||
|
|
||||||
~StatementCreator();
|
|
||||||
/// Destroys the StatementCreator.
|
|
||||||
|
|
||||||
StatementCreator& operator = (const StatementCreator& other);
|
|
||||||
/// Assignment operator.
|
|
||||||
|
|
||||||
void swap(StatementCreator& other);
|
|
||||||
/// Swaps the StatementCreator with another one.
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Statement operator << (const T& t)
|
|
||||||
/// Creates a Statement.
|
|
||||||
{
|
|
||||||
if (!_ptrImpl->isConnected())
|
|
||||||
throw NotConnectedException(_ptrImpl->connectionString());
|
|
||||||
|
|
||||||
Statement stmt(_ptrImpl->createStatementImpl());
|
|
||||||
stmt << t;
|
|
||||||
return stmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Poco::AutoPtr<SessionImpl> _ptrImpl;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
class Data_API StatementCreator
|
||||||
|
/// A StatementCreator creates Statements.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StatementCreator();
|
||||||
|
/// Creates an uninitialized StatementCreator.
|
||||||
|
|
||||||
|
StatementCreator(Poco::AutoPtr<SessionImpl> ptrImpl);
|
||||||
|
/// Creates a StatementCreator.
|
||||||
|
|
||||||
|
StatementCreator(const StatementCreator & other);
|
||||||
|
/// Creates a StatementCreator by copying another one.
|
||||||
|
|
||||||
|
~StatementCreator();
|
||||||
|
/// Destroys the StatementCreator.
|
||||||
|
|
||||||
|
StatementCreator & operator=(const StatementCreator & other);
|
||||||
|
/// Assignment operator.
|
||||||
|
|
||||||
|
void swap(StatementCreator & other);
|
||||||
|
/// Swaps the StatementCreator with another one.
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Statement operator<<(const T & t)
|
||||||
|
/// Creates a Statement.
|
||||||
|
{
|
||||||
|
if (!_ptrImpl->isConnected())
|
||||||
|
throw NotConnectedException(_ptrImpl->connectionString());
|
||||||
|
|
||||||
|
Statement stmt(_ptrImpl->createStatementImpl());
|
||||||
|
stmt << t;
|
||||||
|
return stmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Poco::AutoPtr<SessionImpl> _ptrImpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_StatementCreator_INCLUDED
|
#endif // Data_StatementCreator_INCLUDED
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -23,135 +23,137 @@
|
|||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
|
{
|
||||||
|
|
||||||
namespace Dynamic {
|
namespace Dynamic
|
||||||
|
{
|
||||||
|
|
||||||
class Var;
|
class Var;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DateTime;
|
class DateTime;
|
||||||
|
|
||||||
namespace Data {
|
namespace Data
|
||||||
|
|
||||||
|
|
||||||
class Date;
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API Time
|
|
||||||
/// Time class wraps a DateTime and exposes time related interface.
|
|
||||||
/// The purpose of this class is binding/extraction support for time fields.
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
Time();
|
|
||||||
/// Creates the Time
|
|
||||||
|
|
||||||
Time(int hour, int minute, int second);
|
|
||||||
/// Creates the Time
|
|
||||||
|
|
||||||
Time(const DateTime& dt);
|
|
||||||
/// Creates the Time from DateTime
|
|
||||||
|
|
||||||
~Time();
|
|
||||||
/// Destroys the Time.
|
|
||||||
|
|
||||||
int hour() const;
|
|
||||||
/// Returns the hour.
|
|
||||||
|
|
||||||
int minute() const;
|
|
||||||
/// Returns the minute.
|
|
||||||
|
|
||||||
int second() const;
|
|
||||||
/// Returns the second.
|
|
||||||
|
|
||||||
void assign(int hour, int minute, int second);
|
|
||||||
/// Assigns time.
|
|
||||||
|
|
||||||
Time& operator = (const Time& t);
|
|
||||||
/// Assignment operator for Time.
|
|
||||||
|
|
||||||
Time& operator = (const DateTime& dt);
|
|
||||||
/// Assignment operator for DateTime.
|
|
||||||
|
|
||||||
Time& operator = (const Poco::Dynamic::Var& var);
|
|
||||||
/// Assignment operator for Var.
|
|
||||||
|
|
||||||
bool operator == (const Time& time) const;
|
|
||||||
/// Equality operator.
|
|
||||||
|
|
||||||
bool operator != (const Time& time) const;
|
|
||||||
/// Inequality operator.
|
|
||||||
|
|
||||||
bool operator < (const Time& time) const;
|
|
||||||
/// Less then operator.
|
|
||||||
|
|
||||||
bool operator > (const Time& time) const;
|
|
||||||
/// Greater then operator.
|
|
||||||
|
|
||||||
private:
|
|
||||||
int _hour;
|
|
||||||
int _minute;
|
|
||||||
int _second;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
class Date;
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
inline int Time::hour() const
|
class Data_API Time
|
||||||
{
|
/// Time class wraps a DateTime and exposes time related interface.
|
||||||
return _hour;
|
/// The purpose of this class is binding/extraction support for time fields.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Time();
|
||||||
|
/// Creates the Time
|
||||||
|
|
||||||
|
Time(int hour, int minute, int second);
|
||||||
|
/// Creates the Time
|
||||||
|
|
||||||
|
Time(const DateTime & dt);
|
||||||
|
/// Creates the Time from DateTime
|
||||||
|
|
||||||
|
~Time();
|
||||||
|
/// Destroys the Time.
|
||||||
|
|
||||||
|
int hour() const;
|
||||||
|
/// Returns the hour.
|
||||||
|
|
||||||
|
int minute() const;
|
||||||
|
/// Returns the minute.
|
||||||
|
|
||||||
|
int second() const;
|
||||||
|
/// Returns the second.
|
||||||
|
|
||||||
|
void assign(int hour, int minute, int second);
|
||||||
|
/// Assigns time.
|
||||||
|
|
||||||
|
Time & operator=(const Time & t);
|
||||||
|
/// Assignment operator for Time.
|
||||||
|
|
||||||
|
Time & operator=(const DateTime & dt);
|
||||||
|
/// Assignment operator for DateTime.
|
||||||
|
|
||||||
|
Time & operator=(const Poco::Dynamic::Var & var);
|
||||||
|
/// Assignment operator for Var.
|
||||||
|
|
||||||
|
bool operator==(const Time & time) const;
|
||||||
|
/// Equality operator.
|
||||||
|
|
||||||
|
bool operator!=(const Time & time) const;
|
||||||
|
/// Inequality operator.
|
||||||
|
|
||||||
|
bool operator<(const Time & time) const;
|
||||||
|
/// Less then operator.
|
||||||
|
|
||||||
|
bool operator>(const Time & time) const;
|
||||||
|
/// Greater then operator.
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _hour;
|
||||||
|
int _minute;
|
||||||
|
int _second;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// inlines
|
||||||
|
//
|
||||||
|
inline int Time::hour() const
|
||||||
|
{
|
||||||
|
return _hour;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int Time::minute() const
|
||||||
|
{
|
||||||
|
return _minute;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int Time::second() const
|
||||||
|
{
|
||||||
|
return _second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Time & Time::operator=(const Time & t)
|
||||||
|
{
|
||||||
|
assign(t.hour(), t.minute(), t.second());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Time & Time::operator=(const DateTime & dt)
|
||||||
|
{
|
||||||
|
assign(dt.hour(), dt.minute(), dt.second());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Time::operator==(const Time & time) const
|
||||||
|
{
|
||||||
|
return _hour == time.hour() && _minute == time.minute() && _second == time.second();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Time::operator!=(const Time & time) const
|
||||||
|
{
|
||||||
|
return !(*this == time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Time::operator>(const Time & time) const
|
||||||
|
{
|
||||||
|
return !(*this == time) && !(*this < time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline int Time::minute() const
|
|
||||||
{
|
|
||||||
return _minute;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline int Time::second() const
|
|
||||||
{
|
|
||||||
return _second;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Time& Time::operator = (const Time& t)
|
|
||||||
{
|
|
||||||
assign(t.hour(), t.minute(), t.second());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Time& Time::operator = (const DateTime& dt)
|
|
||||||
{
|
|
||||||
assign(dt.hour(), dt.minute(), dt.second());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Time::operator == (const Time& time) const
|
|
||||||
{
|
|
||||||
return _hour == time.hour() &&
|
|
||||||
_minute == time.minute() &&
|
|
||||||
_second == time.second();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Time::operator != (const Time& time) const
|
|
||||||
{
|
|
||||||
return !(*this == time);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Time::operator > (const Time& time) const
|
|
||||||
{
|
|
||||||
return !(*this == time) && !(*this < time);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -159,71 +161,61 @@ inline bool Time::operator > (const Time& time) const
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Dynamic {
|
{
|
||||||
|
namespace Dynamic
|
||||||
|
|
||||||
template <>
|
|
||||||
class VarHolderImpl<Poco::Data::Time>: public VarHolder
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
VarHolderImpl(const Poco::Data::Time& val): _val(val)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~VarHolderImpl()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::type_info& type() const
|
|
||||||
{
|
|
||||||
return typeid(Poco::Data::Time);
|
|
||||||
}
|
|
||||||
|
|
||||||
void convert(Poco::Timestamp& val) const
|
|
||||||
{
|
|
||||||
Poco::DateTime dt;
|
|
||||||
dt.assign(dt.year(), dt.month(), dt.day(), _val.hour(), _val.minute(), _val.second());
|
|
||||||
val = dt.timestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
void convert(Poco::DateTime& val) const
|
|
||||||
{
|
|
||||||
Poco::DateTime dt;
|
|
||||||
dt.assign(dt.year(), dt.month(), dt.day(), _val.hour(), _val.minute(), _val.second());
|
|
||||||
val = dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
void convert(Poco::LocalDateTime& val) const
|
|
||||||
{
|
|
||||||
Poco::LocalDateTime ldt;
|
|
||||||
ldt.assign(ldt.year(), ldt.month(), ldt.day(), _val.hour(), _val.minute(), _val.second());
|
|
||||||
val = ldt;
|
|
||||||
}
|
|
||||||
|
|
||||||
void convert(std::string& val) const
|
|
||||||
{
|
|
||||||
DateTime dt(0, 1, 1, _val.hour(), _val.minute(), _val.second());
|
|
||||||
val = DateTimeFormatter::format(dt, "%H:%M:%S");
|
|
||||||
}
|
|
||||||
|
|
||||||
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
|
||||||
{
|
|
||||||
return cloneHolder(pVarHolder, _val);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Poco::Data::Time& value() const
|
|
||||||
{
|
|
||||||
return _val;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
VarHolderImpl();
|
|
||||||
Poco::Data::Time _val;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Dynamic
|
template <>
|
||||||
|
class VarHolderImpl<Poco::Data::Time> : public VarHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VarHolderImpl(const Poco::Data::Time & val) : _val(val) { }
|
||||||
|
|
||||||
|
~VarHolderImpl() { }
|
||||||
|
|
||||||
|
const std::type_info & type() const { return typeid(Poco::Data::Time); }
|
||||||
|
|
||||||
|
void convert(Poco::Timestamp & val) const
|
||||||
|
{
|
||||||
|
Poco::DateTime dt;
|
||||||
|
dt.assign(dt.year(), dt.month(), dt.day(), _val.hour(), _val.minute(), _val.second());
|
||||||
|
val = dt.timestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void convert(Poco::DateTime & val) const
|
||||||
|
{
|
||||||
|
Poco::DateTime dt;
|
||||||
|
dt.assign(dt.year(), dt.month(), dt.day(), _val.hour(), _val.minute(), _val.second());
|
||||||
|
val = dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void convert(Poco::LocalDateTime & val) const
|
||||||
|
{
|
||||||
|
Poco::LocalDateTime ldt;
|
||||||
|
ldt.assign(ldt.year(), ldt.month(), ldt.day(), _val.hour(), _val.minute(), _val.second());
|
||||||
|
val = ldt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void convert(std::string & val) const
|
||||||
|
{
|
||||||
|
DateTime dt(0, 1, 1, _val.hour(), _val.minute(), _val.second());
|
||||||
|
val = DateTimeFormatter::format(dt, "%H:%M:%S");
|
||||||
|
}
|
||||||
|
|
||||||
|
VarHolder * clone(Placeholder<VarHolder> * pVarHolder = 0) const { return cloneHolder(pVarHolder, _val); }
|
||||||
|
|
||||||
|
const Poco::Data::Time & value() const { return _val; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
VarHolderImpl();
|
||||||
|
Poco::Data::Time _val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace Poco::Dynamic
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_Time_INCLUDED
|
#endif // Data_Time_INCLUDED
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef Data_Transaction_INCLUDED
|
#ifndef Data_Transaction_INCLUDED
|
||||||
#define Data_Transaction_INCLUDED
|
#define Data_Transaction_INCLUDED
|
||||||
|
|
||||||
@ -24,171 +23,177 @@
|
|||||||
#include "Poco/Logger.h"
|
#include "Poco/Logger.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
namespace Data {
|
|
||||||
|
|
||||||
|
|
||||||
class Data_API Transaction
|
|
||||||
/// Transaction helps with transactions in domain logic.
|
|
||||||
/// When an Transaction object is created, it first checks whether a
|
|
||||||
/// transaction is in progress. If not, a new transaction is created.
|
|
||||||
/// When the Transaction is destroyed, and commit() has been called,
|
|
||||||
/// nothing is done. Otherwise, the current transaction is rolled back.
|
|
||||||
/// See Transaction for more details and purpose of this template.
|
|
||||||
{
|
{
|
||||||
public:
|
namespace Data
|
||||||
Transaction(Poco::Data::Session& session, Poco::Logger* pLogger = 0);
|
|
||||||
/// Creates the Transaction and starts it, using the given database session and logger.
|
|
||||||
|
|
||||||
Transaction(Poco::Data::Session& session, bool start);
|
|
||||||
/// Creates the Transaction, using the given database session.
|
|
||||||
/// If start is true, transaction is started, otherwise begin() must be called
|
|
||||||
/// to start the transaction.
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Transaction(Poco::Data::Session& rSession, T& t, Poco::Logger* pLogger = 0):
|
|
||||||
_rSession(rSession),
|
|
||||||
_pLogger(pLogger)
|
|
||||||
/// Creates the Transaction, using the given database session, transactor and logger.
|
|
||||||
/// The transactor type must provide operator () overload taking non-const Session
|
|
||||||
/// reference as an argument.
|
|
||||||
///
|
|
||||||
/// When transaction is created using this constructor, it is executed and
|
|
||||||
/// committed automatically. If no error occurs, rollback is disabled and does
|
|
||||||
/// not occur at destruction time. If an error occurs resulting in exception being
|
|
||||||
/// thrown, the transaction is rolled back and exception propagated to calling code.
|
|
||||||
///
|
|
||||||
/// Example usage:
|
|
||||||
///
|
|
||||||
/// struct Transactor
|
|
||||||
/// {
|
|
||||||
/// void operator () (Session& session) const
|
|
||||||
/// {
|
|
||||||
/// // do something ...
|
|
||||||
/// }
|
|
||||||
/// };
|
|
||||||
///
|
|
||||||
/// Transactor tr;
|
|
||||||
/// Transaction tn(session, tr);
|
|
||||||
{
|
|
||||||
try { transact(t); }
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
if (_pLogger) _pLogger->error("Error executing transaction.");
|
|
||||||
rollback();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~Transaction();
|
|
||||||
/// Destroys the Transaction.
|
|
||||||
/// Rolls back the current database transaction if it has not been committed
|
|
||||||
/// (by calling commit()), or rolled back (by calling rollback()).
|
|
||||||
///
|
|
||||||
/// If an exception is thrown during rollback, the exception is logged
|
|
||||||
/// and no further action is taken.
|
|
||||||
|
|
||||||
void setIsolation(Poco::UInt32 ti);
|
|
||||||
/// Sets the transaction isolation level.
|
|
||||||
|
|
||||||
Poco::UInt32 getIsolation();
|
|
||||||
/// Returns the transaction isolation level.
|
|
||||||
|
|
||||||
bool hasIsolation(Poco::UInt32 ti);
|
|
||||||
/// Returns true iff the transaction isolation level corresponding
|
|
||||||
/// to the supplied bitmask is supported.
|
|
||||||
|
|
||||||
bool isIsolation(Poco::UInt32 ti);
|
|
||||||
/// Returns true iff the transaction isolation level corresponds
|
|
||||||
/// to the supplied bitmask.
|
|
||||||
|
|
||||||
void execute(const std::string& sql, bool doCommit = true);
|
|
||||||
/// Executes and, if doCommit is true, commits the transaction.
|
|
||||||
/// Passing true value for commit disables rollback during destruction
|
|
||||||
/// of this Transaction object.
|
|
||||||
|
|
||||||
void execute(const std::vector<std::string>& sql);
|
|
||||||
/// Executes all the SQL statements supplied in the vector and, after the last
|
|
||||||
/// one is successfully executed, commits the transaction.
|
|
||||||
/// If an error occurs during execution, transaction is rolled back.
|
|
||||||
/// Passing true value for commit disables rollback during destruction
|
|
||||||
/// of this Transaction object.
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void transact(T& t)
|
|
||||||
/// Executes the transactor and, unless transactor throws an exception,
|
|
||||||
/// commits the transaction.
|
|
||||||
{
|
|
||||||
if (!isActive()) begin();
|
|
||||||
t(_rSession);
|
|
||||||
commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void commit();
|
|
||||||
/// Commits the current transaction.
|
|
||||||
|
|
||||||
void rollback();
|
|
||||||
/// Rolls back the current transaction.
|
|
||||||
|
|
||||||
bool isActive();
|
|
||||||
/// Returns false after the transaction has been committed or rolled back,
|
|
||||||
/// true if the transaction is ongoing.
|
|
||||||
|
|
||||||
void setLogger(Poco::Logger* pLogger);
|
|
||||||
/// Sets the logger for this transaction.
|
|
||||||
/// Transaction does not take the ownership of the pointer.
|
|
||||||
|
|
||||||
private:
|
|
||||||
Transaction();
|
|
||||||
Transaction(const Transaction&);
|
|
||||||
Transaction& operator = (const Transaction&);
|
|
||||||
|
|
||||||
void begin();
|
|
||||||
/// Begins the transaction if the session is already not in transaction.
|
|
||||||
/// Otherwise does nothing.
|
|
||||||
|
|
||||||
Session _rSession;
|
|
||||||
Logger* _pLogger;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Transaction::isActive()
|
|
||||||
{
|
{
|
||||||
return _rSession.isTransaction();
|
|
||||||
|
|
||||||
|
class Data_API Transaction
|
||||||
|
/// Transaction helps with transactions in domain logic.
|
||||||
|
/// When an Transaction object is created, it first checks whether a
|
||||||
|
/// transaction is in progress. If not, a new transaction is created.
|
||||||
|
/// When the Transaction is destroyed, and commit() has been called,
|
||||||
|
/// nothing is done. Otherwise, the current transaction is rolled back.
|
||||||
|
/// See Transaction for more details and purpose of this template.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Transaction(Poco::Data::Session & session, Poco::Logger * pLogger = 0);
|
||||||
|
/// Creates the Transaction and starts it, using the given database session and logger.
|
||||||
|
|
||||||
|
Transaction(Poco::Data::Session & session, bool start);
|
||||||
|
/// Creates the Transaction, using the given database session.
|
||||||
|
/// If start is true, transaction is started, otherwise begin() must be called
|
||||||
|
/// to start the transaction.
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Transaction(Poco::Data::Session & rSession, T & t, Poco::Logger * pLogger = 0) : _rSession(rSession), _pLogger(pLogger)
|
||||||
|
/// Creates the Transaction, using the given database session, transactor and logger.
|
||||||
|
/// The transactor type must provide operator () overload taking non-const Session
|
||||||
|
/// reference as an argument.
|
||||||
|
///
|
||||||
|
/// When transaction is created using this constructor, it is executed and
|
||||||
|
/// committed automatically. If no error occurs, rollback is disabled and does
|
||||||
|
/// not occur at destruction time. If an error occurs resulting in exception being
|
||||||
|
/// thrown, the transaction is rolled back and exception propagated to calling code.
|
||||||
|
///
|
||||||
|
/// Example usage:
|
||||||
|
///
|
||||||
|
/// struct Transactor
|
||||||
|
/// {
|
||||||
|
/// void operator () (Session& session) const
|
||||||
|
/// {
|
||||||
|
/// // do something ...
|
||||||
|
/// }
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// Transactor tr;
|
||||||
|
/// Transaction tn(session, tr);
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
transact(t);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
if (_pLogger)
|
||||||
|
_pLogger->error("Error executing transaction.");
|
||||||
|
rollback();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~Transaction();
|
||||||
|
/// Destroys the Transaction.
|
||||||
|
/// Rolls back the current database transaction if it has not been committed
|
||||||
|
/// (by calling commit()), or rolled back (by calling rollback()).
|
||||||
|
///
|
||||||
|
/// If an exception is thrown during rollback, the exception is logged
|
||||||
|
/// and no further action is taken.
|
||||||
|
|
||||||
|
void setIsolation(Poco::UInt32 ti);
|
||||||
|
/// Sets the transaction isolation level.
|
||||||
|
|
||||||
|
Poco::UInt32 getIsolation();
|
||||||
|
/// Returns the transaction isolation level.
|
||||||
|
|
||||||
|
bool hasIsolation(Poco::UInt32 ti);
|
||||||
|
/// Returns true iff the transaction isolation level corresponding
|
||||||
|
/// to the supplied bitmask is supported.
|
||||||
|
|
||||||
|
bool isIsolation(Poco::UInt32 ti);
|
||||||
|
/// Returns true iff the transaction isolation level corresponds
|
||||||
|
/// to the supplied bitmask.
|
||||||
|
|
||||||
|
void execute(const std::string & sql, bool doCommit = true);
|
||||||
|
/// Executes and, if doCommit is true, commits the transaction.
|
||||||
|
/// Passing true value for commit disables rollback during destruction
|
||||||
|
/// of this Transaction object.
|
||||||
|
|
||||||
|
void execute(const std::vector<std::string> & sql);
|
||||||
|
/// Executes all the SQL statements supplied in the vector and, after the last
|
||||||
|
/// one is successfully executed, commits the transaction.
|
||||||
|
/// If an error occurs during execution, transaction is rolled back.
|
||||||
|
/// Passing true value for commit disables rollback during destruction
|
||||||
|
/// of this Transaction object.
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void transact(T & t)
|
||||||
|
/// Executes the transactor and, unless transactor throws an exception,
|
||||||
|
/// commits the transaction.
|
||||||
|
{
|
||||||
|
if (!isActive())
|
||||||
|
begin();
|
||||||
|
t(_rSession);
|
||||||
|
commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void commit();
|
||||||
|
/// Commits the current transaction.
|
||||||
|
|
||||||
|
void rollback();
|
||||||
|
/// Rolls back the current transaction.
|
||||||
|
|
||||||
|
bool isActive();
|
||||||
|
/// Returns false after the transaction has been committed or rolled back,
|
||||||
|
/// true if the transaction is ongoing.
|
||||||
|
|
||||||
|
void setLogger(Poco::Logger * pLogger);
|
||||||
|
/// Sets the logger for this transaction.
|
||||||
|
/// Transaction does not take the ownership of the pointer.
|
||||||
|
|
||||||
|
private:
|
||||||
|
Transaction();
|
||||||
|
Transaction(const Transaction &);
|
||||||
|
Transaction & operator=(const Transaction &);
|
||||||
|
|
||||||
|
void begin();
|
||||||
|
/// Begins the transaction if the session is already not in transaction.
|
||||||
|
/// Otherwise does nothing.
|
||||||
|
|
||||||
|
Session _rSession;
|
||||||
|
Logger * _pLogger;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Transaction::isActive()
|
||||||
|
{
|
||||||
|
return _rSession.isTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Transaction::setIsolation(Poco::UInt32 ti)
|
||||||
|
{
|
||||||
|
_rSession.setTransactionIsolation(ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Poco::UInt32 Transaction::getIsolation()
|
||||||
|
{
|
||||||
|
return _rSession.getTransactionIsolation();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Transaction::hasIsolation(Poco::UInt32 ti)
|
||||||
|
{
|
||||||
|
return _rSession.isTransactionIsolation(ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Transaction::isIsolation(Poco::UInt32 ti)
|
||||||
|
{
|
||||||
|
return _rSession.isTransactionIsolation(ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Transaction::setLogger(Poco::Logger * pLogger)
|
||||||
|
{
|
||||||
|
_pLogger = pLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // namespace Poco::Data
|
||||||
|
|
||||||
inline void Transaction::setIsolation(Poco::UInt32 ti)
|
|
||||||
{
|
|
||||||
_rSession.setTransactionIsolation(ti);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Poco::UInt32 Transaction::getIsolation()
|
|
||||||
{
|
|
||||||
return _rSession.getTransactionIsolation();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Transaction::hasIsolation(Poco::UInt32 ti)
|
|
||||||
{
|
|
||||||
return _rSession.isTransactionIsolation(ti);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Transaction::isIsolation(Poco::UInt32 ti)
|
|
||||||
{
|
|
||||||
return _rSession.isTransactionIsolation(ti);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void Transaction::setLogger(Poco::Logger* pLogger)
|
|
||||||
{
|
|
||||||
_pLogger = pLogger;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
|
||||||
|
|
||||||
|
|
||||||
#endif // Data_Transaction_INCLUDED
|
#endif // Data_Transaction_INCLUDED
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -22,26 +22,27 @@
|
|||||||
#include "Poco/TextEncoding.h"
|
#include "Poco/TextEncoding.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
class Foundation_API ASCIIEncoding: public TextEncoding
|
class Foundation_API ASCIIEncoding : public TextEncoding
|
||||||
/// 7-bit ASCII text encoding.
|
/// 7-bit ASCII text encoding.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ASCIIEncoding();
|
ASCIIEncoding();
|
||||||
~ASCIIEncoding();
|
~ASCIIEncoding();
|
||||||
const char* canonicalName() const;
|
const char * canonicalName() const;
|
||||||
bool isA(const std::string& encodingName) const;
|
bool isA(const std::string & encodingName) const;
|
||||||
const CharacterMap& characterMap() const;
|
const CharacterMap & characterMap() const;
|
||||||
int convert(const unsigned char* bytes) const;
|
int convert(const unsigned char * bytes) const;
|
||||||
int convert(int ch, unsigned char* bytes, int length) const;
|
int convert(int ch, unsigned char * bytes, int length) const;
|
||||||
int queryConvert(const unsigned char* bytes, int length) const;
|
int queryConvert(const unsigned char * bytes, int length) const;
|
||||||
int sequenceLength(const unsigned char* bytes, int length) const;
|
int sequenceLength(const unsigned char * bytes, int length) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const char* _names[];
|
static const char * _names[];
|
||||||
static const CharacterMap _charMap;
|
static const CharacterMap _charMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,346 +18,340 @@
|
|||||||
#define Foundation_AbstractCache_INCLUDED
|
#define Foundation_AbstractCache_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/KeyValueArgs.h"
|
#include <cstddef>
|
||||||
#include "Poco/ValidArgs.h"
|
|
||||||
#include "Poco/Mutex.h"
|
|
||||||
#include "Poco/Exception.h"
|
|
||||||
#include "Poco/FIFOEvent.h"
|
|
||||||
#include "Poco/EventArgs.h"
|
|
||||||
#include "Poco/Delegate.h"
|
|
||||||
#include "Poco/SharedPtr.h"
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <cstddef>
|
#include "Poco/Delegate.h"
|
||||||
|
#include "Poco/EventArgs.h"
|
||||||
|
#include "Poco/Exception.h"
|
||||||
|
#include "Poco/FIFOEvent.h"
|
||||||
|
#include "Poco/KeyValueArgs.h"
|
||||||
|
#include "Poco/Mutex.h"
|
||||||
|
#include "Poco/SharedPtr.h"
|
||||||
|
#include "Poco/ValidArgs.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
template <class TKey, class TValue, class TStrategy, class TMutex = FastMutex, class TEventMutex = FastMutex>
|
template <class TKey, class TValue, class TStrategy, class TMutex = FastMutex, class TEventMutex = FastMutex>
|
||||||
class AbstractCache
|
class AbstractCache
|
||||||
/// An AbstractCache is the interface of all caches.
|
/// An AbstractCache is the interface of all caches.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FIFOEvent<const KeyValueArgs<TKey, TValue >, TEventMutex > Add;
|
FIFOEvent<const KeyValueArgs<TKey, TValue>, TEventMutex> Add;
|
||||||
FIFOEvent<const KeyValueArgs<TKey, TValue >, TEventMutex > Update;
|
FIFOEvent<const KeyValueArgs<TKey, TValue>, TEventMutex> Update;
|
||||||
FIFOEvent<const TKey, TEventMutex> Remove;
|
FIFOEvent<const TKey, TEventMutex> Remove;
|
||||||
FIFOEvent<const TKey, TEventMutex> Get;
|
FIFOEvent<const TKey, TEventMutex> Get;
|
||||||
FIFOEvent<const EventArgs, TEventMutex> Clear;
|
FIFOEvent<const EventArgs, TEventMutex> Clear;
|
||||||
|
|
||||||
typedef std::map<TKey, SharedPtr<TValue > > DataHolder;
|
typedef std::map<TKey, SharedPtr<TValue>> DataHolder;
|
||||||
typedef typename DataHolder::iterator Iterator;
|
typedef typename DataHolder::iterator Iterator;
|
||||||
typedef typename DataHolder::const_iterator ConstIterator;
|
typedef typename DataHolder::const_iterator ConstIterator;
|
||||||
typedef std::set<TKey> KeySet;
|
typedef std::set<TKey> KeySet;
|
||||||
|
|
||||||
AbstractCache()
|
AbstractCache() { initialize(); }
|
||||||
{
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractCache(const TStrategy & strategy)
|
AbstractCache(const TStrategy & strategy) : _strategy(strategy) { initialize(); }
|
||||||
: _strategy(strategy)
|
|
||||||
{
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~AbstractCache()
|
virtual ~AbstractCache()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
uninitialize();
|
uninitialize();
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
poco_unexpected();
|
poco_unexpected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(const TKey& key, const TValue& val)
|
void add(const TKey & key, const TValue & val)
|
||||||
/// Adds the key value pair to the cache.
|
/// Adds the key value pair to the cache.
|
||||||
/// If for the key already an entry exists, it will be overwritten.
|
/// If for the key already an entry exists, it will be overwritten.
|
||||||
{
|
{
|
||||||
typename TMutex::ScopedLock lock(_mutex);
|
typename TMutex::ScopedLock lock(_mutex);
|
||||||
doAdd(key, val);
|
doAdd(key, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(const TKey& key, const TValue& val)
|
void update(const TKey & key, const TValue & val)
|
||||||
/// Adds the key value pair to the cache. Note that adding a NULL SharedPtr will fail!
|
/// Adds the key value pair to the cache. Note that adding a NULL SharedPtr will fail!
|
||||||
/// If for the key already an entry exists, it will be overwritten.
|
/// If for the key already an entry exists, it will be overwritten.
|
||||||
/// The difference to add is that no remove or add events are thrown in this case,
|
/// The difference to add is that no remove or add events are thrown in this case,
|
||||||
/// just a simply silent update is performed
|
/// just a simply silent update is performed
|
||||||
/// If the key does not exist the behavior is equal to add, ie. an add event is thrown
|
/// If the key does not exist the behavior is equal to add, ie. an add event is thrown
|
||||||
{
|
{
|
||||||
typename TMutex::ScopedLock lock(_mutex);
|
typename TMutex::ScopedLock lock(_mutex);
|
||||||
doUpdate(key, val);
|
doUpdate(key, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(const TKey& key, SharedPtr<TValue > val)
|
void add(const TKey & key, SharedPtr<TValue> val)
|
||||||
/// Adds the key value pair to the cache. Note that adding a NULL SharedPtr will fail!
|
/// Adds the key value pair to the cache. Note that adding a NULL SharedPtr will fail!
|
||||||
/// If for the key already an entry exists, it will be overwritten, ie. first a remove event
|
/// If for the key already an entry exists, it will be overwritten, ie. first a remove event
|
||||||
/// is thrown, then a add event
|
/// is thrown, then a add event
|
||||||
{
|
{
|
||||||
typename TMutex::ScopedLock lock(_mutex);
|
typename TMutex::ScopedLock lock(_mutex);
|
||||||
doAdd(key, val);
|
doAdd(key, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(const TKey& key, SharedPtr<TValue > val)
|
void update(const TKey & key, SharedPtr<TValue> val)
|
||||||
/// Adds the key value pair to the cache. Note that adding a NULL SharedPtr will fail!
|
/// Adds the key value pair to the cache. Note that adding a NULL SharedPtr will fail!
|
||||||
/// If for the key already an entry exists, it will be overwritten.
|
/// If for the key already an entry exists, it will be overwritten.
|
||||||
/// The difference to add is that no remove or add events are thrown in this case,
|
/// The difference to add is that no remove or add events are thrown in this case,
|
||||||
/// just an Update is thrown
|
/// just an Update is thrown
|
||||||
/// If the key does not exist the behavior is equal to add, ie. an add event is thrown
|
/// If the key does not exist the behavior is equal to add, ie. an add event is thrown
|
||||||
{
|
{
|
||||||
typename TMutex::ScopedLock lock(_mutex);
|
typename TMutex::ScopedLock lock(_mutex);
|
||||||
doUpdate(key, val);
|
doUpdate(key, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(const TKey& key)
|
void remove(const TKey & key)
|
||||||
/// Removes an entry from the cache. If the entry is not found,
|
/// Removes an entry from the cache. If the entry is not found,
|
||||||
/// the remove is ignored.
|
/// the remove is ignored.
|
||||||
{
|
{
|
||||||
typename TMutex::ScopedLock lock(_mutex);
|
typename TMutex::ScopedLock lock(_mutex);
|
||||||
Iterator it = _data.find(key);
|
Iterator it = _data.find(key);
|
||||||
doRemove(it);
|
doRemove(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has(const TKey& key) const
|
bool has(const TKey & key) const
|
||||||
/// Returns true if the cache contains a value for the key.
|
/// Returns true if the cache contains a value for the key.
|
||||||
{
|
{
|
||||||
typename TMutex::ScopedLock lock(_mutex);
|
typename TMutex::ScopedLock lock(_mutex);
|
||||||
return doHas(key);
|
return doHas(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<TValue> get(const TKey& key)
|
SharedPtr<TValue> get(const TKey & key)
|
||||||
/// Returns a SharedPtr of the value. The SharedPointer will remain valid
|
/// Returns a SharedPtr of the value. The SharedPointer will remain valid
|
||||||
/// even when cache replacement removes the element.
|
/// even when cache replacement removes the element.
|
||||||
/// If for the key no value exists, an empty SharedPtr is returned.
|
/// If for the key no value exists, an empty SharedPtr is returned.
|
||||||
{
|
{
|
||||||
typename TMutex::ScopedLock lock(_mutex);
|
typename TMutex::ScopedLock lock(_mutex);
|
||||||
return doGet (key);
|
return doGet(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
/// Removes all elements from the cache.
|
/// Removes all elements from the cache.
|
||||||
{
|
{
|
||||||
typename TMutex::ScopedLock lock(_mutex);
|
typename TMutex::ScopedLock lock(_mutex);
|
||||||
doClear();
|
doClear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t size()
|
std::size_t size()
|
||||||
/// Returns the number of cached elements
|
/// Returns the number of cached elements
|
||||||
{
|
{
|
||||||
typename TMutex::ScopedLock lock(_mutex);
|
typename TMutex::ScopedLock lock(_mutex);
|
||||||
doReplace();
|
doReplace();
|
||||||
return _data.size();
|
return _data.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void forceReplace()
|
void forceReplace()
|
||||||
/// Forces cache replacement. Note that Poco's cache strategy use for efficiency reason no background thread
|
/// Forces cache replacement. Note that Poco's cache strategy use for efficiency reason no background thread
|
||||||
/// which periodically triggers cache replacement. Cache Replacement is only started when the cache is modified
|
/// which periodically triggers cache replacement. Cache Replacement is only started when the cache is modified
|
||||||
/// from outside, i.e. add is called, or when a user tries to access an cache element via get.
|
/// from outside, i.e. add is called, or when a user tries to access an cache element via get.
|
||||||
/// In some cases, i.e. expire based caching where for a long time no access to the cache happens,
|
/// In some cases, i.e. expire based caching where for a long time no access to the cache happens,
|
||||||
/// it might be desirable to be able to trigger cache replacement manually.
|
/// it might be desirable to be able to trigger cache replacement manually.
|
||||||
{
|
{
|
||||||
typename TMutex::ScopedLock lock(_mutex);
|
typename TMutex::ScopedLock lock(_mutex);
|
||||||
doReplace();
|
doReplace();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<TKey> getAllKeys()
|
std::set<TKey> getAllKeys()
|
||||||
/// Returns a copy of all keys stored in the cache
|
/// Returns a copy of all keys stored in the cache
|
||||||
{
|
{
|
||||||
typename TMutex::ScopedLock lock(_mutex);
|
typename TMutex::ScopedLock lock(_mutex);
|
||||||
doReplace();
|
doReplace();
|
||||||
ConstIterator it = _data.begin();
|
ConstIterator it = _data.begin();
|
||||||
ConstIterator itEnd = _data.end();
|
ConstIterator itEnd = _data.end();
|
||||||
std::set<TKey> result;
|
std::set<TKey> result;
|
||||||
for (; it != itEnd; ++it)
|
for (; it != itEnd; ++it)
|
||||||
result.insert(it->first);
|
result.insert(it->first);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mutable FIFOEvent<ValidArgs<TKey> > IsValid;
|
mutable FIFOEvent<ValidArgs<TKey>> IsValid;
|
||||||
mutable FIFOEvent<KeySet> Replace;
|
mutable FIFOEvent<KeySet> Replace;
|
||||||
|
|
||||||
void initialize()
|
void initialize()
|
||||||
/// Sets up event registration.
|
/// Sets up event registration.
|
||||||
{
|
{
|
||||||
Add += Delegate<TStrategy, const KeyValueArgs<TKey, TValue> >(&_strategy, &TStrategy::onAdd);
|
Add += Delegate<TStrategy, const KeyValueArgs<TKey, TValue>>(&_strategy, &TStrategy::onAdd);
|
||||||
Update += Delegate<TStrategy, const KeyValueArgs<TKey, TValue> >(&_strategy, &TStrategy::onUpdate);
|
Update += Delegate<TStrategy, const KeyValueArgs<TKey, TValue>>(&_strategy, &TStrategy::onUpdate);
|
||||||
Remove += Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onRemove);
|
Remove += Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onRemove);
|
||||||
Get += Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onGet);
|
Get += Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onGet);
|
||||||
Clear += Delegate<TStrategy, const EventArgs>(&_strategy, &TStrategy::onClear);
|
Clear += Delegate<TStrategy, const EventArgs>(&_strategy, &TStrategy::onClear);
|
||||||
IsValid += Delegate<TStrategy, ValidArgs<TKey> >(&_strategy, &TStrategy::onIsValid);
|
IsValid += Delegate<TStrategy, ValidArgs<TKey>>(&_strategy, &TStrategy::onIsValid);
|
||||||
Replace += Delegate<TStrategy, KeySet>(&_strategy, &TStrategy::onReplace);
|
Replace += Delegate<TStrategy, KeySet>(&_strategy, &TStrategy::onReplace);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninitialize()
|
void uninitialize()
|
||||||
/// Reverts event registration.
|
/// Reverts event registration.
|
||||||
{
|
{
|
||||||
Add -= Delegate<TStrategy, const KeyValueArgs<TKey, TValue> >(&_strategy, &TStrategy::onAdd );
|
Add -= Delegate<TStrategy, const KeyValueArgs<TKey, TValue>>(&_strategy, &TStrategy::onAdd);
|
||||||
Update -= Delegate<TStrategy, const KeyValueArgs<TKey, TValue> >(&_strategy, &TStrategy::onUpdate);
|
Update -= Delegate<TStrategy, const KeyValueArgs<TKey, TValue>>(&_strategy, &TStrategy::onUpdate);
|
||||||
Remove -= Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onRemove);
|
Remove -= Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onRemove);
|
||||||
Get -= Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onGet);
|
Get -= Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onGet);
|
||||||
Clear -= Delegate<TStrategy, const EventArgs>(&_strategy, &TStrategy::onClear);
|
Clear -= Delegate<TStrategy, const EventArgs>(&_strategy, &TStrategy::onClear);
|
||||||
IsValid -= Delegate<TStrategy, ValidArgs<TKey> >(&_strategy, &TStrategy::onIsValid);
|
IsValid -= Delegate<TStrategy, ValidArgs<TKey>>(&_strategy, &TStrategy::onIsValid);
|
||||||
Replace -= Delegate<TStrategy, KeySet>(&_strategy, &TStrategy::onReplace);
|
Replace -= Delegate<TStrategy, KeySet>(&_strategy, &TStrategy::onReplace);
|
||||||
}
|
}
|
||||||
|
|
||||||
void doAdd(const TKey& key, const TValue& val)
|
void doAdd(const TKey & key, const TValue & val)
|
||||||
/// Adds the key value pair to the cache.
|
/// Adds the key value pair to the cache.
|
||||||
/// If for the key already an entry exists, it will be overwritten.
|
/// If for the key already an entry exists, it will be overwritten.
|
||||||
{
|
{
|
||||||
Iterator it = _data.find(key);
|
Iterator it = _data.find(key);
|
||||||
doRemove(it);
|
doRemove(it);
|
||||||
|
|
||||||
KeyValueArgs<TKey, TValue> args(key, val);
|
KeyValueArgs<TKey, TValue> args(key, val);
|
||||||
Add.notify(this, args);
|
Add.notify(this, args);
|
||||||
_data.insert(std::make_pair(key, SharedPtr<TValue>(new TValue(val))));
|
_data.insert(std::make_pair(key, SharedPtr<TValue>(new TValue(val))));
|
||||||
|
|
||||||
doReplace();
|
|
||||||
}
|
|
||||||
|
|
||||||
void doAdd(const TKey& key, SharedPtr<TValue>& val)
|
doReplace();
|
||||||
/// Adds the key value pair to the cache.
|
}
|
||||||
/// If for the key already an entry exists, it will be overwritten.
|
|
||||||
{
|
|
||||||
Iterator it = _data.find(key);
|
|
||||||
doRemove(it);
|
|
||||||
|
|
||||||
KeyValueArgs<TKey, TValue> args(key, *val);
|
void doAdd(const TKey & key, SharedPtr<TValue> & val)
|
||||||
Add.notify(this, args);
|
/// Adds the key value pair to the cache.
|
||||||
_data.insert(std::make_pair(key, val));
|
/// If for the key already an entry exists, it will be overwritten.
|
||||||
|
{
|
||||||
doReplace();
|
Iterator it = _data.find(key);
|
||||||
}
|
doRemove(it);
|
||||||
|
|
||||||
void doUpdate(const TKey& key, const TValue& val)
|
KeyValueArgs<TKey, TValue> args(key, *val);
|
||||||
/// Adds the key value pair to the cache.
|
Add.notify(this, args);
|
||||||
/// If for the key already an entry exists, it will be overwritten.
|
_data.insert(std::make_pair(key, val));
|
||||||
{
|
|
||||||
KeyValueArgs<TKey, TValue> args(key, val);
|
|
||||||
Iterator it = _data.find(key);
|
|
||||||
if (it == _data.end())
|
|
||||||
{
|
|
||||||
Add.notify(this, args);
|
|
||||||
_data.insert(std::make_pair(key, SharedPtr<TValue>(new TValue(val))));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Update.notify(this, args);
|
|
||||||
it->second = SharedPtr<TValue>(new TValue(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
doReplace();
|
|
||||||
}
|
|
||||||
|
|
||||||
void doUpdate(const TKey& key, SharedPtr<TValue>& val)
|
doReplace();
|
||||||
/// Adds the key value pair to the cache.
|
}
|
||||||
/// If for the key already an entry exists, it will be overwritten.
|
|
||||||
{
|
|
||||||
KeyValueArgs<TKey, TValue> args(key, *val);
|
|
||||||
Iterator it = _data.find(key);
|
|
||||||
if (it == _data.end())
|
|
||||||
{
|
|
||||||
Add.notify(this, args);
|
|
||||||
_data.insert(std::make_pair(key, val));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Update.notify(this, args);
|
|
||||||
it->second = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
doReplace();
|
|
||||||
}
|
|
||||||
|
|
||||||
void doRemove(Iterator it)
|
void doUpdate(const TKey & key, const TValue & val)
|
||||||
/// Removes an entry from the cache. If the entry is not found
|
/// Adds the key value pair to the cache.
|
||||||
/// the remove is ignored.
|
/// If for the key already an entry exists, it will be overwritten.
|
||||||
{
|
{
|
||||||
if (it != _data.end())
|
KeyValueArgs<TKey, TValue> args(key, val);
|
||||||
{
|
Iterator it = _data.find(key);
|
||||||
Remove.notify(this, it->first);
|
if (it == _data.end())
|
||||||
_data.erase(it);
|
{
|
||||||
}
|
Add.notify(this, args);
|
||||||
}
|
_data.insert(std::make_pair(key, SharedPtr<TValue>(new TValue(val))));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Update.notify(this, args);
|
||||||
|
it->second = SharedPtr<TValue>(new TValue(val));
|
||||||
|
}
|
||||||
|
|
||||||
bool doHas(const TKey& key) const
|
doReplace();
|
||||||
/// Returns true if the cache contains a value for the key
|
}
|
||||||
{
|
|
||||||
// ask the strategy if the key is valid
|
|
||||||
ConstIterator it = _data.find(key);
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (it != _data.end())
|
void doUpdate(const TKey & key, SharedPtr<TValue> & val)
|
||||||
{
|
/// Adds the key value pair to the cache.
|
||||||
ValidArgs<TKey> args(key);
|
/// If for the key already an entry exists, it will be overwritten.
|
||||||
IsValid.notify(this, args);
|
{
|
||||||
result = args.isValid();
|
KeyValueArgs<TKey, TValue> args(key, *val);
|
||||||
}
|
Iterator it = _data.find(key);
|
||||||
|
if (it == _data.end())
|
||||||
|
{
|
||||||
|
Add.notify(this, args);
|
||||||
|
_data.insert(std::make_pair(key, val));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Update.notify(this, args);
|
||||||
|
it->second = val;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
doReplace();
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<TValue> doGet(const TKey& key)
|
void doRemove(Iterator it)
|
||||||
/// Returns a SharedPtr of the cache entry, returns 0 if for
|
/// Removes an entry from the cache. If the entry is not found
|
||||||
/// the key no value was found
|
/// the remove is ignored.
|
||||||
{
|
{
|
||||||
Iterator it = _data.find(key);
|
if (it != _data.end())
|
||||||
SharedPtr<TValue> result;
|
{
|
||||||
|
Remove.notify(this, it->first);
|
||||||
|
_data.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (it != _data.end())
|
bool doHas(const TKey & key) const
|
||||||
{
|
/// Returns true if the cache contains a value for the key
|
||||||
// inform all strategies that a read-access to an element happens
|
{
|
||||||
Get.notify(this, key);
|
// ask the strategy if the key is valid
|
||||||
// ask all strategies if the key is valid
|
ConstIterator it = _data.find(key);
|
||||||
ValidArgs<TKey> args(key);
|
bool result = false;
|
||||||
IsValid.notify(this, args);
|
|
||||||
|
|
||||||
if (!args.isValid())
|
if (it != _data.end())
|
||||||
{
|
{
|
||||||
doRemove(it);
|
ValidArgs<TKey> args(key);
|
||||||
}
|
IsValid.notify(this, args);
|
||||||
else
|
result = args.isValid();
|
||||||
{
|
}
|
||||||
result = it->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void doClear()
|
SharedPtr<TValue> doGet(const TKey & key)
|
||||||
{
|
/// Returns a SharedPtr of the cache entry, returns 0 if for
|
||||||
static EventArgs _emptyArgs;
|
/// the key no value was found
|
||||||
Clear.notify(this, _emptyArgs);
|
{
|
||||||
_data.clear();
|
Iterator it = _data.find(key);
|
||||||
}
|
SharedPtr<TValue> result;
|
||||||
|
|
||||||
void doReplace()
|
if (it != _data.end())
|
||||||
{
|
{
|
||||||
std::set<TKey> delMe;
|
// inform all strategies that a read-access to an element happens
|
||||||
Replace.notify(this, delMe);
|
Get.notify(this, key);
|
||||||
// delMe contains the to be removed elements
|
// ask all strategies if the key is valid
|
||||||
typename std::set<TKey>::const_iterator it = delMe.begin();
|
ValidArgs<TKey> args(key);
|
||||||
typename std::set<TKey>::const_iterator endIt = delMe.end();
|
IsValid.notify(this, args);
|
||||||
|
|
||||||
for (; it != endIt; ++it)
|
if (!args.isValid())
|
||||||
{
|
{
|
||||||
Iterator itH = _data.find(*it);
|
doRemove(it);
|
||||||
doRemove(itH);
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
|
result = it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TStrategy _strategy;
|
return result;
|
||||||
mutable DataHolder _data;
|
}
|
||||||
mutable TMutex _mutex;
|
|
||||||
|
void doClear()
|
||||||
|
{
|
||||||
|
static EventArgs _emptyArgs;
|
||||||
|
Clear.notify(this, _emptyArgs);
|
||||||
|
_data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void doReplace()
|
||||||
|
{
|
||||||
|
std::set<TKey> delMe;
|
||||||
|
Replace.notify(this, delMe);
|
||||||
|
// delMe contains the to be removed elements
|
||||||
|
typename std::set<TKey>::const_iterator it = delMe.begin();
|
||||||
|
typename std::set<TKey>::const_iterator endIt = delMe.end();
|
||||||
|
|
||||||
|
for (; it != endIt; ++it)
|
||||||
|
{
|
||||||
|
Iterator itH = _data.find(*it);
|
||||||
|
doRemove(itH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TStrategy _strategy;
|
||||||
|
mutable DataHolder _data;
|
||||||
|
mutable TMutex _mutex;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AbstractCache(const AbstractCache& aCache);
|
AbstractCache(const AbstractCache & aCache);
|
||||||
AbstractCache& operator = (const AbstractCache& aCache);
|
AbstractCache & operator=(const AbstractCache & aCache);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user