模块外置

This commit is contained in:
xx
2024-06-07 15:00:31 +08:00
parent 671c4f64f0
commit f3540cd415
129 changed files with 81 additions and 15613 deletions

View File

@@ -1,106 +0,0 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_BUILD_CONFIG_H_
#define _SQL_BUILD_CONFIG_H_
#ifdef STATIC_CONCPP
#define CPPCONN_PUBLIC_FUNC
#endif
#if defined _MSC_VER
#define DLL_EXPORT __declspec(dllexport)
#define DLL_IMPORT __declspec(dllimport)
#define DLL_LOCAL
#elif __GNUC__ >= 4
#define DLL_EXPORT __attribute__ ((visibility ("default")))
#define DLL_IMPORT
#define DLL_LOCAL __attribute__ ((visibility ("hidden")))
#elif defined __SUNPRO_CC || defined __SUNPRO_C
#define DLL_EXPORT __global
#define DLL_IMPORT __global
#define DLL_LOCAL __hidden
#else
#define DLL_EXPORT
#define DLL_IMPORT
#define DLL_LOCAL
#endif
#ifndef CPPCONN_PUBLIC_FUNC
#ifdef connector_jdbc_EXPORTS
#define CPPCONN_PUBLIC_FUNC DLL_EXPORT
#else
// this is for static build
#ifdef CPPCONN_LIB_BUILD
#define CPPCONN_PUBLIC_FUNC
#else
// this is for clients using dynamic lib
#define CPPCONN_PUBLIC_FUNC DLL_IMPORT
#endif
#endif
#endif
#ifdef _MSC_VER
/*
Warning 4251 is about non dll-interface classes being used by ones exported
from our DLL (for example std lib classes or Boost ones). Following
the crowd, we ignore this issue for now.
*/
__pragma(warning (disable:4251))
#elif defined __SUNPRO_CC || defined __SUNPRO_C
#else
/*
These are triggered by, e.g., std::auto_ptr<> which is used by Boost.
*/
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#endif //#ifndef _SQL_BUILD_CONFIG_H_

View File

@@ -1,195 +0,0 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_CALLBACK_H_
#define _SQL_CALLBACK_H_
#include "sqlstring.h"
#include <functional>
namespace sql
{
namespace mysql
{
class MySQL_Connection;
class MySQL_Driver;
}
/*
A callback to be used with `Driver::setCallback()` to define reaction
to the user action request during WebAuthn authentication handshake.
The client library defines default reaction which prints message on stderr.
This callback can be used to change it.
Example usage:
// Use lambda
driver->setCallback(WebAuthn_Callback{[](SQLString msg){
cerr << "User action request: " << msg << endl;
}});
// Disable default behavior (and do nothing upon action request)
driver->setCallback(WebAuthn_Callback{});
// Return to default behavior
driver->setCallbacak(WebAuthn_Callback{nullptr});
// User defined callback
struct My_Callback : WebAuthn_Callback
{
void ActionRequested(SQLString) override;
}
cb;
driver->setCallback(cb);
*/
class WebAuthn_Callback
{
std::function<void(SQLString)> callback_func;
public:
/*
Create a callback that will call given lambda upon user action request.
*/
WebAuthn_Callback(std::function<void(SQLString)>&& cb)
: callback_func{std::move(cb)}
{}
/*
Create an empty callback that will do nothing upon user action request.
This disables the default callback defined by the client library.
*/
WebAuthn_Callback()
: callback_func{[](SQLString){}}
{}
/*
Create a null callback. Setting such callback has the effect of using
the default callback defined by the client library.
*/
WebAuthn_Callback(std::nullptr_t)
{}
/*
Derived class can override this method to react to user action request.
*/
virtual void ActionRequested(sql::SQLString msg)
{
if (callback_func)
callback_func(msg);
}
// Returns true if this callback is not null.
operator bool() const
{
return (bool)callback_func;
}
void operator()(sql::SQLString msg)
{
ActionRequested(msg);
}
};
/*
* Class that provides functionality allowing user code to set the
* callback functions through inheriting, passing the callback as
* constructor parameters or using lambdas.
*/
class Fido_Callback
{
std::function<void(SQLString)> callback_func = nullptr;
bool is_null = false;
public:
/**
* Constructor to set the callback as function or as lambda
*/
Fido_Callback(std::function<void(SQLString)> cb) : callback_func(cb)
{}
Fido_Callback()
{}
/**
* Constructor to reset the callback to default
*/
Fido_Callback(std::nullptr_t) : is_null(true)
{}
/**
* Override this message to receive Fido Action Requests
*/
virtual void FidoActionRequested(sql::SQLString msg)
{
if (callback_func)
callback_func(msg);
}
operator bool() const
{
return !is_null;
}
void operator()(sql::SQLString msg)
{
if (is_null)
return;
FidoActionRequested(msg);
}
friend class mysql::MySQL_Connection;
friend class mysql::MySQL_Driver;
};
} /* namespace sql */
#endif // _SQL_CONNECTION_H_

View File

@@ -1,117 +0,0 @@
/*
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// libmysql defines HAVE_STRTOUL (on win), so we have to follow different pattern in definitions names
// to avoid annoying warnings.
#define HAVE_FUNCTION_STRTOLD 1
#define HAVE_FUNCTION_STRTOLL 1
#define HAVE_FUNCTION_STRTOL 1
#define HAVE_FUNCTION_STRTOULL 1
#define HAVE_FUNCTION_STRTOUL 1
#define HAVE_FUNCTION_STRTOIMAX 1
#define HAVE_FUNCTION_STRTOUMAX 1
#define HAVE_STDINT_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_INT8_T 1
#define HAVE_UINT8_T 1
#define HAVE_INT16_T 1
#define HAVE_UINT16_T 1
#define HAVE_INT32_T 1
#define HAVE_UINT32_T 1
#define HAVE_INT32_T 1
#define HAVE_UINT32_T 1
#define HAVE_INT64_T 1
#define HAVE_UINT64_T 1
#define HAVE_MS_INT8 1
#define HAVE_MS_UINT8 1
#define HAVE_MS_INT16 1
#define HAVE_MS_UINT16 1
#define HAVE_MS_INT32 1
#define HAVE_MS_UINT32 1
#define HAVE_MS_INT64 1
#define HAVE_MS_UINT64 1
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#if defined(HAVE_INTTYPES_H) && !defined(_WIN32)
#include <inttypes.h>
#endif
#if defined(_WIN32)
#ifndef CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES
#if _MSC_VER >= 1600
#include <stdint.h>
#else
#if !defined(HAVE_INT8_T) && defined(HAVE_MS_INT8)
typedef __int8 int8_t;
#endif
#ifdef HAVE_MS_UINT8
typedef unsigned __int8 uint8_t;
#endif
#ifdef HAVE_MS_INT16
typedef __int16 int16_t;
#endif
#ifdef HAVE_MS_UINT16
typedef unsigned __int16 uint16_t;
#endif
#ifdef HAVE_MS_INT32
typedef __int32 int32_t;
#endif
#ifdef HAVE_MS_UINT32
typedef unsigned __int32 uint32_t;
#endif
#ifdef HAVE_MS_INT64
typedef __int64 int64_t;
#endif
#ifdef HAVE_MS_UINT64
typedef unsigned __int64 uint64_t;
#endif
#endif // _MSC_VER >= 1600
#endif // CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES
#endif // _WIN32

View File

@@ -1,285 +0,0 @@
/*
* Copyright (c) 2008, 2020, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_CONNECTION_H_
#define _SQL_CONNECTION_H_
#include <map>
#include "build_config.h"
#include "warning.h"
#include "sqlstring.h"
#include "variant.h"
/*
Options used on ConnectOptionsMap
*/
/*
Connect related
*/
#define OPT_HOSTNAME "hostName"
#define OPT_USERNAME "userName"
#define OPT_PASSWORD "password"
#define OPT_PASSWORD1 "password1"
#define OPT_PASSWORD2 "password2"
#define OPT_PASSWORD3 "password3"
#define OPT_PORT "port"
#define OPT_SOCKET "socket"
#define OPT_PIPE "pipe"
#define OPT_SCHEMA "schema"
#define OPT_MULTI_HOST "OPT_MULTI_HOST"
#define OPT_DNS_SRV "OPT_DNS_SRV"
#define OPT_NAMED_PIPE "OPT_NAMED_PIPE"
#define OPT_INIT_COMMAND "preInit"
#define OPT_POST_INIT_COMMAND "postInit"
#define OPT_LOCAL_INFILE "OPT_LOCAL_INFILE"
#define OPT_LOAD_DATA_LOCAL_DIR "OPT_LOAD_DATA_LOCAL_DIR"
/*
SSL related
*/
#define OPT_SSL_MODE "ssl-mode"
#define OPT_SSL_KEY "ssl-key"
#define OPT_SSL_CERT "ssl-cert"
#define OPT_SSL_CA "ssl-ca"
#define OPT_SSL_CAPATH "ssl-capath"
#define OPT_SSL_CIPHER "ssl-cipher"
#define OPT_SSL_CRL "ssl-crl"
#define OPT_SSL_CRLPATH "ssl-crlpath"
#define OPT_SERVER_PUBLIC_KEY "rsaKey"
#define OPT_TLS_VERSION "tls-version"
/*
Connection related
*/
#define OPT_RECONNECT "OPT_RECONNECT"
#define OPT_RETRY_COUNT "OPT_RETRY_COUNT"
#define OPT_CONNECT_TIMEOUT "OPT_CONNECT_TIMEOUT"
#define OPT_READ_TIMEOUT "OPT_READ_TIMEOUT"
#define OPT_WRITE_TIMEOUT "OPT_WRITE_TIMEOUT"
#define OPT_MAX_ALLOWED_PACKET "OPT_MAX_ALLOWED_PACKET"
#define OPT_NET_BUFFER_LENGTH "OPT_NET_BUFFER_LENGTH"
/*
Connection Attributes
*/
#define OPT_CONNECT_ATTR_ADD "OPT_CONNECT_ATTR_ADD"
#define OPT_CONNECT_ATTR_DELETE "OPT_CONNECT_ATTR_DELETE"
#define OPT_CONNECT_ATTR_RESET "OPT_CONNECT_ATTR_RESET"
/*
Authentication
*/
#define OPT_ENABLE_CLEARTEXT_PLUGIN "OPT_ENABLE_CLEARTEXT_PLUGIN"
#define OPT_CAN_HANDLE_EXPIRED_PASSWORDS "OPT_CAN_HANDLE_EXPIRED_PASSWORDS"
#define OPT_GET_SERVER_PUBLIC_KEY "OPT_GET_SERVER_PUBLIC_KEY"
#define OPT_LEGACY_AUTH "useLegacyAuth"
#define OPT_DEFAULT_AUTH "defaultAuth"
/*
Charracter set results and Metadata
*/
#define OPT_CHARACTER_SET_RESULTS "characterSetResults"
#define OPT_OPTIONAL_RESULTSET_METADATA "OPT_OPTIONAL_RESULTSET_METADATA"
#define OPT_REPORT_DATA_TRUNCATION "OPT_REPORT_DATA_TRUNCATION"
#define OPT_CHARSET_NAME "OPT_CHARSET_NAME"
#define OPT_DEFAULT_STMT_RESULT_TYPE "defaultStatementResultType"
/*
Client side options
*/
#define OPT_CLIENT_COMPRESS "CLIENT_COMPRESS"
#define OPT_CLIENT_FOUND_ROWS "CLIENT_FOUND_ROWS"
#define OPT_CLIENT_IGNORE_SIGPIPE "CLIENT_IGNORE_SIGPIPE"
#define OPT_CLIENT_IGNORE_SPACE "CLIENT_IGNORE_SPACE"
#define OPT_CLIENT_INTERACTIVE "CLIENT_INTERACTIVE"
#define OPT_CLIENT_LOCAL_FILES "CLIENT_LOCAL_FILES"
#define OPT_CLIENT_MULTI_STATEMENTS "CLIENT_MULTI_STATEMENTS"
#define OPT_CLIENT_NO_SCHEMA "CLIENT_NO_SCHEMA"
#define OPT_SET_CHARSET_DIR "charsetDir"
#define OPT_PLUGIN_DIR "pluginDir"
#define OPT_READ_DEFAULT_GROUP "readDefaultGroup"
#define OPT_READ_DEFAULT_FILE "readDefaultFile"
/*
Auth plugin options
*/
#define OPT_OCI_CONFIG_FILE "OPT_OCI_CONFIG_FILE"
#define OPT_AUTHENTICATION_KERBEROS_CLIENT_MODE \
"OPT_AUTHENTICATION_KERBEROS_CLIENT_MODE"
#define OPT_OCI_CLIENT_CONFIG_PROFILE "OPT_OCI_CLIENT_CONFIG_PROFILE"
/*
Telemetry options
*/
#define OPT_OPENTELEMETRY "OPT_OPENTELEMETRY"
namespace sql
{
typedef sql::Variant ConnectPropertyVal;
typedef std::map< sql::SQLString, ConnectPropertyVal > ConnectOptionsMap;
class DatabaseMetaData;
class PreparedStatement;
class Statement;
class Driver;
typedef enum transaction_isolation
{
TRANSACTION_NONE= 0,
TRANSACTION_READ_COMMITTED,
TRANSACTION_READ_UNCOMMITTED,
TRANSACTION_REPEATABLE_READ,
TRANSACTION_SERIALIZABLE
} enum_transaction_isolation;
enum ssl_mode
{
SSL_MODE_DISABLED= 1, SSL_MODE_PREFERRED, SSL_MODE_REQUIRED,
SSL_MODE_VERIFY_CA, SSL_MODE_VERIFY_IDENTITY
};
typedef enum opentelemetry_mode
{
OTEL_DISABLED = 1, OTEL_PREFERRED, OTEL_REQUIRED
} enum_opentelemetry_mode;
class CPPCONN_PUBLIC_FUNC Savepoint
{
/* Prevent use of these */
Savepoint(const Savepoint &);
void operator=(Savepoint &);
public:
Savepoint() {};
virtual ~Savepoint() {};
virtual int getSavepointId() = 0;
virtual sql::SQLString getSavepointName() = 0;
};
class CPPCONN_PUBLIC_FUNC Connection
{
/* Prevent use of these */
Connection(const Connection &);
void operator=(Connection &);
public:
Connection() {};
virtual ~Connection() {};
virtual void clearWarnings() = 0;
virtual Statement *createStatement() = 0;
virtual void close() = 0;
virtual void commit() = 0;
virtual bool getAutoCommit() = 0;
virtual sql::SQLString getCatalog() = 0;
virtual Driver *getDriver() = 0;
virtual sql::SQLString getSchema() = 0;
virtual sql::SQLString getClientInfo() = 0;
virtual void getClientOption(const sql::SQLString & optionName, void * optionValue) = 0;
virtual sql::SQLString getClientOption(const sql::SQLString & optionName) = 0;
virtual DatabaseMetaData * getMetaData() = 0;
virtual enum_transaction_isolation getTransactionIsolation() = 0;
virtual const SQLWarning * getWarnings() = 0;
virtual bool isClosed() = 0;
virtual bool isReadOnly() = 0;
virtual bool isValid() = 0;
virtual bool reconnect() = 0;
virtual sql::SQLString nativeSQL(const sql::SQLString& sql) = 0;
virtual PreparedStatement * prepareStatement(const sql::SQLString& sql) = 0;
virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys) = 0;
virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int* columnIndexes) = 0;
virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency) = 0;
virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) = 0;
virtual PreparedStatement * prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]) = 0;
virtual void releaseSavepoint(Savepoint * savepoint) = 0;
virtual void rollback() = 0;
virtual void rollback(Savepoint * savepoint) = 0;
virtual void setAutoCommit(bool autoCommit) = 0;
virtual void setCatalog(const sql::SQLString& catalog) = 0;
virtual void setSchema(const sql::SQLString& catalog) = 0;
virtual sql::Connection * setClientOption(const sql::SQLString & optionName, const void * optionValue) = 0;
virtual sql::Connection * setClientOption(const sql::SQLString & optionName, const sql::SQLString & optionValue) = 0;
virtual void setHoldability(int holdability) = 0;
virtual void setReadOnly(bool readOnly) = 0;
virtual Savepoint * setSavepoint() = 0;
virtual Savepoint * setSavepoint(const sql::SQLString& name) = 0;
virtual void setTransactionIsolation(enum_transaction_isolation level) = 0;
/* virtual void setTypeMap(Map map) = 0; */
};
} /* namespace sql */
#endif // _SQL_CONNECTION_H_

View File

@@ -1,75 +0,0 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_DATATYPE_H_
#define _SQL_DATATYPE_H_
namespace sql
{
class DataType
{
DataType();
public:
enum {
UNKNOWN = 0,
BIT,
TINYINT,
SMALLINT,
MEDIUMINT,
INTEGER,
BIGINT,
REAL,
DOUBLE,
DECIMAL,
NUMERIC,
CHAR,
BINARY,
VARCHAR,
VARBINARY,
LONGVARCHAR,
LONGVARBINARY,
TIMESTAMP,
DATE,
TIME,
YEAR,
GEOMETRY,
ENUM,
SET,
SQLNULL,
JSON
};
};
} /* namespace */
#endif /* _SQL_DATATYPE_H_ */

View File

@@ -1,106 +0,0 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_DRIVER_H_
#define _SQL_DRIVER_H_
#include "connection.h"
#include "build_config.h"
#include "callback.h"
namespace sql
{
class CPPCONN_PUBLIC_FUNC Driver
{
protected:
virtual ~Driver() {}
public:
// Attempts to make a database connection to the given URL.
virtual Connection * connect(const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password) = 0;
virtual Connection * connect(ConnectOptionsMap & options) = 0;
virtual int getMajorVersion() = 0;
virtual int getMinorVersion() = 0;
virtual int getPatchVersion() = 0;
virtual const sql::SQLString & getName() = 0;
virtual void setCallBack(sql::Fido_Callback &cb) = 0;
virtual void setCallBack(sql::Fido_Callback &&cb) = 0;
virtual void threadInit() = 0;
virtual void threadEnd() = 0;
virtual void setCallBack(sql::WebAuthn_Callback &cb) = 0;
virtual void setCallBack(sql::WebAuthn_Callback &&cb) = 0;
};
} /* namespace sql */
CPPCONN_PUBLIC_FUNC void check(const std::string &);
CPPCONN_PUBLIC_FUNC void check(const std::map<std::string,std::string> &);
/*
Checks if user standard lib is compatible with connector one
*/
inline static void check_lib()
{
check(std::string{});
check(std::map<std::string,std::string>{});
}
extern "C"
{
CPPCONN_PUBLIC_FUNC sql::Driver * _get_driver_instance_by_name(const char * const clientlib);
/* If dynamic loading is disabled in a driver then this function works just like get_driver_instance() */
inline static sql::Driver * get_driver_instance_by_name(const char * const clientlib)
{
check_lib();
return _get_driver_instance_by_name(clientlib);
}
inline static sql::Driver * get_driver_instance()
{
return get_driver_instance_by_name("");
}
}
#endif /* _SQL_DRIVER_H_ */

View File

@@ -1,147 +0,0 @@
/*
* Copyright (c) 2008, 2020, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_EXCEPTION_H_
#define _SQL_EXCEPTION_H_
#include "build_config.h"
#include <stdexcept>
#include <string>
#include <memory>
namespace sql
{
#define MEMORY_ALLOC_OPERATORS(Class) \
void* operator new(size_t size){ return ::operator new(size); } \
void* operator new(size_t, void*) noexcept; \
void* operator new(size_t, const std::nothrow_t&) noexcept; \
void* operator new[](size_t); \
void* operator new[](size_t, void*) noexcept; \
void* operator new[](size_t, const std::nothrow_t&) noexcept; \
void* operator new(size_t N, std::allocator<Class>&);
class SQLException : public std::runtime_error
{
protected:
const std::string sql_state;
const int errNo;
public:
SQLException(const SQLException& e) : std::runtime_error(e.what()), sql_state(e.sql_state), errNo(e.errNo) {}
SQLException(const std::string& reason, const std::string& SQLState, int vendorCode) :
std::runtime_error (reason ),
sql_state (SQLState ),
errNo (vendorCode)
{}
SQLException(const std::string& reason, const std::string& SQLState) : std::runtime_error(reason), sql_state(SQLState), errNo(0) {}
SQLException(const std::string& reason) : std::runtime_error(reason), sql_state("HY000"), errNo(0) {}
SQLException() : std::runtime_error(""), sql_state("HY000"), errNo(0) {}
const std::string & getSQLState() const
{
return sql_state;
}
const char * getSQLStateCStr() const
{
return sql_state.c_str();
}
int getErrorCode() const
{
return errNo;
}
virtual ~SQLException() noexcept {};
protected:
MEMORY_ALLOC_OPERATORS(SQLException)
};
struct MethodNotImplementedException : public SQLException
{
MethodNotImplementedException(const MethodNotImplementedException& e) : SQLException(e.what(), e.sql_state, e.errNo) { }
MethodNotImplementedException(const std::string& reason) : SQLException(reason, "", 0) {}
};
struct InvalidArgumentException : public SQLException
{
InvalidArgumentException(const InvalidArgumentException& e) : SQLException(e.what(), e.sql_state, e.errNo) { }
InvalidArgumentException(const std::string& reason) : SQLException(reason, "", 0) {}
};
struct InvalidInstanceException : public SQLException
{
InvalidInstanceException(const InvalidInstanceException& e) : SQLException(e.what(), e.sql_state, e.errNo) { }
InvalidInstanceException(const std::string& reason) : SQLException(reason, "", 0) {}
};
struct NonScrollableException : public SQLException
{
NonScrollableException(const NonScrollableException& e) : SQLException(e.what(), e.sql_state, e.errNo) { }
NonScrollableException(const std::string& reason) : SQLException(reason, "", 0) {}
};
struct SQLUnsupportedOptionException : public SQLException
{
SQLUnsupportedOptionException(const SQLUnsupportedOptionException& e, const std::string conn_option) :
SQLException(e.what(), e.sql_state, e.errNo),
option(conn_option )
{}
SQLUnsupportedOptionException(const std::string& reason, const std::string conn_option) :
SQLException(reason, "", 0),
option(conn_option )
{}
const char *getConnectionOption() const
{
return option.c_str();
}
~SQLUnsupportedOptionException() noexcept {};
protected:
const std::string option;
};
} /* namespace sql */
#endif /* _SQL_EXCEPTION_H_ */

View File

@@ -1,494 +0,0 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_METADATA_H_
#define _SQL_METADATA_H_
#include <string>
#include <list>
#include "datatype.h"
#include "sqlstring.h"
namespace sql
{
class ResultSet;
class Connection;
class DatabaseMetaData
{
protected:
virtual ~DatabaseMetaData() {}
public:
enum
{
attributeNoNulls = 0,
attributeNullable,
attributeNullableUnknown
};
enum
{
bestRowTemporary = 0,
bestRowTransaction,
bestRowSession
};
enum
{
bestRowUnknown = 0,
bestRowNotPseudo,
bestRowPseudo
};
enum
{
columnNoNulls = 0,
columnNullable,
columnNullableUnknown
};
enum
{
importedKeyCascade = 0,
importedKeyInitiallyDeferred,
importedKeyInitiallyImmediate,
importedKeyNoAction,
importedKeyNotDeferrable,
importedKeyRestrict,
importedKeySetDefault,
importedKeySetNull
};
enum
{
procedureColumnIn = 0,
procedureColumnInOut,
procedureColumnOut,
procedureColumnResult,
procedureColumnReturn,
procedureColumnUnknown,
procedureNoNulls,
procedureNoResult,
procedureNullable,
procedureNullableUnknown,
procedureResultUnknown,
procedureReturnsResult
};
enum
{
sqlStateSQL99 = 0,
sqlStateXOpen
};
enum
{
tableIndexClustered = 0,
tableIndexHashed,
tableIndexOther,
tableIndexStatistic
};
enum
{
versionColumnUnknown = 0,
versionColumnNotPseudo = 1,
versionColumnPseudo = 2
};
enum
{
typeNoNulls = 0,
typeNullable = 1,
typeNullableUnknown = 2
};
enum
{
typePredNone = 0,
typePredChar = 1,
typePredBasic= 2,
typeSearchable = 3
};
virtual bool allProceduresAreCallable() = 0;
virtual bool allTablesAreSelectable() = 0;
virtual bool dataDefinitionCausesTransactionCommit() = 0;
virtual bool dataDefinitionIgnoredInTransactions() = 0;
virtual bool deletesAreDetected(int type) = 0;
virtual bool doesMaxRowSizeIncludeBlobs() = 0;
virtual ResultSet * getAttributes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, const sql::SQLString& attributeNamePattern) = 0;
virtual ResultSet * getBestRowIdentifier(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, int scope, bool nullable) = 0;
virtual ResultSet * getCatalogs() = 0;
virtual const sql::SQLString& getCatalogSeparator() = 0;
virtual const sql::SQLString& getCatalogTerm() = 0;
virtual ResultSet * getColumnPrivileges(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, const sql::SQLString& columnNamePattern) = 0;
virtual ResultSet * getColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, const sql::SQLString& columnNamePattern) = 0;
virtual Connection * getConnection() = 0;
virtual ResultSet * getCrossReference(const sql::SQLString& primaryCatalog, const sql::SQLString& primarySchema, const sql::SQLString& primaryTable, const sql::SQLString& foreignCatalog, const sql::SQLString& foreignSchema, const sql::SQLString& foreignTable) = 0;
virtual unsigned int getDatabaseMajorVersion() = 0;
virtual unsigned int getDatabaseMinorVersion() = 0;
virtual unsigned int getDatabasePatchVersion() = 0;
virtual const sql::SQLString& getDatabaseProductName() = 0;
virtual SQLString getDatabaseProductVersion() = 0;
virtual int getDefaultTransactionIsolation() = 0;
virtual unsigned int getDriverMajorVersion() = 0;
virtual unsigned int getDriverMinorVersion() = 0;
virtual unsigned int getDriverPatchVersion() = 0;
virtual const sql::SQLString& getDriverName() = 0;
virtual const sql::SQLString& getDriverVersion() = 0;
virtual ResultSet * getExportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0;
virtual const sql::SQLString& getExtraNameCharacters() = 0;
virtual const sql::SQLString& getIdentifierQuoteString() = 0;
virtual ResultSet * getImportedKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0;
virtual ResultSet * getIndexInfo(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table, bool unique, bool approximate) = 0;
virtual unsigned int getCDBCMajorVersion() = 0;
virtual unsigned int getCDBCMinorVersion() = 0;
virtual unsigned int getMaxBinaryLiteralLength() = 0;
virtual unsigned int getMaxCatalogNameLength() = 0;
virtual unsigned int getMaxCharLiteralLength() = 0;
virtual unsigned int getMaxColumnNameLength() = 0;
virtual unsigned int getMaxColumnsInGroupBy() = 0;
virtual unsigned int getMaxColumnsInIndex() = 0;
virtual unsigned int getMaxColumnsInOrderBy() = 0;
virtual unsigned int getMaxColumnsInSelect() = 0;
virtual unsigned int getMaxColumnsInTable() = 0;
virtual unsigned int getMaxConnections() = 0;
virtual unsigned int getMaxCursorNameLength() = 0;
virtual unsigned int getMaxIndexLength() = 0;
virtual unsigned int getMaxProcedureNameLength() = 0;
virtual unsigned int getMaxRowSize() = 0;
virtual unsigned int getMaxSchemaNameLength() = 0;
virtual unsigned int getMaxStatementLength() = 0;
virtual unsigned int getMaxStatements() = 0;
virtual unsigned int getMaxTableNameLength() = 0;
virtual unsigned int getMaxTablesInSelect() = 0;
virtual unsigned int getMaxUserNameLength() = 0;
virtual const sql::SQLString& getNumericFunctions() = 0;
virtual ResultSet * getPrimaryKeys(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0;
virtual ResultSet * getProcedureColumns(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern, const sql::SQLString& columnNamePattern) = 0;
virtual ResultSet * getProcedures(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& procedureNamePattern) = 0;
virtual const sql::SQLString& getProcedureTerm() = 0;
virtual int getResultSetHoldability() = 0;
virtual ResultSet * getSchemas() = 0;
virtual const sql::SQLString& getSchemaTerm() = 0;
virtual ResultSet * getSchemaCollation(const sql::SQLString& catalog, const sql::SQLString& schemaPattern) = 0;
virtual ResultSet * getSchemaCharset(const sql::SQLString& catalog, const sql::SQLString& schemaPattern) = 0;
virtual const sql::SQLString& getSearchStringEscape() = 0;
virtual const sql::SQLString& getSQLKeywords() = 0;
virtual int getSQLStateType() = 0;
virtual const sql::SQLString& getStringFunctions() = 0;
virtual ResultSet * getSuperTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0;
virtual ResultSet * getSuperTypes(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern) = 0;
virtual const sql::SQLString& getSystemFunctions() = 0;
virtual ResultSet * getTablePrivileges(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0;
virtual ResultSet * getTables(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern, std::list<sql::SQLString> &types) = 0;
virtual ResultSet * getTableTypes() = 0;
virtual ResultSet * getTableCollation(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0;
virtual ResultSet * getTableCharset(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& tableNamePattern) = 0;
virtual const sql::SQLString& getTimeDateFunctions() = 0;
virtual ResultSet * getTypeInfo() = 0;
virtual ResultSet * getUDTs(const sql::SQLString& catalog, const sql::SQLString& schemaPattern, const sql::SQLString& typeNamePattern, std::list<int> &types) = 0;
virtual SQLString getURL() = 0;
virtual SQLString getUserName() = 0;
virtual ResultSet * getVersionColumns(const sql::SQLString& catalog, const sql::SQLString& schema, const sql::SQLString& table) = 0;
virtual bool insertsAreDetected(int type) = 0;
virtual bool isCatalogAtStart() = 0;
virtual bool isReadOnly() = 0;
virtual bool locatorsUpdateCopy() = 0;
virtual bool nullPlusNonNullIsNull() = 0;
virtual bool nullsAreSortedAtEnd() = 0;
virtual bool nullsAreSortedAtStart() = 0;
virtual bool nullsAreSortedHigh() = 0;
virtual bool nullsAreSortedLow() = 0;
virtual bool othersDeletesAreVisible(int type) = 0;
virtual bool othersInsertsAreVisible(int type) = 0;
virtual bool othersUpdatesAreVisible(int type) = 0;
virtual bool ownDeletesAreVisible(int type) = 0;
virtual bool ownInsertsAreVisible(int type) = 0;
virtual bool ownUpdatesAreVisible(int type) = 0;
virtual bool storesLowerCaseIdentifiers() = 0;
virtual bool storesLowerCaseQuotedIdentifiers() = 0;
virtual bool storesMixedCaseIdentifiers() = 0;
virtual bool storesMixedCaseQuotedIdentifiers() = 0;
virtual bool storesUpperCaseIdentifiers() = 0;
virtual bool storesUpperCaseQuotedIdentifiers() = 0;
virtual bool supportsAlterTableWithAddColumn() = 0;
virtual bool supportsAlterTableWithDropColumn() = 0;
virtual bool supportsANSI92EntryLevelSQL() = 0;
virtual bool supportsANSI92FullSQL() = 0;
virtual bool supportsANSI92IntermediateSQL() = 0;
virtual bool supportsBatchUpdates() = 0;
virtual bool supportsCatalogsInDataManipulation() = 0;
virtual bool supportsCatalogsInIndexDefinitions() = 0;
virtual bool supportsCatalogsInPrivilegeDefinitions() = 0;
virtual bool supportsCatalogsInProcedureCalls() = 0;
virtual bool supportsCatalogsInTableDefinitions() = 0;
virtual bool supportsColumnAliasing() = 0;
virtual bool supportsConvert() = 0;
virtual bool supportsConvert(int fromType, int toType) = 0;
virtual bool supportsCoreSQLGrammar() = 0;
virtual bool supportsCorrelatedSubqueries() = 0;
virtual bool supportsDataDefinitionAndDataManipulationTransactions() = 0;
virtual bool supportsDataManipulationTransactionsOnly() = 0;
virtual bool supportsDifferentTableCorrelationNames() = 0;
virtual bool supportsExpressionsInOrderBy() = 0;
virtual bool supportsExtendedSQLGrammar() = 0;
virtual bool supportsFullOuterJoins() = 0;
virtual bool supportsGetGeneratedKeys() = 0;
virtual bool supportsGroupBy() = 0;
virtual bool supportsGroupByBeyondSelect() = 0;
virtual bool supportsGroupByUnrelated() = 0;
virtual bool supportsIntegrityEnhancementFacility() = 0;
virtual bool supportsLikeEscapeClause() = 0;
virtual bool supportsLimitedOuterJoins() = 0;
virtual bool supportsMinimumSQLGrammar() = 0;
virtual bool supportsMixedCaseIdentifiers() = 0;
virtual bool supportsMixedCaseQuotedIdentifiers() = 0;
virtual bool supportsMultipleOpenResults() = 0;
virtual bool supportsMultipleResultSets() = 0;
virtual bool supportsMultipleTransactions() = 0;
virtual bool supportsNamedParameters() = 0;
virtual bool supportsNonNullableColumns() = 0;
virtual bool supportsOpenCursorsAcrossCommit() = 0;
virtual bool supportsOpenCursorsAcrossRollback() = 0;
virtual bool supportsOpenStatementsAcrossCommit() = 0;
virtual bool supportsOpenStatementsAcrossRollback() = 0;
virtual bool supportsOrderByUnrelated() = 0;
virtual bool supportsOuterJoins() = 0;
virtual bool supportsPositionedDelete() = 0;
virtual bool supportsPositionedUpdate() = 0;
virtual bool supportsResultSetConcurrency(int type, int concurrency) = 0;
virtual bool supportsResultSetHoldability(int holdability) = 0;
virtual bool supportsResultSetType(int type) = 0;
virtual bool supportsSavepoints() = 0;
virtual bool supportsSchemasInDataManipulation() = 0;
virtual bool supportsSchemasInIndexDefinitions() = 0;
virtual bool supportsSchemasInPrivilegeDefinitions() = 0;
virtual bool supportsSchemasInProcedureCalls() = 0;
virtual bool supportsSchemasInTableDefinitions() = 0;
virtual bool supportsSelectForUpdate() = 0;
virtual bool supportsStatementPooling() = 0;
virtual bool supportsStoredProcedures() = 0;
virtual bool supportsSubqueriesInComparisons() = 0;
virtual bool supportsSubqueriesInExists() = 0;
virtual bool supportsSubqueriesInIns() = 0;
virtual bool supportsSubqueriesInQuantifieds() = 0;
virtual bool supportsTableCorrelationNames() = 0;
virtual bool supportsTransactionIsolationLevel(int level) = 0;
virtual bool supportsTransactions() = 0;
virtual bool supportsTypeConversion() = 0; /* SDBC */
virtual bool supportsUnion() = 0;
virtual bool supportsUnionAll() = 0;
virtual bool updatesAreDetected(int type) = 0;
virtual bool usesLocalFilePerTable() = 0;
virtual bool usesLocalFiles() = 0;
virtual ResultSet *getSchemata(const sql::SQLString& catalogName = "") = 0;
virtual ResultSet *getSchemaObjects(const sql::SQLString& catalogName = "",
const sql::SQLString& schemaName = "",
const sql::SQLString& objectType = "",
bool includingDdl = true,
const sql::SQLString& objectName = "",
const sql::SQLString& contextTableName = "") = 0;
virtual ResultSet *getSchemaObjectTypes() = 0;
};
} /* namespace sql */
#endif /* _SQL_METADATA_H_ */

View File

@@ -1,84 +0,0 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_PARAMETER_METADATA_H_
#define _SQL_PARAMETER_METADATA_H_
#include "sqlstring.h"
namespace sql
{
class ParameterMetaData
{
public:
enum
{
parameterModeIn,
parameterModeInOut,
parameterModeOut,
parameterModeUnknown
};
enum
{
parameterNoNulls,
parameterNullable,
parameterNullableUnknown
};
virtual sql::SQLString getParameterClassName(unsigned int param) = 0;
virtual int getParameterCount() = 0;
virtual int getParameterMode(unsigned int param) = 0;
virtual int getParameterType(unsigned int param) = 0;
virtual sql::SQLString getParameterTypeName(unsigned int param) = 0;
virtual int getPrecision(unsigned int param) = 0;
virtual int getScale(unsigned int param) = 0;
virtual int isNullable(unsigned int param) = 0;
virtual bool isSigned(unsigned int param) = 0;
protected:
virtual ~ParameterMetaData() {}
};
} /* namespace sql */
#endif /* _SQL_PARAMETER_METADATA_H_ */

View File

@@ -1,99 +0,0 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_PREPARED_STATEMENT_H_
#define _SQL_PREPARED_STATEMENT_H_
#include <iostream>
#include "statement.h"
namespace sql
{
class Connection;
class ResultSet;
class ResultSetMetaData;
class ParameterMetaData;
class PreparedStatement : public Statement
{
public:
virtual ~PreparedStatement() {}
virtual void clearParameters() = 0;
virtual bool execute(const sql::SQLString& sql) = 0;
virtual bool execute() = 0;
virtual ResultSet *executeQuery(const sql::SQLString& sql) = 0;
virtual ResultSet *executeQuery() = 0;
virtual int executeUpdate(const sql::SQLString& sql) = 0;
virtual int executeUpdate() = 0;
virtual ResultSetMetaData * getMetaData() = 0;
virtual ParameterMetaData * getParameterMetaData() = 0;
virtual bool getMoreResults() = 0;
virtual void setBigInt(unsigned int parameterIndex, const sql::SQLString& value) = 0;
virtual void setBlob(unsigned int parameterIndex, std::istream * blob) = 0;
virtual void setBoolean(unsigned int parameterIndex, bool value) = 0;
virtual void setDateTime(unsigned int parameterIndex, const sql::SQLString& value) = 0;
virtual void setDouble(unsigned int parameterIndex, double value) = 0;
virtual void setInt(unsigned int parameterIndex, int32_t value) = 0;
virtual void setUInt(unsigned int parameterIndex, uint32_t value) = 0;
virtual void setInt64(unsigned int parameterIndex, int64_t value) = 0;
virtual void setUInt64(unsigned int parameterIndex, uint64_t value) = 0;
virtual void setNull(unsigned int parameterIndex, int sqlType) = 0;
virtual void setString(unsigned int parameterIndex, const sql::SQLString& value) = 0;
virtual PreparedStatement * setResultSetType(sql::ResultSet::enum_type type) = 0;
};
} /* namespace sql */
#endif /* _SQL_PREPARED_STATEMENT_H_ */

View File

@@ -1,188 +0,0 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_RESULTSET_H_
#define _SQL_RESULTSET_H_
#include "config.h"
#include <list>
#include <map>
#include <iostream>
#include "sqlstring.h"
#include "resultset_metadata.h"
namespace sql
{
class Statement;
class RowID
{
public:
virtual ~RowID() {}
};
class ResultSet
{
public:
enum
{
CLOSE_CURSORS_AT_COMMIT,
HOLD_CURSORS_OVER_COMMIT
};
enum
{
CONCUR_READ_ONLY,
CONCUR_UPDATABLE
};
enum
{
FETCH_FORWARD,
FETCH_REVERSE,
FETCH_UNKNOWN
};
typedef enum
{
TYPE_FORWARD_ONLY,
TYPE_SCROLL_INSENSITIVE,
TYPE_SCROLL_SENSITIVE
} enum_type;
virtual ~ResultSet() {}
virtual bool absolute(int row) = 0;
virtual void afterLast() = 0;
virtual void beforeFirst() = 0;
virtual void cancelRowUpdates() = 0;
virtual void clearWarnings() = 0;
virtual void close() = 0;
virtual uint32_t findColumn(const sql::SQLString& columnLabel) const = 0;
virtual bool first() = 0;
virtual std::istream * getBlob(uint32_t columnIndex) const = 0;
virtual std::istream * getBlob(const sql::SQLString& columnLabel) const = 0;
virtual bool getBoolean(uint32_t columnIndex) const = 0;
virtual bool getBoolean(const sql::SQLString& columnLabel) const = 0;
virtual int getConcurrency() = 0;
virtual SQLString getCursorName() = 0;
virtual long double getDouble(uint32_t columnIndex) const = 0;
virtual long double getDouble(const sql::SQLString& columnLabel) const = 0;
virtual int getFetchDirection() = 0;
virtual size_t getFetchSize() = 0;
virtual int getHoldability() = 0;
virtual int32_t getInt(uint32_t columnIndex) const = 0;
virtual int32_t getInt(const sql::SQLString& columnLabel) const = 0;
virtual uint32_t getUInt(uint32_t columnIndex) const = 0;
virtual uint32_t getUInt(const sql::SQLString& columnLabel) const = 0;
virtual int64_t getInt64(uint32_t columnIndex) const = 0;
virtual int64_t getInt64(const sql::SQLString& columnLabel) const = 0;
virtual uint64_t getUInt64(uint32_t columnIndex) const = 0;
virtual uint64_t getUInt64(const sql::SQLString& columnLabel) const = 0;
virtual ResultSetMetaData * getMetaData() const = 0;
virtual size_t getRow() const = 0;
virtual RowID * getRowId(uint32_t columnIndex) = 0;
virtual RowID * getRowId(const sql::SQLString & columnLabel) = 0;
virtual const Statement * getStatement() const = 0;
virtual SQLString getString(uint32_t columnIndex) const = 0;
virtual SQLString getString(const sql::SQLString& columnLabel) const = 0;
virtual enum_type getType() const = 0;
virtual void getWarnings() = 0;
virtual void insertRow() = 0;
virtual bool isAfterLast() const = 0;
virtual bool isBeforeFirst() const = 0;
virtual bool isClosed() const = 0;
virtual bool isFirst() const = 0;
virtual bool isLast() const = 0;
virtual bool isNull(uint32_t columnIndex) const = 0;
virtual bool isNull(const sql::SQLString& columnLabel) const = 0;
virtual bool last() = 0;
virtual bool next() = 0;
virtual void moveToCurrentRow() = 0;
virtual void moveToInsertRow() = 0;
virtual bool previous() = 0;
virtual void refreshRow() = 0;
virtual bool relative(int rows) = 0;
virtual bool rowDeleted() = 0;
virtual bool rowInserted() = 0;
virtual bool rowUpdated() = 0;
virtual void setFetchSize(size_t rows) = 0;
virtual size_t rowsCount() const = 0;
virtual bool wasNull() const = 0;
};
} /* namespace sql */
#endif /* _SQL_RESULTSET_H_ */

View File

@@ -1,107 +0,0 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_RESULTSET_METADATA_H_
#define _SQL_RESULTSET_METADATA_H_
#include "sqlstring.h"
#include "datatype.h"
namespace sql
{
class ResultSetMetaData
{
public:
enum
{
columnNoNulls,
columnNullable,
columnNullableUnknown
};
virtual SQLString getCatalogName(unsigned int column) = 0;
virtual unsigned int getColumnCount() = 0;
virtual unsigned int getColumnDisplaySize(unsigned int column) = 0;
virtual SQLString getColumnLabel(unsigned int column) = 0;
virtual SQLString getColumnName(unsigned int column) = 0;
virtual int getColumnType(unsigned int column) = 0;
virtual SQLString getColumnTypeName(unsigned int column) = 0;
virtual SQLString getColumnCharset(unsigned int columnIndex) = 0;
virtual SQLString getColumnCollation(unsigned int columnIndex) = 0;
virtual unsigned int getPrecision(unsigned int column) = 0;
virtual unsigned int getScale(unsigned int column) = 0;
virtual SQLString getSchemaName(unsigned int column) = 0;
virtual SQLString getTableName(unsigned int column) = 0;
virtual bool isAutoIncrement(unsigned int column) = 0;
virtual bool isCaseSensitive(unsigned int column) = 0;
virtual bool isCurrency(unsigned int column) = 0;
virtual bool isDefinitelyWritable(unsigned int column) = 0;
virtual int isNullable(unsigned int column) = 0;
virtual bool isNumeric(unsigned int column) = 0;
virtual bool isReadOnly(unsigned int column) = 0;
virtual bool isSearchable(unsigned int column) = 0;
virtual bool isSigned(unsigned int column) = 0;
virtual bool isWritable(unsigned int column) = 0;
virtual bool isZerofill(unsigned int column) = 0;
protected:
virtual ~ResultSetMetaData() {}
};
} /* namespace sql */
#endif /* _SQL_RESULTSET_METADATA_H_ */

View File

@@ -1,251 +0,0 @@
/*
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_STRING_H_
#define _SQL_STRING_H_
#include <string>
#include <algorithm>
#include "build_config.h"
#include <iostream>
namespace sql
{
class SQLString
{
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4251)
#endif
std::string realStr;
#ifdef _WIN32
#pragma warning(pop)
#endif
public:
#ifdef _WIN32
//TODO something less dirty-hackish.
static const size_t npos = static_cast<std::string::size_type>(-1);
#else
static const size_t npos = std::string::npos;
#endif
~SQLString() {}
SQLString() {}
SQLString(const SQLString & other) : realStr(other.realStr) {}
SQLString(const std::string & other) : realStr(other) {}
SQLString(const char other[]) : realStr(other) {}
SQLString(const char * s, size_t n) : realStr(s, n) {}
// Needed for stuff like SQLString str= "char * string constant"
const SQLString & operator=(const char * s)
{
realStr = s;
return *this;
}
const SQLString & operator=(const std::string & rhs)
{
realStr = rhs;
return *this;
}
const SQLString & operator=(const SQLString & rhs)
{
realStr = rhs.realStr;
return *this;
}
// Conversion to st::string. Comes in play for stuff like std::string str= SQLString_var;
operator const std::string &() const
{
return realStr;
}
/** For access std::string methods. Not sure we need it. Makes it look like some smart ptr.
possibly operator* - will look even more like smart ptr */
std::string * operator ->()
{
return & realStr;
}
int compare(const SQLString& str) const
{
return realStr.compare(str.realStr);
}
int compare(const char * s) const
{
return realStr.compare(s);
}
int compare(size_t pos1, size_t n1, const char * s) const
{
return realStr.compare(pos1, n1, s);
}
int caseCompare(const SQLString &s) const
{
std::string tmp(realStr), str(s);
std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
return tmp.compare(str);
}
int caseCompare(const char * s) const
{
std::string tmp(realStr), str(s);
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
return tmp.compare(str);
}
int caseCompare(size_t pos1, size_t n1, const char * s) const
{
std::string tmp(realStr.c_str() + pos1, n1), str(s);
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
return tmp.compare(str);
}
const std::string & asStdString() const
{
return realStr;
}
const char * c_str() const
{
return realStr.c_str();
}
size_t length() const
{
return realStr.length();
}
SQLString & append(const std::string & str)
{
realStr.append(str);
return *this;
}
SQLString & append(const char * s)
{
realStr.append(s);
return *this;
}
const char& operator[](size_t pos) const
{
return realStr[pos];
}
size_t find(char c, size_t pos = 0) const
{
return realStr.find(c, pos);
}
size_t find(const SQLString & s, size_t pos = 0) const
{
return realStr.find(s.realStr, pos);
}
SQLString substr(size_t pos = 0, size_t n = npos) const
{
return realStr.substr(pos, n);
}
const SQLString& replace(size_t pos1, size_t n1, const SQLString & s)
{
realStr.replace(pos1, n1, s.realStr);
return *this;
}
size_t find_first_of(char c, size_t pos = 0) const
{
return realStr.find_first_of(c, pos);
}
size_t find_last_of(char c, size_t pos = npos) const
{
return realStr.find_last_of(c, pos);
}
const SQLString & operator+=(const SQLString & op2)
{
realStr += op2.realStr;
return *this;
}
};
/*
Operators that can and have to be not a member.
*/
inline const SQLString operator+(const SQLString & op1, const SQLString & op2)
{
return sql::SQLString(op1.asStdString() + op2.asStdString());
}
inline bool operator ==(const SQLString & op1, const SQLString & op2)
{
return (op1.asStdString() == op2.asStdString());
}
inline bool operator !=(const SQLString & op1, const SQLString & op2)
{
return (op1.asStdString() != op2.asStdString());
}
inline bool operator <(const SQLString & op1, const SQLString & op2)
{
return op1.asStdString() < op2.asStdString();
}
}// namespace sql
namespace std
{
// operator << for SQLString output
inline ostream & operator << (ostream & os, const sql::SQLString & str )
{
return os << str.asStdString();
}
}
#endif

View File

@@ -1,117 +0,0 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_STATEMENT_H_
#define _SQL_STATEMENT_H_
#include "config.h"
#include "resultset.h"
#include <string>
namespace sql
{
class ResultSet;
class Connection;
class SQLWarning;
class Statement
{
public:
virtual ~Statement() {};
virtual Connection * getConnection() = 0;
virtual void cancel() = 0;
virtual void clearWarnings() = 0;
virtual void close() = 0;
virtual bool execute(const sql::SQLString& sql) = 0;
virtual ResultSet * executeQuery(const sql::SQLString& sql) = 0;
virtual int executeUpdate(const sql::SQLString& sql) = 0;
virtual size_t getFetchSize() = 0;
virtual unsigned int getMaxFieldSize() = 0;
virtual uint64_t getMaxRows() = 0;
virtual bool getMoreResults() = 0;
virtual unsigned int getQueryTimeout() = 0;
virtual ResultSet * getResultSet() = 0;
virtual sql::ResultSet::enum_type getResultSetType() = 0;
virtual uint64_t getUpdateCount() = 0;
virtual const SQLWarning * getWarnings() = 0;
virtual void setCursorName(const sql::SQLString & name) = 0;
virtual void setEscapeProcessing(bool enable) = 0;
virtual void setFetchSize(size_t rows) = 0;
virtual void setMaxFieldSize(unsigned int max) = 0;
virtual void setMaxRows(unsigned int max) = 0;
virtual void setQueryTimeout(unsigned int seconds) = 0;
virtual Statement * setResultSetType(sql::ResultSet::enum_type type) = 0;
virtual int setQueryAttrBigInt(const sql::SQLString &name, const sql::SQLString& value) = 0;
virtual int setQueryAttrBoolean(const sql::SQLString &name, bool value) = 0;
virtual int setQueryAttrDateTime(const sql::SQLString &name, const sql::SQLString& value) = 0;
virtual int setQueryAttrDouble(const sql::SQLString &name, double value) = 0;
virtual int setQueryAttrInt(const sql::SQLString &name, int32_t value) = 0;
virtual int setQueryAttrUInt(const sql::SQLString &name, uint32_t value) = 0;
virtual int setQueryAttrInt64(const sql::SQLString &name, int64_t value) = 0;
virtual int setQueryAttrUInt64(const sql::SQLString &name, uint64_t value) = 0;
virtual int setQueryAttrNull(const sql::SQLString &name) = 0;
virtual int setQueryAttrString(const sql::SQLString &name, const sql::SQLString& value) = 0;
virtual void clearAttributes() = 0;
};
} /* namespace sql */
#endif /* _SQL_STATEMENT_H_ */

View File

@@ -1,324 +0,0 @@
/*
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_VARIANT_H_
#define _SQL_VARIANT_H_
#include <string>
#include <map>
#include <list>
#include <algorithm>
#include <typeinfo>
#include "build_config.h"
#include "sqlstring.h"
#include "exception.h"
namespace sql
{
class BaseVariantImpl
{
public:
BaseVariantImpl (void *ptr, sql::SQLString vtype) :
cvptr(ptr),
vTypeName(vtype)
{}
virtual ~BaseVariantImpl() {
cvptr=NULL;
}
virtual BaseVariantImpl* Clone()=0;
template<class T>
T* get() const {
if (typeid(T).name() == typeid(void).name()) {
return static_cast< T * > (cvptr);
}
if ((vTypeName == typeid(std::string).name() &&
typeid(T).name() == typeid(sql::SQLString).name()) ||
(vTypeName == typeid(sql::SQLString).name() &&
typeid(T).name() == typeid(std::string).name()) ||
(vTypeName == typeid(std::map< std::string, std::string >).name() &&
typeid(T).name() ==
typeid(std::map< sql::SQLString, sql::SQLString >).name()) ||
(vTypeName ==
typeid(std::map< sql::SQLString, sql::SQLString >).name() &&
typeid(T).name() ==
typeid(std::map< std::string, std::string >).name()) ||
(vTypeName == typeid(std::list< std::string >).name() &&
typeid(T).name() ==
typeid(std::list< sql::SQLString >).name()) ||
(vTypeName ==
typeid(std::list< sql::SQLString >).name() &&
typeid(T).name() ==
typeid(std::list< std::string >).name()))
{
return static_cast< T * > (cvptr);
}
if (typeid(T).name() != vTypeName) {
throw sql::InvalidArgumentException("Variant type doesn't match.");
}
return static_cast< T * > (cvptr);
}
protected:
void *cvptr;
sql::SQLString vTypeName;
};
template<class T>
class VariantImpl : public BaseVariantImpl
{
public:
VariantImpl(T i) : BaseVariantImpl(new T(i), typeid(i).name()) {}
~VariantImpl() {
destroy_content();
}
VariantImpl(VariantImpl& that) : BaseVariantImpl(that) {
copy_content(that);
}
VariantImpl& operator=(VariantImpl& that) {
if (this != &that) {
destroy_content();
if (cvptr == NULL) {
copy_content(that);
}
}
return *this;
}
virtual VariantImpl* Clone() {
return new VariantImpl(*this);
}
private:
void destroy_content() {
T *tmp=static_cast< T * >(cvptr);
if (tmp) {
delete tmp;
cvptr=NULL;
}
}
void copy_content(BaseVariantImpl& that) {
cvptr=new T (*(static_cast< T * > (that.get< void >())));
}
};
template<class T>
class VariantMap : public BaseVariantImpl
{
public:
VariantMap(T i) : BaseVariantImpl(new T(i), typeid(i).name()) {}
~VariantMap() {
destroy_content();
}
VariantMap(VariantMap& that) : BaseVariantImpl(that) {
if (this != &that) {
copy_content(that);
}
}
VariantMap& operator=(VariantMap& that) {
if (this != &that) {
destroy_content();
copy_content(that);
}
return *this;
}
virtual VariantMap* Clone() {
return new VariantMap(*this);
}
private:
void destroy_content() {
T *tmp=static_cast< T *> (cvptr);
if (tmp) {
tmp->clear();
delete tmp;
cvptr=NULL;
}
}
void copy_content(VariantMap& var) {
T *tmp=static_cast< T *> (var.cvptr);
if (tmp) {
cvptr=new T();
typename T::const_iterator cit=tmp->begin();
while(cit != tmp->end()) {
(static_cast< T * >(cvptr))->insert(
std::make_pair(sql::SQLString(cit->first),
sql::SQLString(cit->second)));
++cit;
}
}
}
};
template<class T>
class VariantList : public BaseVariantImpl
{
public:
VariantList(T i) : BaseVariantImpl(new T(i), typeid(i).name()) {}
~VariantList() {
destroy_content();
}
VariantList(VariantList& that) : BaseVariantImpl(that) {
if (this != &that) {
copy_content(that);
}
}
VariantList& operator=(VariantList& that) {
if (this != &that) {
destroy_content();
copy_content(that);
}
return *this;
}
virtual VariantList* Clone() {
return new VariantList(*this);
}
private:
void destroy_content()
{
T *tmp=static_cast< T *> (cvptr);
if (tmp) {
tmp->clear();
delete tmp;
cvptr=NULL;
}
}
void copy_content(VariantList& var)
{
T *tmp=static_cast< T *> (var.cvptr);
if (tmp) {
cvptr=new T();
typename T::const_iterator cit=tmp->begin();
while(cit != tmp->end()) {
(static_cast< T * >(cvptr))->push_back(sql::SQLString(*cit));
++cit;
}
}
}
};
class CPPCONN_PUBLIC_FUNC Variant
{
public:
Variant(const int &i=0) :
variant(new VariantImpl< int >(i)) {}
Variant(const double &i) :
variant(new VariantImpl< double >(i)) {}
Variant(const bool &i) :
variant(new VariantImpl< bool >(i)) {}
Variant(const char* i) :
variant(new VariantImpl< sql::SQLString >(i)) {}
Variant(const std::string &i) :
variant(new VariantImpl< sql::SQLString >(i)) {}
Variant(const sql::SQLString &i) :
variant(new VariantImpl< sql::SQLString >(i)) {}
Variant(const std::list< std::string > &i) :
variant(new VariantList< std::list < std::string > >(i)) {}
Variant(const std::list< sql::SQLString > &i) :
variant(new VariantList< std::list < sql::SQLString > >(i)) {}
Variant(const std::map< std::string, std::string > &i) :
variant(new VariantMap< std::map< std::string, std::string > >(i)) {}
Variant(const std::map< sql::SQLString, sql::SQLString > &i) :
variant(new VariantMap< std::map< sql::SQLString, sql::SQLString > >(i)) {}
~Variant() {
if (variant) {
delete variant;
variant=0;
}
}
Variant(const Variant& that) {
if (this != &that) {
variant=that.variant->Clone();
}
}
Variant& operator=(const Variant& that) {
if (this != &that) {
delete variant;
variant=that.variant->Clone();
}
return *this;
}
template<class T>
T* get() const {
return variant->get<T>();
}
private:
BaseVariantImpl *variant;
};
} /* namespace sql */
#endif /* _SQL_VARIANT_H_ */

View File

@@ -1,53 +0,0 @@
/*
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* */
#define MYCPPCONN_DM_MAJOR_VERSION 8
#define MYCPPCONN_DM_MINOR_VERSION 2
#define MYCPPCONN_DM_PATCH_VERSION 0
#define MYCPPCONN_DM_VERSION "8.2.0"
#define MYCPPCONN_DM_VERSION_ID 8020000
#define MYSQL_CONCPP_LICENSE "GPL-2.0"
#define MYSQL_CONCPP_VERSION_MAJOR 8
#define MYSQL_CONCPP_VERSION_MINOR 2
#define MYSQL_CONCPP_VERSION_MICRO 0
#define MYSQL_CONCPP_VERSION_NUMBER 8020000
/* Driver version info */
#define MYCPPCONN_STATIC_MYSQL_VERSION "8.2.0"
#define MYCPPCONN_STATIC_MYSQL_VERSION_ID 80200
#define MYCPPCONN_BOOST_VERSION

View File

@@ -1,80 +0,0 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SQL_WARNING_H_
#define _SQL_WARNING_H_
#include <stdexcept>
#include <string>
#include <memory>
#include "sqlstring.h"
namespace sql
{
#ifdef _WIN32
#pragma warning (disable : 4290)
//warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif
class SQLWarning
{
public:
SQLWarning(){}
virtual const sql::SQLString & getMessage() const = 0;
virtual const sql::SQLString & getSQLState() const = 0;
virtual int getErrorCode() const = 0;
virtual const SQLWarning * getNextWarning() const = 0;
virtual void setNextWarning(const SQLWarning * _next) = 0;
protected:
virtual ~SQLWarning(){};
SQLWarning(const SQLWarning&){};
private:
const SQLWarning & operator = (const SQLWarning & rhs);
};
} /* namespace sql */
#endif /* _SQL_WARNING_H_ */

View File

@@ -1,233 +0,0 @@
/*
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _MYSQL_CONNECTION_H_
#define _MYSQL_CONNECTION_H_
#include "cppconn/connection.h"
#include <memory>
#if(_WIN32 && CONCPP_BUILD_SHARED)
extern std::string driver_dll_path;
#endif
namespace sql
{
namespace mysql
{
class CPPCONN_PUBLIC_FUNC MySQL_Savepoint : public sql::Savepoint
{
sql::SQLString name;
public:
MySQL_Savepoint(const sql::SQLString &savepoint);
virtual ~MySQL_Savepoint() {}
int getSavepointId();
sql::SQLString getSavepointName();
private:
/* Prevent use of these */
MySQL_Savepoint(const MySQL_Savepoint &);
void operator=(MySQL_Savepoint &);
};
class MySQL_DebugLogger;
struct MySQL_ConnectionData; /* PIMPL */
class MySQL_Statement;
class MySQL_Prepared_Statement;
namespace NativeAPI
{
class NativeConnectionWrapper;
}
class CPPCONN_PUBLIC_FUNC MySQL_Connection : public sql::Connection
{
friend MySQL_Statement;
friend MySQL_Prepared_Statement;
MySQL_Statement * createServiceStmt();
public:
MySQL_Connection(Driver * _driver,
::sql::mysql::NativeAPI::NativeConnectionWrapper & _proxy,
const sql::SQLString& hostName,
const sql::SQLString& userName,
const sql::SQLString& password);
MySQL_Connection(Driver * _driver, ::sql::mysql::NativeAPI::NativeConnectionWrapper & _proxy,
std::map< sql::SQLString, sql::ConnectPropertyVal > & options);
virtual ~MySQL_Connection();
void clearWarnings();
void close();
void commit();
sql::Statement * createStatement();
sql::SQLString escapeString(const sql::SQLString &);
bool getAutoCommit();
sql::SQLString getCatalog();
Driver *getDriver();
sql::SQLString getSchema();
sql::SQLString getClientInfo();
void getClientOption(const sql::SQLString & optionName, void * optionValue);
sql::SQLString getClientOption(const sql::SQLString & optionName);
sql::DatabaseMetaData * getMetaData();
enum_transaction_isolation getTransactionIsolation();
const SQLWarning * getWarnings();
bool isClosed();
bool isReadOnly();
bool isValid();
bool reconnect();
sql::SQLString nativeSQL(const sql::SQLString& sql);
sql::PreparedStatement * prepareStatement(const sql::SQLString& sql);
sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int autoGeneratedKeys);
sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int columnIndexes[]);
sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency);
sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability);
sql::PreparedStatement * prepareStatement(const sql::SQLString& sql, sql::SQLString columnNames[]);
void releaseSavepoint(Savepoint * savepoint) ;
void rollback();
void rollback(Savepoint * savepoint);
void setAutoCommit(bool autoCommit);
void setCatalog(const sql::SQLString& catalog);
void setSchema(const sql::SQLString& catalog);
sql::Connection * setClientOption(const sql::SQLString & optionName, const void * optionValue);
sql::Connection * setClientOption(const sql::SQLString & optionName, const sql::SQLString & optionValue);
void setHoldability(int holdability);
void setReadOnly(bool readOnly);
sql::Savepoint * setSavepoint();
sql::Savepoint * setSavepoint(const sql::SQLString& name);
void setTransactionIsolation(enum_transaction_isolation level);
virtual sql::SQLString getSessionVariable(const sql::SQLString & varname);
virtual void setSessionVariable(const sql::SQLString & varname, const sql::SQLString & value);
virtual void setSessionVariable(const sql::SQLString & varname, unsigned int value);
virtual sql::SQLString getLastStatementInfo();
sql::SQLString getCurrentUser();
private:
/* We do not really think this class has to be subclassed*/
void checkClosed();
void init(std::map< sql::SQLString, sql::ConnectPropertyVal > & properties);
Driver * driver;
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4251)
#endif
std::shared_ptr< NativeAPI::NativeConnectionWrapper > proxy;
#ifdef _WIN32
#pragma warning(pop)
#endif
/* statement handle to execute queries initiated by driver. Perhaps it is
a good idea to move it to a separate helper class */
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4251)
#endif
std::unique_ptr< ::sql::mysql::MySQL_Statement > service;
std::unique_ptr< ::sql::mysql::MySQL_ConnectionData > intern; /* pimpl */
#ifdef _WIN32
#pragma warning(pop)
#endif
/* We need to store the user name for telemetry */
SQLString currentUser;
/* Prevent use of these */
MySQL_Connection(const MySQL_Connection &);
void operator=(MySQL_Connection &);
};
} /* namespace mysql */
} /* namespace sql */
#endif // _MYSQL_CONNECTION_H_
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

View File

@@ -1,162 +0,0 @@
/*
* Copyright (c) 2008, 2020, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _MYSQL_DRIVER_H_
#define _MYSQL_DRIVER_H_
#include "cppconn/driver.h"
#include <memory>
extern "C"
{
CPPCONN_PUBLIC_FUNC void * sql_mysql_get_driver_instance();
}
namespace sql
{
namespace mysql
{
namespace NativeAPI
{
class NativeDriverWrapper;
}
//class sql::mysql::NativeAPI::NativeDriverWrapper;
class CPPCONN_PUBLIC_FUNC MySQL_Driver : public sql::Driver
{
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable: 4251)
#endif
std::unique_ptr< ::sql::mysql::NativeAPI::NativeDriverWrapper > proxy;
#ifdef _WIN32
#pragma warning(pop)
#endif
/*
Note: With current implementation `fido_callback` and `fido_callback_store`
are not really used and should be removed after deprecation of Fido
authentication plugin and when ABI can be changed.
*/
::sql::Fido_Callback* fido_callback = nullptr;
::sql::Fido_Callback fido_callback_store;
/*
Callback function to be called by WebAuthn authentication plugin to notify
the user.
Note: Currently the same callback can be used wih deprecated Fido
authentication plugin.
Note: The `fido_callback` pointer is re-used as a flag to indicate if
the callback was set by a user and its type (WebAuthn vs. Fido).
*/
std::function<void(SQLString)> webauthn_callback;
public:
MySQL_Driver();
MySQL_Driver(const ::sql::SQLString & clientLib);
virtual ~MySQL_Driver();
sql::Connection * connect(const sql::SQLString& hostName, const sql::SQLString& userName, const sql::SQLString& password) override;
sql::Connection * connect(sql::ConnectOptionsMap & options) override;
int getMajorVersion() override;
int getMinorVersion() override;
int getPatchVersion() override;
const sql::SQLString & getName() override;
void setCallBack(sql::Fido_Callback &cb) override;
void setCallBack(sql::Fido_Callback &&cb) override;
void setCallBack(sql::WebAuthn_Callback &cb) override;
void setCallBack(sql::WebAuthn_Callback &&cb) override;
void threadInit() override;
void threadEnd() override;
private:
/* Prevent use of these */
MySQL_Driver(const MySQL_Driver &);
void operator=(MySQL_Driver &);
struct WebAuthn_Callback_Setter;
friend WebAuthn_Callback_Setter;
friend MySQL_Connection;
};
/** We do not hide the function if MYSQLCLIENT_STATIC_BINDING(or anything else) not defined
because the counterpart C function is declared in the cppconn and is always visible.
If dynamic loading is not enabled then its result is just like of get_driver_instance()
*/
CPPCONN_PUBLIC_FUNC MySQL_Driver * _get_driver_instance_by_name(const char * const clientlib);
inline static MySQL_Driver * get_driver_instance_by_name(const char * const clientlib)
{
check_lib();
return sql::mysql::_get_driver_instance_by_name(clientlib);
}
inline static MySQL_Driver * get_driver_instance()
{
return sql::mysql::get_driver_instance_by_name("");
}
inline static MySQL_Driver *get_mysql_driver_instance() { return get_driver_instance(); }
} /* namespace mysql */
} /* namespace sql */
#endif // _MYSQL_DRIVER_H_
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

View File

@@ -1,58 +0,0 @@
/*
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _MYSQL_ERROR_H_
#define _MYSQL_ERROR_H_
namespace sql
{
namespace mysql
{
/* Driver specific errors */
enum DRIVER_ERROR {
/* Underlying client library(cl) can't deal with expired password.
Raised when password actually expires */
deCL_CANT_HANDLE_EXP_PWD= 820
};
} /* namespace mysql */
} /* namespace sql */
#endif /* _MYSQL_ERROR_H_ */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +0,0 @@
# soci/include/private
Private headers do not define any parts of public interface,
are not installed in user's filesystem.
Private headers only define common features used internally.

View File

@@ -1,266 +0,0 @@
//
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, Rafal Bobrowski
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_FIREBIRD_COMMON_H_INCLUDED
#define SOCI_FIREBIRD_COMMON_H_INCLUDED
#include "soci/firebird/soci-firebird.h"
#include "soci-compiler.h"
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <limits>
#include <sstream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
namespace soci
{
namespace details
{
namespace firebird
{
char * allocBuffer(XSQLVAR* var);
void tmEncode(short type, std::tm * src, void * dst);
void tmDecode(short type, void * src, std::tm * dst);
void setTextParam(char const * s, std::size_t size, char * buf_,
XSQLVAR * var);
std::string getTextParam(XSQLVAR const *var);
// Copy contents of a BLOB in buf into the given string.
void copy_from_blob(firebird_statement_backend &st, char *buf, std::string &out);
template <typename IntType>
const char *str2dec(const char * s, IntType &out, short &scale)
{
int sign = 1;
if ('+' == *s)
++s;
else if ('-' == *s)
{
sign = -1;
++s;
}
scale = 0;
bool period = false;
IntType res = 0;
for (out = 0; *s; ++s, out = res)
{
if (*s == '.')
{
if (period)
return s;
period = true;
continue;
}
int d = *s - '0';
if (d < 0 || d > 9)
return s;
res = res * 10 + static_cast<IntType>(d * sign);
if (1 == sign)
{
if (res < out)
return s;
}
else
{
if (res > out)
return s;
}
if (period)
++scale;
}
return s;
}
template <typename T>
inline
T round_for_isc(T value)
{
return value;
}
inline
double round_for_isc(double value)
{
// Unfortunately all the rounding functions are C99 and so are not supported
// by MSVC, so do it manually.
return value < 0 ? value - 0.5 : value + 0.5;
}
//helper template to generate proper code based on compile time type check
template<bool cond> struct cond_to_isc {};
template<> struct cond_to_isc<false>
{
static void checkInteger(short scale, short type)
{
if( scale >= 0 && (type == SQL_SHORT || type == SQL_LONG || type == SQL_INT64) )
throw soci_error("Can't convert non-integral value to integral column type");
}
};
template<> struct cond_to_isc<true>
{
static void checkInteger(short scale,short type) { SOCI_UNUSED(scale) SOCI_UNUSED(type) }
};
template<typename T1>
void to_isc(void * val, XSQLVAR * var, short x_scale = 0)
{
T1 value = *reinterpret_cast<T1*>(val);
short scale = var->sqlscale + x_scale;
short type = var->sqltype & ~1;
long long divisor = 1, multiplier = 1;
cond_to_isc<std::numeric_limits<T1>::is_integer>::checkInteger(scale,type);
for (int i = 0; i > scale; --i)
multiplier *= 10;
for (int i = 0; i < scale; ++i)
divisor *= 10;
switch (type)
{
case SQL_SHORT:
{
int16_t tmp = static_cast<int16_t>(round_for_isc(value*multiplier)/divisor);
std::memcpy(var->sqldata, &tmp, sizeof(int16_t));
}
break;
case SQL_LONG:
{
int32_t tmp = static_cast<int32_t>(round_for_isc(value*multiplier)/divisor);
std::memcpy(var->sqldata, &tmp, sizeof(int32_t));
}
break;
case SQL_INT64:
{
int64_t tmp = static_cast<int64_t>(round_for_isc(value*multiplier)/divisor);
std::memcpy(var->sqldata, &tmp, sizeof(int64_t));
}
break;
case SQL_FLOAT:
{
float sql_value = static_cast<float>(value);
std::memcpy(var->sqldata, &sql_value, sizeof(float));
}
break;
case SQL_DOUBLE:
{
double sql_value = static_cast<double>(value);
std::memcpy(var->sqldata, &sql_value, sizeof(double));
}
break;
default:
throw soci_error("Incorrect data type for numeric conversion");
}
}
template<typename IntType, typename UIntType>
void parse_decimal(void * val, XSQLVAR * var, const char * s)
{
short scale;
UIntType t1;
IntType t2;
if (!*str2dec(s, t1, scale))
std::memcpy(val, &t1, sizeof(t1));
else if (!*str2dec(s, t2, scale))
std::memcpy(val, &t2, sizeof(t2));
else
throw soci_error("Could not parse decimal value.");
to_isc<IntType>(val, var, scale);
}
template<typename IntType>
std::string format_decimal(const void *sqldata, int sqlscale)
{
IntType x = *reinterpret_cast<const IntType *>(sqldata);
std::stringstream out;
out << x;
std::string r = out.str();
if (sqlscale < 0)
{
if (static_cast<int>(r.size()) - (x < 0) <= -sqlscale)
{
r = std::string(size_t(x < 0), '-') +
std::string(-sqlscale - (r.size() - (x < 0)) + 1, '0') +
r.substr(size_t(x < 0), std::string::npos);
}
return r.substr(0, r.size() + sqlscale) + '.' +
r.substr(r.size() + sqlscale, std::string::npos);
}
return r + std::string(sqlscale, '0');
}
template<bool cond> struct cond_from_isc {};
template<> struct cond_from_isc<true> {
static void checkInteger(short scale)
{
std::ostringstream msg;
msg << "Can't convert value with scale " << -scale
<< " to integral type";
throw soci_error(msg.str());
}
};
template<> struct cond_from_isc<false>
{
static void checkInteger(short scale) { SOCI_UNUSED(scale) }
};
template<typename T1>
T1 from_isc(XSQLVAR * var)
{
short scale = var->sqlscale;
T1 tens = 1;
if (scale < 0)
{
cond_from_isc<std::numeric_limits<T1>::is_integer>::checkInteger(scale);
for (int i = 0; i > scale; --i)
{
tens *= 10;
}
}
SOCI_GCC_WARNING_SUPPRESS(cast-align)
switch (var->sqltype & ~1)
{
case SQL_SHORT:
return static_cast<T1>(*reinterpret_cast<int16_t*>(var->sqldata)/tens);
case SQL_LONG:
return static_cast<T1>(*reinterpret_cast<int32_t*>(var->sqldata)/tens);
case SQL_INT64:
return static_cast<T1>(*reinterpret_cast<int64_t*>(var->sqldata)/tens);
case SQL_FLOAT:
return static_cast<T1>(*reinterpret_cast<float*>(var->sqldata));
case SQL_DOUBLE:
return static_cast<T1>(*reinterpret_cast<double*>(var->sqldata));
default:
throw soci_error("Incorrect data type for numeric conversion");
}
SOCI_GCC_WARNING_RESTORE(cast-align)
}
} // namespace firebird
} // namespace details
} // namespace soci
#endif // SOCI_FIREBIRD_COMMON_H_INCLUDED

View File

@@ -1,35 +0,0 @@
//
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, Rafal Bobrowski
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_FIREBIRD_ERROR_H_INCLUDED
#define SOCI_FIREBIRD_ERROR_H_INCLUDED
#include "soci/firebird/soci-firebird.h"
#include <string>
namespace soci
{
namespace details
{
namespace firebird
{
void SOCI_FIREBIRD_DECL get_iscerror_details(ISC_STATUS * status_vector, std::string &msg);
bool SOCI_FIREBIRD_DECL check_iscerror(ISC_STATUS const * status_vector, long errNum);
void SOCI_FIREBIRD_DECL throw_iscerror(ISC_STATUS * status_vector);
} // namespace firebird
} // namespace details
} // namespace soci
#endif // SOCI_FIREBIRD_ERROR_H_INCLUDED

View File

@@ -1,42 +0,0 @@
//
// Copyright (C) 2020 Vadim Zeitlin
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_PRIVATE_SOCI_AUTOSTATEMENT_H_INCLUDED
#define SOCI_PRIVATE_SOCI_AUTOSTATEMENT_H_INCLUDED
namespace soci
{
namespace details
{
// This helper class can be used with any statement backend to initialize and
// cleanup a statement backend object in a RAII way. Normally this is not
// needed because it's done by statement_impl, but this can be handy when using
// a concrete backend inside this backend own code, see e.g. ODBC session
// implementation.
template <typename Backend>
struct auto_statement : Backend
{
template <typename Session>
explicit auto_statement(Session& session)
: Backend(session)
{
this->alloc();
}
~auto_statement() override
{
this->clean_up();
}
};
} // namespace details
} // namespace soci
#endif // SOCI_PRIVATE_SOCI_AUTOSTATEMENT_H_INCLUDED

View File

@@ -1,39 +0,0 @@
//
// Copyright (C) 2015 Vadim Zeitlin
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_PRIVATE_SOCI_COMPILER_H_INCLUDED
#define SOCI_PRIVATE_SOCI_COMPILER_H_INCLUDED
#include "soci-cpp.h"
// SOCI_CHECK_GCC(major,minor) evaluates to 1 when using g++ of at least this
// version or 0 when using g++ of lesser version or not using g++ at all.
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
# define SOCI_CHECK_GCC(major, minor) \
((__GNUC__ > (major)) \
|| (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
#else
# define SOCI_CHECK_GCC(major, minor) 0
#endif
// GCC_WARNING_{SUPPRESS,RESTORE} macros can be used to bracket the code
// producing a specific warning to disable it.
//
// They only work with g++ 4.6+ or clang, warnings are not disabled for earlier
// g++ versions.
#if defined(__clang__) || SOCI_CHECK_GCC(4, 6)
# define SOCI_GCC_WARNING_SUPPRESS(x) \
_Pragma (SOCI_STRINGIZE(GCC diagnostic push)) \
_Pragma (SOCI_STRINGIZE(GCC diagnostic ignored SOCI_STRINGIZE(SOCI_CONCAT(-W,x))))
# define SOCI_GCC_WARNING_RESTORE(x) \
_Pragma (SOCI_STRINGIZE(GCC diagnostic pop))
#else /* gcc < 4.6 or not gcc and not clang at all */
# define SOCI_GCC_WARNING_SUPPRESS(x)
# define SOCI_GCC_WARNING_RESTORE(x)
#endif
#endif // SOCI_PRIVATE_SOCI_COMPILER_H_INCLUDED

View File

@@ -1,30 +0,0 @@
//
// Copyright (C) 2015 Vadim Zeitlin
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_PRIVATE_SOCI_CPP_H_INCLUDED
#define SOCI_PRIVATE_SOCI_CPP_H_INCLUDED
// Some very common preprocessor helpers.
// SOCI_CONCAT() pastes together two tokens after expanding them.
#define SOCI_CONCAT_IMPL(x, y) x ## y
#define SOCI_CONCAT(x, y) SOCI_CONCAT_IMPL(x, y)
// SOCI_STRINGIZE() makes a string of its argument after expanding it.
#define SOCI_STRINGIZE_IMPL(x) #x
#define SOCI_STRINGIZE(x) SOCI_STRINGIZE_IMPL(x)
// SOCI_MAKE_UNIQUE_NAME() creates a uniquely named identifier with the given
// prefix.
//
// It uses __COUNTER__ macro to avoid problems with broken __LINE__ in MSVC
// when using "Edit and Continue" (/ZI) option as there are no compilers known
// to work with SOCI and not support it. If one such is ever discovered, we
// should use __LINE__ for it instead.
#define SOCI_MAKE_UNIQUE_NAME(name) SOCI_CONCAT(name, __COUNTER__)
#endif // SOCI_PRIVATE_SOCI_CPP_H_INCLUDED

View File

@@ -1,80 +0,0 @@
//
// Copyright (C) 2014 Vadim Zeitlin.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_PRIVATE_SOCI_CSTRTOD_H_INCLUDED
#define SOCI_PRIVATE_SOCI_CSTRTOD_H_INCLUDED
#include "soci/error.h"
#include <stdlib.h>
#include <string.h>
namespace soci
{
namespace details
{
// Locale-independent, i.e. always using "C" locale, function for converting
// strings to numbers.
//
// The string must contain a floating point number in "C" locale, i.e. using
// point as decimal separator, and nothing but it. If it does, the converted
// number is returned, otherwise an exception is thrown.
inline
double cstring_to_double(char const* s)
{
// Unfortunately there is no clean way to parse a number in C locale
// without this hack: normally, using std::istringstream with classic
// locale should work, but some standard library implementations are buggy
// and handle non-default locale in thread-unsafe way, by changing the
// global C locale which is unacceptable as it introduces subtle bugs in
// multi-thread programs. So we rely on just the standard C functions and
// try to make them work by tweaking the input into the form appropriate
// for the current locale.
// First try with the original input.
char* end;
double d = strtod(s, &end);
bool parsedOK;
if (*end == '.')
{
// Parsing may have stopped because the current locale uses something
// different from the point as decimal separator, retry with a comma.
//
// In principle, values other than point or comma are possible but they
// don't seem to be used in practice, so for now keep things simple.
size_t const bufSize = strlen(s) + 1;
char* const buf = new char[bufSize];
strcpy(buf, s);
buf[end - s] = ',';
d = strtod(buf, &end);
parsedOK = end != buf && *end == '\0';
delete [] buf;
}
else
{
// Notice that we must detect false positives as well: parsing a string
// using decimal comma should fail when using this function.
parsedOK = end != s && *end == '\0' && !strchr(s, ',');
}
if (!parsedOK)
{
throw soci_error(std::string("Cannot convert data: string \"") + s + "\" "
"is not a number.");
}
return d;
}
} // namespace details
} // namespace soci
#endif // SOCI_PRIVATE_SOCI_CSTRTOD_H_INCLUDED

View File

@@ -1,87 +0,0 @@
//
// Copyright (C) 2020 Vadim Zeitlin.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_PRIVATE_SOCI_CSTRTOI_H_INCLUDED
#define SOCI_PRIVATE_SOCI_CSTRTOI_H_INCLUDED
#include "soci/error.h"
#include <cstdlib>
#include <limits>
namespace soci
{
namespace details
{
// Convert string to a signed value of the given type, checking for overflow.
//
// Fill the provided result parameter and return true on success or false on
// error, e.g. if the string couldn't be converted at all, if anything remains
// in the string after conversion or if the value is out of range.
template <typename T>
bool cstring_to_integer(T& result, char const* buf)
{
char * end;
// No strtoll() on MSVC versions prior to Visual Studio 2013
#if !defined (_MSC_VER) || (_MSC_VER >= 1800)
long long t = strtoll(buf, &end, 10);
#else
long long t = _strtoi64(buf, &end, 10);
#endif
if (end == buf || *end != '\0')
return false;
// successfully converted to long long
// and no other characters were found in the buffer
const T max = (std::numeric_limits<T>::max)();
const T min = (std::numeric_limits<T>::min)();
if (t > static_cast<long long>(max) || t < static_cast<long long>(min))
return false;
result = static_cast<T>(t);
return true;
}
// Similar to the above, but for the unsigned integral types.
template <typename T>
bool cstring_to_unsigned(T& result, char const* buf)
{
char * end;
// No strtoll() on MSVC versions prior to Visual Studio 2013
#if !defined (_MSC_VER) || (_MSC_VER >= 1800)
unsigned long long t = strtoull(buf, &end, 10);
#else
unsigned long long t = _strtoui64(buf, &end, 10);
#endif
if (end == buf || *end != '\0')
return false;
// successfully converted to unsigned long long
// and no other characters were found in the buffer
const T max = (std::numeric_limits<T>::max)();
if (t > static_cast<unsigned long long>(max))
return false;
result = static_cast<T>(t);
return true;
}
} // namespace details
} // namespace soci
#endif // SOCI_PRIVATE_SOCI_CSTRTOI_H_INCLUDED

View File

@@ -1,58 +0,0 @@
//
// Copyright (C) 2014 Vadim Zeitlin.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_PRIVATE_SOCI_DTOCSTR_H_INCLUDED
#define SOCI_PRIVATE_SOCI_DTOCSTR_H_INCLUDED
#include "soci/soci-platform.h"
#include "soci/error.h"
#include <stdlib.h>
#include <stdio.h>
namespace soci
{
namespace details
{
// Locale-independent, i.e. always using "C" locale, function for converting
// floating point number to string.
//
// The resulting string will contain the floating point number in "C" locale,
// i.e. will always use point as decimal separator independently of the current
// locale.
inline
std::string double_to_cstring(double d)
{
// See comments in cstring_to_double() in soci-cstrtod.h, we're dealing
// with the same issues here.
static size_t const bufSize = 32;
char buf[bufSize];
snprintf(buf, bufSize, "%.20g", d);
// Replace any commas which can be used as decimal separator with points.
for (char* p = buf; *p != '\0'; p++ )
{
if (*p == ',')
{
*p = '.';
// There can be at most one comma in this string anyhow.
break;
}
}
return buf;
}
} // namespace details
} // namespace soci
#endif // SOCI_PRIVATE_SOCI_DTOCSTR_H_INCLUDED

View File

@@ -1,129 +0,0 @@
//
// Copyright (C) 2015 Vadim Zeitlin
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_EXCHANGE_CAST_H_INCLUDED
#define SOCI_EXCHANGE_CAST_H_INCLUDED
#include "soci/soci-backend.h"
#include "soci/type-wrappers.h"
#include "soci/blob.h"
#include <cstdint>
#include <ctime>
namespace soci
{
namespace details
{
// cast the given non-null untyped pointer to its corresponding type
template <exchange_type e> struct exchange_type_traits;
template <>
struct exchange_type_traits<x_char>
{
typedef char value_type;
};
template <>
struct exchange_type_traits<x_stdstring>
{
typedef std::string value_type;
};
template <>
struct exchange_type_traits<x_int8>
{
typedef int8_t value_type;
};
template <>
struct exchange_type_traits<x_uint8>
{
typedef uint8_t value_type;
};
template <>
struct exchange_type_traits<x_int16>
{
typedef int16_t value_type;
};
template <>
struct exchange_type_traits<x_uint16>
{
typedef uint16_t value_type;
};
template <>
struct exchange_type_traits<x_int32>
{
typedef int32_t value_type;
};
template <>
struct exchange_type_traits<x_uint32>
{
typedef uint32_t value_type;
};
template <>
struct exchange_type_traits<x_int64>
{
typedef int64_t value_type;
};
template <>
struct exchange_type_traits<x_uint64>
{
typedef uint64_t value_type;
};
template <>
struct exchange_type_traits<x_double>
{
typedef double value_type;
};
template <>
struct exchange_type_traits<x_stdtm>
{
typedef std::tm value_type;
};
template <>
struct exchange_type_traits<x_longstring>
{
typedef long_string value_type;
};
template <>
struct exchange_type_traits<x_xmltype>
{
typedef xml_type value_type;
};
template <>
struct exchange_type_traits<x_blob>
{
typedef blob value_type;
};
// exchange_type_traits not defined for x_statement, x_rowid and x_blob here.
template <exchange_type e>
typename exchange_type_traits<e>::value_type& exchange_type_cast(void *data)
{
return *static_cast<typename exchange_type_traits<e>::value_type*>(data);
}
} // namespace details
} // namespace soci
#endif // SOCI_EXCHANGE_CAST_H_INCLUDED

View File

@@ -1,69 +0,0 @@
//
// Copyright (C) 2015 Vadim Zeitlin.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_PRIVATE_SOCI_MKTIME_H_INCLUDED
#define SOCI_PRIVATE_SOCI_MKTIME_H_INCLUDED
// Not <ctime> because we also want to get timegm() if available.
#include <time.h>
#ifdef _WIN32
#define timegm _mkgmtime
#endif
namespace soci
{
namespace details
{
SOCI_DECL time_t timegm_impl_soci ( struct tm* tb );
template <typename T>
auto timegm_impl(T* t) -> decltype(timegm(t))
{
return timegm(t);
}
template <typename T>
auto timegm_impl(T t) -> time_t
{
return timegm_impl_soci(t);
}
// Fill the provided struct tm with the values corresponding to the given date
// in UTC.
//
// Notice that both years and months are normal human 1-based values here and
// not 1900 or 0-based as in struct tm itself.
inline
void
mktime_from_ymdhms(tm& t,
int year, int month, int day,
int hour, int minute, int second)
{
t.tm_isdst = -1;
t.tm_year = year - 1900;
t.tm_mon = month - 1;
t.tm_mday = day;
t.tm_hour = hour;
t.tm_min = minute;
t.tm_sec = second;
timegm_impl(&t);
}
// Helper function for parsing datetime values.
//
// Throws if the string in buf couldn't be parsed as a date or a time string.
SOCI_DECL void parse_std_tm(char const *buf, std::tm &t);
} // namespace details
} // namespace soci
#endif // SOCI_PRIVATE_SOCI_MKTIME_H_INCLUDED

View File

@@ -1,82 +0,0 @@
#ifndef SOCI_PRIVATE_SOCI_TRIVIAL_BLOB_BACKEND_H_INCLUDED
#define SOCI_PRIVATE_SOCI_TRIVIAL_BLOB_BACKEND_H_INCLUDED
#include "soci/soci-backend.h"
#include <vector>
#include <cstring>
#include <cstdint>
namespace soci
{
namespace details
{
/**
* This Blob implementation uses an explicit buffer that is read from and written to, instead of
* directly communicating with the underlying database.
* Thus, it is intended to be used whenever the underlying database does not offer a more efficient
* way of dealing with BLOBs.
*/
class trivial_blob_backend : public details::blob_backend
{
public:
std::size_t get_len() override { return buffer_.size(); }
std::size_t read_from_start(void* buf, std::size_t toRead,
std::size_t offset = 0) override
{
if (offset > buffer_.size() || (offset == buffer_.size() && offset > 0))
{
throw soci_error("Can't read past-the-end of BLOB data.");
}
// make sure that we don't try to read
// past the end of the data
toRead = std::min<decltype(toRead)>(toRead, buffer_.size() - offset);
memcpy(buf, buffer_.data() + offset, toRead);
return toRead;
}
std::size_t write_from_start(const void* buf, std::size_t toWrite,
std::size_t offset = 0) override
{
if (offset > buffer_.size())
{
throw soci_error("Can't start writing far past-the-end of BLOB data.");
}
buffer_.resize(std::max<std::size_t>(buffer_.size(), offset + toWrite));
memcpy(buffer_.data() + offset, buf, toWrite);
return toWrite;
}
std::size_t append(void const* buf, std::size_t toWrite) override
{
return write_from_start(buf, toWrite, buffer_.size());
}
void trim(std::size_t newLen) override { buffer_.resize(newLen); }
std::size_t set_data(void const* buf, std::size_t toWrite)
{
buffer_.clear();
return write_from_start(buf, toWrite);
}
const std::uint8_t *get_buffer() const { return buffer_.data(); }
protected:
std::vector< std::uint8_t > buffer_;
};
}
}
#endif // SOCI_PRIVATE_SOCI_TRIVIAL_BLOB_BACKEND_H_INCLUDED

View File

@@ -1,157 +0,0 @@
//
// Copyright (C) 2021 Sinitsyn Ilya
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_VECTOR_HELPERS_H_INCLUDED
#define SOCI_VECTOR_HELPERS_H_INCLUDED
#include "soci-exchange-cast.h"
namespace soci
{
namespace details
{
// Helper functions to work with vectors.
template <exchange_type e>
std::vector<typename exchange_type_traits<e>::value_type>& exchange_vector_type_cast(void *data)
{
return *static_cast<std::vector<typename exchange_type_traits<e>::value_type>*>(data);
}
// Get the size of the vector.
inline std::size_t get_vector_size(exchange_type e, void *data)
{
switch (e)
{
case x_char:
return exchange_vector_type_cast<x_char>(data).size();
case x_stdstring:
return exchange_vector_type_cast<x_stdstring>(data).size();
case x_int8:
return exchange_vector_type_cast<x_int8>(data).size();
case x_uint8:
return exchange_vector_type_cast<x_uint8>(data).size();
case x_int16:
return exchange_vector_type_cast<x_int16>(data).size();
case x_uint16:
return exchange_vector_type_cast<x_uint16>(data).size();
case x_int32:
return exchange_vector_type_cast<x_int32>(data).size();
case x_uint32:
return exchange_vector_type_cast<x_uint32>(data).size();
case x_int64:
return exchange_vector_type_cast<x_int64>(data).size();
case x_uint64:
return exchange_vector_type_cast<x_uint64>(data).size();
case x_double:
return exchange_vector_type_cast<x_double>(data).size();
case x_stdtm:
return exchange_vector_type_cast<x_stdtm>(data).size();
case x_xmltype:
return exchange_vector_type_cast<x_xmltype>(data).size();
case x_longstring:
return exchange_vector_type_cast<x_longstring>(data).size();
case x_statement:
case x_rowid:
case x_blob:
break;
}
throw soci_error("Failed to get the size of the vector of non-supported type.");
}
// Set the size of the vector.
inline void resize_vector(exchange_type e, void *data, std::size_t newSize)
{
switch (e)
{
case x_char:
exchange_vector_type_cast<x_char>(data).resize(newSize);
return;
case x_stdstring:
exchange_vector_type_cast<x_stdstring>(data).resize(newSize);
return;
case x_int8:
exchange_vector_type_cast<x_int8>(data).resize(newSize);
return;
case x_uint8:
exchange_vector_type_cast<x_uint8>(data).resize(newSize);
return;
case x_int16:
exchange_vector_type_cast<x_int16>(data).resize(newSize);
return;
case x_uint16:
exchange_vector_type_cast<x_uint16>(data).resize(newSize);
return;
case x_int32:
exchange_vector_type_cast<x_int32>(data).resize(newSize);
return;
case x_uint32:
exchange_vector_type_cast<x_uint32>(data).resize(newSize);
return;
case x_int64:
exchange_vector_type_cast<x_int64>(data).resize(newSize);
return;
case x_uint64:
exchange_vector_type_cast<x_uint64>(data).resize(newSize);
return;
case x_double:
exchange_vector_type_cast<x_double>(data).resize(newSize);
return;
case x_stdtm:
exchange_vector_type_cast<x_stdtm>(data).resize(newSize);
return;
case x_xmltype:
exchange_vector_type_cast<x_xmltype>(data).resize(newSize);
return;
case x_longstring:
exchange_vector_type_cast<x_longstring>(data).resize(newSize);
return;
case x_statement:
case x_rowid:
case x_blob:
break;
}
throw soci_error("Failed to get the size of the vector of non-supported type.");
}
// Get the string at the given index of the vector.
inline std::string& vector_string_value(exchange_type e, void *data, std::size_t ind)
{
switch (e)
{
case x_stdstring:
return exchange_vector_type_cast<x_stdstring>(data).at(ind);
case x_xmltype:
return exchange_vector_type_cast<x_xmltype>(data).at(ind).value;
case x_longstring:
return exchange_vector_type_cast<x_longstring>(data).at(ind).value;
case x_char:
case x_int8:
case x_uint8:
case x_int16:
case x_uint16:
case x_int32:
case x_uint32:
case x_int64:
case x_uint64:
case x_double:
case x_stdtm:
case x_statement:
case x_rowid:
case x_blob:
break;
}
throw soci_error("Can't get the string value from the vector of values with non-supported type.");
}
} // namespace details
} // namespace soci
#endif // SOCI_VECTOR_HELPERS_H_INCLUDED

View File

@@ -1,40 +0,0 @@
//
// Copyright (C) 2008 Maciej Sobczak with contributions from Artyom Tonkikh
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_BACKEND_LOADER_H_INCLUDED
#define SOCI_BACKEND_LOADER_H_INCLUDED
#include "soci/soci-backend.h"
// std
#include <string>
#include <vector>
namespace soci
{
namespace dynamic_backends
{
// only used internally and shouldn't/can't be used from outside the library,
// successful calls to get() should be matched by calls to unget() with the
// same name
backend_factory const & get(std::string const & name);
void unget(std::string const & name);
// provided for advanced user-level management
SOCI_DECL std::vector<std::string> & search_paths();
SOCI_DECL void register_backend(std::string const & name, std::string const & shared_object = std::string());
SOCI_DECL void register_backend(std::string const & name, backend_factory const & factory);
SOCI_DECL std::vector<std::string> list_all();
SOCI_DECL void unload(std::string const & name);
SOCI_DECL void unload_all();
} // namespace dynamic_backends
} // namespace soci
#endif // SOCI_BACKEND_LOADER_H_INCLUDED

View File

@@ -1,216 +0,0 @@
#ifndef SOCI_BIND_VALUES_H_INCLUDED
#define SOCI_BIND_VALUES_H_INCLUDED
#include "soci/soci-platform.h"
#include "exchange-traits.h"
#include "into-type.h"
#include "into.h"
#include "soci-backend.h"
#include "use-type.h"
#include "use.h"
#ifdef SOCI_HAVE_BOOST
# include <boost/fusion/algorithm/iteration/for_each.hpp>
# include <boost/mpl/bool.hpp>
# include <boost/version.hpp>
# if BOOST_VERSION >= 106800
# define SOCI_BOOST_FUSION_FOREACH_REFERENCE &
# else
# define SOCI_BOOST_FUSION_FOREACH_REFERENCE
# endif
#endif // SOCI_HAVE_BOOST
#include <vector>
namespace soci
{
namespace details
{
class use_type_vector: public std::vector<use_type_base *>
{
public:
~use_type_vector()
{
for(iterator iter = begin(), _end = end();
iter != _end; iter++)
delete *iter;
}
void exchange(use_type_ptr const& u) { push_back(u.get()); u.release(); }
template <typename T, typename Indicator>
void exchange(use_container<T, Indicator> const &uc)
{
#ifdef SOCI_HAVE_BOOST
exchange_(uc, (typename boost::fusion::traits::is_sequence<T>::type *)NULL);
#else
exchange_(uc, NULL);
#endif // SOCI_HAVE_BOOST
}
private:
#ifdef SOCI_HAVE_BOOST
template <typename T, typename Indicator>
struct use_sequence
{
use_sequence(use_type_vector &_p, Indicator &_ind)
:p(_p), ind(_ind) {}
template <typename T2>
void operator()(T2 &t2) const
{
p.exchange(use(t2, ind));
}
use_type_vector &p;
Indicator &ind;
private:
SOCI_NOT_COPYABLE(use_sequence)
};
template <typename T>
struct use_sequence<T, details::no_indicator>
{
use_sequence(use_type_vector &_p)
:p(_p) {}
template <typename T2>
void operator()(T2 &t2) const
{
p.exchange(use(t2));
}
use_type_vector &p;
private:
SOCI_NOT_COPYABLE(use_sequence)
};
template <typename T, typename Indicator>
void exchange_(use_container<T, Indicator> const &uc, boost::mpl::true_ * /* fusion sequence */)
{
use_sequence<T, Indicator> f(*this, uc.ind);
boost::fusion::for_each<T,
use_sequence<T, Indicator>
SOCI_BOOST_FUSION_FOREACH_REFERENCE>(uc.t, f);
}
template <typename T>
void exchange_(use_container<T, details::no_indicator> const &uc, boost::mpl::true_ * /* fusion sequence */)
{
use_sequence<T, details::no_indicator> f(*this);
boost::fusion::for_each<T,
use_sequence<T, details::no_indicator>
SOCI_BOOST_FUSION_FOREACH_REFERENCE>(uc.t, f);
}
#endif // SOCI_HAVE_BOOST
template <typename T, typename Indicator>
void exchange_(use_container<T, Indicator> const &uc, ...)
{ exchange(do_use(uc.t, uc.ind, uc.name, typename details::exchange_traits<T>::type_family())); }
template <typename T>
void exchange_(use_container<T, details::no_indicator> const &uc, ...)
{ exchange(do_use(uc.t, uc.name, typename details::exchange_traits<T>::type_family())); }
template <typename T, typename Indicator>
void exchange_(use_container<const T, Indicator> const &uc, ...)
{ exchange(do_use(uc.t, uc.ind, uc.name, typename details::exchange_traits<T>::type_family())); }
template <typename T>
void exchange_(use_container<const T, details::no_indicator> const &uc, ...)
{ exchange(do_use(uc.t, uc.name, typename details::exchange_traits<T>::type_family())); }
};
class into_type_vector: public std::vector<details::into_type_base *>
{
public:
~into_type_vector()
{
for(iterator iter = begin(), _end = end();
iter != _end; iter++)
delete *iter;
}
void exchange(into_type_ptr const& i) { push_back(i.get()); i.release(); }
template <typename T, typename Indicator>
void exchange(into_container<T, Indicator> const &ic)
{
#ifdef SOCI_HAVE_BOOST
exchange_(ic, (typename boost::fusion::traits::is_sequence<T>::type *)NULL);
#else
exchange_(ic, NULL);
#endif // SOCI_HAVE_BOOST
}
private:
#ifdef SOCI_HAVE_BOOST
template <typename T, typename Indicator>
struct into_sequence
{
into_sequence(into_type_vector &_p, Indicator &_ind)
:p(_p), ind(_ind) {}
template <typename T2>
void operator()(T2 &t2) const
{
p.exchange(into(t2, ind));
}
into_type_vector &p;
Indicator &ind;
private:
SOCI_NOT_COPYABLE(into_sequence)
};
template <typename T>
struct into_sequence<T, details::no_indicator>
{
into_sequence(into_type_vector &_p)
:p(_p) {}
template <typename T2>
void operator()(T2 &t2) const
{
p.exchange(into(t2));
}
into_type_vector &p;
private:
SOCI_NOT_COPYABLE(into_sequence)
};
template <typename T, typename Indicator>
void exchange_(into_container<T, Indicator> const &ic, boost::mpl::true_ * /* fusion sequence */)
{
into_sequence<T, Indicator> f(*this, ic.ind);
boost::fusion::for_each<T,
into_sequence<T, Indicator>
SOCI_BOOST_FUSION_FOREACH_REFERENCE>(ic.t, f);
}
template <typename T>
void exchange_(into_container<T, details::no_indicator> const &ic, boost::mpl::true_ * /* fusion sequence */)
{
into_sequence<T, details::no_indicator> f(*this);
boost::fusion::for_each<T,
into_sequence<T, details::no_indicator>
SOCI_BOOST_FUSION_FOREACH_REFERENCE>(ic.t, f);
}
#endif // SOCI_HAVE_BOOST
template <typename T, typename Indicator>
void exchange_(into_container<T, Indicator> const &ic, ...)
{ exchange(do_into(ic.t, ic.ind, typename details::exchange_traits<T>::type_family())); }
template <typename T>
void exchange_(into_container<T, details::no_indicator> const &ic, ...)
{ exchange(do_into(ic.t, typename details::exchange_traits<T>::type_family())); }
};
} // namespace details
}// namespace soci
#endif // SOCI_BIND_VALUES_H_INCLUDED

View File

@@ -1,59 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_BLOB_EXCHANGE_H_INCLUDED
#define SOCI_BLOB_EXCHANGE_H_INCLUDED
#include "soci/blob.h"
#include "soci/into-type.h"
#include "soci/use-type.h"
// std
#include <string>
namespace soci
{
namespace details
{
template <>
class into_type<blob> : public standard_into_type
{
public:
into_type(blob & b) : standard_into_type(&b, x_blob) {}
into_type(blob & b, indicator & ind)
: standard_into_type(&b, x_blob, ind) {}
};
template <>
class use_type<blob> : public standard_use_type
{
public:
use_type(blob & b, std::string const & name = std::string())
: standard_use_type(&b, x_blob, false, name) {}
use_type(blob const & b, std::string const & name = std::string())
: standard_use_type(const_cast<blob *>(&b), x_blob, true, name) {}
use_type(blob & b, indicator & ind,
std::string const & name = std::string())
: standard_use_type(&b, x_blob, ind, false, name) {}
use_type(blob const & b, indicator & ind,
std::string const & name = std::string())
: standard_use_type(const_cast<blob *>(&b), x_blob, ind, true, name) {}
};
template <>
struct exchange_traits<soci::blob>
{
typedef basic_type_tag type_family;
enum { x_type = x_blob };
};
} // namespace details
} // namespace soci
#endif // SOCI_BLOB_EXCHANGE_H_INCLUDED

View File

@@ -1,84 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_BLOB_H_INCLUDED
#define SOCI_BLOB_H_INCLUDED
#include "soci/soci-platform.h"
// std
#include <cstddef>
#include <memory>
namespace soci
{
// basic blob operations
class session;
namespace details
{
class blob_backend;
} // namespace details
class SOCI_DECL blob
{
public:
// Creates an invalid blob object
blob() = default;
explicit blob(session & s);
~blob();
blob(blob &&other) = default;
blob &operator=(blob &&other) = default;
// Checks whether this blob is in a valid state
bool is_valid() const;
// (Re)initializes this blob
void initialize(session &s);
std::size_t get_len();
// offset is backend-specific
[[deprecated("Use read_from_start instead")]]
std::size_t read(std::size_t offset, void * buf, std::size_t toRead);
// Extracts data from this blob into the given buffer.
// At most toRead bytes are extracted (and copied into buf).
// The amount of actually read bytes is returned.
//
// Note: Using an offset > 0 on a blob whose size is less than
// or equal to offset, will throw an exception.
std::size_t read_from_start(void * buf, std::size_t toRead,
std::size_t offset = 0);
// offset is backend-specific
[[deprecated("Use write_from_start instead")]]
std::size_t write(std::size_t offset, const void * buf,
std::size_t toWrite);
// offset starts from 0
std::size_t write_from_start(const void * buf, std::size_t toWrite,
std::size_t offset = 0);
std::size_t append(const void * buf, std::size_t toWrite);
void trim(std::size_t newLen);
details::blob_backend * get_backend() { return backEnd_.get(); }
private:
SOCI_NOT_COPYABLE(blob)
std::unique_ptr<details::blob_backend> backEnd_;
void ensure_initialized();
};
} // namespace soci
#endif

View File

@@ -1,28 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_BOOST_FUSION_H_INCLUDED
#define SOCI_BOOST_FUSION_H_INCLUDED
#ifndef SOCI_MAX_FUSION_SEQUENCE_LENGTH
#define SOCI_MAX_FUSION_SEQUENCE_LENGTH 10
#endif
#include "values.h"
#include "type-conversion-traits.h"
// boost
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/intrinsic/at.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/support/is_sequence.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/utility/enable_if.hpp>
#endif // SOCI_BOOST_FUSION_H_INCLUDED

View File

@@ -1,50 +0,0 @@
//
// Copyright (C) 2008 Maciej Sobczak
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_BOOST_GREGORIAN_DATE_H_INCLUDED
#define SOCI_BOOST_GREGORIAN_DATE_H_INCLUDED
#include "soci/type-conversion-traits.h"
// boost
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <boost/date_time/gregorian/conversion.hpp>
// std
#include <ctime>
namespace soci
{
template<>
struct type_conversion<boost::gregorian::date>
{
typedef std::tm base_type;
static void from_base(
base_type const & in, indicator ind, boost::gregorian::date & out)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type");
}
out = boost::gregorian::date_from_tm(in);
}
struct move_from_base_check :
std::integral_constant<bool, false> {};
static void to_base(
boost::gregorian::date const & in, base_type & out, indicator & ind)
{
out = boost::gregorian::to_tm(in);
ind = i_ok;
}
};
} // namespace soci
#endif // SOCI_BOOST_GREGORIAN_DATE_H_INCLUDED

View File

@@ -1,92 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_BOOST_OPTIONAL_H_INCLUDED
#define SOCI_BOOST_OPTIONAL_H_INCLUDED
#include "soci/type-conversion-traits.h"
// boost
#include <boost/optional.hpp>
#include <boost/optional/optional_io.hpp>
namespace soci
{
// simple fall-back for boost::optional
template <typename T>
struct type_conversion<boost::optional<T> >
{
typedef typename type_conversion<T>::base_type base_type;
struct from_base_check : std::integral_constant<bool, true> {};
static void from_base(base_type const & in, indicator ind,
boost::optional<T> & out)
{
if (ind == i_null)
{
out.reset();
}
else
{
T tmp = T();
type_conversion<T>::from_base(in, ind, tmp);
out = tmp;
}
}
struct move_from_base_check :
std::integral_constant<bool,
!std::is_const<base_type>::value
&& std::is_constructible<boost::optional<T>, typename std::add_rvalue_reference<base_type>::type>::value
> {};
static void move_from_base(base_type & in, indicator ind, boost::optional<T> & out)
{
static_assert(move_from_base_check::value,
"move_to_base can only be used if the target type can be constructed from an rvalue base reference");
if (ind == i_null)
{
out.reset();
}
else
{
out = std::move(in);
}
}
static void to_base(boost::optional<T> const & in,
base_type & out, indicator & ind)
{
if (in.is_initialized())
{
type_conversion<T>::to_base(in.get(), out, ind);
}
else
{
ind = i_null;
}
}
static void move_to_base(boost::optional<T> & in, base_type & out, indicator & ind)
{
if (in.is_initialized())
{
out = std::move(in.get());
ind = i_ok;
}
else
{
ind = i_null;
}
}
};
} // namespace soci
#endif // SOCI_BOOST_OPTIONAL_H_INCLUDED

View File

@@ -1,18 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_BOOST_TUPLE_H_INCLUDED
#define SOCI_BOOST_TUPLE_H_INCLUDED
#include "values.h"
#include "type-conversion-traits.h"
// boost
#include <boost/tuple/tuple.hpp>
#include <boost/fusion/adapted/boost_tuple.hpp>
#endif // SOCI_BOOST_TUPLE_H_INCLUDED

View File

@@ -1,47 +0,0 @@
//
// Copyright (C) 2015 Maciej Sobczak
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_CALLBACKS_H_INCLUDED
#define SOCI_CALLBACKS_H_INCLUDED
namespace soci
{
class session;
// Simple callback interface for reporting failover events.
// The meaning of each operation is intended to be portable,
// but the behaviour details and parameters can be backend-specific.
class SOCI_DECL failover_callback
{
public:
// Called when the failover operation has started,
// after discovering connectivity problems.
virtual void started() {}
// Called after successful failover and creating a new connection;
// the sql parameter denotes the new connection and allows the user
// to replay any initial sequence of commands (like session configuration).
virtual void finished(session & /* sql */) {}
// Called when the attempt to reconnect failed,
// if the user code sets the retry parameter to true,
// then new connection will be attempted;
// the newTarget connection string is a hint that can be ignored
// by external means.
virtual void failed(bool & /* out */ /* retry */,
std::string & /* out */ /* newTarget */) {}
// Called when there was a failure that prevents further failover attempts.
virtual void aborted() {}
};
} // namespace soci
#endif // SOCI_CALLBACKS_H_INCLUDED

View File

@@ -1,149 +0,0 @@
//
// Copyright (C) 2016 Maciej Sobczak
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_COLUMN_INFO_H_INCLUDED
#define SOCI_COLUMN_INFO_H_INCLUDED
#include "soci/soci-backend.h"
#include "soci/type-conversion.h"
#include "soci/values.h"
#include <cstdint>
namespace soci
{
struct SOCI_DECL column_info
{
std::string name;
// DEPRECATED. USE dataType INSTEAD.
data_type type;
db_type dataType;
std::size_t length; // meaningful for text columns only
std::size_t precision;
std::size_t scale;
bool nullable;
};
template <>
struct type_conversion<column_info>
{
typedef values base_type;
static std::size_t get_numeric_value(const values & v,
const std::string & field_name)
{
db_type dt = v.get_properties(field_name).get_db_type();
switch (dt)
{
case db_double:
return static_cast<std::size_t>(
v.get<double>(field_name, 0.0));
case db_int8:
return static_cast<std::size_t>(
v.get<int8_t>(field_name, 0));
case db_uint8:
return static_cast<std::size_t>(
v.get<uint8_t>(field_name, 0));
case db_int16:
return static_cast<std::size_t>(
v.get<int16_t>(field_name, 0));
case db_uint16:
return static_cast<std::size_t>(
v.get<uint16_t>(field_name, 0));
case db_int32:
return static_cast<std::size_t>(
v.get<int32_t>(field_name, 0));
case db_uint32:
return static_cast<std::size_t>(
v.get<uint32_t>(field_name, 0));
case db_int64:
return static_cast<std::size_t>(
v.get<int64_t>(field_name, 0ll));
case db_uint64:
return static_cast<std::size_t>(
v.get<uint64_t>(field_name, 0ull));
default:
return 0u;
}
}
static void from_base(values const & v, indicator /* ind */, column_info & ci)
{
ci.name = v.get<std::string>("COLUMN_NAME");
ci.length = get_numeric_value(v, "CHARACTER_MAXIMUM_LENGTH");
ci.precision = get_numeric_value(v, "NUMERIC_PRECISION");
ci.scale = get_numeric_value(v, "NUMERIC_SCALE");
const std::string & type_name = v.get<std::string>("DATA_TYPE");
if (type_name == "text" || type_name == "TEXT" ||
type_name == "clob" || type_name == "CLOB" ||
type_name.find("char") != std::string::npos ||
type_name.find("CHAR") != std::string::npos)
{
ci.type = dt_string;
ci.dataType = db_string;
}
else if (type_name == "integer" || type_name == "INTEGER")
{
ci.type = dt_integer;
ci.dataType = db_int32;
}
else if (type_name.find("number") != std::string::npos ||
type_name.find("NUMBER") != std::string::npos ||
type_name.find("numeric") != std::string::npos ||
type_name.find("NUMERIC") != std::string::npos)
{
if (ci.scale != 0)
{
ci.type = dt_double;
ci.dataType = db_double;
}
else
{
ci.type = dt_integer;
ci.dataType = db_int32;
}
}
else if (type_name.find("time") != std::string::npos ||
type_name.find("TIME") != std::string::npos ||
type_name.find("date") != std::string::npos ||
type_name.find("DATE") != std::string::npos)
{
ci.type = dt_date;
ci.dataType = db_date;
}
else if (type_name.find("blob") != std::string::npos ||
type_name.find("BLOB") != std::string::npos ||
type_name.find("oid") != std::string::npos ||
type_name.find("OID") != std::string::npos)
{
ci.type = dt_blob;
ci.dataType = db_blob;
}
else if (type_name.find("xml") != std::string::npos ||
type_name.find("XML") != std::string::npos)
{
ci.type = dt_xml;
ci.dataType = db_xml;
}
else
{
// this seems to be a safe default
ci.type = dt_string;
ci.dataType = db_string;
}
const std::string & nullable_s = v.get<std::string>("IS_NULLABLE");
ci.nullable = (nullable_s == "YES");
}
};
} // namespace soci
#endif // SOCI_COLUMN_INFO_H_INCLUDED

View File

@@ -1,99 +0,0 @@
//
// Copyright (C) 2013 Vadim Zeitlin
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_CONNECTION_PARAMETERS_H_INCLUDED
#define SOCI_CONNECTION_PARAMETERS_H_INCLUDED
#include "soci/soci-platform.h"
#include <map>
#include <string>
namespace soci
{
// Names of some predefined options and their values.
extern SOCI_DECL char const * option_reconnect;
extern SOCI_DECL char const * option_true;
namespace details
{
class dynamic_backend_ref;
} // namespace details
class backend_factory;
// Simple container for the information used when opening a session.
class SOCI_DECL connection_parameters
{
public:
connection_parameters();
connection_parameters(backend_factory const & factory, std::string const & connectString);
connection_parameters(std::string const & backendName, std::string const & connectString);
explicit connection_parameters(std::string const & fullConnectString);
connection_parameters(connection_parameters const& other);
connection_parameters(connection_parameters && other);
connection_parameters& operator=(connection_parameters const& other);
connection_parameters& operator=(connection_parameters && other);
~connection_parameters();
// Retrieve the backend and the connection strings specified in the ctor.
backend_factory const * get_factory() const { return factory_; }
void set_connect_string(const std::string & connectString) { connectString_ = connectString; }
std::string const & get_connect_string() const { return connectString_; }
// Set the value of the given option, overwriting any previous value.
void set_option(const char * name, std::string const & value)
{
options_[name] = value;
}
// Return true if the option with the given name was found and fill the
// provided parameter with its value.
bool get_option(const char * name, std::string & value) const
{
Options::const_iterator const it = options_.find(name);
if (it == options_.end())
return false;
value = it->second;
return true;
}
// Return true if the option with the given name was found with option_true
// value.
bool is_option_on(const char * name) const
{
std::string value;
return get_option(name, value) && value == option_true;
}
private:
void reset_after_move();
// The backend and connection string specified in our ctor.
backend_factory const * factory_;
std::string connectString_;
// References the backend name used for obtaining the factor from
// dynamic_backends.
details::dynamic_backend_ref * backendRef_;
// We store all the values as strings for simplicity.
typedef std::map<std::string, std::string> Options;
Options options_;
};
} // namespace soci
#endif // SOCI_CONNECTION_PARAMETERS_H_INCLUDED

View File

@@ -1,41 +0,0 @@
//
// Copyright (C) 2008 Maciej Sobczak
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_CONNECTION_POOL_H_INCLUDED
#define SOCI_CONNECTION_POOL_H_INCLUDED
#include "soci/soci-platform.h"
// std
#include <cstddef>
namespace soci
{
class session;
class SOCI_DECL connection_pool
{
public:
explicit connection_pool(std::size_t size);
~connection_pool();
session & at(std::size_t pos);
std::size_t lease();
bool try_lease(std::size_t & pos, int timeout);
void give_back(std::size_t pos);
private:
struct connection_pool_impl;
connection_pool_impl * pimpl_;
SOCI_NOT_COPYABLE(connection_pool)
};
}
#endif // SOCI_CONNECTION_POOL_H_INCLUDED

View File

@@ -1,293 +0,0 @@
//
// Copyright (C) 2011-2013 Denis Chapligin
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_DB2_H_INCLUDED
#define SOCI_DB2_H_INCLUDED
#include <soci/soci-platform.h>
#ifdef SOCI_DB2_SOURCE
# define SOCI_DB2_DECL SOCI_DECL_EXPORT
#else
# define SOCI_DB2_DECL SOCI_DECL_IMPORT
#endif
#include <soci/soci-backend.h>
#include <cstddef>
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#include <sqlcli1.h>
namespace soci
{
namespace details { namespace db2
{
enum binding_method
{
BOUND_BY_NONE,
BOUND_BY_NAME,
BOUND_BY_POSITION
};
inline SQLPOINTER int_as_ptr(int n)
{
union
{
SQLPOINTER p;
int n;
} u;
u.n = n;
return u.p;
}
}}
static const std::size_t maxBuffer = 1024 * 1024 * 1024; //CLI limit is about 3 GB, but 1GB should be enough
class SOCI_DB2_DECL db2_soci_error : public soci_error {
public:
db2_soci_error(std::string const & msg, SQLRETURN rc) : soci_error(msg),errorCode(rc) {};
~db2_soci_error() noexcept override { };
//We have to extract error information before exception throwing, cause CLI handles could be broken at the construction time
static const std::string sqlState(std::string const & msg,const SQLSMALLINT htype,const SQLHANDLE hndl);
SQLRETURN errorCode;
};
// Option allowing to specify the "driver completion" parameter of
// SQLDriverConnect(). Its possible values are the same as the allowed values
// for this parameter in the official DB2 CLI, i.e. one of SQL_DRIVER_XXX
// (in string form as all options are strings currently).
extern SOCI_DB2_DECL char const * db2_option_driver_complete;
struct db2_statement_backend;
struct SOCI_DB2_DECL db2_standard_into_type_backend : details::standard_into_type_backend
{
db2_standard_into_type_backend(db2_statement_backend &st)
: statement_(st),buf(NULL)
{}
void define_by_pos(int& position, void* data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch, indicator* ind) override;
void clean_up() override;
db2_statement_backend& statement_;
char* buf;
void *data;
details::exchange_type type;
int position;
SQLSMALLINT cType;
SQLLEN valueLen;
};
struct SOCI_DB2_DECL db2_vector_into_type_backend : details::vector_into_type_backend
{
db2_vector_into_type_backend(db2_statement_backend &st)
: statement_(st),buf(NULL)
{}
void define_by_pos(int& position, void* data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator* ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
void clean_up() override;
db2_statement_backend& statement_;
void prepare_indicators(std::size_t size);
std::vector<SQLLEN> indVec;
void *data;
char *buf;
int position_;
details::exchange_type type;
SQLSMALLINT cType;
std::size_t colSize;
};
struct SOCI_DB2_DECL db2_standard_use_type_backend : details::standard_use_type_backend
{
db2_standard_use_type_backend(db2_statement_backend &st)
: statement_(st),buf(NULL),ind(0)
{}
void bind_by_pos(int& position, void* data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const& name, void* data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const* ind) override;
void post_use(bool gotData, indicator* ind) override;
void clean_up() override;
db2_statement_backend& statement_;
void *prepare_for_bind(SQLLEN &size, SQLSMALLINT &sqlType, SQLSMALLINT &cType);
void *data;
details::exchange_type type;
int position;
std::string name;
char* buf;
SQLLEN ind;
};
struct SOCI_DB2_DECL db2_vector_use_type_backend : details::vector_use_type_backend
{
db2_vector_use_type_backend(db2_statement_backend &st)
: statement_(st),buf(NULL) {}
void bind_by_pos(int& position, void* data, details::exchange_type type) override;
void bind_by_name(std::string const& name, void* data, details::exchange_type type) override;
void pre_use(indicator const* ind) override;
std::size_t size() override;
void clean_up() override;
db2_statement_backend& statement_;
void prepare_indicators(std::size_t size);
void *prepare_for_bind(SQLUINTEGER &size,SQLSMALLINT &sqlType, SQLSMALLINT &cType);
std::vector<SQLLEN> indVec;
void *data;
char *buf;
details::exchange_type type;
std::size_t colSize;
int position;
};
struct db2_session_backend;
struct SOCI_DB2_DECL db2_statement_backend : details::statement_backend
{
db2_statement_backend(db2_session_backend &session);
void alloc() override;
void clean_up() override;
void prepare(std::string const& query, details::statement_type eType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const& query) override;
int prepare_for_describe() override;
void describe_column(int colNum, db_type& dbtype, std::string& columnName) override;
size_t column_size(int col);
db2_standard_into_type_backend* make_into_type_backend() override;
db2_standard_use_type_backend* make_use_type_backend() override;
db2_vector_into_type_backend* make_vector_into_type_backend() override;
db2_vector_use_type_backend* make_vector_use_type_backend() override;
db2_session_backend& session_;
SQLHANDLE hStmt;
std::string query_;
std::vector<std::string> names_;
bool hasVectorUseElements;
SQLUINTEGER numRowsFetched;
details::db2::binding_method use_binding_method_;
};
struct db2_rowid_backend : details::rowid_backend
{
db2_rowid_backend(db2_session_backend &session);
~db2_rowid_backend() override;
};
struct db2_blob_backend : details::blob_backend
{
db2_blob_backend(db2_session_backend& session);
~db2_blob_backend() override;
std::size_t get_len() override;
std::size_t read_from_start(void* buf, std::size_t toRead, std::size_t offset = 0) override;
std::size_t write_from_start(const void* buf, std::size_t toWrite, std::size_t offset = 0) override;
std::size_t append(const void* buf, std::size_t toWrite) override;
void trim(std::size_t newLen) override;
db2_session_backend& session_;
};
struct db2_session_backend : details::session_backend
{
db2_session_backend(connection_parameters const& parameters);
~db2_session_backend() override;
bool is_connected() override;
void begin() override;
void commit() override;
void rollback() override;
std::string get_dummy_from_table() const override { return "sysibm.sysdummy1"; }
std::string get_backend_name() const override { return "DB2"; }
void clean_up();
db2_statement_backend* make_statement_backend() override;
db2_rowid_backend* make_rowid_backend() override;
db2_blob_backend* make_blob_backend() override;
void parseConnectString(std::string const &);
void parseKeyVal(std::string const &);
std::string connection_string_;
bool autocommit;
bool in_transaction;
SQLHANDLE hEnv; /* Environment handle */
SQLHANDLE hDbc; /* Connection handle */
};
struct SOCI_DB2_DECL db2_backend_factory : backend_factory
{
db2_backend_factory() {}
db2_session_backend* make_session(
connection_parameters const & parameters) const override;
};
extern SOCI_DB2_DECL db2_backend_factory const db2;
extern "C"
{
// for dynamic backend loading
SOCI_DB2_DECL backend_factory const* factory_db2();
SOCI_DB2_DECL void register_factory_db2();
} // extern "C"
} // namespace soci
#endif // SOCI_DB2_H_INCLUDED

View File

@@ -1,194 +0,0 @@
//
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_EMPTY_H_INCLUDED
#define SOCI_EMPTY_H_INCLUDED
#include <soci/soci-platform.h>
#ifdef SOCI_EMPTY_SOURCE
# define SOCI_EMPTY_DECL SOCI_DECL_EXPORT
#else
# define SOCI_EMPTY_DECL SOCI_DECL_IMPORT
#endif
#include <soci/soci-backend.h>
#include <cstddef>
#include <string>
namespace soci
{
struct empty_statement_backend;
struct SOCI_EMPTY_DECL empty_standard_into_type_backend : details::standard_into_type_backend
{
empty_standard_into_type_backend(empty_statement_backend &st)
: statement_(st)
{}
void define_by_pos(int& position, void* data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch, indicator* ind) override;
void clean_up() override;
empty_statement_backend& statement_;
};
struct SOCI_EMPTY_DECL empty_vector_into_type_backend : details::vector_into_type_backend
{
empty_vector_into_type_backend(empty_statement_backend &st)
: statement_(st)
{}
void define_by_pos(int& position, void* data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator* ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
void clean_up() override;
empty_statement_backend& statement_;
};
struct SOCI_EMPTY_DECL empty_standard_use_type_backend : details::standard_use_type_backend
{
empty_standard_use_type_backend(empty_statement_backend &st)
: statement_(st)
{}
void bind_by_pos(int& position, void* data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const& name, void* data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const* ind) override;
void post_use(bool gotData, indicator* ind) override;
void clean_up() override;
empty_statement_backend& statement_;
};
struct SOCI_EMPTY_DECL empty_vector_use_type_backend : details::vector_use_type_backend
{
empty_vector_use_type_backend(empty_statement_backend &st)
: statement_(st) {}
void bind_by_pos(int& position, void* data, details::exchange_type type) override;
void bind_by_name(std::string const& name, void* data, details::exchange_type type) override;
void pre_use(indicator const* ind) override;
std::size_t size() override;
void clean_up() override;
empty_statement_backend& statement_;
};
struct empty_session_backend;
struct SOCI_EMPTY_DECL empty_statement_backend : details::statement_backend
{
empty_statement_backend(empty_session_backend &session);
void alloc() override;
void clean_up() override;
void prepare(std::string const& query, details::statement_type eType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const& query) override;
int prepare_for_describe() override;
void describe_column(int colNum, db_type& dbtype, std::string& columnName) override;
empty_standard_into_type_backend* make_into_type_backend() override;
empty_standard_use_type_backend* make_use_type_backend() override;
empty_vector_into_type_backend* make_vector_into_type_backend() override;
empty_vector_use_type_backend* make_vector_use_type_backend() override;
empty_session_backend& session_;
};
struct empty_rowid_backend : details::rowid_backend
{
empty_rowid_backend(empty_session_backend &session);
~empty_rowid_backend() override;
};
struct empty_blob_backend : details::blob_backend
{
empty_blob_backend(empty_session_backend& session);
~empty_blob_backend() override;
std::size_t get_len() override;
std::size_t read_from_start(void * buf, std::size_t toRead, std::size_t offset = 0) override;
std::size_t write_from_start(const void * buf, std::size_t toWrite, std::size_t offset = 0) override;
std::size_t append(const void* buf, std::size_t toWrite) override;
void trim(std::size_t newLen) override;
empty_session_backend& session_;
};
struct empty_session_backend : details::session_backend
{
empty_session_backend(connection_parameters const& parameters);
~empty_session_backend() override;
bool is_connected() override { return true; }
void begin() override;
void commit() override;
void rollback() override;
std::string get_dummy_from_table() const override { return std::string(); }
std::string get_backend_name() const override { return "empty"; }
void clean_up();
empty_statement_backend* make_statement_backend() override;
empty_rowid_backend* make_rowid_backend() override;
empty_blob_backend* make_blob_backend() override;
};
struct SOCI_EMPTY_DECL empty_backend_factory : backend_factory
{
empty_backend_factory() {}
empty_session_backend* make_session(connection_parameters const& parameters) const override;
};
extern SOCI_EMPTY_DECL empty_backend_factory const empty;
extern "C"
{
// for dynamic backend loading
SOCI_EMPTY_DECL backend_factory const* factory_empty();
SOCI_EMPTY_DECL void register_factory_empty();
} // extern "C"
} // namespace soci
#endif // SOCI_EMPTY_H_INCLUDED

View File

@@ -1,66 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak
// Copyright (C) 2015 Vadim Zeitlin
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_ERROR_H_INCLUDED
#define SOCI_ERROR_H_INCLUDED
#include "soci/soci-platform.h"
// std
#include <stdexcept>
#include <string>
namespace soci
{
class SOCI_DECL soci_error : public std::runtime_error
{
public:
explicit soci_error(std::string const & msg);
soci_error(soci_error const& e) noexcept;
soci_error& operator=(soci_error const& e) noexcept;
~soci_error() noexcept override;
// Returns just the error message itself, without the context.
std::string get_error_message() const;
// Returns the full error message combining the message given to the ctor
// with all the available context records.
char const* what() const noexcept override;
// This is used only by SOCI itself to provide more information about the
// exception as it bubbles up. It can be called multiple times, with the
// first call adding the lowest level context and the last one -- the
// highest level context.
void add_context(std::string const& context);
// Basic error classes.
enum error_category
{
connection_error,
invalid_statement,
no_privilege,
no_data,
constraint_violation,
unknown_transaction_state,
system_error,
unknown
};
// Basic error classification support
virtual error_category get_error_category() const { return unknown; }
private:
// Optional extra information (currently just the context data).
class soci_error_extra_info* info_;
};
} // namespace soci
#endif // SOCI_ERROR_H_INCLUDED

View File

@@ -1,190 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_EXCHANGE_TRAITS_H_INCLUDED
#define SOCI_EXCHANGE_TRAITS_H_INCLUDED
#include "soci/soci-types.h"
#include "soci/type-conversion-traits.h"
#include "soci/soci-backend.h"
#include "soci/type-wrappers.h"
// std
#include <cstdint>
#include <ctime>
#include <string>
#include <vector>
namespace soci
{
namespace details
{
struct basic_type_tag {};
struct user_type_tag {};
template <typename T>
struct exchange_traits
{
// this is used for tag-dispatch between implementations for basic types
// and user-defined types
typedef user_type_tag type_family;
enum // anonymous
{
x_type =
exchange_traits
<
typename type_conversion<T>::base_type
>::x_type
};
};
template <>
struct exchange_traits<int8_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_int8 };
};
template <>
struct exchange_traits<uint8_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_uint8 };
};
template <>
struct exchange_traits<int16_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_int16 };
};
template <>
struct exchange_traits<uint16_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_uint16 };
};
template <>
struct exchange_traits<int32_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_int32 };
};
template <>
struct exchange_traits<uint32_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_uint32 };
};
template <>
struct exchange_traits<int64_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_int64 };
};
template <>
struct exchange_traits<uint64_t>
{
typedef basic_type_tag type_family;
enum { x_type = x_uint64 };
};
#if defined(SOCI_INT64_IS_LONG)
template <>
struct exchange_traits<long long> : exchange_traits<int64_t>
{
};
template <>
struct exchange_traits<unsigned long long> : exchange_traits<uint64_t>
{
};
#elif defined(SOCI_LONG_IS_64_BIT)
template <>
struct exchange_traits<long> : exchange_traits<int64_t>
{
};
template <>
struct exchange_traits<unsigned long> : exchange_traits<uint64_t>
{
};
#else
template <>
struct exchange_traits<long> : exchange_traits<int32_t>
{
};
template <>
struct exchange_traits<unsigned long> : exchange_traits<uint32_t>
{
};
#endif
template <>
struct exchange_traits<double>
{
typedef basic_type_tag type_family;
enum { x_type = x_double };
};
template <>
struct exchange_traits<char>
{
typedef basic_type_tag type_family;
enum { x_type = x_char };
};
template <>
struct exchange_traits<std::string>
{
typedef basic_type_tag type_family;
enum { x_type = x_stdstring };
};
template <>
struct exchange_traits<std::tm>
{
typedef basic_type_tag type_family;
enum { x_type = x_stdtm };
};
template <typename T>
struct exchange_traits<std::vector<T> >
{
typedef typename exchange_traits<T>::type_family type_family;
enum { x_type = exchange_traits<T>::x_type };
};
// handling of wrapper types
template <>
struct exchange_traits<xml_type>
{
typedef basic_type_tag type_family;
enum { x_type = x_xmltype };
};
template <>
struct exchange_traits<long_string>
{
typedef basic_type_tag type_family;
enum { x_type = x_longstring };
};
} // namespace details
} // namespace soci
#endif // SOCI_EXCHANGE_TRAITS_H_INCLUDED

View File

@@ -1,356 +0,0 @@
//
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, Rafal Bobrowski
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
#ifndef SOCI_FIREBIRD_H_INCLUDED
#define SOCI_FIREBIRD_H_INCLUDED
#include <soci/soci-platform.h>
#ifdef SOCI_FIREBIRD_SOURCE
# define SOCI_FIREBIRD_DECL SOCI_DECL_EXPORT
#else
# define SOCI_FIREBIRD_DECL SOCI_DECL_IMPORT
#endif
#ifdef _WIN32
#include <ciso646> // To understand and/or/not on MSVC9
#endif
#include <soci/soci-backend.h>
#include <ibase.h> // FireBird
#include <cstdlib>
#include <vector>
#include <string>
#include <cstdint>
namespace soci
{
std::size_t const stat_size = 20;
// size of buffer for error messages. All examples use this value.
// Anyone knows, where it is stated that 512 bytes is enough ?
std::size_t const SOCI_FIREBIRD_ERRMSG = 512;
class SOCI_FIREBIRD_DECL firebird_soci_error : public soci_error
{
public:
firebird_soci_error(std::string const & msg,
ISC_STATUS const * status = 0);
~firebird_soci_error() noexcept override {};
std::vector<ISC_STATUS> status_;
};
enum BuffersType
{
eStandard, eVector
};
struct firebird_blob_backend;
struct firebird_statement_backend;
struct firebird_standard_into_type_backend : details::standard_into_type_backend
{
firebird_standard_into_type_backend(firebird_statement_backend &st)
: statement_(st), data_(NULL), type_(), position_(0), buf_(NULL), indISCHolder_(0)
{}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch,
indicator *ind) override;
void clean_up() override;
firebird_statement_backend &statement_;
virtual void exchangeData();
void *data_;
details::exchange_type type_;
int position_;
char *buf_;
short indISCHolder_;
};
struct firebird_vector_into_type_backend : details::vector_into_type_backend
{
firebird_vector_into_type_backend(firebird_statement_backend &st)
: statement_(st), data_(NULL), type_(), position_(0), buf_(NULL), indISCHolder_(0)
{}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator *ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
void clean_up() override;
firebird_statement_backend &statement_;
virtual void exchangeData(std::size_t row);
void *data_;
details::exchange_type type_;
int position_;
char *buf_;
short indISCHolder_;
};
struct firebird_standard_use_type_backend : details::standard_use_type_backend
{
firebird_standard_use_type_backend(firebird_statement_backend &st)
: statement_(st), data_(NULL), type_(), position_(0), buf_(NULL), indISCHolder_(0),
blob_(NULL)
{}
void bind_by_pos(int &position,
void *data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const *ind) override;
void post_use(bool gotData, indicator *ind) override;
void clean_up() override;
firebird_statement_backend &statement_;
virtual void exchangeData();
void *data_;
details::exchange_type type_;
int position_;
char *buf_;
short indISCHolder_;
private:
// Allocate a temporary blob, fill it with the data from the provided
// string and copy its ID into buf_.
void copy_to_blob(const std::string& in);
// This is used for types mapping to CLOB.
firebird_blob_backend* blob_;
};
struct firebird_vector_use_type_backend : details::vector_use_type_backend
{
firebird_vector_use_type_backend(firebird_statement_backend &st)
: statement_(st), data_(NULL), type_(), position_(0), buf_(NULL), indISCHolder_(0),
blob_(NULL)
{}
void bind_by_pos(int &position,
void *data, details::exchange_type type) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type) override;
void pre_use(indicator const *ind) override;
std::size_t size() override;
void clean_up() override;
firebird_statement_backend &statement_;
virtual void exchangeData(std::size_t row);
void *data_;
details::exchange_type type_;
int position_;
indicator const *inds_;
char *buf_;
short indISCHolder_;
private:
// Allocate a temporary blob, fill it with the data from the provided
// string and copy its ID into buf_.
void copy_to_blob(const std::string &in);
// This is used for types mapping to CLOB.
firebird_blob_backend *blob_;
};
struct firebird_session_backend;
struct firebird_statement_backend : details::statement_backend
{
firebird_statement_backend(firebird_session_backend &session);
void alloc() override;
void clean_up() override;
void prepare(std::string const &query,
details::statement_type eType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const &query) override;
int prepare_for_describe() override;
void describe_column(int colNum,
db_type &dbtype,
std::string &columnName) override;
firebird_standard_into_type_backend * make_into_type_backend() override;
firebird_standard_use_type_backend * make_use_type_backend() override;
firebird_vector_into_type_backend * make_vector_into_type_backend() override;
firebird_vector_use_type_backend * make_vector_use_type_backend() override;
firebird_session_backend &session_;
isc_stmt_handle stmtp_;
XSQLDA * sqldap_;
XSQLDA * sqlda2p_;
bool boundByName_;
bool boundByPos_;
friend struct firebird_vector_into_type_backend;
friend struct firebird_standard_into_type_backend;
friend struct firebird_vector_use_type_backend;
friend struct firebird_standard_use_type_backend;
protected:
int rowsFetched_;
bool endOfRowSet_;
long long rowsAffectedBulk_; // number of rows affected by the last bulk operation
virtual void exchangeData(bool gotData, int row);
virtual void prepareSQLDA(XSQLDA ** sqldap, short size = 10);
virtual void rewriteQuery(std::string const & query,
std::vector<char> & buffer);
virtual void rewriteParameters(std::string const & src,
std::vector<char> & dst);
BuffersType intoType_;
BuffersType useType_;
std::vector<std::vector<indicator> > inds_;
std::vector<void*> intos_;
std::vector<void*> uses_;
// named parameters
std::map <std::string, int> names_;
bool procedure_;
};
struct firebird_blob_backend : details::blob_backend
{
firebird_blob_backend(firebird_session_backend &session);
~firebird_blob_backend() override;
std::size_t get_len() override;
std::size_t read_from_start(void * buf, std::size_t toRead, std::size_t offset = 0) override;
std::size_t write_from_start(const void * buf, std::size_t toWrite, std::size_t offset = 0) override;
std::size_t append(const void *buf, std::size_t toWrite) override;
void trim(std::size_t newLen) override;
// Writes the current data into the database by allocating a new BLOB
// object for it.
//
// Returns The ID of the newly created BLOB object
ISC_QUAD save_to_db();
void assign(ISC_QUAD const & bid);
private:
void open();
long getBLOBInfo();
void load();
void writeBuffer(std::size_t offset, void const * buf,
std::size_t toWrite);
void closeBlob();
firebird_session_backend &session_;
ISC_QUAD blob_id_;
// BLOB id was fetched from database (true)
// or this is new BLOB
bool from_db_;
isc_blob_handle blob_handle_;
// buffer for BLOB data
std::vector<std::uint8_t> data_;
bool loaded_;
long max_seg_size_;
};
struct firebird_session_backend : details::session_backend
{
firebird_session_backend(connection_parameters const & parameters);
~firebird_session_backend() override;
bool is_connected() override;
void begin() override;
void commit() override;
void rollback() override;
bool get_next_sequence_value(session & s,
std::string const & sequence, long long & value) override;
std::string get_dummy_from_table() const override { return "rdb$database"; }
std::string get_backend_name() const override { return "firebird"; }
void cleanUp();
firebird_statement_backend * make_statement_backend() override;
details::rowid_backend* make_rowid_backend() override;
firebird_blob_backend * make_blob_backend() override;
bool get_option_decimals_as_strings() { return decimals_as_strings_; }
// Returns the pointer to the current transaction handle, starting a new
// transaction if necessary.
//
// The returned pointer should
isc_tr_handle* current_transaction();
isc_db_handle dbhp_;
private:
isc_tr_handle trhp_;
bool decimals_as_strings_;
};
struct firebird_backend_factory : backend_factory
{
firebird_backend_factory() {}
firebird_session_backend * make_session(
connection_parameters const & parameters) const override;
};
extern SOCI_FIREBIRD_DECL firebird_backend_factory const firebird;
extern "C"
{
// for dynamic backend loading
SOCI_FIREBIRD_DECL backend_factory const * factory_firebird();
SOCI_FIREBIRD_DECL void register_factory_firebird();
} // extern "C"
} // namespace soci
#endif // SOCI_FIREBIRD_H_INCLUDED

View File

@@ -1,155 +0,0 @@
#ifndef SOCI_FIXED_SIZE_INTS_H_INCLUDED
#define SOCI_FIXED_SIZE_INTS_H_INCLUDED
#include "soci/soci-types.h"
#include "soci/type-conversion-traits.h"
#include <cstdint>
namespace soci
{
// Completion of dt_[u]int* bindings for all architectures.
// This allows us to extract values on types where the type definition is
// specific to the underlying architecture. E.g. Unix defines a int64_t as
// long. This would make it impossible to extract a dt_int64 value as both
// long and long long. With the following type_conversion specializations,
// this becomes possible.
#if defined(SOCI_INT64_IS_LONG)
template <>
struct type_conversion<long long>
{
typedef int64_t base_type;
static void from_base(base_type const & in, indicator ind, long long & out)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type.");
}
out = static_cast<long long>(in);
}
static void to_base(long long const & in, base_type & out, indicator & ind)
{
out = static_cast<base_type>(in);
ind = i_ok;
}
};
template <>
struct type_conversion<unsigned long long>
{
typedef uint64_t base_type;
static void from_base(base_type const & in, indicator ind, unsigned long long & out)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type.");
}
out = static_cast<unsigned long long>(in);
}
static void to_base(unsigned long long const & in, base_type & out, indicator & ind)
{
out = static_cast<base_type>(in);
ind = i_ok;
}
};
#elif defined(SOCI_LONG_IS_64_BIT)
template <>
struct type_conversion<long>
{
typedef int64_t base_type;
static void from_base(base_type const & in, indicator ind, long & out)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type.");
}
out = static_cast<long>(in);
}
static void to_base(long const & in, base_type & out, indicator & ind)
{
out = static_cast<base_type>(in);
ind = i_ok;
}
};
template <>
struct type_conversion<unsigned long>
{
typedef uint64_t base_type;
static void from_base(base_type const & in, indicator ind, unsigned long & out)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type.");
}
out = static_cast<unsigned long>(in);
}
static void to_base(unsigned long const & in, base_type & out, indicator & ind)
{
out = static_cast<base_type>(in);
ind = i_ok;
}
};
#else
template <>
struct type_conversion<long>
{
typedef int32_t base_type;
static void from_base(base_type const & in, indicator ind, long & out)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type.");
}
out = static_cast<long>(in);
}
static void to_base(long const & in, base_type & out, indicator & ind)
{
out = static_cast<base_type>(in);
ind = i_ok;
}
};
template <>
struct type_conversion<unsigned long>
{
typedef uint32_t base_type;
static void from_base(base_type const & in, indicator ind, unsigned long & out)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type.");
}
out = static_cast<unsigned long>(in);
}
static void to_base(unsigned long const & in, base_type & out, indicator & ind)
{
out = static_cast<base_type>(in);
ind = i_ok;
}
};
#endif
} // namespace soci
#endif // SOCI_FIXED_SIZE_INTS_H_INCLUDED

View File

@@ -1,213 +0,0 @@
//
// Copyright (C) 2004-2016 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_INTO_TYPE_H_INCLUDED
#define SOCI_INTO_TYPE_H_INCLUDED
#include "soci/soci-backend.h"
#include "soci/type-ptr.h"
#include "soci/exchange-traits.h"
// std
#include <cstddef>
#include <vector>
namespace soci
{
class session;
namespace details
{
class prepare_temp_type;
class standard_into_type_backend;
class vector_into_type_backend;
class statement_impl;
// this is intended to be a base class for all classes that deal with
// defining output data
class into_type_base
{
public:
virtual ~into_type_base() {}
virtual void define(statement_impl & st, int & position) = 0;
virtual void pre_exec(int num) = 0;
virtual void pre_fetch() = 0;
virtual void post_fetch(bool gotData, bool calledFromFetch) = 0;
virtual void clean_up() = 0;
virtual std::size_t size() const = 0; // returns the number of elements
virtual void resize(std::size_t /* sz */) {} // used for vectors only
};
typedef type_ptr<into_type_base> into_type_ptr;
// standard types
class SOCI_DECL standard_into_type : public into_type_base
{
public:
standard_into_type(void * data, exchange_type type)
: data_(data), type_(type), ind_(NULL), backEnd_(NULL) {}
standard_into_type(void * data, exchange_type type, indicator & ind)
: data_(data), type_(type), ind_(&ind), backEnd_(NULL)
{
// Backends won't initialize the indicator if no data is retrieved, so
// do it here, like this we can be sure it has a defined value even if
// an exception is thrown before anything else happens.
*ind_ = i_null;
}
~standard_into_type() override;
protected:
void post_fetch(bool gotData, bool calledFromFetch) override;
private:
void define(statement_impl & st, int & position) override;
void pre_exec(int num) override;
void pre_fetch() override;
void clean_up() override;
std::size_t size() const override { return 1; }
// conversion hook (from base type to arbitrary user type)
virtual void convert_from_base() {}
void * data_;
exchange_type type_;
indicator * ind_;
standard_into_type_backend * backEnd_;
};
// into type base class for vectors
class SOCI_DECL vector_into_type : public into_type_base
{
public:
vector_into_type(void * data, exchange_type type)
: data_(data), type_(type), indVec_(NULL),
begin_(0), end_(NULL), backEnd_(NULL) {}
vector_into_type(void * data, exchange_type type,
std::size_t begin, std::size_t * end)
: data_(data), type_(type), indVec_(NULL),
begin_(begin), end_(end), backEnd_(NULL) {}
vector_into_type(void * data, exchange_type type,
std::vector<indicator> & ind)
: data_(data), type_(type), indVec_(&ind),
begin_(0), end_(NULL), backEnd_(NULL) {}
vector_into_type(void * data, exchange_type type,
std::vector<indicator> & ind,
std::size_t begin, std::size_t * end)
: data_(data), type_(type), indVec_(&ind),
begin_(begin), end_(end), backEnd_(NULL) {}
~vector_into_type() override;
protected:
void post_fetch(bool gotData, bool calledFromFetch) override;
void define(statement_impl & st, int & position) override;
void pre_exec(int num) override;
void pre_fetch() override;
void clean_up() override;
void resize(std::size_t sz) override;
std::size_t size() const override;
void * data_;
exchange_type type_;
std::vector<indicator> * indVec_;
std::size_t begin_;
std::size_t * end_;
vector_into_type_backend * backEnd_;
virtual void convert_from_base() {}
};
// implementation for the basic types (those which are supported by the library
// out of the box without user-provided conversions)
template <typename T>
class into_type : public standard_into_type
{
public:
into_type(T & t)
: standard_into_type(&t,
static_cast<exchange_type>(exchange_traits<T>::x_type)) {}
into_type(T & t, indicator & ind)
: standard_into_type(&t,
static_cast<exchange_type>(exchange_traits<T>::x_type), ind) {}
};
template <typename T>
class into_type<std::vector<T> > : public vector_into_type
{
public:
into_type(std::vector<T> & v)
: vector_into_type(&v,
static_cast<exchange_type>(exchange_traits<T>::x_type)) {}
into_type(std::vector<T> & v, std::size_t begin, std::size_t * end)
: vector_into_type(&v,
static_cast<exchange_type>(exchange_traits<T>::x_type),
begin, end) {}
into_type(std::vector<T> & v, std::vector<indicator> & ind)
: vector_into_type(&v,
static_cast<exchange_type>(exchange_traits<T>::x_type), ind) {}
into_type(std::vector<T> & v, std::vector<indicator> & ind,
std::size_t begin, std::size_t * end)
: vector_into_type(&v,
static_cast<exchange_type>(exchange_traits<T>::x_type), ind,
begin, end) {}
};
// helper dispatchers for basic types
template <typename T>
into_type_ptr do_into(T & t, basic_type_tag)
{
return into_type_ptr(new into_type<T>(t));
}
template <typename T>
into_type_ptr do_into(T & t, indicator & ind, basic_type_tag)
{
return into_type_ptr(new into_type<T>(t, ind));
}
template <typename T>
into_type_ptr do_into(T & t, std::vector<indicator> & ind, basic_type_tag)
{
return into_type_ptr(new into_type<T>(t, ind));
}
template <typename T>
into_type_ptr do_into(std::vector<T> & t,
std::size_t begin, std::size_t * end, basic_type_tag)
{
return into_type_ptr(new into_type<std::vector<T> >(t, begin, end));
}
template <typename T>
into_type_ptr do_into(std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, std::size_t * end, basic_type_tag)
{
return into_type_ptr(new into_type<std::vector<T> >(t, ind, begin, end));
}
} // namespace details
} // namespace soci
#endif // SOCI_INTO_TYPE_H_INCLUDED

View File

@@ -1,97 +0,0 @@
//
// Copyright (C) 2004-2016 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_INTO_H_INCLUDED
#define SOCI_INTO_H_INCLUDED
#include "soci/into-type.h"
#include "soci/exchange-traits.h"
#include "soci/type-conversion.h"
// std
#include <cstddef>
#include <vector>
namespace soci
{
// the into function is a helper for defining output variables
// these helpers work with both basic and user-defined types thanks to
// the tag-dispatching, as defined in exchange_traits template
namespace details
{
template <typename T, typename Indicator>
struct into_container
{
into_container(T &_t, Indicator &_ind)
: t(_t), ind(_ind) {}
T &t;
Indicator &ind;
private:
SOCI_NOT_ASSIGNABLE(into_container)
};
typedef void no_indicator;
template <typename T>
struct into_container<T, no_indicator>
{
into_container(T &_t)
: t(_t) {}
T &t;
private:
SOCI_NOT_ASSIGNABLE(into_container)
};
} // namespace details
template <typename T>
details::into_container<T, details::no_indicator>
into(T &t)
{ return details::into_container<T, details::no_indicator>(t); }
template <typename T, typename Indicator>
details::into_container<T, Indicator>
into(T &t, Indicator &ind)
{ return details::into_container<T, Indicator>(t, ind); }
// for char buffer with run-time size information
template <typename T>
details::into_type_ptr into(T & t, std::size_t bufSize)
{
return details::into_type_ptr(new details::into_type<T>(t, bufSize));
}
// vectors with index ranges
template <typename T>
details::into_type_ptr into(std::vector<T> & t,
std::size_t begin, std::size_t & end)
{
return details::do_into(t, begin, &end,
typename details::exchange_traits<std::vector<T> >::type_family());
}
template <typename T>
details::into_type_ptr into(std::vector<T> & t, std::vector<indicator> & ind)
{
return details::do_into(t, ind,
typename details::exchange_traits<std::vector<T> >::type_family());
}
template <typename T>
details::into_type_ptr into(std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, std::size_t & end)
{
return details::do_into(t, ind, begin, &end,
typename details::exchange_traits<std::vector<T> >::type_family());
}
} // namespace soci
#endif // SOCI_INTO_H_INCLUDED

View File

@@ -1,49 +0,0 @@
//
// Copyright (C) 2023 Robert Adam
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_IS_DETECTED_H_INCLUDED
#define SOCI_IS_DETECTED_H_INCLUDED
#include <type_traits>
namespace soci
{
namespace details
{
template<typename...>
using void_t = void;
using false_type = std::integral_constant<bool, false>;
using true_type = std::integral_constant<bool, true>;
// Implementation from https://blog.tartanllama.xyz/detection-idiom/
// Note, this is a stub that we require until standard C++ gets support
// for the detection idiom that is not experimental (and thus can be
// assumed to be present).
namespace detector_detail
{
template <template <class...> class Trait, class Enabler, class... Args>
struct is_detected : false_type {};
template <template <class...> class Trait, class... Args>
struct is_detected<Trait, void_t<Trait<Args...>>, Args...> : true_type {};
}
template <template <class...> class Trait, class... Args>
using is_detected = typename detector_detail::is_detected<Trait, void, Args...>::type;
}
}
#endif // SOCI_IS_DETECTED_H_INCLUDED

View File

@@ -1,82 +0,0 @@
//
// Copyright (C) 2014 Vadim Zeitlin
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_LOGGER_H_INCLUDED
#define SOCI_LOGGER_H_INCLUDED
#include "soci/soci-platform.h"
#include <ostream>
namespace soci
{
// Allows to customize the logging of database operations performed by SOCI.
//
// To do it, derive your own class from logger_impl and override its pure
// virtual start_query() and do_clone() methods (overriding the other methods
// is optional), then call session::set_logger() with a logger object using
// your implementation.
class SOCI_DECL logger_impl
{
public:
logger_impl() {}
virtual ~logger_impl();
// Called to indicate that a new query is about to be executed.
virtual void start_query(std::string const & query) = 0;
logger_impl * clone() const;
// These methods are for compatibility only as they're used to implement
// session basic logging support, you should only override them if you want
// to use session::set_stream() and similar methods with your custom logger.
virtual void set_stream(std::ostream * s);
virtual std::ostream * get_stream() const;
virtual std::string get_last_query() const;
private:
// Override to return a new heap-allocated copy of this object.
virtual logger_impl * do_clone() const = 0;
// Non-copyable
logger_impl(logger_impl const &);
logger_impl & operator=(logger_impl const &);
};
// A wrapper class representing a logger.
//
// Unlike logger_impl, this class has value semantics and can be manipulated
// easily without any danger of memory leaks or dereferencing a NULL pointer.
class SOCI_DECL logger
{
public:
// No default constructor, must always have an associated logger_impl.
// Create a logger using the provided non-NULL implementation (an exception
// is thrown if the pointer is NULL). The logger object takes ownership of
// the pointer and will delete it.
logger(logger_impl * impl);
logger(logger const & other);
logger& operator=(logger const & other);
~logger();
void start_query(std::string const & query) { m_impl->start_query(query); }
// Methods used for the implementation of session basic logging support.
void set_stream(std::ostream * s) { m_impl->set_stream(s); }
std::ostream * get_stream() const { return m_impl->get_stream(); }
std::string get_last_query() const { return m_impl->get_last_query(); }
private:
logger_impl * m_impl;
};
} // namespace soci
#endif // SOCI_LOGGER_H_INCLUDED

View File

@@ -1,314 +0,0 @@
//
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton
// MySQL backend copyright (C) 2006 Pawel Aleksander Fedorynski
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_MYSQL_H_INCLUDED
#define SOCI_MYSQL_H_INCLUDED
#include <soci/soci-platform.h>
#ifdef SOCI_MYSQL_SOURCE
# define SOCI_MYSQL_DECL SOCI_DECL_EXPORT
#else
# define SOCI_MYSQL_DECL SOCI_DECL_IMPORT
#endif
#include <soci/soci-backend.h>
#include <private/soci-trivial-blob-backend.h>
#ifdef _WIN32
#include <winsock.h> // SOCKET
#endif // _WIN32
// Some version of mysql.h contain trailing comma in an enum declaration that
// trigger -Wpedantic, so suppress it as there is nothing to be done about it
// using the macros defined in our private soci-compiler.h header, that we can
// only include when building SOCI itself.
#ifdef SOCI_MYSQL_SOURCE
#include "soci-compiler.h"
#endif
#ifdef SOCI_GCC_WARNING_SUPPRESS
SOCI_GCC_WARNING_SUPPRESS(pedantic)
#endif
#include <mysql.h> // MySQL Client
#include <errmsg.h> // MySQL Error codes
#ifdef SOCI_GCC_WARNING_RESTORE
SOCI_GCC_WARNING_RESTORE(pedantic)
#endif
#include <vector>
namespace soci
{
class SOCI_MYSQL_DECL mysql_soci_error : public soci_error
{
public:
mysql_soci_error(std::string const & msg, int errNum)
: soci_error(msg), err_num_(errNum), cat_(unknown) {
if(errNum == CR_CONNECTION_ERROR ||
errNum == CR_CONN_HOST_ERROR ||
errNum == CR_SERVER_GONE_ERROR ||
errNum == CR_SERVER_LOST ||
errNum == 1927) { // Lost connection to backend server
cat_ = connection_error;
}
}
error_category get_error_category() const override { return cat_; }
unsigned int err_num_;
error_category cat_;
};
struct mysql_statement_backend;
struct mysql_standard_into_type_backend : details::standard_into_type_backend
{
mysql_standard_into_type_backend(mysql_statement_backend &st)
: statement_(st) {}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch,
indicator *ind) override;
void clean_up() override;
mysql_statement_backend &statement_;
void *data_;
details::exchange_type type_;
int position_;
};
struct mysql_vector_into_type_backend : details::vector_into_type_backend
{
mysql_vector_into_type_backend(mysql_statement_backend &st)
: statement_(st) {}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator *ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
void clean_up() override;
mysql_statement_backend &statement_;
void *data_;
details::exchange_type type_;
int position_;
};
struct mysql_standard_use_type_backend : details::standard_use_type_backend
{
mysql_standard_use_type_backend(mysql_statement_backend &st)
: statement_(st), position_(0), buf_(NULL) {}
void bind_by_pos(int &position,
void *data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const *ind) override;
void post_use(bool gotData, indicator *ind) override;
void clean_up() override;
mysql_statement_backend &statement_;
void *data_;
details::exchange_type type_;
int position_;
std::string name_;
char *buf_;
};
struct mysql_vector_use_type_backend : details::vector_use_type_backend
{
mysql_vector_use_type_backend(mysql_statement_backend &st)
: statement_(st), position_(0) {}
void bind_by_pos(int &position,
void *data, details::exchange_type type) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type) override;
void pre_use(indicator const *ind) override;
std::size_t size() override;
void clean_up() override;
mysql_statement_backend &statement_;
void *data_;
details::exchange_type type_;
int position_;
std::string name_;
std::vector<char *> buffers_;
};
struct mysql_session_backend;
struct mysql_statement_backend : details::statement_backend
{
mysql_statement_backend(mysql_session_backend &session);
void alloc() override;
void clean_up() override;
void prepare(std::string const &query,
details::statement_type eType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const &query) override;
int prepare_for_describe() override;
void describe_column(int colNum,
db_type &dbtype,
std::string &columnName) override;
data_type to_data_type(db_type dbt) const override;
mysql_standard_into_type_backend * make_into_type_backend() override;
mysql_standard_use_type_backend * make_use_type_backend() override;
mysql_vector_into_type_backend * make_vector_into_type_backend() override;
mysql_vector_use_type_backend * make_vector_use_type_backend() override;
mysql_session_backend &session_;
MYSQL_RES *result_;
// The query is split into chunks, separated by the named parameters;
// e.g. for "SELECT id FROM ttt WHERE name = :foo AND gender = :bar"
// we will have query chunks "SELECT id FROM ttt WHERE name = ",
// "AND gender = " and names "foo", "bar".
std::vector<std::string> queryChunks_;
std::vector<std::string> names_; // list of names for named binds
long long rowsAffectedBulk_; // number of rows affected by the last bulk operation
int numberOfRows_; // number of rows retrieved from the server
int currentRow_; // "current" row number to consume in postFetch
int rowsToConsume_; // number of rows to be consumed in postFetch
bool justDescribed_; // to optimize row description with immediately
// following actual statement execution
// Set to true if the last column passed to describe_column() was a
// MEDIUMINT UNSIGNED one, see to_data_type().
bool lastDescribedUnsignedMediumInt_ = false;
// Prefetch the row offsets in order to use mysql_row_seek() for
// random access to rows, since mysql_data_seek() is expensive.
std::vector<MYSQL_ROW_OFFSET> resultRowOffsets_;
bool hasIntoElements_;
bool hasVectorIntoElements_;
bool hasUseElements_;
bool hasVectorUseElements_;
// the following maps are used for finding data buffers according to
// use elements specified by the user
typedef std::map<int, char **> UseByPosBuffersMap;
UseByPosBuffersMap useByPosBuffers_;
typedef std::map<std::string, char **> UseByNameBuffersMap;
UseByNameBuffersMap useByNameBuffers_;
};
struct mysql_rowid_backend : details::rowid_backend
{
mysql_rowid_backend(mysql_session_backend &session);
~mysql_rowid_backend() override;
};
class mysql_blob_backend : public details::trivial_blob_backend
{
public:
mysql_blob_backend(mysql_session_backend &session);
~mysql_blob_backend() override;
std::size_t hex_str_size() const;
void write_hex_str(char *buf, std::size_t size) const;
std::string as_hex_str() const;
void load_from_hex_str(const char* str, std::size_t length);
};
struct mysql_session_backend : details::session_backend
{
mysql_session_backend(connection_parameters const & parameters);
~mysql_session_backend() override;
bool is_connected() override;
void begin() override;
void commit() override;
void rollback() override;
bool get_last_insert_id(session&, std::string const&, long long&) override;
// Note that MySQL supports both "SELECT 2+2" and "SELECT 2+2 FROM DUAL"
// syntaxes, but there doesn't seem to be any reason to use the longer one.
std::string get_dummy_from_table() const override { return std::string(); }
std::string get_backend_name() const override { return "mysql"; }
void clean_up();
mysql_statement_backend * make_statement_backend() override;
mysql_rowid_backend * make_rowid_backend() override;
mysql_blob_backend * make_blob_backend() override;
std::string get_table_names_query() const override
{
return "SELECT table_name AS 'TABLE_NAME' FROM information_schema.tables WHERE table_schema = DATABASE()";
}
MYSQL *conn_;
};
struct mysql_backend_factory : backend_factory
{
mysql_backend_factory() {}
mysql_session_backend * make_session(
connection_parameters const & parameters) const override;
};
extern SOCI_MYSQL_DECL mysql_backend_factory const mysql;
extern "C"
{
// for dynamic backend loading
SOCI_MYSQL_DECL backend_factory const * factory_mysql();
SOCI_MYSQL_DECL void register_factory_mysql();
} // extern "C"
} // namespace soci
#endif // SOCI_MYSQL_H_INCLUDED

View File

@@ -1,22 +0,0 @@
//
// Copyright (C) 2015 Vadim Zeitlin
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_NORETURN_H_INCLUDED
#define SOCI_NORETURN_H_INCLUDED
// Define a portable SOCI_NORETURN macro.
//
// TODO-C++11: Use [[noreturn]] attribute.
#if defined(__GNUC__)
# define SOCI_NORETURN __attribute__((noreturn)) void
#elif defined(_MSC_VER)
# define SOCI_NORETURN __declspec(noreturn) void
#else
# define SOCI_NORETURN void
#endif
#endif // SOCI_NORETURN_H_INCLUDED

View File

@@ -1,624 +0,0 @@
//
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_ODBC_H_INCLUDED
#define SOCI_ODBC_H_INCLUDED
#include <soci/soci-platform.h>
#ifdef SOCI_ODBC_SOURCE
# define SOCI_ODBC_DECL SOCI_DECL_EXPORT
#else
# define SOCI_ODBC_DECL SOCI_DECL_IMPORT
#endif
#include <vector>
#include <soci/soci-backend.h>
#include <sstream>
#if defined(_MSC_VER) || defined(__MINGW32__)
#include <windows.h>
#endif
#include <sqlext.h> // ODBC
#include <string.h> // strcpy()
namespace soci
{
namespace details
{
// TODO: Do we want to make it a part of public interface? --mloskot
std::size_t const odbc_max_buffer_length = 100 * 1024 * 1024;
// select max size from following MSDN article
// https://msdn.microsoft.com/en-us/library/ms130896.aspx
SQLLEN const ODBC_MAX_COL_SIZE = 8000;
// This cast is only used to avoid compiler warnings when passing strings
// to ODBC functions, the returned string may *not* be really modified.
inline SQLCHAR* sqlchar_cast(std::string const& s)
{
return reinterpret_cast<SQLCHAR*>(const_cast<char*>(s.c_str()));
}
}
// Option allowing to specify the "driver completion" parameter of
// SQLDriverConnect(). Its possible values are the same as the allowed values
// for this parameter in the official ODBC, i.e. one of SQL_DRIVER_XXX (in
// string form as all options are strings currently).
extern SOCI_ODBC_DECL char const * odbc_option_driver_complete;
struct odbc_statement_backend;
// Helper of into and use backends.
class odbc_standard_type_backend_base
{
protected:
odbc_standard_type_backend_base(odbc_statement_backend &st)
: statement_(st) {}
// Check if we need to pass 64 bit integers as strings to the database as
// some drivers don't support them directly.
inline bool use_string_for_bigint() const;
// If we do need to use strings for 64 bit integers, this constant defines
// the maximal string length needed.
enum
{
// This is the length of decimal representation of UINT64_MAX + 1.
max_bigint_length = 21
};
// IBM DB2 driver is not compliant to ODBC spec for indicators in 64bit
// SQLLEN is still defined 32bit (int) but spec requires 64bit (long)
inline bool requires_noncompliant_32bit_sqllen() const;
inline SQLLEN get_sqllen_from_value(const SQLLEN val) const;
inline void set_sqllen_from_value(SQLLEN &target, const SQLLEN val) const;
inline bool supports_negative_tinyint() const;
inline bool can_convert_to_unsigned_sql_type() const;
odbc_statement_backend &statement_;
private:
SOCI_NOT_COPYABLE(odbc_standard_type_backend_base)
};
struct odbc_standard_into_type_backend : details::standard_into_type_backend,
private odbc_standard_type_backend_base
{
odbc_standard_into_type_backend(odbc_statement_backend &st)
: odbc_standard_type_backend_base(st), buf_(0)
{}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch,
indicator *ind) override;
void clean_up() override;
char *buf_; // generic buffer
void *data_;
details::exchange_type type_;
int position_;
SQLSMALLINT odbcType_;
SQLLEN valueLen_;
private:
SOCI_NOT_COPYABLE(odbc_standard_into_type_backend)
};
struct odbc_vector_into_type_backend : details::vector_into_type_backend,
private odbc_standard_type_backend_base
{
odbc_vector_into_type_backend(odbc_statement_backend &st)
: odbc_standard_type_backend_base(st),
data_(NULL), buf_(NULL), position_(0) {}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator *ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
void clean_up() override;
// Normally data retrieved from the database is handled in post_fetch(),
// however we may need to call SQLFetch() multiple times, so we call this
// function instead after each call to it to retrieve the given range of
// rows.
void do_post_fetch_rows(std::size_t beginRow, std::size_t endRow);
// IBM DB2 driver is not compliant to ODBC spec for indicators in 64bit
// SQLLEN is still defined 32bit (int) but spec requires 64bit (long)
inline SQLLEN get_sqllen_from_vector_at(std::size_t idx) const;
// Rebind the single vector value at the given index to the first row.
// Used when vector values are fetched by single row.
void rebind_row(std::size_t rowInd);
std::vector<SQLLEN> indHolderVec_;
void *data_;
char *buf_; // generic buffer
details::exchange_type type_;
std::size_t colSize_; // size of the string column (used for strings)
SQLSMALLINT odbcType_;
int position_;
};
struct odbc_standard_use_type_backend : details::standard_use_type_backend,
private odbc_standard_type_backend_base
{
odbc_standard_use_type_backend(odbc_statement_backend &st)
: odbc_standard_type_backend_base(st),
position_(-1), data_(0), buf_(0), indHolder_(0) {}
void bind_by_pos(int &position,
void *data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const *ind) override;
void post_use(bool gotData, indicator *ind) override;
void clean_up() override;
// Return the pointer to the buffer containing data to be used by ODBC.
// This can be either data_ itself or buf_, that is allocated by this
// function if necessary.
//
// Also fill in the size of the data and SQL and C types of it.
void* prepare_for_bind(SQLLEN &size,
SQLSMALLINT &sqlType, SQLSMALLINT &cType);
int position_;
void *data_;
details::exchange_type type_;
char *buf_;
SQLLEN indHolder_;
private:
// Copy string data to buf_ and set size, sqlType and cType to the values
// appropriate for strings.
void copy_from_string(std::string const& s,
SQLLEN& size,
SQLSMALLINT& sqlType,
SQLSMALLINT& cType);
};
struct odbc_vector_use_type_backend : details::vector_use_type_backend,
private odbc_standard_type_backend_base
{
odbc_vector_use_type_backend(odbc_statement_backend &st)
: odbc_standard_type_backend_base(st),
data_(NULL), buf_(NULL) {}
// helper function for preparing indicators
// (as part of the define_by_pos)
void prepare_indicators(std::size_t size);
// helper of pre_use(), return the pointer to the data to be used by ODBC.
void* prepare_for_bind(SQLUINTEGER &size, SQLSMALLINT &sqlType, SQLSMALLINT &cType);
void bind_by_pos(int &position,
void *data, details::exchange_type type) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type) override;
void pre_use(indicator const *ind) override;
std::size_t size() override;
void clean_up() override;
// IBM DB2 driver is not compliant to ODBC spec for indicators in 64bit
// SQLLEN is still defined 32bit (int) but spec requires 64bit (long)
inline void set_sqllen_from_vector_at(const std::size_t idx, const SQLLEN val);
std::vector<SQLLEN> indHolderVec_;
void *data_;
details::exchange_type type_;
int position_;
char *buf_; // generic buffer
std::size_t colSize_; // size of the string column (used for strings)
// used for strings only
std::size_t maxSize_;
};
struct odbc_session_backend;
struct odbc_statement_backend : details::statement_backend
{
odbc_statement_backend(odbc_session_backend &session);
void alloc() override;
void clean_up() override;
void prepare(std::string const &query,
details::statement_type eType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const &query) override;
int prepare_for_describe() override;
void describe_column(int colNum,
db_type &dbtype,
std::string &columnName) override;
data_type to_data_type(db_type dbt) const override;
// helper for defining into vector<string>
std::size_t column_size(int position);
odbc_standard_into_type_backend * make_into_type_backend() override;
odbc_standard_use_type_backend * make_use_type_backend() override;
odbc_vector_into_type_backend * make_vector_into_type_backend() override;
odbc_vector_use_type_backend * make_vector_use_type_backend() override;
odbc_session_backend &session_;
SQLHSTMT hstmt_;
SQLULEN numRowsFetched_;
bool fetchVectorByRows_;
bool hasVectorUseElements_;
bool boundByName_;
bool boundByPos_;
long long rowsAffected_; // number of rows affected by the last operation
std::string query_;
std::vector<std::string> names_; // list of names for named binds
// This vector, containing non-owning non-null pointers, can be empty if
// we're not using any vector "intos".
std::vector<odbc_vector_into_type_backend*> intos_;
private:
// fetch() helper wrapping SQLFetch() call for the given range of rows.
exec_fetch_result do_fetch(int beginRow, int endRow);
};
struct odbc_rowid_backend : details::rowid_backend
{
odbc_rowid_backend(odbc_session_backend &session);
~odbc_rowid_backend() override;
};
struct odbc_blob_backend : details::blob_backend
{
odbc_blob_backend(odbc_session_backend &session);
~odbc_blob_backend() override;
std::size_t get_len() override;
std::size_t read_from_start(void *buf, std::size_t toRead, std::size_t offset = 0) override;
std::size_t write_from_start(const void *buf, std::size_t toWrite, std::size_t offset = 0) override;
std::size_t append(const void *buf, std::size_t toWrite) override;
void trim(std::size_t newLen) override;
odbc_session_backend &session_;
};
struct odbc_session_backend : details::session_backend
{
odbc_session_backend(connection_parameters const & parameters);
~odbc_session_backend() override;
bool is_connected() override;
void begin() override;
void commit() override;
void rollback() override;
bool get_next_sequence_value(session & s,
std::string const & sequence, long long & value) override;
bool get_last_insert_id(session & s,
std::string const & table, long long & value) override;
std::string get_dummy_from_table() const override;
std::string get_backend_name() const override { return "odbc"; }
void configure_connection();
void reset_transaction();
void clean_up();
odbc_statement_backend * make_statement_backend() override;
odbc_rowid_backend * make_rowid_backend() override;
odbc_blob_backend * make_blob_backend() override;
enum database_product
{
prod_uninitialized, // Never returned by get_database_product().
prod_db2,
prod_firebird,
prod_mssql,
prod_mysql,
prod_oracle,
prod_postgresql,
prod_sqlite,
prod_unknown = -1
};
// Determine the type of the database we're connected to.
SOCI_ODBC_DECL database_product get_database_product() const;
// Return full ODBC connection string.
std::string get_connection_string() const { return connection_string_; }
SQLHENV henv_;
SQLHDBC hdbc_;
std::string connection_string_;
private:
mutable database_product product_;
};
class SOCI_ODBC_DECL odbc_soci_error : public soci_error
{
SQLCHAR message_[SQL_MAX_MESSAGE_LENGTH + 1];
SQLCHAR sqlstate_[SQL_SQLSTATE_SIZE + 1];
SQLINTEGER sqlcode_;
public:
odbc_soci_error(SQLSMALLINT htype,
SQLHANDLE hndl,
std::string const & msg)
: soci_error(interpret_odbc_error(htype, hndl, msg))
{
}
error_category get_error_category() const override
{
const char* const s = reinterpret_cast<const char*>(sqlstate_);
if ((s[0] == '0' && s[1] == '8') ||
strcmp(s, "HYT01") == 0)
return connection_error;
if (strcmp(s, "23000") == 0 ||
strcmp(s, "40002") == 0 ||
strcmp(s, "44000") == 0)
return constraint_violation;
if (strcmp(s, "HY014") == 0)
return system_error;
return unknown;
}
SQLCHAR const * odbc_error_code() const
{
return sqlstate_;
}
SQLINTEGER native_error_code() const
{
return sqlcode_;
}
SQLCHAR const * odbc_error_message() const
{
return message_;
}
private:
std::string interpret_odbc_error(SQLSMALLINT htype, SQLHANDLE hndl, std::string const& msg)
{
const char* socierror = NULL;
SQLSMALLINT length, i = 1;
switch ( SQLGetDiagRecA(htype, hndl, i, sqlstate_, &sqlcode_,
message_, SQL_MAX_MESSAGE_LENGTH + 1,
&length) )
{
case SQL_SUCCESS:
// The error message was successfully retrieved.
break;
case SQL_INVALID_HANDLE:
socierror = "[SOCI]: Invalid handle.";
break;
case SQL_ERROR:
socierror = "[SOCI]: SQLGetDiagRec() error.";
break;
case SQL_SUCCESS_WITH_INFO:
socierror = "[SOCI]: Error message too long.";
break;
case SQL_NO_DATA:
socierror = "[SOCI]: No error.";
break;
default:
socierror = "[SOCI]: Unexpected SQLGetDiagRec() return value.";
break;
}
if (socierror)
{
// Use our own error message if we failed to retrieve the ODBC one.
strcpy(reinterpret_cast<char*>(message_), socierror);
// Use "General warning" SQLSTATE code.
strcpy(reinterpret_cast<char*>(sqlstate_), "01000");
sqlcode_ = 0;
}
std::ostringstream ss;
ss << "Error " << msg << ": " << message_ << " (SQL state " << sqlstate_ << ")";
return ss.str();
}
};
inline bool is_odbc_error(SQLRETURN rc)
{
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO && rc != SQL_NO_DATA)
{
return true;
}
else
{
return false;
}
}
inline bool odbc_standard_type_backend_base::use_string_for_bigint() const
{
// Oracle ODBC driver doesn't support SQL_C_[SU]BIGINT data types
// (see appendix G.1 of Oracle Database Administrator's reference at
// http://docs.oracle.com/cd/B19306_01/server.102/b15658/app_odbc.htm),
// so we need a special workaround for this case and we represent 64
// bit integers as strings and rely on ODBC driver for transforming
// them to SQL_NUMERIC.
return statement_.session_.get_database_product()
== odbc_session_backend::prod_oracle;
}
inline bool odbc_standard_type_backend_base::requires_noncompliant_32bit_sqllen() const
{
// IBM DB2 did not implement the ODBC specification for indicator sizes in 64bit.
// They still use SQLLEN as 32bit even if the driver is compiled 64bit
// This breaks the backend in terms of using indicators
// see: https://bugs.php.net/bug.php?id=54007
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
return statement_.session_.get_database_product()
== odbc_session_backend::prod_db2;
#else
return false;
#endif
}
inline SQLLEN odbc_standard_type_backend_base::get_sqllen_from_value(const SQLLEN val) const
{
if (requires_noncompliant_32bit_sqllen())
{
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#elif defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wstrict-aliasing"
#endif
return *reinterpret_cast<const int*>(&val);
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#elif defined(__clang__)
#pragma clang diagnostic pop
#endif
}
return val;
}
inline void odbc_standard_type_backend_base::set_sqllen_from_value(SQLLEN &target, const SQLLEN val) const
{
if (requires_noncompliant_32bit_sqllen())
{
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#elif defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wstrict-aliasing"
#endif
reinterpret_cast<int*>(&target)[0] = *reinterpret_cast<const int*>(&val);
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#elif defined(__clang__)
#pragma clang diagnostic pop
#endif
}
else
{
target = val;
}
}
inline bool odbc_standard_type_backend_base::supports_negative_tinyint() const
{
// MSSQL ODBC driver only supports a range of [0..255] for tinyint.
return statement_.session_.get_database_product()
!= odbc_session_backend::prod_mssql;
}
inline bool odbc_standard_type_backend_base::can_convert_to_unsigned_sql_type() const
{
// MSSQL ODBC driver seemingly can't handle the conversion of unsigned C
// types to their respective unsigned SQL type because they are out of
// range for their supported signed types. This results in the error
// "Numeric value out of range (SQL state 22003)".
// The only place it works is with tinyint values as their range is
// [0..255], i.e. they have enough space for unsigned values anyway.
return statement_.session_.get_database_product()
!= odbc_session_backend::prod_mssql;
}
inline SQLLEN odbc_vector_into_type_backend::get_sqllen_from_vector_at(std::size_t idx) const
{
if (requires_noncompliant_32bit_sqllen())
{
return reinterpret_cast<const int*>(&indHolderVec_[0])[idx];
}
return indHolderVec_[idx];
}
inline void odbc_vector_use_type_backend::set_sqllen_from_vector_at(const std::size_t idx, const SQLLEN val)
{
if (requires_noncompliant_32bit_sqllen())
{
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#elif defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wstrict-aliasing"
#endif
reinterpret_cast<int*>(&indHolderVec_[0])[idx] = *reinterpret_cast<const int*>(&val);
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#elif defined(__clang__)
#pragma clang diagnostic pop
#endif
}
else
{
indHolderVec_[idx] = val;
}
}
struct odbc_backend_factory : backend_factory
{
odbc_backend_factory() {}
odbc_session_backend * make_session(
connection_parameters const & parameters) const override;
};
extern SOCI_ODBC_DECL odbc_backend_factory const odbc;
extern "C"
{
// for dynamic backend loading
SOCI_ODBC_DECL backend_factory const * factory_odbc();
SOCI_ODBC_DECL void register_factory_odbc();
} // extern "C"
} // namespace soci
#endif // SOCI_EMPTY_H_INCLUDED

View File

@@ -1,183 +0,0 @@
//
// Copyright (C) 2004-2016 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_ONCE_TEMP_TYPE_H_INCLUDED
#define SOCI_ONCE_TEMP_TYPE_H_INCLUDED
#include "soci/soci-platform.h"
#include "soci/ref-counted-statement.h"
#include "soci/prepare-temp-type.h"
namespace soci
{
class session;
namespace details
{
class ref_counted_statement;
// this needs to be lightweight and copyable
class SOCI_DECL once_temp_type
{
public:
once_temp_type(session & s);
once_temp_type(once_temp_type const & o);
once_temp_type & operator=(once_temp_type const & o);
~once_temp_type() noexcept(false);
template <typename T>
once_temp_type & operator<<(T const & t)
{
rcst_->accumulate(t);
return *this;
}
once_temp_type & operator,(into_type_ptr const &);
once_temp_type & operator,(use_type_ptr const &);
template <typename T, typename Indicator>
once_temp_type &operator,(into_container<T, Indicator> const &ic)
{
rcst_->exchange(ic);
return *this;
}
template <typename T, typename Indicator>
once_temp_type &operator,(use_container<T, Indicator> const &uc)
{
rcst_->exchange(uc);
return *this;
}
private:
ref_counted_statement * rcst_;
};
// this needs to be lightweight and copyable
class once_type
{
public:
once_type() : session_(NULL) {}
once_type(session * s) : session_(s) {}
void set_session(session * s)
{
session_ = s;
}
template <typename T>
once_temp_type operator<<(T const & t)
{
once_temp_type o(*session_);
o << t;
return o;
}
private:
session * session_;
};
// this needs to be lightweight and copyable
class prepare_type
{
public:
prepare_type() : session_(NULL) {}
prepare_type(session * s) : session_(s) {}
void set_session(session * s)
{
session_ = s;
}
template <typename T>
prepare_temp_type operator<<(T const & t)
{
prepare_temp_type p(*session_);
p << t;
return p;
}
private:
session * session_;
};
} // namespace details
// Note: ddl_type is intended to be used just as once_temp_type,
// but since it can be also used directly (explicitly) by the user code,
// it is declared outside of the namespace details.
class SOCI_DECL ddl_type
{
public:
ddl_type(session & s);
ddl_type(const ddl_type & d);
ddl_type & operator=(const ddl_type & d);
~ddl_type() noexcept(false);
void create_table(const std::string & tableName);
void add_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision, int scale);
void alter_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision, int scale);
void drop_column(const std::string & tableName,
const std::string & columnName);
ddl_type & column(const std::string & columnName, db_type dt,
int precision = 0, int scale = 0);
ddl_type & unique(const std::string & name,
const std::string & columnNames);
ddl_type & primary_key(const std::string & name,
const std::string & columnNames);
ddl_type & foreign_key(const std::string & name,
const std::string & columnNames,
const std::string & refTableName,
const std::string & refColumnNames);
ddl_type & operator()(const std::string & arbitrarySql);
// helper function for handling delimiters
// between various parts of DDL statements
void set_tail(const std::string & tail);
// The functions below still work but are deprecated (but we don't give
// deprecation warnings for them because there is no real harm in using
// them).
//
// Use the overloads taking db_type instead in the new code.
void add_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision, int scale)
{
add_column(tableName, columnName, details::to_db_type(dt), precision, scale);
}
void alter_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision, int scale)
{
alter_column(tableName, columnName, details::to_db_type(dt), precision, scale);
}
ddl_type & column(const std::string & columnName, data_type dt,
int precision = 0, int scale = 0)
{
return column(columnName, details::to_db_type(dt), precision, scale);
}
private:
session * s_;
details::ref_counted_statement * rcst_;
};
} // namespace soci
#endif

View File

@@ -1,492 +0,0 @@
//
// Copyright (C) 2004-2016 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_ORACLE_H_INCLUDED
#define SOCI_ORACLE_H_INCLUDED
#include <soci/soci-platform.h>
#ifdef SOCI_ORACLE_SOURCE
# define SOCI_ORACLE_DECL SOCI_DECL_EXPORT
#else
# define SOCI_ORACLE_DECL SOCI_DECL_IMPORT
#endif
#include <soci/soci-backend.h>
#include <oci.h> // OCI
#include <sstream>
#include <vector>
#ifdef _MSC_VER
#pragma warning(disable:4512 4511)
#endif
namespace soci
{
class SOCI_ORACLE_DECL oracle_soci_error : public soci_error
{
public:
oracle_soci_error(std::string const & msg, int errNum = 0);
error_category get_error_category() const override { return cat_; }
int err_num_;
error_category cat_;
};
struct oracle_statement_backend;
struct oracle_standard_into_type_backend : details::standard_into_type_backend
{
oracle_standard_into_type_backend(oracle_statement_backend &st)
: statement_(st), defnp_(NULL), indOCIHolder_(0),
data_(NULL), buf_(NULL) {}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_exec(int num) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch,
indicator *ind) override;
void clean_up() override;
oracle_statement_backend &statement_;
OCIDefine *defnp_;
sb2 indOCIHolder_;
void *data_;
void *ociData_;
char *buf_; // generic buffer
details::exchange_type type_;
ub2 rCode_;
};
struct oracle_vector_into_type_backend : details::vector_into_type_backend
{
oracle_vector_into_type_backend(oracle_statement_backend &st)
: statement_(st), defnp_(NULL),
data_(NULL), buf_(NULL), user_ranges_(true) {}
void define_by_pos(int &position,
void *data, details::exchange_type type) override
{
user_ranges_ = false;
define_by_pos_bulk(position, data, type, 0, &end_var_);
}
void define_by_pos_bulk(
int & position, void * data, details::exchange_type type,
std::size_t begin, std::size_t * end) override;
void pre_exec(int num) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator *ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
std::size_t full_size();
void clean_up() override;
// helper function for preparing indicators and sizes_ vectors
// (as part of the define_by_pos)
void prepare_indicators(std::size_t size);
oracle_statement_backend &statement_;
OCIDefine *defnp_;
std::vector<sb2> indOCIHolderVec_;
void *data_;
char *buf_; // generic buffer
details::exchange_type type_;
std::size_t begin_;
std::size_t * end_;
std::size_t end_var_;
bool user_ranges_;
std::size_t colSize_; // size of the string column (used for strings)
std::vector<ub2> sizes_; // sizes of data fetched (used for strings)
std::vector<ub2> rCodes_;
};
struct oracle_standard_use_type_backend : details::standard_use_type_backend
{
oracle_standard_use_type_backend(oracle_statement_backend &st)
: statement_(st), bindp_(NULL), indOCIHolder_(0),
data_(NULL), buf_(NULL) {}
void bind_by_pos(int &position,
void *data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type, bool readOnly) override;
// common part for bind_by_pos and bind_by_name
void prepare_for_bind(void *&data, sb4 &size, ub2 &oracleType, bool readOnly);
void pre_exec(int num) override;
void pre_use(indicator const *ind) override;
void post_use(bool gotData, indicator *ind) override;
void clean_up() override;
oracle_statement_backend &statement_;
OCIBind *bindp_;
sb2 indOCIHolder_;
void *data_;
void *ociData_;
bool readOnly_;
char *buf_; // generic buffer
details::exchange_type type_;
};
struct oracle_vector_use_type_backend : details::vector_use_type_backend
{
oracle_vector_use_type_backend(oracle_statement_backend &st)
: statement_(st), bindp_(NULL),
data_(NULL), buf_(NULL), bind_position_(0) {}
void bind_by_pos(int & position,
void * data, details::exchange_type type) override
{
bind_by_pos_bulk(position, data, type, 0, &end_var_);
}
void bind_by_pos_bulk(int & position,
void * data, details::exchange_type type,
std::size_t begin, std::size_t * end) override;
void bind_by_name(const std::string & name,
void * data, details::exchange_type type) override
{
bind_by_name_bulk(name, data, type, 0, &end_var_);
}
void bind_by_name_bulk(std::string const &name,
void *data, details::exchange_type type,
std::size_t begin, std::size_t * end) override;
// pre_use() helper
void prepare_for_bind(void *&data, sb4 &size, ub2 &oracleType);
// helper function for preparing indicators and sizes_ vectors
// (as part of the bind_by_pos and bind_by_name)
void prepare_indicators(std::size_t size);
void pre_use(indicator const *ind) override;
std::size_t size() override; // active size (might be lower than full vector size)
std::size_t full_size(); // actual size of the user-provided vector
void clean_up() override;
oracle_statement_backend &statement_;
OCIBind *bindp_;
std::vector<sb2> indOCIHolderVec_;
void *data_;
char *buf_; // generic buffer
details::exchange_type type_;
std::size_t begin_;
std::size_t * end_;
std::size_t end_var_;
// used for strings only
std::vector<ub2> sizes_;
std::size_t maxSize_;
// name is used if non-empty, otherwise position
std::string bind_name_;
int bind_position_;
};
struct oracle_session_backend;
struct oracle_statement_backend : details::statement_backend
{
oracle_statement_backend(oracle_session_backend &session);
void alloc() override;
void clean_up() override;
void prepare(std::string const &query,
details::statement_type eType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const &query) override;
int prepare_for_describe() override;
void describe_column(int colNum,
db_type &dbtype,
std::string &columnName) override;
// helper for defining into vector<string>
std::size_t column_size(int position);
oracle_standard_into_type_backend * make_into_type_backend() override;
oracle_standard_use_type_backend * make_use_type_backend() override;
oracle_vector_into_type_backend * make_vector_into_type_backend() override;
oracle_vector_use_type_backend * make_vector_use_type_backend() override;
oracle_session_backend &session_;
OCIStmt *stmtp_;
bool boundByName_;
bool boundByPos_;
bool noData_;
};
struct oracle_rowid_backend : details::rowid_backend
{
oracle_rowid_backend(oracle_session_backend &session);
~oracle_rowid_backend() override;
OCIRowid *rowidp_;
};
struct oracle_blob_backend : details::blob_backend
{
typedef OCILobLocator * locator_t;
oracle_blob_backend(oracle_session_backend &session);
~oracle_blob_backend() override;
std::size_t get_len() override;
std::size_t read_from_start(void * buf, std::size_t toRead, std::size_t offset = 0) override;
std::size_t write_from_start(const void * buf, std::size_t toWrite, std::size_t offset = 0) override;
std::size_t append(const void *buf, std::size_t toWrite) override;
void trim(std::size_t newLen) override;
locator_t get_lob_locator() const;
void set_lob_locator(locator_t locator, bool initialized = true);
void reset();
void ensure_initialized();
private:
std::size_t do_deprecated_read(std::size_t offset, void *buf, std::size_t toRead) override
{
// Offsets are 1-based in Oracle
return read_from_start(buf, toRead, offset - 1);
}
std::size_t do_deprecated_write(std::size_t offset, const void *buf, std::size_t toWrite) override
{
// Offsets are 1-based in Oracle
return write_from_start(buf, toWrite, offset - 1);
}
oracle_session_backend &session_;
locator_t lobp_;
// If this is true, then the locator lobp_ points to something useful
// (instead of being the equivalent to a pointer with random value)
bool initialized_;
};
struct oracle_session_backend : details::session_backend
{
oracle_session_backend(std::string const & serviceName,
std::string const & userName,
std::string const & password,
int mode,
bool decimals_as_strings = false,
int charset = 0,
int ncharset = 0);
~oracle_session_backend() override;
bool is_connected() override;
void begin() override;
void commit() override;
void rollback() override;
std::string get_table_names_query() const override
{
return "select table_name"
" from user_tables";
}
std::string get_column_descriptions_query() const override
{
return "select column_name,"
" data_type,"
" char_length as character_maximum_length,"
" data_precision as numeric_precision,"
" data_scale as numeric_scale,"
" decode(nullable, 'Y', 'YES', 'N', 'NO') as is_nullable"
" from user_tab_columns"
" where table_name = :t";
}
std::string create_column_type(db_type dt,
int precision, int scale) override
{
// Oracle-specific SQL syntax:
std::string res;
switch (dt)
{
case db_string:
{
std::ostringstream oss;
if (precision == 0)
{
oss << "clob";
}
else
{
oss << "varchar(" << precision << ")";
}
res += oss.str();
}
break;
case db_date:
res += "timestamp";
break;
case db_double:
{
std::ostringstream oss;
if (precision == 0)
{
oss << "number";
}
else
{
oss << "number(" << precision << ", " << scale << ")";
}
res += oss.str();
}
break;
case db_int16:
res += "smallint";
break;
case db_int32:
res += "integer";
break;
case db_int64:
res += "number";
break;
case db_uint64:
res += "number";
break;
case db_blob:
res += "blob";
break;
case db_xml:
res += "xmltype";
break;
default:
throw soci_error("this db_type is not supported in create_column");
}
return res;
}
std::string add_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision, int scale) override
{
return "alter table " + tableName + " add " +
columnName + " " + create_column_type(dt, precision, scale);
}
std::string alter_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision, int scale) override
{
return "alter table " + tableName + " modify " +
columnName + " " + create_column_type(dt, precision, scale);
}
std::string empty_blob() override
{
return "empty_blob()";
}
std::string nvl() override
{
return "nvl";
}
bool get_next_sequence_value(session &s,
std::string const &sequence, long long &value) override;
std::string get_dummy_from_table() const override { return "dual"; }
std::string get_backend_name() const override { return "oracle"; }
void clean_up();
oracle_statement_backend * make_statement_backend() override;
oracle_rowid_backend * make_rowid_backend() override;
oracle_blob_backend * make_blob_backend() override;
bool get_option_decimals_as_strings() { return decimals_as_strings_; }
// Return either SQLT_FLT or SQLT_BDOUBLE as the type to use when binding
// values of C type "double" (the latter is preferable but might not be
// always available).
ub2 get_double_sql_type() const;
OCIEnv *envhp_;
OCIServer *srvhp_;
OCIError *errhp_;
OCISvcCtx *svchp_;
OCISession *usrhp_;
bool decimals_as_strings_;
};
struct oracle_backend_factory : backend_factory
{
oracle_backend_factory() {}
oracle_session_backend * make_session(
connection_parameters const & parameters) const override;
};
extern SOCI_ORACLE_DECL oracle_backend_factory const oracle;
extern "C"
{
// for dynamic backend loading
SOCI_ORACLE_DECL backend_factory const * factory_oracle();
SOCI_ORACLE_DECL void register_factory_oracle();
} // extern "C"
} // namespace soci
#endif

View File

@@ -1,442 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Copyright (C) 2011 Gevorg Voskanyan
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_POSTGRESQL_H_INCLUDED
#define SOCI_POSTGRESQL_H_INCLUDED
#include <soci/soci-platform.h>
#ifdef SOCI_POSTGRESQL_SOURCE
# define SOCI_POSTGRESQL_DECL SOCI_DECL_EXPORT
#else
# define SOCI_POSTGRESQL_DECL SOCI_DECL_IMPORT
#endif
#include <soci/soci-backend.h>
#include "soci/connection-parameters.h"
#include <libpq-fe.h>
#include <vector>
#include <unordered_map>
namespace soci
{
class SOCI_POSTGRESQL_DECL postgresql_soci_error : public soci_error
{
public:
postgresql_soci_error(std::string const & msg, char const * sqlst);
std::string sqlstate() const;
error_category get_error_category() const override { return cat_; }
private:
char sqlstate_[ 5 ]; // not std::string to keep copy-constructor no-throw
error_category cat_;
};
struct postgresql_session_backend;
namespace details
{
// A class thinly encapsulating PGresult. Its main purpose is to ensure that
// PQclear() is always called, avoiding result memory leaks.
class postgresql_result
{
public:
// Creates a wrapper for the given, possibly NULL, result. The wrapper
// object takes ownership of the result object and will call PQclear() on it.
explicit postgresql_result(
postgresql_session_backend & sessionBackend,
PGresult * result)
: sessionBackend_(sessionBackend)
{
init(result);
}
// Frees any currently stored result pointer and takes ownership of the
// given one.
void reset(PGresult* result = NULL)
{
clear();
init(result);
}
// Check whether the status is PGRES_COMMAND_OK and throw an exception if
// it is different. Notice that if the query can return any results,
// check_for_data() below should be used instead to verify whether anything
// was returned or not.
//
// The provided error message is used only for the exception being thrown
// and should describe the operation which yielded this result.
void check_for_errors(char const* errMsg) const;
// Check whether the status indicates successful query completion, either
// with the return results (in which case true is returned) or without them
// (then false is returned). If the status corresponds to an error, throws
// an exception, just as check_for_errors().
bool check_for_data(char const* errMsg) const;
// Implicit conversion to const PGresult: this is somewhat dangerous but
// allows us to avoid changing the existing code that uses PGresult and
// avoids the really bad problem with calling PQclear() twice accidentally
// as this would require a conversion to non-const pointer that we do not
// provide.
operator const PGresult*() const { return result_; }
// Get the associated result (which may be NULL). Unlike the implicit
// conversion above, this one returns a non-const pointer, so you should be
// careful to avoid really modifying it.
PGresult* get_result() const { return result_; }
// Dtor frees the result.
~postgresql_result() { clear(); }
private:
void init(PGresult* result)
{
result_ = result;
}
void clear()
{
// Notice that it is safe to call PQclear() with NULL pointer, it
// simply does nothing in this case.
PQclear(result_);
}
postgresql_session_backend & sessionBackend_;
PGresult* result_;
SOCI_NOT_COPYABLE(postgresql_result)
};
} // namespace details
struct postgresql_statement_backend;
struct postgresql_standard_into_type_backend : details::standard_into_type_backend
{
postgresql_standard_into_type_backend(postgresql_statement_backend & st)
: statement_(st) {}
void define_by_pos(int & position,
void * data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch,
indicator * ind) override;
void clean_up() override;
postgresql_statement_backend & statement_;
void * data_;
details::exchange_type type_;
int position_;
};
struct postgresql_vector_into_type_backend : details::vector_into_type_backend
{
postgresql_vector_into_type_backend(postgresql_statement_backend & st)
: statement_(st), user_ranges_(true) {}
void define_by_pos(int & position,
void * data, details::exchange_type type) override
{
user_ranges_ = false;
define_by_pos_bulk(position, data, type, 0, &end_var_);
}
void define_by_pos_bulk(int & position,
void * data, details::exchange_type type,
std::size_t begin, std::size_t * end) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator * ind) override;
void resize(std::size_t sz) override;
std::size_t size() override; // active size (might be lower than full vector size)
std::size_t full_size(); // actual size of the user-provided vector
void clean_up() override;
postgresql_statement_backend & statement_;
void * data_;
details::exchange_type type_;
std::size_t begin_;
std::size_t * end_;
std::size_t end_var_;
bool user_ranges_;
int position_;
};
struct postgresql_standard_use_type_backend : details::standard_use_type_backend
{
postgresql_standard_use_type_backend(postgresql_statement_backend & st)
: statement_(st), position_(0), buf_(NULL) {}
void bind_by_pos(int & position,
void * data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const & name,
void * data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const * ind) override;
void post_use(bool gotData, indicator * ind) override;
void clean_up() override;
postgresql_statement_backend & statement_;
void * data_;
details::exchange_type type_;
int position_;
std::string name_;
char * buf_;
private:
// Allocate buf_ of appropriate size and copy string data into it.
void copy_from_string(std::string const& s);
};
struct postgresql_vector_use_type_backend : details::vector_use_type_backend
{
postgresql_vector_use_type_backend(postgresql_statement_backend & st)
: statement_(st), position_(0) {}
void bind_by_pos(int & position,
void * data, details::exchange_type type) override
{
bind_by_pos_bulk(position, data, type, 0, &end_var_);
}
void bind_by_pos_bulk(int & position,
void * data, details::exchange_type type,
std::size_t begin, std::size_t * end) override;
void bind_by_name(std::string const & name,
void * data, details::exchange_type type) override
{
bind_by_name_bulk(name, data, type, 0, &end_var_);
}
void bind_by_name_bulk(const std::string & name,
void * data, details::exchange_type type,
std::size_t begin, std::size_t * end) override;
void pre_use(indicator const * ind) override;
std::size_t size() override; // active size (might be lower than full vector size)
std::size_t full_size(); // actual size of the user-provided vector
void clean_up() override;
postgresql_statement_backend & statement_;
void * data_;
details::exchange_type type_;
std::size_t begin_;
std::size_t * end_;
std::size_t end_var_;
int position_;
std::string name_;
std::vector<char *> buffers_;
};
struct postgresql_statement_backend : details::statement_backend
{
postgresql_statement_backend(postgresql_session_backend & session,
bool single_row_mode);
~postgresql_statement_backend() override;
void alloc() override;
void clean_up() override;
void prepare(std::string const & query,
details::statement_type stType) override;
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const & query) override;
int prepare_for_describe() override;
void describe_column(int colNum,
db_type & dbtype,
std::string & columnName) override;
postgresql_standard_into_type_backend * make_into_type_backend() override;
postgresql_standard_use_type_backend * make_use_type_backend() override;
postgresql_vector_into_type_backend * make_vector_into_type_backend() override;
postgresql_vector_use_type_backend * make_vector_use_type_backend() override;
postgresql_session_backend & session_;
bool single_row_mode_;
details::postgresql_result result_;
std::string query_;
details::statement_type stType_;
std::string statementName_;
std::vector<std::string> names_; // list of names for named binds
long long rowsAffectedBulk_; // number of rows affected by the last bulk operation
int numberOfRows_; // number of rows retrieved from the server
int currentRow_; // "current" row number to consume in postFetch
int rowsToConsume_; // number of rows to be consumed in postFetch
bool justDescribed_; // to optimize row description with immediately
// following actual statement execution
bool hasIntoElements_;
bool hasVectorIntoElements_;
bool hasUseElements_;
bool hasVectorUseElements_;
// the following maps are used for finding data buffers according to
// use elements specified by the user
typedef std::map<int, char **> UseByPosBuffersMap;
UseByPosBuffersMap useByPosBuffers_;
typedef std::map<std::string, char **> UseByNameBuffersMap;
UseByNameBuffersMap useByNameBuffers_;
// the following map is used to keep the results of column
// type queries with custom types
typedef std::unordered_map<unsigned long, char> CategoryByColumnOID;
CategoryByColumnOID categoryByColumnOID_;
};
struct postgresql_rowid_backend : details::rowid_backend
{
postgresql_rowid_backend(postgresql_session_backend & session);
~postgresql_rowid_backend() override;
unsigned long value_;
};
class postgresql_blob_backend : public details::blob_backend
{
public:
struct blob_details
{
// OID of the large object
unsigned long oid;
// File descriptor of the large object
int fd;
blob_details();
blob_details(unsigned long oid, int fd);
};
postgresql_blob_backend(postgresql_session_backend & session);
~postgresql_blob_backend() override;
std::size_t get_len() override;
std::size_t read_from_start(void * buf, std::size_t toRead, std::size_t offset = 0) override;
std::size_t write_from_start(const void * buf, std::size_t toWrite, std::size_t offset = 0) override;
std::size_t append(const void * buf, std::size_t toWrite) override;
void trim(std::size_t newLen) override;
const blob_details &get_blob_details() const;
void set_blob_details(const blob_details &details);
bool get_destroy_on_close() const;
void set_destroy_on_close(bool destroy);
void set_clone_before_modify(bool clone);
void init();
void reset();
private:
postgresql_session_backend & session_;
blob_details details_;
bool destroy_on_close_;
bool clone_before_modify_;
std::size_t seek(std::size_t toOffset, int from);
void clone();
};
struct postgresql_session_backend : details::session_backend
{
postgresql_session_backend(connection_parameters const & parameters,
bool single_row_mode);
~postgresql_session_backend() override;
void connect(connection_parameters const & parameters);
bool is_connected() override;
void begin() override;
void commit() override;
void rollback() override;
void deallocate_prepared_statement(const std::string & statementName);
bool get_next_sequence_value(session & s,
std::string const & sequence, long long & value) override;
std::string get_dummy_from_table() const override { return std::string(); }
std::string get_backend_name() const override { return "postgresql"; }
void clean_up();
postgresql_statement_backend * make_statement_backend() override;
postgresql_rowid_backend * make_rowid_backend() override;
postgresql_blob_backend * make_blob_backend() override;
std::string get_next_statement_name();
int statementCount_;
bool single_row_mode_;
PGconn * conn_;
connection_parameters connectionParameters_;
};
struct postgresql_backend_factory : backend_factory
{
postgresql_backend_factory() {}
postgresql_session_backend * make_session(
connection_parameters const & parameters) const override;
};
extern SOCI_POSTGRESQL_DECL postgresql_backend_factory const postgresql;
extern "C"
{
// for dynamic backend loading
SOCI_POSTGRESQL_DECL backend_factory const * factory_postgresql();
SOCI_POSTGRESQL_DECL void register_factory_postgresql();
} // extern "C"
} // namespace soci
#endif // SOCI_POSTGRESQL_H_INCLUDED

View File

@@ -1,65 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_PREPARE_TEMP_TYPE_INCLUDED
#define SOCI_PREPARE_TEMP_TYPE_INCLUDED
#include "soci/into-type.h"
#include "soci/use-type.h"
#include "soci/use.h"
#include "soci/ref-counted-prepare-info.h"
namespace soci
{
namespace details
{
// this needs to be lightweight and copyable
class SOCI_DECL prepare_temp_type
{
public:
prepare_temp_type(session &);
prepare_temp_type(prepare_temp_type const &);
prepare_temp_type & operator=(prepare_temp_type const &);
~prepare_temp_type();
template <typename T>
prepare_temp_type & operator<<(T const & t)
{
rcpi_->accumulate(t);
return *this;
}
prepare_temp_type & operator,(into_type_ptr const & i);
template <typename T, typename Indicator>
prepare_temp_type &operator,(into_container<T, Indicator> const &ic)
{
rcpi_->exchange(ic);
return *this;
}
template <typename T, typename Indicator>
prepare_temp_type &operator,(use_container<T, Indicator> const &uc)
{
rcpi_->exchange(uc);
return *this;
}
ref_counted_prepare_info * get_prepare_info() const { return rcpi_; }
private:
ref_counted_prepare_info * rcpi_;
};
} // namespace details
} // namespace soci
#endif

View File

@@ -1,90 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_PROCEDURE_H_INCLUDED
#define SOCI_PROCEDURE_H_INCLUDED
#include "soci/statement.h"
namespace soci
{
namespace details
{
class SOCI_DECL procedure_impl : public statement_impl
{
public:
procedure_impl(session & s) : statement_impl(s), refCount_(1) {}
procedure_impl(prepare_temp_type const & prep);
void inc_ref() { ++refCount_; }
void dec_ref()
{
if (--refCount_ == 0)
{
delete this;
}
}
private:
int refCount_;
};
} // namespace details
class SOCI_DECL procedure
{
public:
// this is a conversion constructor
procedure(details::prepare_temp_type const & prep)
: impl_(new details::procedure_impl(prep)), gotData_(false) {}
~procedure() { impl_->dec_ref(); }
// copy is supported here
procedure(procedure const & other)
: impl_(other.impl_), gotData_(other.gotData_)
{
impl_->inc_ref();
}
void operator=(procedure const & other)
{
other.impl_->inc_ref();
impl_->dec_ref();
impl_ = other.impl_;
gotData_ = other.gotData_;
}
// forwarders to procedure_impl
// (or rather to its base interface from statement_impl)
bool execute(bool withDataExchange = false)
{
gotData_ = impl_->execute(withDataExchange);
return gotData_;
}
bool fetch()
{
gotData_ = impl_->fetch();
return gotData_;
}
bool got_data() const
{
return gotData_;
}
private:
details::procedure_impl * impl_;
bool gotData_;
};
} // namespace soci
#endif

View File

@@ -1,57 +0,0 @@
//
// Copyright (C) 2013 Mateusz Loskot <mateusz@loskot.net>
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_QUERY_TRANSFORMATION_H_INCLUDED
#define SOCI_QUERY_TRANSFORMATION_H_INCLUDED
#include "soci/soci-platform.h"
#include <string>
namespace soci
{
namespace details
{
// Query transformation is a mechanism that enables user to apply
// any string-to-string transformation to SQL statement just
// before it is executed.
// Transformation procedure is specified by user,
// be it a function or an arbitrary type as long as it
// defines operator() with the appropriate signature:
// unary function takes any type converible-to std::string
// and returns std::string.
class query_transformation_function
{
public:
virtual ~query_transformation_function() {}
virtual std::string operator()(std::string const&) const = 0;
};
template <typename T>
class query_transformation : public query_transformation_function
{
public:
query_transformation(T callback)
: callback_(callback)
{}
std::string operator()(std::string const& query) const override
{
return callback_(query);
}
private:
T callback_;
};
} // namespace details
} // namespace soci
#endif // SOCI_QUERY_TRANSFORMATION_H_INCLUDED

View File

@@ -1,66 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_REF_COUNTED_PREPARE_INFO_INCLUDED
#define SOCI_REF_COUNTED_PREPARE_INFO_INCLUDED
#include "soci/bind-values.h"
#include "soci/ref-counted-statement.h"
// std
#include <string>
#include <vector>
namespace soci
{
class session;
namespace details
{
class procedure_impl;
class statement_impl;
class into_type_base;
// this class conveys only the statement text and the bind/define info
// it exists only to be passed to statement's constructor
class ref_counted_prepare_info : public ref_counted_statement_base
{
public:
ref_counted_prepare_info(session& s)
: ref_counted_statement_base(s)
{}
void exchange(use_type_ptr const& u) { uses_.exchange(u); }
template <typename T, typename Indicator>
void exchange(use_container<T, Indicator> const &uc)
{ uses_.exchange(uc); }
void exchange(into_type_ptr const& i) { intos_.exchange(i); }
template <typename T, typename Indicator>
void exchange(into_container<T, Indicator> const &ic)
{ intos_.exchange(ic); }
void final_action() override;
private:
friend class statement_impl;
friend class procedure_impl;
into_type_vector intos_;
use_type_vector uses_;
std::string get_query() const;
};
} // namespace details
} // namespace soci
#endif

View File

@@ -1,102 +0,0 @@
//
// Copyright (C) 2004-2016 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_REF_COUNTED_STATEMENT_H_INCLUDED
#define SOCI_REF_COUNTED_STATEMENT_H_INCLUDED
#include "soci/statement.h"
#include "soci/into-type.h"
#include "soci/use-type.h"
// std
#include <sstream>
namespace soci
{
namespace details
{
// this class is a base for both "once" and "prepare" statements
class SOCI_DECL ref_counted_statement_base
{
public:
ref_counted_statement_base(session& s);
virtual ~ref_counted_statement_base() {}
virtual void final_action() = 0;
void inc_ref() { ++refCount_; }
void dec_ref()
{
if (--refCount_ == 0)
{
try
{
if (tail_.empty() == false)
{
accumulate(tail_);
}
final_action();
}
catch (...)
{
delete this;
throw;
}
delete this;
}
}
template <typename T>
void accumulate(T const & t) { get_query_stream() << t; }
void set_tail(const std::string & tail) { tail_ = tail; }
void set_need_comma(bool need_comma) { need_comma_ = need_comma; }
bool get_need_comma() const { return need_comma_; }
protected:
// this function allows to break the circular dependenc
// between session and this class
std::ostringstream & get_query_stream();
int refCount_;
session & session_;
// used mainly for portable ddl
std::string tail_;
bool need_comma_;
private:
SOCI_NOT_COPYABLE(ref_counted_statement_base)
};
// this class is supposed to be a vehicle for the "once" statements
// it executes the whole statement in its destructor
class ref_counted_statement : public ref_counted_statement_base
{
public:
ref_counted_statement(session & s)
: ref_counted_statement_base(s), st_(s) {}
void final_action() override;
template <typename T>
void exchange(T &t) { st_.exchange(t); }
private:
statement st_;
};
} // namespace details
} // namespace soci
#endif

View File

@@ -1,80 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_INTO_ROW_H_INCLUDED
#define SOCI_INTO_ROW_H_INCLUDED
#include "soci/into-type.h"
#include "soci/exchange-traits.h"
#include "soci/row.h"
#include "soci/statement.h"
// std
#include <cstddef>
namespace soci
{
namespace details
{
// Support selecting into a row for dynamic queries
template <>
class into_type<row>
: public into_type_base // bypass the standard_into_type
{
public:
into_type(row & r) : r_(r) {}
into_type(row & r, indicator &) : r_(r) {}
private:
// special handling for Row
void define(statement_impl & st, int & /* position */) override
{
st.set_row(&r_);
// actual row description is performed
// as part of the statement execute
}
void pre_exec(int /* num */) override {}
void pre_fetch() override {}
void post_fetch(bool gotData, bool /* calledFromFetch */) override
{
r_.reset_get_counter();
if (gotData)
{
// this is used only to re-dispatch to derived class, if any
// (the derived class might be generated automatically by
// user conversions)
convert_from_base();
}
}
void clean_up() override {}
std::size_t size() const override { return 1; }
virtual void convert_from_base() {}
row & r_;
SOCI_NOT_COPYABLE(into_type)
};
template <>
struct exchange_traits<row>
{
typedef basic_type_tag type_family;
};
} // namespace details
} // namespace soci
#endif

View File

@@ -1,202 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_ROW_H_INCLUDED
#define SOCI_ROW_H_INCLUDED
#include "soci/type-holder.h"
#include "soci/blob.h"
#include "soci/type-conversion-traits.h"
#include "soci/soci-backend.h"
#include "soci/type-conversion.h"
// std
#include <cstddef>
#include <map>
#include <string>
#include <vector>
namespace soci
{
class SOCI_DECL column_properties
{
// use getters/setters in case we want to make some
// of the getters lazy in the future
public:
std::string get_name() const { return name_; }
// DEPRECATED. USE get_db_type() INSTEAD.
data_type get_data_type() const { return dataType_; }
db_type get_db_type() const { return dbType_; }
void set_name(std::string const& name) { name_ = name; }
// DEPRECATED. USE set_db_type(db_type) INSTEAD.
void set_data_type(data_type dataType) { dataType_ = dataType; }
void set_db_type(db_type dataType) { dbType_ = dataType; }
private:
std::string name_;
// DEPRECATED. USE exchangeDataType_ INSTEAD.
data_type dataType_;
db_type dbType_;
};
class SOCI_DECL row
{
public:
row();
~row();
row(row &&other) = default;
row &operator=(row &&other) = default;
void uppercase_column_names(bool forceToUpper);
void add_properties(column_properties const& cp);
std::size_t size() const;
void clean_up();
indicator get_indicator(std::size_t pos) const;
indicator get_indicator(std::string const& name) const;
template <typename T>
inline void add_holder(T* t, indicator* ind)
{
holders_.push_back(details::holder::make_holder(t));
indicators_.push_back(ind);
}
column_properties const& get_properties(std::size_t pos) const;
column_properties const& get_properties(std::string const& name) const;
template <typename T>
T get(std::size_t pos) const
{
typedef typename type_conversion<T>::base_type base_type;
static_assert(details::can_use_from_base<type_conversion<T>>(),
"Can't use row::get() with this type (not convertible/copy-assignable from base_type) - did you mean to use move_as?");
base_type const& baseVal =
holders_.at(pos)->get<base_type>(details::value_cast_tag{});
T ret;
type_conversion<T>::from_base(baseVal, *indicators_.at(pos), ret);
return ret;
}
template <typename T>
T move_as(std::size_t pos) const
{
typedef typename type_conversion<T>::base_type base_type;
static_assert(details::can_use_move_from_base<T, base_type>(),
"row::move_as() can only be called with types that can be instantiated from a base type rvalue reference");
base_type & baseVal =
holders_.at(pos)->get<base_type>(details::value_reference_tag{});
T ret;
type_conversion<T>::move_from_base(baseVal, *indicators_.at(pos), ret);
return ret;
}
template <typename T>
T get(std::size_t pos, T const &nullValue) const
{
if (i_null == *indicators_.at(pos))
{
return nullValue;
}
return get<T>(pos);
}
template <typename T>
T move_as(std::size_t pos, T const &nullValue) const
{
if (i_null == *indicators_.at(pos))
{
return nullValue;
}
return move_as<T>(pos);
}
template <typename T>
T get(std::string const &name) const
{
std::size_t const pos = find_column(name);
return get<T>(pos);
}
template <typename T>
T move_as(std::string const &name) const
{
std::size_t const pos = find_column(name);
return move_as<T>(pos);
}
template <typename T>
T get(std::string const &name, T const &nullValue) const
{
std::size_t const pos = find_column(name);
if (i_null == *indicators_[pos])
{
return nullValue;
}
return get<T>(pos);
}
template <typename T>
T move_as(std::string const &name, T const &nullValue) const
{
std::size_t const pos = find_column(name);
if (i_null == *indicators_[pos])
{
return nullValue;
}
return move_as<T>(pos);
}
template <typename T>
row const& operator>>(T& value) const
{
value = get<T>(currentPos_);
++currentPos_;
return *this;
}
void skip(std::size_t num = 1) const
{
currentPos_ += num;
}
void reset_get_counter() const
{
currentPos_ = 0;
}
private:
SOCI_NOT_COPYABLE(row)
std::size_t find_column(std::string const& name) const;
std::vector<column_properties> columns_;
std::vector<details::holder*> holders_;
std::vector<indicator*> indicators_;
std::map<std::string, std::size_t> index_;
bool uppercaseColumnNames_;
mutable std::size_t currentPos_;
};
template <>
blob SOCI_DECL row::move_as<blob>(std::size_t pos) const;
} // namespace soci
#endif // SOCI_ROW_H_INCLUDED

View File

@@ -1,59 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_ROWID_EXCHANGE_H_INCLUDED
#define SOCI_ROWID_EXCHANGE_H_INCLUDED
#include "soci/rowid.h"
#include "soci/into-type.h"
#include "soci/use-type.h"
#include "soci/exchange-traits.h"
// std
#include <string>
namespace soci
{
namespace details
{
template <>
class use_type<rowid> : public standard_use_type
{
public:
use_type(rowid & rid, std::string const & name = std::string())
: standard_use_type(&rid, x_rowid, false, name) {}
use_type(rowid const & rid, std::string const & name = std::string())
: standard_use_type(const_cast<rowid *>(&rid), x_rowid, true, name) {}
use_type(rowid & rid, indicator & ind,
std::string const & name = std::string())
: standard_use_type(&rid, x_rowid, ind, false, name) {}
use_type(rowid const & rid, indicator & ind,
std::string const & name = std::string())
: standard_use_type(const_cast<rowid *>(&rid), x_rowid, ind, true, name) {}
};
template <>
class into_type<rowid> : public standard_into_type
{
public:
into_type(rowid & rid) : standard_into_type(&rid, x_rowid) {}
into_type(rowid & rid, indicator & ind)
:standard_into_type(&rid, x_rowid, ind) {}
};
template <>
struct exchange_traits<soci::rowid>
{
typedef basic_type_tag type_family;
};
} // namespace details
} // namespace soci
#endif // SOCI_ROWID_EXCHANGE_H_INCLUDED

View File

@@ -1,41 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_ROWID_H_INCLUDED
#define SOCI_ROWID_H_INCLUDED
#include "soci/soci-platform.h"
namespace soci
{
class session;
namespace details
{
class rowid_backend;
} // namespace details
// ROWID support
class SOCI_DECL rowid
{
public:
explicit rowid(session & s);
~rowid();
details::rowid_backend * get_backend() { return backEnd_; }
private:
details::rowid_backend *backEnd_;
};
} // namespace soci
#endif

View File

@@ -1,241 +0,0 @@
//
// Copyright (C) 2006-2008 Mateusz Loskot
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_ROWSET_H_INCLUDED
#define SOCI_ROWSET_H_INCLUDED
#include "soci/soci-platform.h"
#include "soci/statement.h"
// std
#include <iterator>
#include <memory>
namespace soci
{
//
// rowset iterator of input category.
//
template <typename T>
class rowset_iterator
{
public:
// Standard iterator traits
typedef std::input_iterator_tag iterator_category;
typedef T value_type;
typedef T * pointer;
typedef T & reference;
typedef ptrdiff_t difference_type;
// Constructors
rowset_iterator()
: st_(0), define_(0)
{}
rowset_iterator(statement & st, T & define)
: st_(&st), define_(&define)
{
// Fetch first row to properly initialize iterator
++(*this);
}
// Access operators
reference operator*() const
{
return (*define_);
}
pointer operator->() const
{
return &(operator*());
}
// Iteration operators
rowset_iterator & operator++()
{
// Fetch next row from dataset
if (st_->fetch() == false)
{
// Set iterator to non-derefencable state (pass-the-end)
st_ = 0;
define_ = 0;
}
return (*this);
}
rowset_iterator operator++(int)
{
rowset_iterator tmp(*this);
++(*this);
return tmp;
}
// Comparison operators
bool operator==(rowset_iterator const & rhs) const
{
return (st_== rhs.st_ && define_ == rhs.define_);
}
bool operator!=(rowset_iterator const & rhs) const
{
return ((*this == rhs) == false);
}
private:
statement * st_;
T * define_;
}; // class rowset_iterator
namespace details
{
//
// Implementation of rowset
//
template <typename T>
class rowset_impl
{
public:
typedef rowset_iterator<T> iterator;
rowset_impl()
: refs_(1), st_(nullptr), define_(nullptr)
{
}
rowset_impl(details::prepare_temp_type const & prep)
: refs_(1), st_(new statement(prep)), define_(new T())
{
st_->exchange_for_rowset(into(*define_));
st_->execute();
}
void incRef()
{
++refs_;
}
void decRef()
{
if (--refs_ == 0)
{
delete this;
}
}
iterator begin() const
{
// No ownership transfer occurs here. Empty rowset doesn't have any valid begin iterator.
return st_ ? iterator(*st_, *define_) : iterator();
}
iterator end() const
{
return iterator();
}
private:
unsigned int refs_;
const std::unique_ptr<statement> st_;
const std::unique_ptr<T> define_;
SOCI_NOT_COPYABLE(rowset_impl)
}; // class rowset_impl
} // namespace details
//
// rowset is a thin wrapper on statement and provides access to STL-like input iterator.
// The rowset_iterator can be used to easily loop through statement results and
// use STL algorithms accepting input iterators.
//
template <typename T = soci::row>
class rowset
{
public:
typedef T value_type;
typedef rowset_iterator<T> iterator;
typedef rowset_iterator<T> const_iterator;
// this is a conversion constructor
rowset(details::prepare_temp_type const& prep)
: pimpl_(new details::rowset_impl<T>(prep))
{
}
rowset(rowset const & other)
: pimpl_(other.pimpl_)
{
pimpl_->incRef();
}
rowset()
: pimpl_(new details::rowset_impl<T>())
{
}
// Due to the existence of conversion from session to prepare_temp_type, it
// would have been possible to construct a rowset from session if we didn't
// delete this ctor -- so do delete it because it doesn't make sense to
// provide such constructor.
rowset(session const& session) = delete;
~rowset()
{
pimpl_->decRef();
}
rowset& operator=(rowset const& rhs)
{
if (&rhs != this)
{
rhs.pimpl_->incRef();
pimpl_->decRef();
pimpl_ = rhs.pimpl_;
}
return *this;
}
void clear()
{
*this = rowset();
}
const_iterator begin() const
{
return pimpl_->begin();
}
const_iterator end() const
{
return pimpl_->end();
}
private:
// Pointer to implementation - the body
details::rowset_impl<T>* pimpl_;
}; // class rowset
} // namespace soci
#endif // SOCI_ROWSET_H_INCLUDED

View File

@@ -1,239 +0,0 @@
//
// Copyright (C) 2004-2016 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_SESSION_H_INCLUDED
#define SOCI_SESSION_H_INCLUDED
#include "soci/soci-platform.h"
#include "soci/once-temp-type.h"
#include "soci/query_transformation.h"
#include "soci/connection-parameters.h"
#include "soci/logger.h"
// std
#include <cstddef>
#include <memory>
#include <ostream>
#include <sstream>
#include <string>
namespace soci
{
class values;
class backend_factory;
namespace details
{
class session_backend;
class statement_backend;
class rowid_backend;
class blob_backend;
} // namespace details
class connection_pool;
class failover_callback;
class SOCI_DECL session
{
private:
void set_query_transformation_(std::unique_ptr<details::query_transformation_function>&& qtf);
public:
session();
explicit session(connection_parameters const & parameters);
session(backend_factory const & factory, std::string const & connectString);
session(std::string const & backendName, std::string const & connectString);
explicit session(std::string const & connectString);
explicit session(connection_pool & pool);
session(session &&other);
session &operator=(session &&other);
~session();
void open(connection_parameters const & parameters);
void open(backend_factory const & factory, std::string const & connectString);
void open(std::string const & backendName, std::string const & connectString);
void open(std::string const & connectString);
void close();
void reconnect();
// check if we have a working connection to the database
bool is_connected() const noexcept;
void begin();
void commit();
void rollback();
// once and prepare are for syntax sugar only
details::once_type once;
details::prepare_type prepare;
// even more sugar
template <typename T>
details::once_temp_type operator<<(T const & t) { return once << t; }
std::ostringstream & get_query_stream();
std::string get_query() const;
template <typename T>
void set_query_transformation(T callback)
{
set_query_transformation_(std::make_unique<details::query_transformation<T>>(callback));
}
// Support for custom logging of database operations.
// Set the custom logger to use.
void set_logger(logger const & logger);
// Return the currently used logger, by default, this is an instance of a
// standard SOCI logger.
logger const & get_logger() const;
// support for basic logging (use set_logger() for more control).
void set_log_stream(std::ostream * s);
std::ostream * get_log_stream() const;
void log_query(std::string const & query);
std::string get_last_query() const;
void set_got_data(bool gotData);
bool got_data() const;
void uppercase_column_names(bool forceToUpper);
bool get_uppercase_column_names() const;
// Functions for dealing with sequence/auto-increment values.
// If true is returned, value is filled with the next value from the given
// sequence. Otherwise either the sequence is invalid (doesn't exist) or
// the current backend doesn't support sequences. If you use sequences for
// automatically generating primary key values, you should use
// get_last_insert_id() after the insertion in this case.
bool get_next_sequence_value(std::string const & sequence, long long & value);
// If true is returned, value is filled with the last auto-generated value
// for this table (although some backends ignore the table argument and
// return the last value auto-generated in this session).
bool get_last_insert_id(std::string const & table, long long & value);
// Returns once_temp_type for the internally composed query
// for the list of tables in the current schema.
// Since this query usually returns multiple results (for multiple tables),
// it makes sense to bind std::vector<std::string> for the single output field.
details::once_temp_type get_table_names();
// Returns prepare_temp_type for the internally composed query
// for the list of tables in the current schema.
// Since this is intended for use with statement objects, where results are obtained one row after another,
// it makes sense to bind std::string for the output field.
details::prepare_temp_type prepare_table_names();
// Returns prepare_temp_type for the internally composed query
// for the list of column descriptions.
// Since this is intended for use with statement objects, where results are obtained one row after another,
// it makes sense to bind either std::string for each output field or soci::column_info for the whole row.
// Note: table_name is a non-const reference to prevent temporary objects,
// this argument is bound as a regular "use" element.
details::prepare_temp_type prepare_column_descriptions(std::string & table_name);
// Functions for basic portable DDL statements.
ddl_type create_table(const std::string & tableName);
void drop_table(const std::string & tableName);
void truncate_table(const std::string & tableName);
ddl_type add_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision = 0, int scale = 0);
ddl_type alter_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision = 0, int scale = 0);
ddl_type drop_column(const std::string & tableName,
const std::string & columnName);
std::string empty_blob();
std::string nvl();
// And some functions to help with writing portable DML statements.
// Get the name of the dummy table that needs to be used in the FROM clause
// of a SELECT statement not operating on any tables, e.g. "dual" for
// Oracle. The returned string is empty if no such table is needed.
std::string get_dummy_from_table() const;
// Returns a possibly empty string that needs to be used as a FROM clause
// of a SELECT statement not operating on any tables, e.g. " FROM DUAL"
// (notice the leading space).
std::string get_dummy_from_clause() const;
// Sets the failover callback object.
void set_failover_callback(failover_callback & callback);
// for diagnostics and advanced users
// (downcast it to expected back-end session class)
details::session_backend * get_backend() { return backEnd_; }
std::string get_backend_name() const;
// The functions below still work but are deprecated (but we don't give
// deprecation warnings for them because there is no real harm in using
// them).
//
// Use the overloads taking db_type instead in the new code.
ddl_type add_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision = 0, int scale = 0)
{
return add_column(tableName, columnName, details::to_db_type(dt),
precision, scale);
}
ddl_type alter_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision = 0, int scale = 0)
{
return alter_column(tableName, columnName, details::to_db_type(dt),
precision, scale);
}
details::statement_backend * make_statement_backend();
details::rowid_backend * make_rowid_backend();
details::blob_backend * make_blob_backend();
private:
SOCI_NOT_COPYABLE(session)
void reset_after_move();
std::ostringstream query_stream_;
std::unique_ptr<details::query_transformation_function> query_transformation_;
logger logger_;
connection_parameters lastConnectParameters_;
bool uppercaseColumnNames_;
details::session_backend * backEnd_;
bool gotData_;
bool isFromPool_;
std::size_t poolPosition_;
connection_pool * pool_;
};
} // namespace soci
#endif // SOCI_SESSION_H_INCLUDED

View File

@@ -1,591 +0,0 @@
//
// Copyright (C) 2004-2016 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_BACKEND_H_INCLUDED
#define SOCI_BACKEND_H_INCLUDED
#include "soci/soci-platform.h"
#include "soci/error.h"
// std
#include <cstddef>
#include <map>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <cstring>
namespace soci
{
// data types, as seen by the user
enum db_type
{
db_string,
db_int8,
db_uint8,
db_int16,
db_uint16,
db_int32,
db_uint32,
db_int64,
db_uint64,
db_double,
db_date,
db_blob,
db_xml
};
// DEPRECATED. USE db_type INSTEAD.
enum data_type
{
dt_string, dt_date, dt_double, dt_integer, dt_long_long, dt_unsigned_long_long,
dt_blob, dt_xml
};
// the enum type for indicator variables
enum indicator { i_ok, i_null, i_truncated };
class session;
class failover_callback;
namespace details
{
// data types, as used to describe exchange format
enum exchange_type
{
x_char,
x_stdstring,
x_int8,
x_uint8,
x_int16,
x_uint16,
x_int32,
x_uint32,
x_int64,
x_uint64,
x_double,
x_stdtm,
x_statement,
x_rowid,
x_blob,
x_xmltype,
x_longstring,
// Deprecated synonyms.
x_short = x_int16,
x_integer = x_int32,
x_long_long = x_int64,
x_unsigned_long_long = x_uint64
};
// type of statement (used for optimizing statement preparation)
enum statement_type
{
st_one_time_query,
st_repeatable_query
};
// (lossless) conversion from the legacy data type enum
inline db_type to_db_type(data_type dt)
{
switch (dt)
{
case dt_string: return db_string;
case dt_date: return db_date;
case dt_double: return db_double;
case dt_integer: return db_int32;
case dt_long_long: return db_int64;
case dt_unsigned_long_long: return db_uint64;
case dt_blob: return db_blob;
case dt_xml: return db_xml;
}
// unreachable
return db_string;
}
// polymorphic into type backend
class standard_into_type_backend
{
public:
standard_into_type_backend() {}
virtual ~standard_into_type_backend() {}
virtual void define_by_pos(int& position, void* data, exchange_type type) = 0;
virtual void pre_exec(int /* num */) {}
virtual void pre_fetch() = 0;
virtual void post_fetch(bool gotData, bool calledFromFetch, indicator* ind) = 0;
virtual void clean_up() = 0;
private:
SOCI_NOT_COPYABLE(standard_into_type_backend)
};
class vector_into_type_backend
{
public:
vector_into_type_backend() {}
virtual ~vector_into_type_backend() {}
virtual void define_by_pos_bulk(
int & /* position */, void * /* data */, exchange_type /* type */,
std::size_t /* begin */, std::size_t * /* end */)
{
throw soci_error("into bulk iterators are not supported with this backend");
}
virtual void define_by_pos(int& position, void* data, exchange_type type) = 0;
virtual void pre_exec(int /* num */) {}
virtual void pre_fetch() = 0;
virtual void post_fetch(bool gotData, indicator* ind) = 0;
virtual void resize(std::size_t sz) = 0;
virtual std::size_t size() = 0;
virtual void clean_up() = 0;
private:
SOCI_NOT_COPYABLE(vector_into_type_backend)
};
// polymorphic use type backend
class standard_use_type_backend
{
public:
standard_use_type_backend() {}
virtual ~standard_use_type_backend() {}
virtual void bind_by_pos(int& position, void* data,
exchange_type type, bool readOnly) = 0;
virtual void bind_by_name(std::string const& name,
void* data, exchange_type type, bool readOnly) = 0;
virtual void pre_exec(int /* num */) {}
virtual void pre_use(indicator const* ind) = 0;
virtual void post_use(bool gotData, indicator * ind) = 0;
virtual void clean_up() = 0;
private:
SOCI_NOT_COPYABLE(standard_use_type_backend)
};
class vector_use_type_backend
{
public:
vector_use_type_backend() {}
virtual ~vector_use_type_backend() {}
virtual void bind_by_pos(int& position, void* data, exchange_type type) = 0;
virtual void bind_by_pos_bulk(int& /* position */, void* /* data */, exchange_type /* type */,
std::size_t /* begin */, std::size_t * /* end */)
{
throw soci_error("using bulk iterators are not supported with this backend");
}
virtual void bind_by_name(std::string const& name,
void* data, exchange_type type) = 0;
virtual void bind_by_name_bulk(std::string const& /* name */,
void* /* data */, exchange_type /* type */,
std::size_t /* begin */, std::size_t * /* end */)
{
throw soci_error("using bulk iterators are not supported with this backend");
}
virtual void pre_exec(int /* num */) {}
virtual void pre_use(indicator const* ind) = 0;
virtual std::size_t size() = 0;
virtual void clean_up() = 0;
private:
SOCI_NOT_COPYABLE(vector_use_type_backend)
};
// polymorphic statement backend
class statement_backend
{
public:
statement_backend() {}
virtual ~statement_backend() {}
virtual void alloc() = 0;
virtual void clean_up() = 0;
virtual void prepare(std::string const& query, statement_type eType) = 0;
enum exec_fetch_result
{
ef_success,
ef_no_data
};
virtual exec_fetch_result execute(int number) = 0;
virtual exec_fetch_result fetch(int number) = 0;
virtual long long get_affected_rows() = 0;
virtual int get_number_of_rows() = 0;
virtual std::string get_parameter_name(int index) const = 0;
virtual std::string rewrite_for_procedure_call(std::string const& query) = 0;
virtual int prepare_for_describe() = 0;
virtual void describe_column(int colNum,
db_type& dbtype,
std::string& column_name) = 0;
// Function converting db_type to legacy data_type: this is mostly, but not
// quite, backend-independent because different backends handled the same
// type differently before db_type introduction.
virtual data_type to_data_type(db_type dbt) const
{
switch (dbt)
{
case db_string: return dt_string;
case db_date: return dt_date;
case db_double: return dt_double;
case db_int8:
case db_uint8:
case db_int16:
case db_uint16:
case db_int32: return dt_integer;
case db_uint32:
case db_int64: return dt_long_long;
case db_uint64: return dt_unsigned_long_long;
case db_blob: return dt_blob;
case db_xml: return dt_xml;
}
// unreachable
return dt_string;
}
virtual standard_into_type_backend* make_into_type_backend() = 0;
virtual standard_use_type_backend* make_use_type_backend() = 0;
virtual vector_into_type_backend* make_vector_into_type_backend() = 0;
virtual vector_use_type_backend* make_vector_use_type_backend() = 0;
private:
SOCI_NOT_COPYABLE(statement_backend)
};
// polymorphic RowID backend
class rowid_backend
{
public:
virtual ~rowid_backend() {}
};
// polymorphic blob backend
class blob_backend
{
public:
blob_backend() {}
virtual ~blob_backend() {}
virtual std::size_t get_len() = 0;
virtual std::size_t read_from_start(void* buf, std::size_t toRead, std::size_t offset) = 0;
virtual std::size_t write_from_start(const void* buf, std::size_t toWrite, std::size_t offset) = 0;
virtual std::size_t append(const void* buf, std::size_t toWrite) = 0;
virtual void trim(std::size_t newLen) = 0;
// Deprecated functions with backend-specific semantics preserved only for
// compatibility.
[[deprecated("Use read_from_start instead")]]
std::size_t read(std::size_t offset, void* buf, std::size_t toRead) { return do_deprecated_read(offset, buf, toRead); }
[[deprecated("Use write_from_start instead")]]
virtual std::size_t write(std::size_t offset, const void* buf, std::size_t toWrite) { return do_deprecated_write(offset, buf, toWrite); }
private:
virtual std::size_t do_deprecated_read(std::size_t offset, void* buf, std::size_t toRead) { return read_from_start(buf, toRead, offset); }
virtual std::size_t do_deprecated_write(std::size_t offset, const void* buf, std::size_t toWrite) { return write_from_start(buf, toWrite, offset); }
SOCI_NOT_COPYABLE(blob_backend)
};
// polymorphic session backend
class session_backend
{
public:
session_backend() : failoverCallback_(NULL), session_(NULL) {}
virtual ~session_backend() {}
virtual bool is_connected() = 0;
virtual void begin() = 0;
virtual void commit() = 0;
virtual void rollback() = 0;
// At least one of these functions is usually not implemented for any given
// backend as RDBMS support either sequences or auto-generated values, so
// we don't declare them as pure virtuals to avoid having to define trivial
// versions of them in the derived classes. However every backend should
// define at least one of them to allow the code using auto-generated values
// to work.
virtual bool get_next_sequence_value(session&, std::string const&, long long&)
{
return false;
}
virtual bool get_last_insert_id(session&, std::string const&, long long&)
{
return false;
}
// There is a set of standard SQL metadata structures that can be
// queried in a portable way - backends that are standard compliant
// do not need to override the following methods, which are intended
// to return a proper query for basic metadata statements.
// Returns a parameterless query for the list of table names in the current schema.
virtual std::string get_table_names_query() const
{
return "select table_name as \"TABLE_NAME\""
" from information_schema.tables"
" where table_schema = 'public'";
}
// Returns a query with a single parameter (table name) for the list
// of columns and their properties.
virtual std::string get_column_descriptions_query() const
{
return "select column_name as \"COLUMN_NAME\","
" data_type as \"DATA_TYPE\","
" character_maximum_length as \"CHARACTER_MAXIMUM_LENGTH\","
" numeric_precision as \"NUMERIC_PRECISION\","
" numeric_scale as \"NUMERIC_SCALE\","
" is_nullable as \"IS_NULLABLE\""
" from information_schema.columns"
" where table_schema = 'public' and table_name = :t";
}
virtual std::string create_table(const std::string & tableName)
{
return "create table " + tableName + " (";
}
virtual std::string drop_table(const std::string & tableName)
{
return "drop table " + tableName;
}
virtual std::string truncate_table(const std::string & tableName)
{
return "truncate table " + tableName;
}
virtual std::string create_column_type(db_type dt,
int precision, int scale)
{
// PostgreSQL was selected as a baseline for the syntax:
std::string res;
switch (dt)
{
case db_string:
{
std::ostringstream oss;
if (precision == 0)
{
oss << "text";
}
else
{
oss << "varchar(" << precision << ")";
}
res += oss.str();
}
break;
case db_date:
res += "timestamp";
break;
case db_double:
{
std::ostringstream oss;
if (precision == 0)
{
oss << "numeric";
}
else
{
oss << "numeric(" << precision << ", " << scale << ")";
}
res += oss.str();
}
break;
case db_int16:
case db_uint16:
res += "smallint";
break;
case db_int32:
case db_uint32:
res += "integer";
break;
case db_int64:
case db_uint64:
res += "bigint";
break;
case db_blob:
res += "oid";
break;
case db_xml:
res += "xml";
break;
default:
throw soci_error("this db_type is not supported in create_column");
}
return res;
}
virtual std::string add_column(const std::string & tableName,
const std::string & columnName,
db_type dt,
int precision, int scale)
{
return "alter table " + tableName + " add column " + columnName +
" " + create_column_type(dt, precision, scale);
}
virtual std::string alter_column(const std::string & tableName,
const std::string & columnName,
db_type dt,
int precision, int scale)
{
return "alter table " + tableName + " alter column " +
columnName + " type " +
create_column_type(dt, precision, scale);
}
virtual std::string drop_column(const std::string & tableName,
const std::string & columnName)
{
return "alter table " + tableName +
" drop column " + columnName;
}
virtual std::string constraint_unique(const std::string & name,
const std::string & columnNames)
{
return "constraint " + name +
" unique (" + columnNames + ")";
}
virtual std::string constraint_primary_key(const std::string & name,
const std::string & columnNames)
{
return "constraint " + name +
" primary key (" + columnNames + ")";
}
virtual std::string constraint_foreign_key(const std::string & name,
const std::string & columnNames,
const std::string & refTableName,
const std::string & refColumnNames)
{
return "constraint " + name +
" foreign key (" + columnNames + ")" +
" references " + refTableName + " (" + refColumnNames + ")";
}
virtual std::string empty_blob()
{
return "lo_creat(-1)";
}
virtual std::string nvl()
{
return "coalesce";
}
virtual std::string get_dummy_from_table() const = 0;
void set_failover_callback(failover_callback & callback, session & sql)
{
failoverCallback_ = &callback;
session_ = &sql;
}
virtual std::string get_backend_name() const = 0;
virtual statement_backend* make_statement_backend() = 0;
virtual rowid_backend* make_rowid_backend() = 0;
virtual blob_backend* make_blob_backend() = 0;
// The functions below still work but are deprecated (but we don't give
// deprecation warnings for them because there is no real harm in using
// them).
//
// Use the overloads taking db_type instead in the new code.
std::string create_column_type(data_type dt, int precision, int scale)
{
return create_column_type(to_db_type(dt), precision, scale);
}
std::string add_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision, int scale)
{
return add_column(tableName, columnName, to_db_type(dt), precision, scale);
}
std::string alter_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision, int scale)
{
return alter_column(tableName, columnName, to_db_type(dt), precision, scale);
}
failover_callback * failoverCallback_;
session * session_;
private:
SOCI_NOT_COPYABLE(session_backend)
};
} // namespace details
// simple base class for the session back-end factory
class connection_parameters;
class SOCI_DECL backend_factory
{
public:
backend_factory() {}
virtual ~backend_factory() {}
virtual details::session_backend* make_session(
connection_parameters const& parameters) const = 0;
};
} // namespace soci
#endif // SOCI_BACKEND_H_INCLUDED

View File

@@ -1,16 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCICONFIG_H_INCLUDED
#define SOCICONFIG_H_INCLUDED
//
// SOCI has been build with support for:
//
//@CONFIGURED_VARIABLES@
#endif // SOCICONFIG_H_INCLUDED

View File

@@ -1,197 +0,0 @@
//
// Copyright (C) 2006-2008 Mateusz Loskot
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_PLATFORM_H_INCLUDED
#define SOCI_PLATFORM_H_INCLUDED
//disable MSVC deprecated warnings
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdarg.h>
#include <string.h>
#include <string>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <memory>
#include "soci/soci-config.h" // for SOCI_HAVE_CXX11
#if defined(_MSC_VER)
#define LL_FMT_FLAGS "I64"
#else
#define LL_FMT_FLAGS "ll"
#endif
// Portability hacks for Microsoft Visual C++ compiler
#ifdef _MSC_VER
#include <stdlib.h>
//Disables warnings about STL objects need to have dll-interface and/or
//base class must have dll interface
#pragma warning(disable:4251 4275)
// Define if you have the vsnprintf variants.
#if _MSC_VER < 1500
# define vsnprintf _vsnprintf
#endif
// Define if you have the snprintf variants.
#if _MSC_VER < 1900
# define snprintf _snprintf
#endif
// Define if you have the strtoll and strtoull variants.
#if _MSC_VER < 1300
# error "Visual C++ versions prior 1300 don't support _strtoi64 and _strtoui64"
#elif _MSC_VER >= 1300 && _MSC_VER < 1800
namespace std {
inline long long strtoll(char const* str, char** str_end, int base)
{
return _strtoi64(str, str_end, base);
}
inline unsigned long long strtoull(char const* str, char** str_end, int base)
{
return _strtoui64(str, str_end, base);
}
}
#endif // _MSC_VER < 1800
#endif // _MSC_VER
#if defined(__CYGWIN__) || defined(__MINGW32__)
#include <stdlib.h>
namespace std {
using ::strtoll;
using ::strtoull;
}
#endif
#ifdef _WIN32
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0502 //_WIN32_WINNT_WS03, VS2015 support: https://msdn.microsoft.com/de-de/library/6sehtctf.aspx
# endif
# ifdef SOCI_DLL
# define SOCI_DECL_EXPORT __declspec(dllexport)
# define SOCI_DECL_IMPORT __declspec(dllimport)
# endif
#elif defined(SOCI_HAVE_VISIBILITY_SUPPORT)
# define SOCI_DECL_EXPORT __attribute__ (( visibility("default") ))
# define SOCI_DECL_IMPORT __attribute__ (( visibility("default") ))
#endif
#ifndef SOCI_DECL_EXPORT
# define SOCI_DECL_EXPORT
# define SOCI_DECL_IMPORT
#endif
// Define SOCI_DECL
#ifdef SOCI_SOURCE
# define SOCI_DECL SOCI_DECL_EXPORT
#else
# define SOCI_DECL SOCI_DECL_IMPORT
#endif
// C++11 features are always available in MSVS as it has no separate C++98
// mode, we just need to check for the minimal compiler version supporting them
// (see https://msdn.microsoft.com/en-us/library/hh567368.aspx).
#ifdef _MSC_VER
#if _MSC_VER < 1900
#error This version of SOCI requires MSVS 2015 or later.
#endif
#if _MSVC_LANG >= 201703L
#define SOCI_HAVE_CXX17
#endif
#else
#if __cplusplus < 201402L
#error This version of SOCI requires C++14.
#endif
#if __cplusplus >= 201703L
#define SOCI_HAVE_CXX17
#endif
#endif
// Define SOCI_ALLOW_DEPRECATED_BEGIN and SOCI_ALLOW_DEPRECATED_END
// Ref.: https://www.fluentcpp.com/2019/08/30/how-to-disable-a-warning-in-cpp/
#if defined(__GNUC__) || defined(__clang__)
# define SOCI_ALLOW_DEPRECATED_BEGIN \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated\"") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
# define SOCI_ALLOW_DEPRECATED_END \
_Pragma("GCC diagnostic pop")
#elif defined(_MSC_VER)
# define SOCI_ALLOW_DEPRECATED_BEGIN \
__pragma(warning(push)) \
__pragma(warning(disable: 4973 )) \
__pragma(warning(disable: 4974 )) \
__pragma(warning(disable: 4995 )) \
__pragma(warning(disable: 4996 ))
# define SOCI_ALLOW_DEPRECATED_END \
__pragma(warning(pop))
# define SOCI_DONT_WARN(statement) statement
#else
# pragma message("WARNING: SOCI_ALLOW_DEPRECATED_* not available for this compilet")
# define SOCI_ALLOW_DEPRECATED_BEGIN
# define SOCI_ALLOW_DEPRECATED_END
#endif
#define SOCI_NOT_ASSIGNABLE(classname) \
public: \
classname(const classname&) = default; \
private: \
classname& operator=(const classname&) = delete;
#define SOCI_NOT_COPYABLE(classname) \
classname(const classname&) = delete; \
classname& operator=(const classname&) = delete;
#define SOCI_UNUSED(x) (void)x;
// This macro can be used to avoid warnings from MSVC (and sometimes from gcc,
// if initialization is indirect) about "uninitialized" variables that are
// actually always initialized. Using this macro makes it clear that the
// initialization is only necessary to avoid compiler warnings and also will
// allow us to define it as doing nothing if we ever use a compiler warning
// about initializing variables unnecessarily.
#define SOCI_DUMMY_INIT(x) (x)
// And this one can be used to return after calling a "[[noreturn]]" function.
// Here the problem is that MSVC complains about unreachable code in this case
// (but only in release builds, where optimizations are enabled), while other
// compilers complain about missing return statement without it.
#if defined(_MSC_VER) && defined(NDEBUG)
#define SOCI_DUMMY_RETURN(x)
#else
#define SOCI_DUMMY_RETURN(x) return x
#endif
#define SOCI_OS_LINUX 0x0001
#define SOCI_OS_FREE_BSD 0x0002
#define SOCI_OS_APPLE 0x0003
#define SOCI_OS_WINDOWS 0x0004
#if defined(linux) || defined(__linux) || defined(__linux__)
#define SOCI_OS SOCI_OS_LINUX
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#define SOCI_OS SOCI_OS_FREE_BSD
#elif defined(__APPLE__)
#define SOCI_OS SOCI_OS_APPLE
#elif defined(_WIN32) || defined(_WIN64)
#define SOCI_OS SOCI_OS_WINDOWS
#endif
#if !defined(SOCI_OS)
#error "Unknown platform"
#endif
#endif // SOCI_PLATFORM_H_INCLUDED

View File

@@ -1,244 +0,0 @@
//
// Copyright (C) 2008 Maciej Sobczak
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_SIMPLE_H_INCLUDED
#define SOCI_SIMPLE_H_INCLUDED
#include "soci/soci-platform.h"
#include <cstdint>
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
// session
typedef void * session_handle;
SOCI_DECL session_handle soci_create_session(char const * connectionString);
SOCI_DECL void soci_destroy_session(session_handle s);
SOCI_DECL void soci_begin(session_handle s);
SOCI_DECL void soci_commit(session_handle s);
SOCI_DECL void soci_rollback(session_handle s);
SOCI_DECL int soci_session_state(session_handle s);
SOCI_DECL char const * soci_session_error_message(session_handle s);
// blob
typedef void *blob_handle;
SOCI_DECL blob_handle soci_create_blob(session_handle s);
SOCI_DECL void soci_destroy_blob(blob_handle b);
SOCI_DECL int soci_blob_get_len(blob_handle b);
[[deprecated("Use soci_blob_read_from_start instead")]]
SOCI_DECL int soci_blob_read(blob_handle b, int offset, char *buf, int toRead);
SOCI_DECL int soci_blob_read_from_start(blob_handle b, char *buf, int toRead, int offset = 0);
[[deprecated("Use soci_blob_write_from_start instead")]]
SOCI_DECL int soci_blob_write(blob_handle b, int offset, char const *buf, int toWrite);
SOCI_DECL int soci_blob_write_from_start(blob_handle b, char const *buf, int toWrite, int offset = 0);
SOCI_DECL int soci_blob_append(blob_handle b, char const *buf, int toWrite);
SOCI_DECL int soci_blob_trim(blob_handle b, int newLen);
SOCI_DECL int soci_blob_state(blob_handle b);
SOCI_DECL char const * soci_blob_error_message(blob_handle b);
// statement
typedef void * statement_handle;
SOCI_DECL statement_handle soci_create_statement(session_handle s);
SOCI_DECL void soci_destroy_statement(statement_handle st);
// positional bind of into elments (the functions return the position for convenience)
SOCI_DECL int soci_into_string (statement_handle st);
SOCI_DECL int soci_into_int (statement_handle st);
SOCI_DECL int soci_into_long_long(statement_handle st);
SOCI_DECL int soci_into_int8 (statement_handle st);
SOCI_DECL int soci_into_uint8 (statement_handle st);
SOCI_DECL int soci_into_int16 (statement_handle st);
SOCI_DECL int soci_into_uint16 (statement_handle st);
SOCI_DECL int soci_into_int32 (statement_handle st);
SOCI_DECL int soci_into_uint32 (statement_handle st);
SOCI_DECL int soci_into_int64 (statement_handle st);
SOCI_DECL int soci_into_uint64 (statement_handle st);
SOCI_DECL int soci_into_double (statement_handle st);
SOCI_DECL int soci_into_date (statement_handle st);
SOCI_DECL int soci_into_blob (statement_handle st);
// vector versions
SOCI_DECL int soci_into_string_v (statement_handle st);
SOCI_DECL int soci_into_int_v (statement_handle st);
SOCI_DECL int soci_into_long_long_v(statement_handle st);
SOCI_DECL int soci_into_int8_v (statement_handle st);
SOCI_DECL int soci_into_uint8_v (statement_handle st);
SOCI_DECL int soci_into_int16_v (statement_handle st);
SOCI_DECL int soci_into_uint16_v (statement_handle st);
SOCI_DECL int soci_into_int32_v (statement_handle st);
SOCI_DECL int soci_into_uint32_v (statement_handle st);
SOCI_DECL int soci_into_int64_v (statement_handle st);
SOCI_DECL int soci_into_uint64_v (statement_handle st);
SOCI_DECL int soci_into_double_v (statement_handle st);
SOCI_DECL int soci_into_date_v (statement_handle st);
// positional read of into elements
SOCI_DECL int soci_get_into_state (statement_handle st, int position);
SOCI_DECL char const * soci_get_into_string (statement_handle st, int position);
SOCI_DECL int soci_get_into_int (statement_handle st, int position);
SOCI_DECL long long soci_get_into_long_long(statement_handle st, int position);
SOCI_DECL int8_t soci_get_into_int8 (statement_handle st, int position);
SOCI_DECL uint8_t soci_get_into_uint8 (statement_handle st, int position);
SOCI_DECL int16_t soci_get_into_int16 (statement_handle st, int position);
SOCI_DECL uint16_t soci_get_into_uint16 (statement_handle st, int position);
SOCI_DECL int32_t soci_get_into_int32 (statement_handle st, int position);
SOCI_DECL uint32_t soci_get_into_uint32 (statement_handle st, int position);
SOCI_DECL int64_t soci_get_into_int64 (statement_handle st, int position);
SOCI_DECL uint64_t soci_get_into_uint64 (statement_handle st, int position);
SOCI_DECL double soci_get_into_double (statement_handle st, int position);
SOCI_DECL char const * soci_get_into_date (statement_handle st, int position);
SOCI_DECL blob_handle soci_get_into_blob (statement_handle st, int position);
// positional (re)size of vectors
SOCI_DECL int soci_into_get_size_v(statement_handle st);
SOCI_DECL void soci_into_resize_v (statement_handle st, int new_size);
// positional read of vectors
SOCI_DECL int soci_get_into_state_v (statement_handle st, int position, int index);
SOCI_DECL char const * soci_get_into_string_v (statement_handle st, int position, int index);
SOCI_DECL int soci_get_into_int_v (statement_handle st, int position, int index);
SOCI_DECL long long soci_get_into_long_long_v(statement_handle st, int position, int index);
SOCI_DECL int8_t soci_get_into_int8_v (statement_handle st, int position, int index);
SOCI_DECL uint8_t soci_get_into_uint8_v (statement_handle st, int position, int index);
SOCI_DECL int16_t soci_get_into_int16_v (statement_handle st, int position, int index);
SOCI_DECL uint16_t soci_get_into_uint16_v (statement_handle st, int position, int index);
SOCI_DECL int32_t soci_get_into_int32_v (statement_handle st, int position, int index);
SOCI_DECL uint32_t soci_get_into_uint32_v (statement_handle st, int position, int index);
SOCI_DECL int64_t soci_get_into_int64_v (statement_handle st, int position, int index);
SOCI_DECL uint64_t soci_get_into_uint64_v (statement_handle st, int position, int index);
SOCI_DECL double soci_get_into_double_v (statement_handle st, int position, int index);
SOCI_DECL char const * soci_get_into_date_v (statement_handle st, int position, int index);
// named bind of use elements
SOCI_DECL void soci_use_string (statement_handle st, char const * name);
SOCI_DECL void soci_use_int (statement_handle st, char const * name);
SOCI_DECL void soci_use_long_long(statement_handle st, char const * name);
SOCI_DECL void soci_use_int8 (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint8 (statement_handle st, char const * name);
SOCI_DECL void soci_use_int16 (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint16 (statement_handle st, char const * name);
SOCI_DECL void soci_use_int32 (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint32 (statement_handle st, char const * name);
SOCI_DECL void soci_use_int64 (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint64 (statement_handle st, char const * name);
SOCI_DECL void soci_use_double (statement_handle st, char const * name);
SOCI_DECL void soci_use_date (statement_handle st, char const * name);
SOCI_DECL void soci_use_blob (statement_handle st, char const * name);
// vector versions
SOCI_DECL void soci_use_string_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_int_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_long_long_v(statement_handle st, char const * name);
SOCI_DECL void soci_use_int8_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint8_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_int16_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint16_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_int32_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint32_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_int64_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_uint64_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_double_v (statement_handle st, char const * name);
SOCI_DECL void soci_use_date_v (statement_handle st, char const * name);
// named write of use elements
SOCI_DECL void soci_set_use_state (statement_handle st, char const * name, int state);
SOCI_DECL void soci_set_use_string (statement_handle st, char const * name, char const * val);
SOCI_DECL void soci_set_use_int (statement_handle st, char const * name, int val);
SOCI_DECL void soci_set_use_long_long(statement_handle st, char const * name, long long val);
SOCI_DECL void soci_set_use_int8 (statement_handle st, char const * name, int8_t val);
SOCI_DECL void soci_set_use_uint8 (statement_handle st, char const * name, uint8_t val);
SOCI_DECL void soci_set_use_int18 (statement_handle st, char const * name, int16_t val);
SOCI_DECL void soci_set_use_uint18 (statement_handle st, char const * name, uint16_t val);
SOCI_DECL void soci_set_use_int32 (statement_handle st, char const * name, int32_t val);
SOCI_DECL void soci_set_use_uint32 (statement_handle st, char const * name, uint32_t val);
SOCI_DECL void soci_set_use_int64 (statement_handle st, char const * name, int64_t val);
SOCI_DECL void soci_set_use_uint64 (statement_handle st, char const * name, uint64_t val);
SOCI_DECL void soci_set_use_double (statement_handle st, char const * name, double val);
SOCI_DECL void soci_set_use_date (statement_handle st, char const * name, char const * val);
SOCI_DECL void soci_set_use_blob (statement_handle st, char const * name, blob_handle blob);
// positional (re)size of vectors
SOCI_DECL int soci_use_get_size_v(statement_handle st);
SOCI_DECL void soci_use_resize_v (statement_handle st, int new_size);
// named write of use vectors
SOCI_DECL void soci_set_use_state_v(statement_handle st,
char const * name, int index, int state);
SOCI_DECL void soci_set_use_string_v(statement_handle st,
char const * name, int index, char const * val);
SOCI_DECL void soci_set_use_int_v(statement_handle st,
char const * name, int index, int val);
SOCI_DECL void soci_set_use_long_long_v(statement_handle st,
char const * name, int index, long long val);
SOCI_DECL void soci_set_use_int8_v(statement_handle st,
char const * name, int index, int8_t val);
SOCI_DECL void soci_set_use_uint8_v(statement_handle st,
char const * name, int index, uint8_t val);
SOCI_DECL void soci_set_use_int16_v(statement_handle st,
char const * name, int index, int16_t val);
SOCI_DECL void soci_set_use_uint16_v(statement_handle st,
char const * name, int index, uint16_t val);
SOCI_DECL void soci_set_use_int32_v(statement_handle st,
char const * name, int index, int32_t val);
SOCI_DECL void soci_set_use_uint32_v(statement_handle st,
char const * name, int index, uint32_t val);
SOCI_DECL void soci_set_use_int64_v(statement_handle st,
char const * name, int index, int64_t val);
SOCI_DECL void soci_set_use_uint64_v(statement_handle st,
char const * name, int index, uint64_t val);
SOCI_DECL void soci_set_use_double_v(statement_handle st,
char const * name, int index, double val);
SOCI_DECL void soci_set_use_date_v(statement_handle st,
char const * name, int index, char const * val);
// named read of use elements (for modifiable use values)
SOCI_DECL int soci_get_use_state (statement_handle st, char const * name);
SOCI_DECL char const * soci_get_use_string (statement_handle st, char const * name);
SOCI_DECL int soci_get_use_int (statement_handle st, char const * name);
SOCI_DECL long long soci_get_use_long_long(statement_handle st, char const * name);
SOCI_DECL int8_t soci_get_use_int8 (statement_handle st, char const * name);
SOCI_DECL uint8_t soci_get_use_uint8 (statement_handle st, char const * name);
SOCI_DECL int16_t soci_get_use_int16 (statement_handle st, char const * name);
SOCI_DECL uint16_t soci_get_use_uint16 (statement_handle st, char const * name);
SOCI_DECL int32_t soci_get_use_int32 (statement_handle st, char const * name);
SOCI_DECL uint32_t soci_get_use_uint32 (statement_handle st, char const * name);
SOCI_DECL int64_t soci_get_use_int64 (statement_handle st, char const * name);
SOCI_DECL uint64_t soci_get_use_uint64 (statement_handle st, char const * name);
SOCI_DECL double soci_get_use_double (statement_handle st, char const * name);
SOCI_DECL char const * soci_get_use_date (statement_handle st, char const * name);
SOCI_DECL blob_handle soci_get_use_blob (statement_handle st, char const * name);
// statement preparation and execution
SOCI_DECL void soci_prepare(statement_handle st, char const * query);
SOCI_DECL int soci_execute(statement_handle st, int withDataExchange);
SOCI_DECL long long soci_get_affected_rows(statement_handle st);
SOCI_DECL int soci_fetch(statement_handle st);
SOCI_DECL int soci_got_data(statement_handle st);
SOCI_DECL int soci_statement_state(statement_handle s);
SOCI_DECL char const * soci_statement_error_message(statement_handle s);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // SOCI_SIMPLE_H_INCLUDED

View File

@@ -1,15 +0,0 @@
#ifndef SOCI_TYPES_H_INCLUDED
#define SOCI_TYPES_H_INCLUDED
#include "soci/soci-platform.h"
#if defined(__GNUC__) || defined(__clang__)
#if defined(__LP64__)
#define SOCI_LONG_IS_64_BIT 1
#if SOCI_OS == SOCI_OS_LINUX || SOCI_OS == SOCI_OS_FREE_BSD
#define SOCI_INT64_IS_LONG 1
#endif
#endif
#endif
#endif // SOCI_TYPES_H_INCLUDED

View File

@@ -1,63 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_H_INCLUDED
#define SOCI_H_INCLUDED
// namespace soci
#include "soci/soci-platform.h"
#include "soci/backend-loader.h"
#include "soci/blob.h"
#include "soci/blob-exchange.h"
#include "soci/column-info.h"
#include "soci/connection-pool.h"
#include "soci/error.h"
#include "soci/exchange-traits.h"
#include "soci/fixed-size-ints.h"
#include "soci/into.h"
#include "soci/into-type.h"
#include "soci/once-temp-type.h"
#include "soci/prepare-temp-type.h"
#include "soci/procedure.h"
#include "soci/ref-counted-prepare-info.h"
#include "soci/ref-counted-statement.h"
#include "soci/row.h"
#include "soci/row-exchange.h"
#include "soci/rowid.h"
#include "soci/rowid-exchange.h"
#include "soci/rowset.h"
#include "soci/session.h"
#include "soci/soci-backend.h"
#include "soci/statement.h"
#include "soci/transaction.h"
#include "soci/type-conversion.h"
#include "soci/type-conversion-traits.h"
#include "soci/type-holder.h"
#include "soci/type-ptr.h"
#include "soci/type-wrappers.h"
#include "soci/use.h"
#include "soci/use-type.h"
#include "soci/values.h"
#include "soci/values-exchange.h"
// namespace boost
#ifdef SOCI_USE_BOOST
#include <boost/version.hpp>
#if defined(BOOST_VERSION) && BOOST_VERSION >= 103500
#include "soci/boost-fusion.h"
#endif // BOOST_VERSION
#include "soci/boost-optional.h"
#include "soci/boost-tuple.h"
#include "soci/boost-gregorian-date.h"
#endif // SOCI_USE_BOOST
// C++17
#ifdef SOCI_HAVE_CXX17
#include "soci/std-optional.h"
#endif // SOCI_HAVE_CXX17
#endif // SOCI_H_INCLUDED

View File

@@ -1,384 +0,0 @@
//
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_SQLITE3_H_INCLUDED
#define SOCI_SQLITE3_H_INCLUDED
#include <soci/soci-platform.h>
#ifdef SOCI_SQLITE3_SOURCE
# define SOCI_SQLITE3_DECL SOCI_DECL_EXPORT
#else
# define SOCI_SQLITE3_DECL SOCI_DECL_IMPORT
#endif
#include <cstdarg>
#include <cstdint>
#include <vector>
#include <soci/soci-backend.h>
#include <private/soci-trivial-blob-backend.h>
// Disable flood of nonsense warnings generated for SQLite
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4510 4512 4610)
#endif
namespace sqlite_api
{
#if SQLITE_VERSION_NUMBER < 3003010
// The sqlite3_destructor_type typedef introduced in 3.3.10
// http://www.sqlite.org/cvstrac/tktview?tn=2191
typedef void (*sqlite3_destructor_type)(void*);
#endif
#include <sqlite3.h>
} // namespace sqlite_api
#undef SQLITE_STATIC
#define SQLITE_STATIC ((sqlite_api::sqlite3_destructor_type)0)
#ifdef _MSC_VER
#pragma warning(pop)
#endif
namespace soci
{
class SOCI_SQLITE3_DECL sqlite3_soci_error : public soci_error
{
public:
sqlite3_soci_error(std::string const & msg, int result);
int result() const;
private:
int result_;
};
struct sqlite3_statement_backend;
struct sqlite3_standard_into_type_backend : details::standard_into_type_backend
{
sqlite3_standard_into_type_backend(sqlite3_statement_backend &st)
: statement_(st), data_(0), type_(), position_(0)
{
}
void define_by_pos(int &position,
void *data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, bool calledFromFetch,
indicator *ind) override;
void clean_up() override;
sqlite3_statement_backend &statement_;
void *data_;
details::exchange_type type_;
int position_;
};
struct sqlite3_vector_into_type_backend : details::vector_into_type_backend
{
sqlite3_vector_into_type_backend(sqlite3_statement_backend &st)
: statement_(st), data_(0), type_(), position_(0)
{
}
void define_by_pos(int& position, void* data, details::exchange_type type) override;
void pre_fetch() override;
void post_fetch(bool gotData, indicator* ind) override;
void resize(std::size_t sz) override;
std::size_t size() override;
void clean_up() override;
sqlite3_statement_backend& statement_;
void *data_;
details::exchange_type type_;
int position_;
};
struct sqlite3_standard_use_type_backend : details::standard_use_type_backend
{
sqlite3_standard_use_type_backend(sqlite3_statement_backend &st);
void bind_by_pos(int &position,
void *data, details::exchange_type type, bool readOnly) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type, bool readOnly) override;
void pre_use(indicator const *ind) override;
void post_use(bool gotData, indicator *ind) override;
void clean_up() override;
sqlite3_statement_backend &statement_;
void *data_; // pointer to used data: soci::use(myvariable) --> data_ = &myvariable
details::exchange_type type_; // type of data_
int position_; // binding position
std::string name_; // binding name
};
struct sqlite3_vector_use_type_backend : details::vector_use_type_backend
{
sqlite3_vector_use_type_backend(sqlite3_statement_backend &st)
: statement_(st), data_(0), type_(), position_(0)
{
}
void bind_by_pos(int &position,
void *data, details::exchange_type type) override;
void bind_by_name(std::string const &name,
void *data, details::exchange_type type) override;
void pre_use(indicator const *ind) override;
std::size_t size() override;
void clean_up() override;
sqlite3_statement_backend &statement_;
void *data_;
details::exchange_type type_;
int position_;
std::string name_;
};
struct sqlite3_column_buffer
{
std::size_t size_;
union
{
const char *constData_;
char *data_;
};
};
struct sqlite3_column
{
bool isNull_;
// DEPRECATED. USE dataType_ INSTEAD.
data_type type_;
db_type dataType_;
union
{
sqlite3_column_buffer buffer_;
int8_t int8_;
uint8_t uint8_;
int16_t int16_;
uint16_t uint16_;
int32_t int32_;
uint32_t uint32_;
sqlite_api::sqlite3_int64 int64_;
sqlite_api::sqlite3_uint64 uint64_;
double double_;
};
};
typedef std::vector<sqlite3_column> sqlite3_row;
typedef std::vector<sqlite3_row> sqlite3_recordset;
struct sqlite3_column_info
{
// DEPRECATED. USE dataType_ INSTEAD.
data_type type_;
db_type dataType_;
std::string name_;
};
typedef std::vector<sqlite3_column_info> sqlite3_column_info_list;
struct sqlite3_session_backend;
struct sqlite3_statement_backend : details::statement_backend
{
sqlite3_statement_backend(sqlite3_session_backend &session);
void alloc() override;
void clean_up() override;
void prepare(std::string const &query,
details::statement_type eType) override;
void reset_if_needed();
void reset();
exec_fetch_result execute(int number) override;
exec_fetch_result fetch(int number) override;
long long get_affected_rows() override;
int get_number_of_rows() override;
std::string get_parameter_name(int index) const override;
std::string rewrite_for_procedure_call(std::string const &query) override;
int prepare_for_describe() override;
void describe_column(int colNum,
db_type &dbtype,
std::string &columnName) override;
sqlite3_standard_into_type_backend * make_into_type_backend() override;
sqlite3_standard_use_type_backend * make_use_type_backend() override;
sqlite3_vector_into_type_backend * make_vector_into_type_backend() override;
sqlite3_vector_use_type_backend * make_vector_use_type_backend() override;
sqlite3_session_backend &session_;
sqlite_api::sqlite3_stmt *stmt_;
sqlite3_recordset dataCache_;
sqlite3_recordset useData_;
bool databaseReady_;
bool boundByName_;
bool boundByPos_;
sqlite3_column_info_list columns_;
bool hasVectorIntoElements_;
long long rowsAffectedBulk_; // number of rows affected by the last bulk operation
private:
exec_fetch_result load_rowset(int totalRows);
exec_fetch_result load_one();
exec_fetch_result bind_and_execute(int number);
};
struct sqlite3_rowid_backend : details::rowid_backend
{
sqlite3_rowid_backend(sqlite3_session_backend &session);
~sqlite3_rowid_backend() override;
unsigned long value_;
};
struct sqlite3_blob_backend : details::trivial_blob_backend
{
sqlite3_blob_backend(sqlite3_session_backend &session);
~sqlite3_blob_backend() override;
void ensure_buffer_initialized();
};
struct sqlite3_session_backend : details::session_backend
{
sqlite3_session_backend(connection_parameters const & parameters);
~sqlite3_session_backend() override;
bool is_connected() override { return true; }
void begin() override;
void commit() override;
void rollback() override;
bool get_last_insert_id(session&, std::string const&, long long&) override;
std::string empty_blob() override
{
return "x\'\'";
}
std::string get_dummy_from_table() const override { return std::string(); }
std::string get_backend_name() const override { return "sqlite3"; }
void clean_up();
sqlite3_statement_backend * make_statement_backend() override;
sqlite3_rowid_backend * make_rowid_backend() override;
sqlite3_blob_backend * make_blob_backend() override;
std::string get_table_names_query() const override
{
return "select name as \"TABLE_NAME\""
" from sqlite_master where type = 'table'";
}
std::string get_column_descriptions_query() const override
{
return "select name as 'COLUMN_NAME',"
" 0 as 'CHARACTER_MAXIMUM_LENGTH',"
" 0 as 'NUMERIC_PRECISION',"
" case when type like '%real%' or type like '%float%' or type like '%double%' then 255 else 0 end as 'NUMERIC_SCALE',"
" case"
" when type like 'text' or type like 'clob' or type like '%char%' then 'text'"
" when type like '%int%' or type like '%number%' or type like '%numeric%' then 'integer'"
" when type like '%real%' or type like '%float%' or type like '%double%' then 'number'"
" else type"
" end as 'DATA_TYPE',"
" case when \"notnull\" = 0 then 'YES' else 'NO' end as 'IS_NULLABLE'"
" from (select name, lower(type) as type, \"notnull\" from pragma_table_info(:t))";
}
std::string create_column_type(db_type dt,
int , int ) override
{
switch (dt)
{
case db_xml:
case db_string:
return "text";
case db_double:
return "real";
case db_date:
return "integer";
case db_int8:
return "tinyint";
case db_uint8:
return "unsignedtinyint";
case db_int16:
return "smallint";
case db_uint16:
return "unsignedsmallint";
case db_int32:
return "integer";
case db_uint32:
return "unsignedint";
case db_int64:
return "bigint";
case db_uint64:
return "unsignedbigint";
case db_blob:
return "blob";
default:
throw soci_error("this db_type is not supported in create_column");
}
}
sqlite_api::sqlite3 *conn_;
// This flag is set to true if the internal sqlite_sequence table exists in
// the database.
bool sequence_table_exists_;
};
struct sqlite3_backend_factory : backend_factory
{
sqlite3_backend_factory() {}
sqlite3_session_backend * make_session(
connection_parameters const & parameters) const override;
};
extern SOCI_SQLITE3_DECL sqlite3_backend_factory const sqlite3;
extern "C"
{
// for dynamic backend loading
SOCI_SQLITE3_DECL backend_factory const * factory_sqlite3();
SOCI_SQLITE3_DECL void register_factory_sqlite3();
} // extern "C"
} // namespace soci
#endif // SOCI_SQLITE3_H_INCLUDED

View File

@@ -1,329 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_STATEMENT_H_INCLUDED
#define SOCI_STATEMENT_H_INCLUDED
#include "soci/bind-values.h"
#include "soci/into-type.h"
#include "soci/into.h"
#include "soci/noreturn.h"
#include "soci/use-type.h"
#include "soci/use.h"
#include "soci/soci-backend.h"
#include "soci/row.h"
#include "soci/blob.h"
// std
#include <cstddef>
#include <string>
#include <vector>
namespace soci
{
class session;
class values;
namespace details
{
class into_type_base;
class use_type_base;
class prepare_temp_type;
class SOCI_DECL statement_impl
{
public:
explicit statement_impl(session & s);
explicit statement_impl(prepare_temp_type const & prep);
~statement_impl();
void alloc();
void bind(values & v);
void exchange(into_type_ptr const & i) { intos_.exchange(i); }
template <typename T, typename Indicator>
void exchange(into_container<T, Indicator> const &ic)
{ intos_.exchange(ic); }
void exchange(use_type_ptr const & u) { uses_.exchange(u); }
template <typename T, typename Indicator>
void exchange(use_container<T, Indicator> const &uc)
{ uses_.exchange(uc); }
void clean_up();
void bind_clean_up();
void prepare(std::string const & query,
statement_type eType = st_repeatable_query);
void define_and_bind();
void undefine_and_bind();
bool execute(bool withDataExchange = false);
long long get_affected_rows();
bool fetch();
void describe();
void set_row(row * r);
void exchange_for_rowset(into_type_ptr const & i) { exchange_for_rowset_(i); }
template<typename T, typename Indicator>
void exchange_for_rowset(into_container<T, Indicator> const &ic)
{ exchange_for_rowset_(ic); }
// for diagnostics and advanced users
// (downcast it to expected back-end statement class)
statement_backend * get_backend() { return backEnd_; }
standard_into_type_backend * make_into_type_backend();
standard_use_type_backend * make_use_type_backend();
vector_into_type_backend * make_vector_into_type_backend();
vector_use_type_backend * make_vector_use_type_backend();
void inc_ref();
void dec_ref();
session & session_;
std::string rewrite_for_procedure_call(std::string const & query);
protected:
into_type_vector intos_;
use_type_vector uses_;
std::vector<indicator *> indicators_;
private:
// Call this method from a catch clause (only!) to rethrow the exception
// after adding the context in which it happened, including the provided
// description of the operation that failed, the SQL query and, if
// applicable, its parameters.
SOCI_NORETURN rethrow_current_exception_with_context(char const* operation);
int refCount_;
row * row_;
std::size_t fetchSize_;
std::size_t initialFetchSize_;
std::string query_;
into_type_vector intosForRow_;
int definePositionForRow_;
template <typename Into>
void exchange_for_rowset_(Into const &i)
{
if (intos_.empty() == false)
{
throw soci_error("Explicit into elements not allowed with rowset.");
}
intos_.exchange(i);
int definePosition = 1;
for(into_type_vector::iterator iter = intos_.begin(),
end = intos_.end();
iter != end; iter++)
{ (*iter)->define(*this, definePosition); }
definePositionForRow_ = definePosition;
}
template <typename T, typename Indicator>
void exchange_for_row(into_container<T, Indicator> const &ic)
{ intosForRow_.exchange(ic); }
void exchange_for_row(into_type_ptr const & i) { intosForRow_.exchange(i); }
void define_for_row();
template<typename T>
void into_row()
{
T * t = new T();
indicator * ind = new indicator(i_ok);
row_->add_holder(t, ind);
exchange_for_row(into(*t, *ind));
}
template<db_type>
void bind_into();
bool alreadyDescribed_;
std::size_t intos_size();
std::size_t uses_size();
void pre_exec(int num);
void pre_fetch();
void pre_use();
void post_fetch(bool gotData, bool calledFromFetch);
void post_use(bool gotData);
bool resize_intos(std::size_t upperBound = 0);
void truncate_intos();
soci::details::statement_backend * backEnd_;
SOCI_NOT_COPYABLE(statement_impl)
};
template<>
void statement_impl::into_row<blob>();
} // namespace details
// Statement is a handle class for statement_impl
// (this provides copyability to otherwise non-copyable type)
class SOCI_DECL statement
{
public:
statement(session & s)
: impl_(new details::statement_impl(s)), gotData_(false) {}
statement(details::prepare_temp_type const & prep)
: impl_(new details::statement_impl(prep)), gotData_(false) {}
~statement() { impl_->dec_ref(); }
// copy is supported for this handle class
statement(statement const & other)
: impl_(other.impl_)
{
impl_->inc_ref();
}
void operator=(statement const & other)
{
other.impl_->inc_ref();
impl_->dec_ref();
impl_ = other.impl_;
gotData_ = other.gotData_;
}
void alloc() { impl_->alloc(); }
void bind(values & v) { impl_->bind(v); }
void exchange(details::into_type_ptr const & i) { impl_->exchange(i); }
template <typename T, typename Indicator>
void exchange(details::into_container<T, Indicator> const &ic) { impl_->exchange(ic); }
void exchange(details::use_type_ptr const & u) { impl_->exchange(u); }
template <typename T, typename Indicator>
void exchange(details::use_container<T, Indicator> const &uc) { impl_->exchange(uc); }
void clean_up() { impl_->clean_up(); }
void bind_clean_up() { impl_->bind_clean_up(); }
void prepare(std::string const & query,
details::statement_type eType = details::st_repeatable_query)
{
impl_->prepare(query, eType);
}
void define_and_bind() { impl_->define_and_bind(); }
void undefine_and_bind() { impl_->undefine_and_bind(); }
bool execute(bool withDataExchange = false)
{
gotData_ = impl_->execute(withDataExchange);
return gotData_;
}
long long get_affected_rows()
{
return impl_->get_affected_rows();
}
bool fetch()
{
gotData_ = impl_->fetch();
return gotData_;
}
bool got_data() const { return gotData_; }
void describe() { impl_->describe(); }
void set_row(row * r) { impl_->set_row(r); }
template <typename T, typename Indicator>
void exchange_for_rowset(details::into_container<T, Indicator> const & ic)
{
impl_->exchange_for_rowset(ic);
}
void exchange_for_rowset(details::into_type_ptr const & i)
{
impl_->exchange_for_rowset(i);
}
// for diagnostics and advanced users
// (downcast it to expected back-end statement class)
details::statement_backend * get_backend()
{
return impl_->get_backend();
}
details::standard_into_type_backend * make_into_type_backend()
{
return impl_->make_into_type_backend();
}
details::standard_use_type_backend * make_use_type_backend()
{
return impl_->make_use_type_backend();
}
details::vector_into_type_backend * make_vector_into_type_backend()
{
return impl_->make_vector_into_type_backend();
}
details::vector_use_type_backend * make_vector_use_type_backend()
{
return impl_->make_vector_use_type_backend();
}
std::string rewrite_for_procedure_call(std::string const & query)
{
return impl_->rewrite_for_procedure_call(query);
}
private:
details::statement_impl * impl_;
bool gotData_;
};
namespace details
{
// exchange_traits for statement
template <>
struct exchange_traits<statement>
{
typedef basic_type_tag type_family;
enum { x_type = x_statement };
};
// into and use types for Statement (for nested statements and cursors)
template <>
class into_type<statement> : public standard_into_type
{
public:
into_type(statement & s) : standard_into_type(&s, x_statement) {}
into_type(statement & s, indicator & ind)
: standard_into_type(&s, x_statement, ind) {}
};
template <>
class use_type<statement> : public standard_use_type
{
public:
use_type(statement & s, std::string const & name = std::string())
: standard_use_type(&s, x_statement, false, name) {}
use_type(statement & s, indicator & ind,
std::string const & name = std::string())
: standard_use_type(&s, x_statement, ind, false, name) {}
// Note: there is no const version of use for statement,
// because most likely it would not make much sense anyway.
};
} // namespace details
} // namespace soci
#endif // SOCI_STATEMENT_H_INCLUDED

View File

@@ -1,55 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_STD_OPTIONAL_H_INCLUDED
#define SOCI_STD_OPTIONAL_H_INCLUDED
#include "soci/type-conversion-traits.h"
#include <optional>
namespace soci
{
// simple fall-back for std::optional
template <typename T>
struct type_conversion<std::optional<T> >
{
typedef typename type_conversion<T>::base_type base_type;
static void from_base(base_type const & in, indicator ind,
std::optional<T> & out)
{
if (ind == i_null)
{
out.reset();
}
else
{
T tmp = T();
type_conversion<T>::from_base(in, ind, tmp);
out = tmp;
}
}
static void to_base(std::optional<T> const & in,
base_type & out, indicator & ind)
{
if (in)
{
type_conversion<T>::to_base(*in, out, ind);
}
else
{
ind = i_null;
}
}
};
} // namespace soci
#endif // SOCI_STD_OPTIONAL_H_INCLUDED

View File

@@ -1,36 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_TRANSACTION_H_INCLUDED
#define SOCI_TRANSACTION_H_INCLUDED
#include "soci/soci-platform.h"
#include "soci/session.h"
namespace soci
{
class SOCI_DECL transaction
{
public:
explicit transaction(session& sql);
~transaction();
void commit();
void rollback();
private:
bool handled_;
session& sql_;
SOCI_NOT_COPYABLE(transaction)
};
} // namespace soci
#endif // SOCI_TRANSACTION_H_INCLUDED

View File

@@ -1,149 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_TYPE_CONVERSION_TRAITS_H_INCLUDED
#define SOCI_TYPE_CONVERSION_TRAITS_H_INCLUDED
#include "soci/soci-backend.h"
#include "soci/is-detected.h"
#include <type_traits>
namespace soci
{
// default traits class type_conversion, acts as pass through for row::get() or row::move_as()
// when no actual conversion is needed.
template <typename T, typename Enable = void>
struct type_conversion
{
typedef T base_type;
struct from_base_check : std::integral_constant<bool, std::is_constructible<T, const base_type>::value> {};
static void from_base(base_type const& in, indicator ind, T & out)
{
static_assert(from_base_check::value,
"from_base can only be used if the target type can be constructed from an lvalue base reference");
assert_non_null(ind);
out = in;
}
struct move_from_base_check :
std::integral_constant<bool,
!std::is_const<base_type>::value
&& std::is_constructible<T, typename std::add_rvalue_reference<base_type>::type>::value
> {};
static void move_from_base(base_type & in, indicator ind, T & out)
{
static_assert(move_from_base_check::value,
"move_to_base can only be used if the target type can be constructed from an rvalue base reference");
assert_non_null(ind);
out = std::move(in);
}
static void to_base(T const & in, base_type & out, indicator & ind)
{
out = in;
ind = i_ok;
}
static void move_to_base(T & in, base_type & out, indicator & ind)
{
out = std::move(in);
ind = i_ok;
}
private:
static void assert_non_null(indicator ind)
{
if (ind == i_null)
{
throw soci_error("Null value not allowed for this type");
}
}
};
namespace details
{
#if !defined(_MSC_VER) || (_MSC_VER >= 1910)
// MSVC 2015 and earlier don't support SFINAE on return types
#define SOCI_HAS_RET_TYPE_SFINAE
#endif
template<typename T>
using from_base_check_t = decltype(T::from_base_check::value);
template<typename T>
using move_from_base_check_t = decltype(T::move_from_base_check::value);
template<typename T>
using supports_from_base_check = is_detected<from_base_check_t, T>;
template<typename T>
using supports_move_from_base_check = is_detected<move_from_base_check_t, T>;
#ifdef SOCI_HAS_RET_TYPE_SFINAE
template<typename Trait>
constexpr auto can_use_from_base()
-> typename std::enable_if<supports_from_base_check<Trait>::value, bool>::type
{
return Trait::from_base_check::value;
}
template<typename Trait>
constexpr auto can_use_from_base()
-> typename std::enable_if<!supports_from_base_check<Trait>::value, bool>::type
{
return true;
}
template<typename Trait>
constexpr auto can_use_move_from_base()
-> typename std::enable_if<supports_move_from_base_check<Trait>::value, bool>::type
{
return Trait::from_base_check::value;
}
template<typename Trait>
constexpr auto can_use_move_from_base()
-> typename std::enable_if<!supports_move_from_base_check<Trait>::value, bool>::type
{
// Default to assuming that the special move_from_base function is not implemented
// TODO: Find clever template magic to add a metaprogramming check for a suitable
// move_from_base implementation
return false;
}
#undef SOCI_HAS_RET_TYPE_SFINAE
#else
// Always return true - if it doesn't work the user will get a cryptic compiler error but at least
// it will compile properly for cases in which things do indeed work
template<typename Trait>
constexpr auto can_use_from_base()
{
return true;
}
template<typename Trait>
constexpr auto can_use_move_from_base()
{
return true;
}
#endif
}
} // namespace soci
#endif // SOCI_TYPE_CONVERSION_TRAITS_H_INCLUDED

View File

@@ -1,509 +0,0 @@
//
// Copyright (C) 2004-2016 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_TYPE_CONVERSION_H_INCLUDED
#define SOCI_TYPE_CONVERSION_H_INCLUDED
#include "soci/type-conversion-traits.h"
#include "soci/into-type.h"
#include "soci/use-type.h"
// std
#include <cstddef>
#include <string>
#include <vector>
namespace soci
{
namespace details
{
// this class is used to ensure correct order of construction
// of into_type and use_type elements that use type_conversion
template <typename T>
struct base_value_holder
{
base_value_holder()
: ownInd_(i_ok)
{}
typename type_conversion<T>::base_type val_;
indicator ownInd_;
};
// Automatically create into_type from a type_conversion
template <typename T>
class conversion_into_type
: private base_value_holder<T>,
public into_type<typename type_conversion<T>::base_type>
{
public:
typedef typename type_conversion<T>::base_type base_type;
conversion_into_type(T & value)
: into_type<base_type>(base_value_holder<T>::val_, base_value_holder<T>::ownInd_)
, value_(value)
, ind_(base_value_holder<T>::ownInd_)
{
}
conversion_into_type(T & value, indicator & ind)
: into_type<base_type>(base_value_holder<T>::val_, ind)
, value_(value)
, ind_(ind)
{
}
private:
void convert_from_base() override
{
type_conversion<T>::from_base(
base_value_holder<T>::val_, ind_, value_);
}
T & value_;
// ind_ refers to either ownInd_, or the one provided by the user
// in any case, ind_ refers to some valid indicator
// and can be used by conversion routines
indicator & ind_;
SOCI_NOT_COPYABLE(conversion_into_type)
};
// Automatically create use_type from a type_conversion
template <typename T>
class conversion_use_type
: private base_value_holder<T>,
public use_type<typename type_conversion<T>::base_type>
{
public:
typedef typename type_conversion<T>::base_type base_type;
conversion_use_type(T & value, std::string const & name = std::string())
: use_type<base_type>(base_value_holder<T>::val_, base_value_holder<T>::ownInd_, name)
, value_(value)
, ind_(base_value_holder<T>::ownInd_)
, readOnly_(false)
{
// TODO: likely to be removed (SHA: c166625a28f7c907318134f625ff5acea7d9a1f8)
//convert_to_base();
}
conversion_use_type(T const & value, std::string const & name = std::string())
: use_type<base_type>(base_value_holder<T>::val_, base_value_holder<T>::ownInd_, name)
, value_(const_cast<T &>(value))
, ind_(base_value_holder<T>::ownInd_)
, readOnly_(true)
{
// TODO: likely to be removed (SHA: c166625a28f7c907318134f625ff5acea7d9a1f8)
//convert_to_base();
}
conversion_use_type(T & value, indicator & ind,
std::string const & name = std::string())
: use_type<base_type>(base_value_holder<T>::val_, ind, name)
, value_(value)
, ind_(ind)
, readOnly_(false)
{
// TODO: likely to be removed (SHA: c166625a28f7c907318134f625ff5acea7d9a1f8)
//convert_to_base();
}
conversion_use_type(T const & value, indicator & ind,
std::string const & name = std::string())
: use_type<base_type>(base_value_holder<T>::val_, ind, name)
, value_(const_cast<T &>(value))
, ind_(ind)
, readOnly_(true)
{
// TODO: likely to be removed (SHA: c166625a28f7c907318134f625ff5acea7d9a1f8)
//convert_to_base();
}
void convert_from_base() override
{
// NOTE:
// readOnly_ flag indicates that use_type object has been generated
// based on non-const object passed by user as input argument.
// For const objects, this is effectively no-op conversion.
// See standard_use_type::post_use() for more details.
if (readOnly_ == false)
{
type_conversion<T>::from_base(
base_value_holder<T>::val_, ind_, value_);
}
}
void convert_to_base() override
{
if (ind_ == i_null)
{
// A null indicator was explicitly passed to use(val, ind).
// Therefore, NULL should be put into the database, and there is
// normally no reason to convert the value.
//
// However, if ind_ were ownInd_ itself, and if a prepared statement
// were repeatedly executed, we still need to do it in order to
// give the custom conversion a chance to update the indicator
// based on the actual value being used.
if (&ind_ != &(base_value_holder<T>::ownInd_))
{
// We really have nothing to do here, notably do not call the
// custom conversion which could overwrite the explicit i_null
// specified by the caller.
return;
}
}
type_conversion<T>::to_base(value_,
base_value_holder<T>::val_, ind_);
}
private:
T & value_;
// ind_ refers to either ownInd_, or the one provided by the user
// in any case, ind_ refers to some valid indicator
// and can be used by conversion routines
indicator & ind_;
const bool readOnly_;
SOCI_NOT_COPYABLE(conversion_use_type)
};
// this class is used to ensure correct order of construction
// of vector based into_type and use_type elements that use type_conversion
template <typename T>
struct base_vector_holder
{
base_vector_holder(std::size_t sz = 0) : vec_(sz) {}
mutable std::vector<typename type_conversion<T>::base_type> vec_;
};
// Automatically create a std::vector based into_type from a type_conversion
template <typename T>
class conversion_into_type<std::vector<T> >
: private base_vector_holder<T>,
public into_type<std::vector<typename type_conversion<T>::base_type> >
{
public:
typedef typename std::vector
<
typename type_conversion<T>::base_type
> base_type;
conversion_into_type(std::vector<T> & value,
std::size_t begin = 0, std::size_t * end = NULL)
: base_vector_holder<T>(value.size()),
into_type<base_type>(
base_vector_holder<T>::vec_, ownInd_, begin, end),
value_(value),
ownInd_(),
ind_(ownInd_),
begin_(begin),
end_(end)
{
user_ranges_ = end != NULL;
}
conversion_into_type(std::vector<T> & value, std::vector<indicator> & ind,
std::size_t begin = 0, std::size_t * end = NULL)
: base_vector_holder<T>(value.size()),
into_type<base_type>(
base_vector_holder<T>::vec_, ind, begin, end),
value_(value),
ind_(ind),
begin_(begin),
end_(end)
{
user_ranges_ = end != NULL;
}
std::size_t size() const override
{
// the user might have resized his vector in the meantime
// -> synchronize the base-value mirror to have the same size
std::size_t const userSize = value_.size();
base_vector_holder<T>::vec_.resize(userSize);
return into_type<base_type>::size();
}
void resize(std::size_t sz) override
{
into_type<base_type>::resize(sz);
std::size_t actual_size = base_vector_holder<T>::vec_.size();
value_.resize(actual_size);
ind_.resize(actual_size);
}
private:
void convert_from_base() override
{
if (user_ranges_)
{
for (std::size_t i = begin_; i != *end_; ++i)
{
type_conversion<T>::from_base(
base_vector_holder<T>::vec_[i], ind_[i], value_[i]);
}
}
else
{
std::size_t const sz = base_vector_holder<T>::vec_.size();
for (std::size_t i = 0; i != sz; ++i)
{
type_conversion<T>::from_base(
base_vector_holder<T>::vec_[i], ind_[i], value_[i]);
}
}
}
std::vector<T> & value_;
std::vector<indicator> ownInd_;
// ind_ refers to either ownInd_, or the one provided by the user
// in any case, ind_ refers to some valid vector of indicators
// and can be used by conversion routines
std::vector<indicator> & ind_;
std::size_t begin_;
std::size_t * end_;
bool user_ranges_;
SOCI_NOT_COPYABLE(conversion_into_type)
};
// Automatically create a std::vector based use_type from a type_conversion
template <typename T>
class conversion_use_type<std::vector<T> >
: private base_vector_holder<T>,
public use_type<std::vector<typename type_conversion<T>::base_type> >
{
public:
typedef typename std::vector
<
typename type_conversion<T>::base_type
> base_type;
conversion_use_type(const std::vector<T> & value,
std::string const & name=std::string())
: base_vector_holder<T>(value.size()),
use_type<base_type>(
base_vector_holder<T>::vec_, ownInd_, 0, NULL, name),
value_(value),
ownInd_(),
ind_(ownInd_),
begin_(0),
end_(NULL),
user_ranges_(false)
{
}
conversion_use_type(const std::vector<T> & value,
std::size_t begin, std::size_t * end,
std::string const & name=std::string())
: base_vector_holder<T>(value.size()),
use_type<base_type>(
base_vector_holder<T>::vec_, ownInd_, begin, end, name),
value_(value),
ownInd_(),
ind_(ownInd_),
begin_(begin),
end_(end)
{
user_ranges_ = end != NULL;
}
conversion_use_type(const std::vector<T> & value,
std::vector<indicator> & ind,
std::string const & name = std::string())
: base_vector_holder<T>(value.size()),
use_type<base_type>(
base_vector_holder<T>::vec_, ind, 0, NULL, name),
value_(value),
ind_(ind),
begin_(0),
end_(NULL),
user_ranges_(false)
{
}
conversion_use_type(const std::vector<T> & value,
std::vector<indicator> & ind,
std::size_t begin, std::size_t * end,
std::string const & name = std::string())
: base_vector_holder<T>(value.size()),
use_type<base_type>(
base_vector_holder<T>::vec_, ind, begin, end, name),
value_(value),
ind_(ind),
begin_(begin),
end_(end)
{
user_ranges_ = end != NULL;
}
private:
void convert_to_base() override
{
std::size_t const sz = value_.size();
base_vector_holder<T>::vec_.resize(sz);
ind_.resize(sz);
if (user_ranges_)
{
for (std::size_t i = begin_; i != *end_; ++i)
{
type_conversion<T>::to_base(value_[i],
base_vector_holder<T>::vec_[i], ind_[i]);
}
}
else
{
for (std::size_t i = 0; i != sz; ++i)
{
type_conversion<T>::to_base(value_[i],
base_vector_holder<T>::vec_[i], ind_[i]);
}
}
}
const std::vector<T> & value_;
std::vector<indicator> ownInd_;
// ind_ refers to either ownInd_, or the one provided by the user
// in any case, ind_ refers to some valid vector of indicators
// and can be used by conversion routines
std::vector<indicator> & ind_;
std::size_t begin_;
std::size_t * end_;
bool user_ranges_;
SOCI_NOT_COPYABLE(conversion_use_type)
};
template <typename T>
into_type_ptr do_into(T & t, user_type_tag)
{
return into_type_ptr(new conversion_into_type<T>(t));
}
template <typename T>
into_type_ptr do_into(T & t, indicator & ind, user_type_tag)
{
return into_type_ptr(new conversion_into_type<T>(t, ind));
}
template <typename T>
into_type_ptr do_into(std::vector<T> & t,
std::size_t begin, size_t * end, user_type_tag)
{
return into_type_ptr(
new conversion_into_type<std::vector<T> >(t, begin, end));
}
template <typename T>
into_type_ptr do_into(std::vector<T> & t, std::vector<indicator> & ind,
user_type_tag)
{
return into_type_ptr(new conversion_into_type<std::vector<T> >(t, ind));
}
template <typename T>
into_type_ptr do_into(std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, size_t * end, user_type_tag)
{
return into_type_ptr(
new conversion_into_type<std::vector<T> >(t, ind, begin, end));
}
template <typename T>
use_type_ptr do_use(T & t, std::string const & name, user_type_tag)
{
return use_type_ptr(new conversion_use_type<T>(t, name));
}
template <typename T>
use_type_ptr do_use(T const & t, std::string const & name, user_type_tag)
{
return use_type_ptr(new conversion_use_type<T>(t, name));
}
template <typename T>
use_type_ptr do_use(T & t, indicator & ind,
std::string const & name, user_type_tag)
{
return use_type_ptr(new conversion_use_type<T>(t, ind, name));
}
template <typename T>
use_type_ptr do_use(T const & t, indicator & ind,
std::string const & name, user_type_tag)
{
return use_type_ptr(new conversion_use_type<T>(t, ind, name));
}
template <typename T>
use_type_ptr do_use(std::vector<T> & t,
std::size_t begin, size_t * end,
std::string const & name, user_type_tag)
{
return use_type_ptr(
new conversion_use_type<std::vector<T> >(t, begin, end, name));
}
template <typename T>
use_type_ptr do_use(const std::vector<T> & t,
std::size_t begin, size_t * end,
std::string const & name, user_type_tag)
{
return use_type_ptr(
new conversion_use_type<std::vector<T> >(t, begin, end, name));
}
template <typename T>
use_type_ptr do_use(std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, size_t * end,
std::string const & name, user_type_tag)
{
return use_type_ptr(
new conversion_use_type<std::vector<T> >(t, ind, begin, end, name));
}
template <typename T>
use_type_ptr do_use(const std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, size_t * end,
std::string const & name, user_type_tag)
{
return use_type_ptr(
new conversion_use_type<std::vector<T> >(t, ind, begin, end, name));
}
} // namespace details
} // namespace soci
#endif // SOCI_TYPE_CONVERSION_H_INCLUDED

View File

@@ -1,449 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_TYPE_HOLDER_H_INCLUDED
#define SOCI_TYPE_HOLDER_H_INCLUDED
#include "soci/blob.h"
#include "soci/error.h"
#include "soci/soci-backend.h"
#include "soci/soci-types.h"
#include <cstdint>
#include <ctime>
#include <limits>
#include <sstream>
#include <type_traits>
#include <typeinfo>
namespace soci
{
namespace details
{
// Returns U* as T*, if the dynamic type of the pointer is really T.
//
// This should be used instead of dynamic_cast<> because using it doesn't work
// when using libc++ and ELF visibility together. Luckily, when we don't need
// the full power of the cast, but only need to check if the types are the
// same, it can be done by comparing their type info objects.
//
// This function does _not_ replace dynamic_cast<> in all cases and notably
// doesn't allow the input pointer to be null.
template <typename T, typename U>
T* checked_ptr_cast(U* ptr)
{
// Check if they're identical first, as an optimization, and then compare
// their names to make it actually work with libc++.
std::type_info const& ti_ptr = typeid(*ptr);
std::type_info const& ti_ret = typeid(T);
if (&ti_ptr != &ti_ret && std::strcmp(ti_ptr.name(), ti_ret.name()) != 0)
{
return NULL;
}
return static_cast<T*>(ptr);
}
template <typename T, typename U, typename Enable = void>
struct soci_return_same
{
static inline T& value(U&)
{
throw std::bad_cast();
}
};
template <typename T, typename U>
struct soci_return_same<
T, U,
typename std::enable_if<std::is_same<T, U>::value>::type>
{
static inline T& value(U& val)
{
return val;
}
};
// Type safe conversion that throws if the types are mismatched
template <typename T, typename U, typename Enable = void>
struct soci_cast
{
static inline T cast(U)
{
throw std::bad_cast();
}
};
// Type safe conversion that is a noop
template <typename T, typename U>
struct soci_cast<
T, U,
typename std::enable_if<std::is_same<T, U>::value>::type>
{
static inline T cast(U val)
{
return val;
}
};
// Type safe conversion that is widening the type
template <typename T, typename U>
struct soci_cast<
T, U,
typename std::enable_if<(
!std::is_same<T, U>::value &&
std::is_integral<T>::value &&
std::is_integral<U>::value
)>::type>
{
static inline T cast(U val) {
intmax_t t_min = static_cast<intmax_t>((std::numeric_limits<T>::min)());
intmax_t u_min = static_cast<intmax_t>((std::numeric_limits<U>::min)());
uintmax_t t_max = static_cast<uintmax_t>((std::numeric_limits<T>::max)());
uintmax_t u_max = static_cast<uintmax_t>((std::numeric_limits<U>::max)());
#ifdef _MSC_VER
// As long as we don't require C++17, we must disable the warning
// "conditional expression is constant" as it can give false positives here.
#pragma warning(push)
#pragma warning(disable:4127)
#endif
if ((t_min > u_min && val < static_cast<U>(t_min)) ||
(t_max < u_max && val > static_cast<U>(t_max)))
{
throw std::bad_cast();
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
return static_cast<T>(val);
}
};
union type_holder
{
std::string* s;
int8_t* i8;
int16_t* i16;
int32_t* i32;
int64_t* i64;
uint8_t* u8;
uint16_t* u16;
uint32_t* u32;
uint64_t* u64;
double* d;
std::tm* t;
blob* b;
};
template <typename T>
struct type_holder_trait;
template <>
struct type_holder_trait<std::string>
{
static const db_type type = db_string;
};
template <>
struct type_holder_trait<int8_t>
{
static const db_type type = db_int8;
};
template <>
struct type_holder_trait<int16_t>
{
static const db_type type = db_int16;
};
template <>
struct type_holder_trait<int32_t>
{
static const db_type type = db_int32;
};
template <>
struct type_holder_trait<int64_t>
{
static const db_type type = db_int64;
};
template <>
struct type_holder_trait<uint8_t>
{
static const db_type type = db_uint8;
};
template <>
struct type_holder_trait<uint16_t>
{
static const db_type type = db_uint16;
};
template <>
struct type_holder_trait<uint32_t>
{
static const db_type type = db_uint32;
};
template <>
struct type_holder_trait<uint64_t>
{
static const db_type type = db_uint64;
};
#if defined(SOCI_INT64_IS_LONG)
template <>
struct type_holder_trait<long long> : type_holder_trait<int64_t>
{
};
template <>
struct type_holder_trait<unsigned long long> : type_holder_trait<uint64_t>
{
};
#elif defined(SOCI_LONG_IS_64_BIT)
template <>
struct type_holder_trait<long> : type_holder_trait<int64_t>
{
};
template <>
struct type_holder_trait<unsigned long> : type_holder_trait<uint64_t>
{
};
#else
template <>
struct type_holder_trait<long> : type_holder_trait<int32_t>
{
};
template <>
struct type_holder_trait<unsigned long> : type_holder_trait<uint32_t>
{
};
#endif
template <>
struct type_holder_trait<double>
{
static const db_type type = db_double;
};
template <>
struct type_holder_trait<std::tm>
{
static const db_type type = db_date;
};
template <>
struct type_holder_trait<blob>
{
static const db_type type = db_blob;
};
struct value_cast_tag{};
struct value_reference_tag{};
// Class for storing type data instances in a container of holder objects
class holder
{
public:
template <typename T>
static holder* make_holder(T* val)
{
return new holder(type_holder_trait<T>::type, val);
}
~holder()
{
switch (dt_)
{
case db_double:
delete val_.d;
break;
case db_int8:
delete val_.i8;
break;
case db_int16:
delete val_.i16;
break;
case db_int32:
delete val_.i32;
break;
case db_int64:
delete val_.i64;
break;
case db_uint8:
delete val_.u8;
break;
case db_uint16:
delete val_.u16;
break;
case db_uint32:
delete val_.u32;
break;
case db_uint64:
delete val_.u64;
break;
case db_date:
delete val_.t;
break;
case db_blob:
delete val_.b;
break;
case db_xml:
case db_string:
delete val_.s;
break;
}
}
#ifdef _MSC_VER
// MSVC complains about "unreachable code" even though all
// code here can be reached.
#pragma warning(push)
#pragma warning(disable:4702)
#endif
template <typename T>
T get(value_cast_tag)
{
switch (dt_)
{
case db_int8:
return soci_cast<T, int8_t>::cast(*val_.i8);
case db_int16:
return soci_cast<T, int16_t>::cast(*val_.i16);
case db_int32:
return soci_cast<T, int32_t>::cast(*val_.i32);
case db_int64:
return soci_cast<T, int64_t>::cast(*val_.i64);
case db_uint8:
return soci_cast<T, uint8_t>::cast(*val_.u8);
case db_uint16:
return soci_cast<T, uint16_t>::cast(*val_.u16);
case db_uint32:
return soci_cast<T, uint32_t>::cast(*val_.u32);
case db_uint64:
return soci_cast<T, uint64_t>::cast(*val_.u64);
case db_double:
return soci_cast<T, double>::cast(*val_.d);
case db_date:
return soci_cast<T, std::tm>::cast(*val_.t);
case db_blob:
// blob is not copyable
break;
case db_xml:
case db_string:
return soci_cast<T, std::string>::cast(*val_.s);
}
throw std::bad_cast();
}
template <typename T>
T& get(value_reference_tag)
{
switch (dt_)
{
case db_int8:
return soci_return_same<T, int8_t>::value(*val_.i8);
case db_int16:
return soci_return_same<T, int16_t>::value(*val_.i16);
case db_int32:
return soci_return_same<T, int32_t>::value(*val_.i32);
case db_int64:
return soci_return_same<T, int64_t>::value(*val_.i64);
case db_uint8:
return soci_return_same<T, uint8_t>::value(*val_.u8);
case db_uint16:
return soci_return_same<T, uint16_t>::value(*val_.u16);
case db_uint32:
return soci_return_same<T, uint32_t>::value(*val_.u32);
case db_uint64:
return soci_return_same<T, uint64_t>::value(*val_.u64);
case db_double:
return soci_return_same<T, double>::value(*val_.d);
case db_date:
return soci_return_same<T, std::tm>::value(*val_.t);
case db_blob:
return soci_return_same<T, blob>::value(*val_.b);
case db_xml:
case db_string:
return soci_return_same<T, std::string>::value(*val_.s);
}
throw std::bad_cast();
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
private:
holder(db_type dt, void* val) : dt_(dt)
{
switch (dt_)
{
case db_double:
val_.d = static_cast<double*>(val);
return;
case db_int8:
val_.i8 = static_cast<int8_t*>(val);
return;
case db_int16:
val_.i16 = static_cast<int16_t*>(val);
return;
case db_int32:
val_.i32 = static_cast<int32_t*>(val);
return;
case db_int64:
val_.i64 = static_cast<int64_t*>(val);
return;
case db_uint8:
val_.u8 = static_cast<uint8_t*>(val);
return;
case db_uint16:
val_.u16 = static_cast<uint16_t*>(val);
return;
case db_uint32:
val_.u32 = static_cast<uint32_t*>(val);
return;
case db_uint64:
val_.u64 = static_cast<uint64_t*>(val);
return;
case db_date:
val_.t = static_cast<std::tm*>(val);
return;
case db_blob:
val_.b = static_cast<blob*>(val);
return;
case db_xml:
case db_string:
val_.s = static_cast<std::string*>(val);
return;
}
// This should be unreachable
std::ostringstream ss;
ss << "Created holder with unsupported type " << std::to_string(dt);
throw soci_error(ss.str());
}
const db_type dt_;
type_holder val_;
};
} // namespace details
} // namespace soci
#endif // SOCI_TYPE_HOLDER_H_INCLUDED

View File

@@ -1,30 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_TYPE_PTR_H_INCLUDED
#define SOCI_TYPE_PTR_H_INCLUDED
namespace soci { namespace details {
template <typename T>
class type_ptr
{
public:
type_ptr(T * p) : p_(p) {}
~type_ptr() { delete p_; }
T * get() const { return p_; }
void release() const { p_ = 0; }
private:
mutable T * p_;
};
} // namespace details
} // namespace soci
#endif // SOCI_TYPE_PTR_H_INCLUDED

View File

@@ -1,33 +0,0 @@
//
// Copyright (C) 2016 Maciej Sobczak
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_TYPE_WRAPPERS_H_INCLUDED
#define SOCI_TYPE_WRAPPERS_H_INCLUDED
namespace soci
{
// These wrapper types can be used by the application
// with 'into' and 'use' elements in order to guide the library
// in selecting specialized methods for binding and transferring data;
// if the target database does not provide any such specialized methods,
// it is expected to handle these wrappers as equivalent
// to their contained field types.
struct xml_type
{
std::string value;
};
struct long_string
{
std::string value;
};
} // namespace soci
#endif // SOCI_TYPE_WRAPPERS_H_INCLUDED

View File

@@ -1,340 +0,0 @@
//
// Copyright (C) 2004-2016 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_USE_TYPE_H_INCLUDED
#define SOCI_USE_TYPE_H_INCLUDED
#include "soci/soci-platform.h"
#include "soci/soci-backend.h"
#include "soci/type-ptr.h"
#include "soci/exchange-traits.h"
// std
#include <cstddef>
#include <ostream>
#include <string>
#include <vector>
namespace soci { namespace details {
class statement_impl;
// this is intended to be a base class for all classes that deal with
// binding input data (and OUT PL/SQL variables)
class SOCI_DECL use_type_base
{
public:
virtual ~use_type_base() {}
virtual void bind(statement_impl & st, int & position) = 0;
virtual std::string get_name() const = 0;
virtual void dump_value(std::ostream& os) const = 0;
virtual void pre_exec(int num) = 0;
virtual void pre_use() = 0;
virtual void post_use(bool gotData) = 0;
virtual void clean_up() = 0;
virtual std::size_t size() const = 0; // returns the number of elements
};
typedef type_ptr<use_type_base> use_type_ptr;
class SOCI_DECL standard_use_type : public use_type_base
{
public:
standard_use_type(void* data, exchange_type type,
bool readOnly, std::string const& name = std::string())
: data_(data)
, type_(type)
, ind_(NULL)
, readOnly_(readOnly)
, name_(name)
, backEnd_(NULL)
{
// FIXME: This was added with Ilia's patch
// https://github.com/SOCI/soci/commit/c166625a28f7c907318134f625ff5acea7d9a1f8
// but it seems to be a troublemaker, causing duplicated conversions
//convert_to_base();
}
standard_use_type(void* data, exchange_type type, indicator& ind,
bool readOnly, std::string const& name = std::string())
: data_(data)
, type_(type)
, ind_(&ind)
, readOnly_(readOnly)
, name_(name)
, backEnd_(NULL)
{
// FIXME
//convert_to_base();
}
~standard_use_type() override;
void bind(statement_impl & st, int & position) override;
std::string get_name() const override { return name_; }
void dump_value(std::ostream& os) const override;
virtual void * get_data() { return data_; }
// conversion hook (from arbitrary user type to base type)
virtual void convert_to_base() {}
virtual void convert_from_base() {}
protected:
void pre_use() override;
private:
void pre_exec(int num) override;
void post_use(bool gotData) override;
void clean_up() override;
std::size_t size() const override { return 1; }
void* data_;
exchange_type type_;
indicator* ind_;
bool readOnly_;
std::string name_;
standard_use_type_backend* backEnd_;
};
class SOCI_DECL vector_use_type : public use_type_base
{
public:
vector_use_type(void* data, exchange_type type,
std::string const& name = std::string())
: data_(data)
, type_(type)
, ind_(NULL)
, begin_(0)
, end_(NULL)
, name_(name)
, backEnd_(NULL)
{}
vector_use_type(void* data, exchange_type type,
std::size_t begin, std::size_t * end,
std::string const& name = std::string())
: data_(data)
, type_(type)
, ind_(NULL)
, begin_(begin)
, end_(end)
, name_(name)
, backEnd_(NULL)
{}
vector_use_type(void* data, exchange_type type,
std::vector<indicator> const& ind,
std::string const& name = std::string())
: data_(data)
, type_(type)
, ind_(&ind)
, begin_(0)
, end_(NULL)
, name_(name)
, backEnd_(NULL)
{}
vector_use_type(void* data, exchange_type type,
std::vector<indicator> const& ind,
std::size_t begin, std::size_t * end,
std::string const& name = std::string())
: data_(data)
, type_(type)
, ind_(&ind)
, begin_(begin)
, end_(end)
, name_(name)
, backEnd_(NULL)
{}
~vector_use_type() override;
private:
void bind(statement_impl& st, int & position) override;
std::string get_name() const override { return name_; }
void dump_value(std::ostream& os) const override;
void pre_exec(int num) override;
void pre_use() override;
void post_use(bool) override { /* nothing to do */ }
void clean_up() override;
std::size_t size() const override;
void* data_;
exchange_type type_;
std::vector<indicator> const* ind_;
std::size_t begin_;
std::size_t * end_;
std::string name_;
vector_use_type_backend * backEnd_;
virtual void convert_to_base() {}
};
// implementation for the basic types (those which are supported by the library
// out of the box without user-provided conversions)
template <typename T>
class use_type : public standard_use_type
{
public:
use_type(T& t, std::string const& name = std::string())
: standard_use_type(&t,
static_cast<exchange_type>(exchange_traits<T>::x_type), false, name)
{}
use_type(T const& t, std::string const& name = std::string())
: standard_use_type(const_cast<T*>(&t),
static_cast<exchange_type>(exchange_traits<T>::x_type), true, name)
{}
use_type(T& t, indicator& ind, std::string const& name = std::string())
: standard_use_type(&t,
static_cast<exchange_type>(exchange_traits<T>::x_type), ind, false, name)
{}
use_type(T const& t, indicator& ind, std::string const& name = std::string())
: standard_use_type(const_cast<T*>(&t),
static_cast<exchange_type>(exchange_traits<T>::x_type), ind, true, name)
{}
};
template <typename T>
class use_type<std::vector<T> > : public vector_use_type
{
public:
use_type(std::vector<T>& v, std::string const& name = std::string())
: vector_use_type(&v,
static_cast<exchange_type>(exchange_traits<T>::x_type), name)
{}
use_type(std::vector<T>& v, std::size_t begin, std::size_t * end,
std::string const& name = std::string())
: vector_use_type(&v,
static_cast<exchange_type>(exchange_traits<T>::x_type), begin, end, name)
{}
use_type(std::vector<T> const& v, std::string const& name = std::string())
: vector_use_type(const_cast<std::vector<T>*>(&v),
static_cast<exchange_type>(exchange_traits<T>::x_type), name)
{}
use_type(std::vector<T> const& v, std::size_t begin, std::size_t * end,
std::string const& name = std::string())
: vector_use_type(const_cast<std::vector<T>*>(&v),
static_cast<exchange_type>(exchange_traits<T>::x_type), begin, end, name)
{}
use_type(std::vector<T>& v, std::vector<indicator> const& ind,
std::string const& name = std::string())
: vector_use_type(&v,
static_cast<exchange_type>(exchange_traits<T>::x_type), ind, name)
{}
use_type(std::vector<T>& v, std::vector<indicator> const& ind,
std::size_t begin, std::size_t * end, std::string const& name = std::string())
: vector_use_type(&v,
static_cast<exchange_type>(exchange_traits<T>::x_type), ind, begin, end, name)
{}
use_type(std::vector<T> const& v, std::vector<indicator> const& ind,
std::string const& name = std::string())
: vector_use_type(const_cast<std::vector<T> *>(&v),
static_cast<exchange_type>(exchange_traits<T>::x_type), ind, name)
{}
use_type(std::vector<T> const& v, std::vector<indicator> const& ind,
std::size_t begin, std::size_t * end, std::string const& name = std::string())
: vector_use_type(const_cast<std::vector<T> *>(&v),
static_cast<exchange_type>(exchange_traits<T>::x_type), ind, begin, end, name)
{}
};
// helper dispatchers for basic types
template <typename T>
use_type_ptr do_use(T & t, std::string const & name, basic_type_tag)
{
return use_type_ptr(new use_type<T>(t, name));
}
template <typename T>
use_type_ptr do_use(T const & t, std::string const & name, basic_type_tag)
{
return use_type_ptr(new use_type<T>(t, name));
}
template <typename T>
use_type_ptr do_use(T & t, indicator & ind,
std::string const & name, basic_type_tag)
{
return use_type_ptr(new use_type<T>(t, ind, name));
}
template <typename T>
use_type_ptr do_use(T const & t, indicator & ind,
std::string const & name, basic_type_tag)
{
return use_type_ptr(new use_type<T>(t, ind, name));
}
template <typename T>
use_type_ptr do_use(T & t, std::vector<indicator> & ind,
std::string const & name, basic_type_tag)
{
return use_type_ptr(new use_type<T>(t, ind, name));
}
template <typename T>
use_type_ptr do_use(T const & t, std::vector<indicator> & ind,
std::string const & name, basic_type_tag)
{
return use_type_ptr(new use_type<T>(t, ind, name));
}
template <typename T>
use_type_ptr do_use(std::vector<T> & t,
std::size_t begin, std::size_t * end,
std::string const & name, basic_type_tag)
{
return use_type_ptr(
new use_type<std::vector<T> >(t, begin, end, name));
}
template <typename T>
use_type_ptr do_use(const std::vector<T> & t,
std::size_t begin, std::size_t * end,
std::string const & name, basic_type_tag)
{
return use_type_ptr(
new use_type<std::vector<T> >(t, begin, end, name));
}
template <typename T>
use_type_ptr do_use(std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, std::size_t * end,
std::string const & name, basic_type_tag)
{
return use_type_ptr(
new use_type<std::vector<T> >(t, ind, begin, end, name));
}
template <typename T>
use_type_ptr do_use(const std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, std::size_t * end,
std::string const & name, basic_type_tag)
{
return use_type_ptr(
new use_type<std::vector<T> >(t, ind, begin, end, name));
}
} // namespace details
} // namesapce soci
#endif // SOCI_USE_TYPE_H_INCLUDED

View File

@@ -1,123 +0,0 @@
//
// Copyright (C) 2004-2016 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_USE_H_INCLUDED
#define SOCI_USE_H_INCLUDED
#include "soci/use-type.h"
#include "soci/exchange-traits.h"
#include "soci/type-conversion.h"
#include "soci/soci-backend.h"
namespace soci
{
namespace details
{
template <typename T, typename Indicator>
struct use_container
{
use_container(T &_t, Indicator &_ind, const std::string &_name)
: t(_t), ind(_ind), name(_name) {}
T &t;
Indicator &ind;
const std::string &name;
private:
SOCI_NOT_ASSIGNABLE(use_container)
};
typedef void no_indicator;
template <typename T>
struct use_container<T, no_indicator>
{
use_container(T &_t, const std::string &_name)
: t(_t), name(_name) {}
T &t;
const std::string &name;
private:
SOCI_NOT_ASSIGNABLE(use_container)
};
} // namespace details
// soci::use is deleted for rvalues because it will likely lead to subtle stack-use-after-scope bugs.
template <typename T>
details::use_container<T, details::no_indicator> use(T &&t, const std::string &name = std::string()) = delete;
template <typename T>
details::use_container<const T, indicator> use(T &&t, indicator & ind, std::string const &name = std::string()) = delete;
template <typename T>
details::use_container<T, details::no_indicator> use(T &t, const std::string &name = std::string())
{ return details::use_container<T, details::no_indicator>(t, name); }
template <typename T>
details::use_container<const T, details::no_indicator> use(T const &t, const std::string &name = std::string())
{ return details::use_container<const T, details::no_indicator>(t, name); }
template <typename T>
details::use_container<T, indicator> use(T &t, indicator & ind, std::string const &name = std::string())
{ return details::use_container<T, indicator>(t, ind, name); }
template <typename T>
details::use_container<const T, indicator> use(T const &t, indicator & ind, std::string const &name = std::string())
{ return details::use_container<const T, indicator>(t, ind, name); }
// vector containers
template <typename T>
details::use_container<T, std::vector<indicator> >
use(T &t, std::vector<indicator> & ind, const std::string &name = std::string())
{ return details::use_container<T, std::vector<indicator> >(t, ind, name); }
template <typename T>
details::use_container<std::vector<T>, details::no_indicator >
use(std::vector<T> &t, const std::string &name = std::string())
{ return details::use_container<std::vector<T>, details::no_indicator>(t, name); }
// vectors with index ranges
template <typename T>
details::use_type_ptr use(std::vector<T> & t,
std::size_t begin, std::size_t & end,
const std::string &name = std::string())
{
return details::do_use(t, begin, &end, name,
typename details::exchange_traits<std::vector<T> >::type_family());
}
template <typename T>
details::use_type_ptr use(const std::vector<T> & t,
std::size_t begin, std::size_t & end,
const std::string &name = std::string())
{
return details::do_use(t, begin, &end, name,
typename details::exchange_traits<std::vector<T> >::type_family());
}
template <typename T>
details::use_type_ptr use(std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, std::size_t & end,
const std::string &name = std::string())
{
return details::do_use(t, ind, begin, &end, name,
typename details::exchange_traits<std::vector<T> >::type_family());
}
template <typename T>
details::use_type_ptr use(const std::vector<T> & t, std::vector<indicator> & ind,
std::size_t begin, std::size_t & end,
const std::string &name = std::string())
{
return details::do_use(t, ind, begin, &end, name,
typename details::exchange_traits<std::vector<T> >::type_family());
}
} // namespace soci
#endif // SOCI_USE_H_INCLUDED

View File

@@ -1,150 +0,0 @@
//
// Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef SOCI_VALUES_EXCHANGE_H_INCLUDED
#define SOCI_VALUES_EXCHANGE_H_INCLUDED
#include "soci/values.h"
#include "soci/into-type.h"
#include "soci/use-type.h"
#include "soci/row-exchange.h"
// std
#include <cstddef>
#include <sstream>
#include <string>
#include <vector>
namespace soci
{
namespace details
{
template <>
struct exchange_traits<values>
{
typedef basic_type_tag type_family;
// dummy value to satisfy the template engine, never used
enum { x_type = 0 };
};
template <>
class use_type<values> : public use_type_base
{
public:
use_type(values & v, std::string const & /*name*/ = std::string())
: v_(v)
{}
// we ignore the possibility to have the whole values as NULL
use_type(values & v, indicator /*ind*/, std::string const & /*name*/ = std::string())
: v_(v)
{}
void bind(details::statement_impl & st, int & /*position*/) override
{
v_.uppercase_column_names(st.session_.get_uppercase_column_names());
convert_to_base();
st.bind(v_);
}
std::string get_name() const override
{
std::ostringstream oss;
oss << "(";
std::size_t const num_columns = v_.get_number_of_columns();
for (std::size_t n = 0; n < num_columns; ++n)
{
if (n != 0)
oss << ", ";
oss << v_.get_properties(n).get_name();
}
oss << ")";
return oss.str();
}
void dump_value(std::ostream& os) const override
{
// TODO: Dump all columns.
os << "<value>";
}
void pre_exec(int /* num */) override {}
void post_use(bool /*gotData*/) override
{
v_.reset_get_counter();
convert_from_base();
}
void pre_use() override {convert_to_base();}
void clean_up() override {v_.clean_up();}
std::size_t size() const override { return 1; }
// these are used only to re-dispatch to derived class
// (the derived class might be generated automatically by
// user conversions)
virtual void convert_to_base() {}
virtual void convert_from_base() {}
private:
values & v_;
SOCI_NOT_COPYABLE(use_type)
};
// this is not supposed to be used - no support for bulk ORM
template <>
class use_type<std::vector<values> >
{
private:
use_type();
};
template <>
class into_type<values> : public into_type<row>
{
public:
into_type(values & v)
: into_type<row>(v.get_row()), v_(v)
{}
into_type(values & v, indicator & ind)
: into_type<row>(v.get_row(), ind), v_(v)
{}
void clean_up() override
{
v_.clean_up();
}
private:
values & v_;
SOCI_NOT_COPYABLE(into_type)
};
// this is not supposed to be used - no support for bulk ORM
template <>
class into_type<std::vector<values> >
{
private:
into_type();
};
} // namespace details
} // namespace soci
#endif // SOCI_VALUES_EXCHANGE_H_INCLUDED

Some files were not shown because too many files have changed in this diff Show More