mirror of
https://github.com/rbock/sqlpp11.git
synced 2026-01-03 03:30:35 -06:00
Cleanup the code of the MySQL connector (#509)
* Move the code for sqlpp::mysql::detail::connection_handle_t to include/sqlpp11/mysql/detail/connection_handle.h * Move the code for sqlpp::mysql::detail::prepared_statement_handle_t to include/sqlpp11/mysql/detail/prepared_statement_handle.h * Move the code for sqlpp::mysql::detail::result_handle to include/sqlpp11/mysql/detail/result_handle.h * Rename sqlpp::mysql::detail::connection_handle_t -> sqlpp::mysql::detail::connection_handle * Rename sqlpp::mysql::serializer_t -> sqlpp::mysql::context_t * Add const qualifiers to sqlpp::mysql::context_t::escape() and its parameter. * Rename class/struct types, variables and functions from CamelCase to snake_case. * Remove a superfluous function that forwards the call to mysql_close().
This commit is contained in:
@@ -26,91 +26,21 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <sqlpp11/chrono.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
#include <sqlpp11/mysql/detail/prepared_statement_handle.h>
|
||||
#include <sqlpp11/mysql/sqlpp_mysql.h>
|
||||
|
||||
#include <iostream>
|
||||
#ifdef _MSC_VER
|
||||
#include <iso646.h>
|
||||
#endif
|
||||
#include <memory>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace mysql
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct result_meta_data_t
|
||||
{
|
||||
size_t index;
|
||||
unsigned long bound_len;
|
||||
my_bool bound_is_null;
|
||||
my_bool bound_error;
|
||||
std::vector<char> bound_text_buffer; // also for blobs
|
||||
const char** text_buffer;
|
||||
size_t* len;
|
||||
bool* is_null;
|
||||
};
|
||||
|
||||
struct prepared_statement_handle_t
|
||||
{
|
||||
struct wrapped_bool
|
||||
{
|
||||
my_bool value;
|
||||
|
||||
wrapped_bool() : value(false)
|
||||
{
|
||||
}
|
||||
wrapped_bool(bool v) : value(v)
|
||||
{
|
||||
}
|
||||
wrapped_bool(const wrapped_bool&) = default;
|
||||
wrapped_bool(wrapped_bool&&) = default;
|
||||
wrapped_bool& operator=(const wrapped_bool&) = default;
|
||||
wrapped_bool& operator=(wrapped_bool&&) = default;
|
||||
~wrapped_bool() = default;
|
||||
};
|
||||
|
||||
MYSQL_STMT* mysql_stmt;
|
||||
std::vector<MYSQL_BIND> stmt_params;
|
||||
std::vector<MYSQL_TIME> stmt_date_time_param_buffer;
|
||||
std::vector<wrapped_bool> stmt_param_is_null; // my_bool is bool after 8.0, and vector<bool> is bad
|
||||
std::vector<MYSQL_BIND> result_params;
|
||||
std::vector<result_meta_data_t> result_param_meta_data;
|
||||
bool debug;
|
||||
|
||||
prepared_statement_handle_t(MYSQL_STMT* stmt, size_t no_of_parameters, size_t no_of_columns, bool debug_)
|
||||
: mysql_stmt(stmt),
|
||||
stmt_params(no_of_parameters, MYSQL_BIND{}),
|
||||
stmt_date_time_param_buffer(no_of_parameters, MYSQL_TIME{}),
|
||||
stmt_param_is_null(no_of_parameters, false),
|
||||
result_params(no_of_columns, MYSQL_BIND{}),
|
||||
result_param_meta_data(no_of_columns, result_meta_data_t{}),
|
||||
debug(debug_)
|
||||
{
|
||||
}
|
||||
|
||||
prepared_statement_handle_t(const prepared_statement_handle_t&) = delete;
|
||||
prepared_statement_handle_t(prepared_statement_handle_t&&) = default;
|
||||
prepared_statement_handle_t& operator=(const prepared_statement_handle_t&) = delete;
|
||||
prepared_statement_handle_t& operator=(prepared_statement_handle_t&&) = default;
|
||||
|
||||
~prepared_statement_handle_t()
|
||||
{
|
||||
if (mysql_stmt)
|
||||
mysql_stmt_close(mysql_stmt);
|
||||
}
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
return !mysql_stmt;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
class bind_result_t
|
||||
{
|
||||
std::shared_ptr<detail::prepared_statement_handle_t> _handle;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <memory>
|
||||
#include <sqlpp11/chrono.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
#include <sqlpp11/mysql/detail/result_handle.h>
|
||||
#include <sqlpp11/mysql/sqlpp_mysql.h>
|
||||
#include <sqlpp11/mysql/char_result_row.h>
|
||||
|
||||
@@ -41,35 +42,9 @@ namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct result_handle
|
||||
inline auto check_first_digit(const char* text, bool digit_flag) -> bool
|
||||
{
|
||||
MYSQL_RES* mysql_res;
|
||||
bool debug;
|
||||
|
||||
result_handle(MYSQL_RES* res, bool debug_) : mysql_res(res), debug(debug_)
|
||||
{
|
||||
}
|
||||
|
||||
result_handle(const result_handle&) = delete;
|
||||
result_handle(result_handle&&) = default;
|
||||
result_handle& operator=(const result_handle&) = delete;
|
||||
result_handle& operator=(result_handle&&) = default;
|
||||
|
||||
~result_handle()
|
||||
{
|
||||
if (mysql_res)
|
||||
mysql_free_result(mysql_res);
|
||||
}
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
return !mysql_res;
|
||||
}
|
||||
};
|
||||
|
||||
inline auto check_first_digit(const char* text, bool digitFlag) -> bool
|
||||
{
|
||||
if (digitFlag)
|
||||
if (digit_flag)
|
||||
{
|
||||
if (not std::isdigit(*text))
|
||||
{
|
||||
@@ -88,9 +63,9 @@ namespace sqlpp
|
||||
|
||||
inline auto check_date_digits(const char* text) -> bool
|
||||
{
|
||||
for (const auto digitFlag : {true, true, true, true, false, true, true, false, true, true}) // YYYY-MM-DD
|
||||
for (const auto digit_flag : {true, true, true, true, false, true, true, false, true, true}) // YYYY-MM-DD
|
||||
{
|
||||
if (not check_first_digit(text, digitFlag))
|
||||
if (not check_first_digit(text, digit_flag))
|
||||
return false;
|
||||
++text;
|
||||
}
|
||||
@@ -99,9 +74,9 @@ namespace sqlpp
|
||||
|
||||
inline auto check_time_digits(const char* text) -> bool
|
||||
{
|
||||
for (const auto digitFlag : {true, true, false, true, true, false, true, true}) // hh:mm:ss
|
||||
for (const auto digit_flag : {true, true, false, true, true, false, true, true}) // hh:mm:ss
|
||||
{
|
||||
if (not check_first_digit(text, digitFlag))
|
||||
if (not check_first_digit(text, digit_flag))
|
||||
return false;
|
||||
++text;
|
||||
}
|
||||
|
||||
@@ -33,11 +33,11 @@
|
||||
#include <sqlpp11/mysql/bind_result.h>
|
||||
#include <sqlpp11/mysql/char_result.h>
|
||||
#include <sqlpp11/mysql/connection_config.h>
|
||||
#include <sqlpp11/mysql/detail/connection_handle.h>
|
||||
#include <sqlpp11/mysql/prepared_statement.h>
|
||||
#include <sqlpp11/mysql/remove.h>
|
||||
#include <sqlpp11/mysql/update.h>
|
||||
#include <sqlpp11/serialize.h>
|
||||
#include <sqlpp11/mysql/sqlpp_mysql.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
@@ -48,9 +48,9 @@ namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct MySqlThreadInitializer
|
||||
struct mysql_thread_initializer
|
||||
{
|
||||
MySqlThreadInitializer()
|
||||
mysql_thread_initializer()
|
||||
{
|
||||
if (!mysql_thread_safe())
|
||||
{
|
||||
@@ -59,7 +59,7 @@ namespace sqlpp
|
||||
mysql_thread_init();
|
||||
}
|
||||
|
||||
~MySqlThreadInitializer()
|
||||
~mysql_thread_initializer()
|
||||
{
|
||||
mysql_thread_end();
|
||||
}
|
||||
@@ -67,90 +67,10 @@ namespace sqlpp
|
||||
|
||||
inline void thread_init()
|
||||
{
|
||||
thread_local MySqlThreadInitializer threadInitializer;
|
||||
thread_local mysql_thread_initializer thread_initializer;
|
||||
}
|
||||
|
||||
inline void connect(MYSQL* mysql, const connection_config& config)
|
||||
{
|
||||
if (config.connect_timeout_seconds != 0 &&
|
||||
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, &config.connect_timeout_seconds))
|
||||
{
|
||||
throw sqlpp::exception("MySQL: could not set option MYSQL_OPT_CONNECT_TIMEOUT");
|
||||
}
|
||||
|
||||
if (!mysql_real_connect(mysql, config.host.empty() ? nullptr : config.host.c_str(),
|
||||
config.user.empty() ? nullptr : config.user.c_str(),
|
||||
config.password.empty() ? nullptr : config.password.c_str(), nullptr, config.port,
|
||||
config.unix_socket.empty() ? nullptr : config.unix_socket.c_str(), config.client_flag))
|
||||
{
|
||||
throw sqlpp::exception("MySQL: could not connect to server: " + std::string(mysql_error(mysql)));
|
||||
}
|
||||
|
||||
if (mysql_set_character_set(mysql, config.charset.c_str()))
|
||||
{
|
||||
throw sqlpp::exception("MySQL error: can't set character set " + config.charset);
|
||||
}
|
||||
|
||||
if (not config.database.empty() and mysql_select_db(mysql, config.database.c_str()))
|
||||
{
|
||||
throw sqlpp::exception("MySQL error: can't select database '" + config.database + "'");
|
||||
}
|
||||
}
|
||||
|
||||
inline void handle_cleanup(MYSQL* mysql)
|
||||
{
|
||||
mysql_close(mysql);
|
||||
}
|
||||
|
||||
struct connection_handle_t
|
||||
{
|
||||
std::shared_ptr<const connection_config> config;
|
||||
std::unique_ptr<MYSQL, void (*)(MYSQL*)> mysql;
|
||||
|
||||
connection_handle_t(const std::shared_ptr<const connection_config>& conf) :
|
||||
config(conf),
|
||||
mysql(mysql_init(nullptr), handle_cleanup)
|
||||
{
|
||||
if (not mysql)
|
||||
{
|
||||
throw sqlpp::exception("MySQL: could not init mysql data structure");
|
||||
}
|
||||
|
||||
if (config->auto_reconnect)
|
||||
{
|
||||
my_bool my_true = true;
|
||||
if (mysql_options(native_handle(), MYSQL_OPT_RECONNECT, &my_true))
|
||||
{
|
||||
throw sqlpp::exception("MySQL: could not set option MYSQL_OPT_RECONNECT");
|
||||
}
|
||||
}
|
||||
|
||||
connect(native_handle(), *config);
|
||||
}
|
||||
|
||||
connection_handle_t(const connection_handle_t&) = delete;
|
||||
connection_handle_t(connection_handle_t&&) = default;
|
||||
connection_handle_t& operator=(const connection_handle_t&) = delete;
|
||||
connection_handle_t& operator=(connection_handle_t&&) = default;
|
||||
|
||||
MYSQL* native_handle() const
|
||||
{
|
||||
return mysql.get();
|
||||
}
|
||||
|
||||
bool check_connection() const
|
||||
{
|
||||
auto nh = native_handle();
|
||||
return nh && (mysql_ping(nh) == 0);
|
||||
}
|
||||
|
||||
void reconnect()
|
||||
{
|
||||
connect(native_handle(), *config);
|
||||
}
|
||||
};
|
||||
|
||||
inline void execute_statement(std::unique_ptr<connection_handle_t>& handle, const std::string& statement)
|
||||
inline void execute_statement(std::unique_ptr<connection_handle>& handle, const std::string& statement)
|
||||
{
|
||||
thread_init();
|
||||
|
||||
@@ -185,7 +105,7 @@ namespace sqlpp
|
||||
}
|
||||
}
|
||||
|
||||
inline std::shared_ptr<detail::prepared_statement_handle_t> prepare_statement(std::unique_ptr<connection_handle_t>& handle,
|
||||
inline std::shared_ptr<detail::prepared_statement_handle_t> prepare_statement(std::unique_ptr<connection_handle>& handle,
|
||||
const std::string& statement,
|
||||
size_t no_of_parameters,
|
||||
size_t no_of_columns)
|
||||
@@ -235,12 +155,12 @@ namespace sqlpp
|
||||
// Forward declaration
|
||||
class connection_base;
|
||||
|
||||
struct serializer_t
|
||||
struct context_t
|
||||
{
|
||||
serializer_t(const connection_base& db) : _db(db)
|
||||
context_t(const connection_base& db) : _db(db)
|
||||
{
|
||||
}
|
||||
serializer_t(const connection_base&&) = delete;
|
||||
context_t(const connection_base&&) = delete;
|
||||
|
||||
template <typename T>
|
||||
std::ostream& operator<<(T t)
|
||||
@@ -248,7 +168,7 @@ namespace sqlpp
|
||||
return _os << t;
|
||||
}
|
||||
|
||||
std::string escape(std::string arg);
|
||||
std::string escape(const std::string& arg) const;
|
||||
|
||||
std::string str() const
|
||||
{
|
||||
@@ -259,9 +179,9 @@ namespace sqlpp
|
||||
sqlpp::detail::float_safe_ostringstream _os;
|
||||
};
|
||||
|
||||
std::integral_constant<char, '`'> get_quote_left(const serializer_t&);
|
||||
std::integral_constant<char, '`'> get_quote_left(const context_t&);
|
||||
|
||||
std::integral_constant<char, '`'> get_quote_right(const serializer_t&);
|
||||
std::integral_constant<char, '`'> get_quote_right(const context_t&);
|
||||
|
||||
class connection_base : public sqlpp::connection
|
||||
{
|
||||
@@ -336,11 +256,11 @@ namespace sqlpp
|
||||
using _connection_base_t = connection_base;
|
||||
using _config_t = connection_config;
|
||||
using _config_ptr_t = std::shared_ptr<const _config_t>;
|
||||
using _handle_t = detail::connection_handle_t;
|
||||
using _handle_t = detail::connection_handle;
|
||||
using _handle_ptr_t = std::unique_ptr<_handle_t>;
|
||||
|
||||
using _prepared_statement_t = ::sqlpp::mysql::prepared_statement_t;
|
||||
using _context_t = serializer_t;
|
||||
using _context_t = context_t;
|
||||
using _serializer_context_t = _context_t;
|
||||
using _interpreter_context_t = _context_t;
|
||||
|
||||
@@ -594,7 +514,7 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
// Method definition moved outside of class because it needs connection_base
|
||||
inline std::string serializer_t::escape(std::string arg)
|
||||
inline std::string context_t::escape(const std::string& arg) const
|
||||
{
|
||||
return _db.escape(arg);
|
||||
}
|
||||
|
||||
117
include/sqlpp11/mysql/detail/connection_handle.h
Normal file
117
include/sqlpp11/mysql/detail/connection_handle.h
Normal file
@@ -0,0 +1,117 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 - 2017, Roland Bock
|
||||
* Copyright (c) 2023, Vesselin Atanasov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sqlpp11/mysql/connection_config.h>
|
||||
#include <sqlpp11/mysql/sqlpp_mysql.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace mysql
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
inline void connect(MYSQL* mysql, const connection_config& config)
|
||||
{
|
||||
if (config.connect_timeout_seconds != 0 &&
|
||||
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, &config.connect_timeout_seconds))
|
||||
{
|
||||
throw sqlpp::exception("MySQL: could not set option MYSQL_OPT_CONNECT_TIMEOUT");
|
||||
}
|
||||
|
||||
if (!mysql_real_connect(mysql, config.host.empty() ? nullptr : config.host.c_str(),
|
||||
config.user.empty() ? nullptr : config.user.c_str(),
|
||||
config.password.empty() ? nullptr : config.password.c_str(), nullptr, config.port,
|
||||
config.unix_socket.empty() ? nullptr : config.unix_socket.c_str(), config.client_flag))
|
||||
{
|
||||
throw sqlpp::exception("MySQL: could not connect to server: " + std::string(mysql_error(mysql)));
|
||||
}
|
||||
|
||||
if (mysql_set_character_set(mysql, config.charset.c_str()))
|
||||
{
|
||||
throw sqlpp::exception("MySQL error: can't set character set " + config.charset);
|
||||
}
|
||||
|
||||
if (not config.database.empty() and mysql_select_db(mysql, config.database.c_str()))
|
||||
{
|
||||
throw sqlpp::exception("MySQL error: can't select database '" + config.database + "'");
|
||||
}
|
||||
}
|
||||
|
||||
struct connection_handle
|
||||
{
|
||||
std::shared_ptr<const connection_config> config;
|
||||
std::unique_ptr<MYSQL, void (*)(MYSQL*)> mysql;
|
||||
|
||||
connection_handle(const std::shared_ptr<const connection_config>& conf) :
|
||||
config(conf),
|
||||
mysql(mysql_init(nullptr), mysql_close)
|
||||
{
|
||||
if (not mysql)
|
||||
{
|
||||
throw sqlpp::exception("MySQL: could not init mysql data structure");
|
||||
}
|
||||
|
||||
if (config->auto_reconnect)
|
||||
{
|
||||
my_bool my_true = true;
|
||||
if (mysql_options(native_handle(), MYSQL_OPT_RECONNECT, &my_true))
|
||||
{
|
||||
throw sqlpp::exception("MySQL: could not set option MYSQL_OPT_RECONNECT");
|
||||
}
|
||||
}
|
||||
|
||||
connect(native_handle(), *config);
|
||||
}
|
||||
|
||||
connection_handle(const connection_handle&) = delete;
|
||||
connection_handle(connection_handle&&) = default;
|
||||
connection_handle& operator=(const connection_handle&) = delete;
|
||||
connection_handle& operator=(connection_handle&&) = default;
|
||||
|
||||
MYSQL* native_handle() const
|
||||
{
|
||||
return mysql.get();
|
||||
}
|
||||
|
||||
bool check_connection() const
|
||||
{
|
||||
auto nh = native_handle();
|
||||
return nh && (mysql_ping(nh) == 0);
|
||||
}
|
||||
|
||||
void reconnect()
|
||||
{
|
||||
connect(native_handle(), *config);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace sqlpp
|
||||
107
include/sqlpp11/mysql/detail/prepared_statement_handle.h
Normal file
107
include/sqlpp11/mysql/detail/prepared_statement_handle.h
Normal file
@@ -0,0 +1,107 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 - 2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sqlpp11/mysql/sqlpp_mysql.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace mysql
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct result_meta_data_t
|
||||
{
|
||||
size_t index;
|
||||
unsigned long bound_len;
|
||||
my_bool bound_is_null;
|
||||
my_bool bound_error;
|
||||
std::vector<char> bound_text_buffer; // also for blobs
|
||||
const char** text_buffer;
|
||||
size_t* len;
|
||||
bool* is_null;
|
||||
};
|
||||
|
||||
struct prepared_statement_handle_t
|
||||
{
|
||||
struct wrapped_bool
|
||||
{
|
||||
my_bool value;
|
||||
|
||||
wrapped_bool() : value(false)
|
||||
{
|
||||
}
|
||||
wrapped_bool(bool v) : value(v)
|
||||
{
|
||||
}
|
||||
wrapped_bool(const wrapped_bool&) = default;
|
||||
wrapped_bool(wrapped_bool&&) = default;
|
||||
wrapped_bool& operator=(const wrapped_bool&) = default;
|
||||
wrapped_bool& operator=(wrapped_bool&&) = default;
|
||||
~wrapped_bool() = default;
|
||||
};
|
||||
|
||||
MYSQL_STMT* mysql_stmt;
|
||||
std::vector<MYSQL_BIND> stmt_params;
|
||||
std::vector<MYSQL_TIME> stmt_date_time_param_buffer;
|
||||
std::vector<wrapped_bool> stmt_param_is_null; // my_bool is bool after 8.0, and vector<bool> is bad
|
||||
std::vector<MYSQL_BIND> result_params;
|
||||
std::vector<result_meta_data_t> result_param_meta_data;
|
||||
bool debug;
|
||||
|
||||
prepared_statement_handle_t(MYSQL_STMT* stmt, size_t no_of_parameters, size_t no_of_columns, bool debug_)
|
||||
: mysql_stmt(stmt),
|
||||
stmt_params(no_of_parameters, MYSQL_BIND{}),
|
||||
stmt_date_time_param_buffer(no_of_parameters, MYSQL_TIME{}),
|
||||
stmt_param_is_null(no_of_parameters, false),
|
||||
result_params(no_of_columns, MYSQL_BIND{}),
|
||||
result_param_meta_data(no_of_columns, result_meta_data_t{}),
|
||||
debug(debug_)
|
||||
{
|
||||
}
|
||||
|
||||
prepared_statement_handle_t(const prepared_statement_handle_t&) = delete;
|
||||
prepared_statement_handle_t(prepared_statement_handle_t&&) = default;
|
||||
prepared_statement_handle_t& operator=(const prepared_statement_handle_t&) = delete;
|
||||
prepared_statement_handle_t& operator=(prepared_statement_handle_t&&) = default;
|
||||
|
||||
~prepared_statement_handle_t()
|
||||
{
|
||||
if (mysql_stmt)
|
||||
mysql_stmt_close(mysql_stmt);
|
||||
}
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
return !mysql_stmt;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace sqlpp
|
||||
62
include/sqlpp11/mysql/detail/result_handle.h
Normal file
62
include/sqlpp11/mysql/detail/result_handle.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 - 2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace mysql
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct result_handle
|
||||
{
|
||||
MYSQL_RES* mysql_res;
|
||||
bool debug;
|
||||
|
||||
result_handle(MYSQL_RES* res, bool debug_) : mysql_res(res), debug(debug_)
|
||||
{
|
||||
}
|
||||
|
||||
result_handle(const result_handle&) = delete;
|
||||
result_handle(result_handle&&) = default;
|
||||
result_handle& operator=(const result_handle&) = delete;
|
||||
result_handle& operator=(result_handle&&) = default;
|
||||
|
||||
~result_handle()
|
||||
{
|
||||
if (mysql_res)
|
||||
mysql_free_result(mysql_res);
|
||||
}
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
return !mysql_res;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace mysql
|
||||
} // namespace sqlpp
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sqlpp11/chrono.h>
|
||||
|
||||
namespace sqlpp
|
||||
|
||||
@@ -32,17 +32,17 @@
|
||||
namespace sqlpp
|
||||
{
|
||||
template <typename First, typename... Args>
|
||||
mysql::serializer_t& serialize(const concat_t<First, Args...>& t, mysql::serializer_t& context)
|
||||
mysql::context_t& serialize(const concat_t<First, Args...>& t, mysql::context_t& ctx)
|
||||
{
|
||||
context << "CONCAT(";
|
||||
interpret_tuple(t._args, ',', context);
|
||||
context << ')';
|
||||
return context;
|
||||
ctx << "CONCAT(";
|
||||
interpret_tuple(t._args, ',', ctx);
|
||||
ctx << ')';
|
||||
return ctx;
|
||||
}
|
||||
|
||||
inline mysql::serializer_t& serialize(const insert_default_values_data_t&, mysql::serializer_t& context)
|
||||
inline mysql::context_t& serialize(const insert_default_values_data_t&, mysql::context_t& ctx)
|
||||
{
|
||||
context << " () VALUES()";
|
||||
return context;
|
||||
ctx << " () VALUES()";
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace
|
||||
}
|
||||
|
||||
sqlpp::mysql::connection connection{config};
|
||||
sqlpp::mysql::serializer_t printer{connection};
|
||||
sqlpp::mysql::context_t printer{connection};
|
||||
|
||||
const auto result = serialize(expr, printer).str();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user