From c550dca89ecd8062d8d3898a039672bd1111c8db Mon Sep 17 00:00:00 2001 From: MeanSquaredError <35379301+MeanSquaredError@users.noreply.github.com> Date: Thu, 17 Aug 2023 08:26:54 +0300 Subject: [PATCH] Cleanup SQLite3 connector code (#514) * Move the code for sqlpp::sqlite3::detail::prepared_statement_handle_t to include/sqlpp11/sqlite3/detail/prepared_statement_handle.h * Whitespace * Move the code for sqlpp::sqlite3::detail::connection_handle to include/sqlpp11/sqlite3/detail/connection_handle.h * Rename sqlpp::sqlite3::serializer_t -> sqlpp::sqlite3::context_t * Add const qualifiers to sqlpp::mysql::context_t::escape() and its parameter. * Change method argument types "const std::string" -> "const std::string&" * Remove a superfluous function that forwards the call to sqlite3_close(). * Move initialization of sqlpp::sqlite3::detail::prepared_statement_handle_t data members from the constructor into the member initialization list. * Rename method parameter from CamelCase to snake_case. --- include/sqlpp11/sqlite3/bind_result.h | 18 +-- include/sqlpp11/sqlite3/connection.h | 75 ++----------- .../sqlite3/detail/connection_handle.h | 106 ++++++++++++++++++ .../{ => detail}/prepared_statement_handle.h | 8 +- include/sqlpp11/sqlite3/insert_or.h | 4 +- include/sqlpp11/sqlite3/prepared_statement.h | 2 +- include/sqlpp11/sqlite3/serializer.h | 20 ++-- tests/sqlite3/serialize/compare.h | 2 +- 8 files changed, 140 insertions(+), 95 deletions(-) create mode 100644 include/sqlpp11/sqlite3/detail/connection_handle.h rename include/sqlpp11/sqlite3/{ => detail}/prepared_statement_handle.h (97%) diff --git a/include/sqlpp11/sqlite3/bind_result.h b/include/sqlpp11/sqlite3/bind_result.h index b47d99aa..05e39ebe 100644 --- a/include/sqlpp11/sqlite3/bind_result.h +++ b/include/sqlpp11/sqlite3/bind_result.h @@ -30,8 +30,8 @@ #include #include #include +#include #include -#include #ifdef _MSC_VER #include @@ -45,9 +45,9 @@ namespace sqlpp { namespace detail { - inline auto check_first_digit(const char* text, bool digitFlag) -> bool + inline auto check_first_digit(const char* text, bool digit_flag) -> bool { - if (digitFlag) + if (digit_flag) { if (not std::isdigit(*text)) { @@ -66,9 +66,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; } @@ -77,9 +77,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; } @@ -88,9 +88,9 @@ namespace sqlpp inline auto check_ms_digits(const char* text) -> bool { - for (const auto digitFlag : {true, true, true}) + for (const auto digit_flag : {true, true, true}) { - if (not check_first_digit(text, digitFlag)) + if (not check_first_digit(text, digit_flag)) return false; ++text; } diff --git a/include/sqlpp11/sqlite3/connection.h b/include/sqlpp11/sqlite3/connection.h index a8457143..174ca0f2 100644 --- a/include/sqlpp11/sqlite3/connection.h +++ b/include/sqlpp11/sqlite3/connection.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -65,66 +66,6 @@ namespace sqlpp namespace detail { - inline void handle_cleanup(::sqlite3* sqlite) - { - sqlite3_close(sqlite); - } - - struct connection_handle - { - std::shared_ptr config; - std::unique_ptr<::sqlite3, void (*)(::sqlite3*)> sqlite; - - connection_handle(const std::shared_ptr& conf) : - config(conf), - sqlite(nullptr, handle_cleanup) - { -#ifdef SQLPP_DYNAMIC_LOADING - init_sqlite(""); -#endif - - ::sqlite3* sqlite_ptr; - const auto rc = sqlite3_open_v2(conf->path_to_database.c_str(), &sqlite_ptr, conf->flags, - conf->vfs.empty() ? nullptr : conf->vfs.c_str()); - if (rc != SQLITE_OK) - { - const std::string msg = sqlite3_errmsg(sqlite_ptr); - sqlite3_close(sqlite_ptr); - throw sqlpp::exception("Sqlite3 error: Can't open database: " + msg); - } - - sqlite.reset(sqlite_ptr); - -#ifdef SQLITE_HAS_CODEC - if (conf->password.size() > 0) - { - int ret = sqlite3_key(native_handle(), conf->password.data(), conf->password.size()); - if (ret != SQLITE_OK) - { - const std::string msg = sqlite3_errmsg(native_handle()); - sqlite3_close(native_handle()); - throw sqlpp::exception("Sqlite3 error: Can't set password to database: " + msg); - } - } -#endif - } - - connection_handle(const connection_handle&) = delete; - connection_handle(connection_handle&&) = default; - connection_handle& operator=(const connection_handle&) = delete; - connection_handle& operator=(connection_handle&&) = default; - - ::sqlite3* native_handle() const - { - return sqlite.get(); - } - - bool check_connection() const - { - return native_handle() != nullptr; - } - }; - inline detail::prepared_statement_handle_t prepare_statement(std::unique_ptr& handle, const std::string& statement) { @@ -167,9 +108,9 @@ namespace sqlpp // Forward declaration class connection_base; - struct serializer_t + struct context_t { - serializer_t(const connection_base& db) : _db(db), _count(1) + context_t(const connection_base& db) : _db(db), _count(1) { } @@ -179,7 +120,7 @@ namespace sqlpp return _os << t; } - std::string escape(std::string arg); + std::string escape(const std::string& arg) const; std::string str() const { @@ -297,7 +238,7 @@ namespace sqlpp using _handle_ptr_t = std::unique_ptr<_handle_t>; using _prepared_statement_t = 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; @@ -572,7 +513,7 @@ namespace sqlpp } //! report a rollback failure (will be called by transactions in case of a rollback failure in the destructor) - void report_rollback_failure(const std::string message) noexcept + void report_rollback_failure(const std::string& message) noexcept { std::cerr << "Sqlite3 message:" << message << std::endl; } @@ -588,7 +529,7 @@ namespace sqlpp return _handle->native_handle(); } - schema_t attach(const connection_config& config, const std::string name) + schema_t attach(const connection_config& config, const std::string& name) { auto prepared = prepare_statement(_handle, "ATTACH '" + escape(config.path_to_database) + "' AS " + escape(name)); @@ -608,7 +549,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); } diff --git a/include/sqlpp11/sqlite3/detail/connection_handle.h b/include/sqlpp11/sqlite3/detail/connection_handle.h new file mode 100644 index 00000000..aa01f060 --- /dev/null +++ b/include/sqlpp11/sqlite3/detail/connection_handle.h @@ -0,0 +1,106 @@ +#pragma once + +/* + * Copyright (c) 2013 - 2016, 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. + */ + +#ifdef SQLPP_USE_SQLCIPHER +#include +#else +#include +#endif + +#ifdef SQLPP_DYNAMIC_LOADING +#include +#endif + +namespace sqlpp +{ + namespace sqlite3 + { +#ifdef SQLPP_DYNAMIC_LOADING + using namespace dynamic; +#endif + + namespace detail + { + struct connection_handle + { + std::shared_ptr config; + std::unique_ptr<::sqlite3, int (*)(::sqlite3*)> sqlite; + + connection_handle(const std::shared_ptr& conf) : + config(conf), + sqlite(nullptr, sqlite3_close) + { +#ifdef SQLPP_DYNAMIC_LOADING + init_sqlite(""); +#endif + + ::sqlite3* sqlite_ptr; + const auto rc = sqlite3_open_v2(conf->path_to_database.c_str(), &sqlite_ptr, conf->flags, + conf->vfs.empty() ? nullptr : conf->vfs.c_str()); + if (rc != SQLITE_OK) + { + const std::string msg = sqlite3_errmsg(sqlite_ptr); + sqlite3_close(sqlite_ptr); + throw sqlpp::exception("Sqlite3 error: Can't open database: " + msg); + } + + sqlite.reset(sqlite_ptr); + +#ifdef SQLITE_HAS_CODEC + if (conf->password.size() > 0) + { + int ret = sqlite3_key(native_handle(), conf->password.data(), conf->password.size()); + if (ret != SQLITE_OK) + { + const std::string msg = sqlite3_errmsg(native_handle()); + sqlite3_close(native_handle()); + throw sqlpp::exception("Sqlite3 error: Can't set password to database: " + msg); + } + } +#endif + } + + connection_handle(const connection_handle&) = delete; + connection_handle(connection_handle&&) = default; + connection_handle& operator=(const connection_handle&) = delete; + connection_handle& operator=(connection_handle&&) = default; + + ::sqlite3* native_handle() const + { + return sqlite.get(); + } + + bool check_connection() const + { + return native_handle() != nullptr; + } + }; + } // namespace detail + } // namespace sqlite3 +} // namespace sqlpp diff --git a/include/sqlpp11/sqlite3/prepared_statement_handle.h b/include/sqlpp11/sqlite3/detail/prepared_statement_handle.h similarity index 97% rename from include/sqlpp11/sqlite3/prepared_statement_handle.h rename to include/sqlpp11/sqlite3/detail/prepared_statement_handle.h index d06bce94..6ad2a25e 100644 --- a/include/sqlpp11/sqlite3/prepared_statement_handle.h +++ b/include/sqlpp11/sqlite3/detail/prepared_statement_handle.h @@ -53,12 +53,11 @@ namespace sqlpp } prepared_statement_handle_t(const prepared_statement_handle_t&) = delete; - prepared_statement_handle_t(prepared_statement_handle_t&& rhs) + prepared_statement_handle_t(prepared_statement_handle_t&& rhs) : + sqlite_statement(rhs.sqlite_statement), + debug(rhs.debug) { - sqlite_statement = rhs.sqlite_statement; rhs.sqlite_statement = nullptr; - - debug = rhs.debug; } prepared_statement_handle_t& operator=(const prepared_statement_handle_t&) = delete; prepared_statement_handle_t& operator=(prepared_statement_handle_t&& rhs) @@ -87,7 +86,6 @@ namespace sqlpp } }; } - } // namespace sqlite3 } // namespace sqlpp diff --git a/include/sqlpp11/sqlite3/insert_or.h b/include/sqlpp11/sqlite3/insert_or.h index 00ded378..349d4fd8 100644 --- a/include/sqlpp11/sqlite3/insert_or.h +++ b/include/sqlpp11/sqlite3/insert_or.h @@ -136,13 +136,13 @@ namespace sqlpp return {blank_insert_or_ignore_t().into(table)}; } - inline sqlite3::serializer_t& serialize(const sqlite3::insert_or_replace_name_t&, sqlite3::serializer_t& context) + inline sqlite3::context_t& serialize(const sqlite3::insert_or_replace_name_t&, sqlite3::context_t& context) { context << "INSERT OR REPLACE "; return context; } - inline sqlite3::serializer_t& serialize(const sqlite3::insert_or_ignore_name_t&, sqlite3::serializer_t& context) + inline sqlite3::context_t& serialize(const sqlite3::insert_or_ignore_name_t&, sqlite3::context_t& context) { context << "INSERT OR IGNORE "; return context; diff --git a/include/sqlpp11/sqlite3/prepared_statement.h b/include/sqlpp11/sqlite3/prepared_statement.h index bda11914..1ca526cc 100644 --- a/include/sqlpp11/sqlite3/prepared_statement.h +++ b/include/sqlpp11/sqlite3/prepared_statement.h @@ -37,7 +37,7 @@ #include #include -#include +#include #ifdef _MSC_VER #pragma warning(push) diff --git a/include/sqlpp11/sqlite3/serializer.h b/include/sqlpp11/sqlite3/serializer.h index b4b02cd1..a72bc3f5 100644 --- a/include/sqlpp11/sqlite3/serializer.h +++ b/include/sqlpp11/sqlite3/serializer.h @@ -48,7 +48,7 @@ namespace sqlpp { // Serialize parameters template - sqlite3::serializer_t& serialize(const parameter_t&, sqlite3::serializer_t& context) + sqlite3::context_t& serialize(const parameter_t&, sqlite3::context_t& context) { context << "?" << context.count(); context.pop_count(); @@ -58,7 +58,7 @@ namespace sqlpp // disable some stuff that won't work with sqlite3 #if SQLITE_VERSION_NUMBER < 3008003 template - sqlite3::serializer_t& serialize(const with_data_t&, sqlite3::serializer_t& context) + sqlite3::context_t& serialize(const with_data_t&, sqlite3::context_t& context) { static_assert(wrong_t::value, "Sqlite3: No support for with before version 3.8.3"); return context; @@ -66,28 +66,28 @@ namespace sqlpp #endif template - sqlite3::serializer_t& serialize(const any_t&, sqlite3::context_t& context) { static_assert(wrong_t&, sqlite3::serializer_t& context) + sqlite3::context_t& serialize(const some_t::value, "Sqlite3: No support for some()"); return context; } template - sqlite3::serializer_t& serialize(const pre_join_t&, sqlite3::serializer_t& context) + sqlite3::context_t& serialize(const pre_join_t&, sqlite3::context_t& context) { static_assert(wrong_t::value, "Sqlite3: No support for outer join"); return context; } template - sqlite3::serializer_t& serialize(const pre_join_t&, sqlite3::serializer_t& context) + sqlite3::context_t& serialize(const pre_join_t&, sqlite3::context_t& context) { static_assert(wrong_t::value, "Sqlite3: No support for right_outer join"); return context; @@ -95,7 +95,7 @@ namespace sqlpp // Some special treatment of data types template - sqlite3::serializer_t& serialize(const time_point_operand& t, sqlite3::serializer_t& context) + sqlite3::context_t& serialize(const time_point_operand& t, sqlite3::context_t& context) { const auto dp = ::sqlpp::chrono::floor<::date::days>(t._t); const auto time = ::date::make_time(t._t - dp); @@ -104,14 +104,14 @@ namespace sqlpp return context; } - inline sqlite3::serializer_t& serialize(const day_point_operand& t, sqlite3::serializer_t& context) + inline sqlite3::context_t& serialize(const day_point_operand& t, sqlite3::context_t& context) { const auto ymd = ::date::year_month_day{t._t}; context << "DATE('" << ymd << "')"; return context; } - inline sqlite3::serializer_t& serialize(const floating_point_operand& t, sqlite3::serializer_t& context) + inline sqlite3::context_t& serialize(const floating_point_operand& t, sqlite3::context_t& context) { if (std::isnan(t._t)) context << "'NaN'"; @@ -129,7 +129,7 @@ namespace sqlpp // sqlite3 accepts only signed integers, // so we MUST perform a conversion from unsigned to signed - inline sqlite3::serializer_t& serialize(const unsigned_integral_operand& t, sqlite3::serializer_t& context) + inline sqlite3::context_t& serialize(const unsigned_integral_operand& t, sqlite3::context_t& context) { context << static_cast(t._t); return context; diff --git a/tests/sqlite3/serialize/compare.h b/tests/sqlite3/serialize/compare.h index f4483379..4084400b 100644 --- a/tests/sqlite3/serialize/compare.h +++ b/tests/sqlite3/serialize/compare.h @@ -51,7 +51,7 @@ namespace config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; config.debug = true; sqlpp::sqlite3::connection connection{config}; - sqlpp::sqlite3::serializer_t printer{connection}; + sqlpp::sqlite3::context_t printer{connection}; const auto result = serialize(expr, printer).str();