diff --git a/include/sqlpp11/mysql/char_result.h b/include/sqlpp11/mysql/char_result.h index ad2fa265..f67feeee 100644 --- a/include/sqlpp11/mysql/char_result.h +++ b/include/sqlpp11/mysql/char_result.h @@ -71,7 +71,7 @@ namespace sqlpp const auto date_digits = std::vector{1, 1, 1, 1, 0, 1, 1, 0, 1, 1}; // 2015-10-28 const auto time_digits = std::vector{0, 1, 1, 0, 1, 1, 0, 1, 1}; // T23:00:12 - auto check_digits(const char* text, const std::vector& digitFlags) -> bool + inline auto check_digits(const char* text, const std::vector& digitFlags) -> bool { for (const auto digitFlag : digitFlags) { diff --git a/include/sqlpp11/mysql/connection.h b/include/sqlpp11/mysql/connection.h index 9bb45d16..1959abe8 100644 --- a/include/sqlpp11/mysql/connection.h +++ b/include/sqlpp11/mysql/connection.h @@ -63,12 +63,12 @@ namespace sqlpp } }; - void thread_init() + inline void thread_init() { thread_local MySqlThreadInitializer threadInitializer; } - void connect(MYSQL* mysql, const connection_config& config) + inline void connect(MYSQL* mysql, const connection_config& config) { if (!mysql_real_connect(mysql, config.host.empty() ? nullptr : config.host.c_str(), config.user.empty() ? nullptr : config.user.c_str(), @@ -89,7 +89,7 @@ namespace sqlpp } } - void handle_cleanup(MYSQL* mysql) + inline void handle_cleanup(MYSQL* mysql) { mysql_close(mysql); } @@ -136,7 +136,7 @@ namespace sqlpp } }; - void execute_statement(detail::connection_handle_t& handle, const std::string& statement) + inline void execute_statement(detail::connection_handle_t& handle, const std::string& statement) { thread_init(); @@ -151,7 +151,7 @@ namespace sqlpp } } - void execute_prepared_statement(detail::prepared_statement_handle_t& prepared_statement) + inline void execute_prepared_statement(detail::prepared_statement_handle_t& prepared_statement) { thread_init(); @@ -171,7 +171,7 @@ namespace sqlpp } } - std::shared_ptr prepare_statement(detail::connection_handle_t& handle, + inline std::shared_ptr prepare_statement(detail::connection_handle_t& handle, const std::string& statement, size_t no_of_parameters, size_t no_of_columns) @@ -213,7 +213,7 @@ namespace sqlpp }; // This will also cleanup when the program shuts down - void global_library_init(int argc = 0, char** argv = nullptr, char** groups = nullptr) + inline void global_library_init(int argc = 0, char** argv = nullptr, char** groups = nullptr) { static const auto global_init_and_end = scoped_library_initializer_t(argc, argv, groups); } diff --git a/tests/mysql/usage/CMakeLists.txt b/tests/mysql/usage/CMakeLists.txt index bbea5292..ffa394db 100644 --- a/tests/mysql/usage/CMakeLists.txt +++ b/tests/mysql/usage/CMakeLists.txt @@ -1,29 +1,68 @@ +# Copyright (c) 2013 - 2021, 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. + find_package(Threads REQUIRED) -macro(build_and_run arg) - add_executable(Sqlpp11MySQL${arg} ${arg}.cpp) - target_link_libraries(Sqlpp11MySQL${arg} PRIVATE Threads::Threads) - target_link_libraries(Sqlpp11MySQL${arg} PRIVATE sqlpp11::sqlpp11) - target_link_libraries(Sqlpp11MySQL${arg} PRIVATE MySQL::MySQL) - target_link_libraries(Sqlpp11MySQL${arg} PRIVATE date::date) - if(${arg} STREQUAL "JsonTest") - target_link_libraries(Sqlpp11MySQL${arg} PRIVATE MySQL::MySQL) - endif() - if(NOT MSVC) - target_compile_options(Sqlpp11MySQL${arg} PRIVATE -Wall -Wextra -pedantic) - endif() - add_test(${arg} Sqlpp11MySQL${arg}) -endmacro() +add_library(sqlpp11_mysql_testing INTERFACE) +target_include_directories(sqlpp11_mysql_testing INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + +set(test_names +Json +CustomQuery +DateTime +Sample +Select +Union +DynamicSelect +MoveConstructor +Prepared +Truncated +Update +Remove + ) + +create_test_sourcelist(test_sources test_main.cpp ${test_names}) +add_executable(sqlpp11_mysql_tests ${test_sources}) +target_link_libraries(sqlpp11_mysql_tests PRIVATE sqlpp11 sqlpp11_testing sqlpp11_mysql_testing) +target_link_libraries(sqlpp11_mysql_tests PRIVATE sqlpp11::sqlpp11) +target_link_libraries(sqlpp11_mysql_tests PRIVATE Threads::Threads) +target_link_libraries(sqlpp11_mysql_tests PRIVATE MySQL::MySQL) +target_link_libraries(sqlpp11_mysql_tests PRIVATE date::date) +if(NOT MSVC) + target_compile_options(sqlpp11_mysql_tests PRIVATE -Wall -Wextra -pedantic) +endif() + +# conditionally bump to a higher C++ standard to test compatibility +if (SQLPP11_TESTS_CXX_STD) +set_property(TARGET sqlpp11_mysql_tests PROPERTY CXX_STANDARD ${SQLPP11_TESTS_CXX_STD}) +set_property(TARGET sqlpp11_mysql_tests PROPERTY CXX_STANDARD_REQUIRED yes) + set_property(TARGET sqlpp11_mysql_tests PROPERTY CXX_EXTENSIONS no) +endif() + +foreach(test IN LISTS test_names) + add_test(NAME sqlpp11.mysql.tests.${test} + COMMAND sqlpp11_mysql_tests ${test} + ) +endforeach() -build_and_run(JsonTest) -build_and_run(CustomQuery) -build_and_run(DateTimeTest) -build_and_run(SampleTest) -build_and_run(SelectTest) -build_and_run(UnionTest) -build_and_run(DynamicSelectTest) -build_and_run(MoveConstructorTest) -build_and_run(PreparedTest) -build_and_run(TruncatedTest) -build_and_run(UpdateTest) -build_and_run(RemoveTest) diff --git a/tests/mysql/usage/CustomQuery.cpp b/tests/mysql/usage/CustomQuery.cpp index af0995fa..32794fc5 100644 --- a/tests/mysql/usage/CustomQuery.cpp +++ b/tests/mysql/usage/CustomQuery.cpp @@ -62,7 +62,7 @@ namespace const auto tab = TabSample{}; namespace mysql = sqlpp::mysql; -int main() +int CustomQuery(int, char*[]) { mysql::global_library_init(); diff --git a/tests/mysql/usage/DateTimeTest.cpp b/tests/mysql/usage/DateTime.cpp similarity index 99% rename from tests/mysql/usage/DateTimeTest.cpp rename to tests/mysql/usage/DateTime.cpp index 1cfc848a..e53da8ca 100644 --- a/tests/mysql/usage/DateTimeTest.cpp +++ b/tests/mysql/usage/DateTime.cpp @@ -69,7 +69,7 @@ namespace } namespace mysql = sqlpp::mysql; -int main() +int DateTime(int, char*[]) { auto config = std::make_shared(); config->user = "root"; @@ -164,4 +164,5 @@ int main() { std::cerr << "Unkown exception" << std::endl; } + return 0; } diff --git a/tests/mysql/usage/DynamicSelectTest.cpp b/tests/mysql/usage/DynamicSelect.cpp similarity index 98% rename from tests/mysql/usage/DynamicSelectTest.cpp rename to tests/mysql/usage/DynamicSelect.cpp index 6253c5e5..9493750d 100644 --- a/tests/mysql/usage/DynamicSelectTest.cpp +++ b/tests/mysql/usage/DynamicSelect.cpp @@ -39,7 +39,7 @@ const auto library_raii = sqlpp::mysql::scoped_library_initializer_t{}; namespace mysql = sqlpp::mysql; -int main() +int DynamicSelect(int, char*[]) { auto config = std::make_shared(); config->user = "root"; @@ -87,4 +87,5 @@ int main() std::cerr << "Exception: " << e.what() << std::endl; return 1; } + return 0; } diff --git a/tests/mysql/usage/JsonTest.cpp b/tests/mysql/usage/Json.cpp similarity index 96% rename from tests/mysql/usage/JsonTest.cpp rename to tests/mysql/usage/Json.cpp index ad1b4136..e51eaafb 100644 --- a/tests/mysql/usage/JsonTest.cpp +++ b/tests/mysql/usage/Json.cpp @@ -28,16 +28,18 @@ // JSON support only in MYSQL 5.7.8 and later #if !USE_MARIADB && (LIBMYSQL_VERSION_ID < 50708) -int main() +int Json(int, char*[]) { std::cerr << "Warning: not testing Json, because the MySQL version id is less than 50708" << std::endl; + return 0; } #else // JSON support only in MariaDB 10.2.7 and later #if USE_MARIADB && (MARIADB_VERSION_ID < 100207) -int main() +int Json(int, char*[]) { std::cerr << "Warning: not testing Json, because the MariaDB version id is less than 100207" << std::endl; + return 0; } #else @@ -51,7 +53,7 @@ namespace test } namespace mysql = sqlpp::mysql; -int main() +int Json(int, char*[]) { mysql::global_library_init(); @@ -99,6 +101,7 @@ int main() std::cerr << "Exception: " << e.what() << std::endl; return 1; } + return 0; } #endif #endif diff --git a/tests/mysql/usage/MoveConstructorTest.cpp b/tests/mysql/usage/MoveConstructor.cpp similarity index 98% rename from tests/mysql/usage/MoveConstructorTest.cpp rename to tests/mysql/usage/MoveConstructor.cpp index 4e47dee7..1e650198 100644 --- a/tests/mysql/usage/MoveConstructorTest.cpp +++ b/tests/mysql/usage/MoveConstructor.cpp @@ -38,7 +38,7 @@ #include namespace mysql = sqlpp::mysql; -int main() +int MoveConstructor(int, char*[]) { mysql::global_library_init(); @@ -93,4 +93,5 @@ int main() std::cerr << "Exception: " << e.what() << std::endl; return 1; } + return 0; } diff --git a/tests/mysql/usage/Prepared.cpp b/tests/mysql/usage/Prepared.cpp new file mode 100644 index 00000000..3115a5fe --- /dev/null +++ b/tests/mysql/usage/Prepared.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013 - 2016, 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 "TabSample.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +const auto library_raii = sqlpp::mysql::scoped_library_initializer_t{0, nullptr, nullptr}; + +SQLPP_ALIAS_PROVIDER(left) + +namespace sql = sqlpp::mysql; +const auto tab = TabSample{}; + +void testPreparedStatementResult(sql::connection& db) +{ + auto preparedSelectAll = db.prepare(sqlpp::select(count(tab.alpha)).from(tab).unconditionally()); + auto preparedUpdateAll = db.prepare(sqlpp::update(tab).set(tab.gamma = false).unconditionally()); + + { + // explicit result scope + // if results are released update should execute without exception + auto result = db(preparedSelectAll); + std::ignore = result.front().count; + } + + db(preparedUpdateAll); +} + +int Prepared(int, char*[]) +{ + auto config = std::make_shared(); + config->user = "root"; + config->database = "sqlpp_mysql"; + config->debug = true; + try + { + sql::connection db(config); + } + catch (const sqlpp::exception& e) + { + std::cerr << "For testing, you'll need to create a database sqlpp_mysql for user root (no password)" << std::endl; + std::cerr << e.what() << std::endl; + return 1; + } + try + { + sql::connection db(config); + db.execute(R"(DROP TABLE IF EXISTS tab_sample)"); + db.execute(R"(CREATE TABLE tab_sample ( + alpha bigint(20) AUTO_INCREMENT, + beta varchar(255) DEFAULT NULL, + gamma bool DEFAULT NULL, + PRIMARY KEY (alpha) + ))"); + db.execute(R"(DROP TABLE IF EXISTS tab_foo)"); + db.execute(R"(CREATE TABLE tab_foo ( + omega bigint(20) DEFAULT NULL + ))"); + + testPreparedStatementResult(db); + } + catch (const std::exception& e) + { + std::cerr << "Exception: " << e.what() << std::endl; + return 1; + } + return 0; +} diff --git a/tests/mysql/usage/PreparedTest.cpp b/tests/mysql/usage/PreparedTest.cpp deleted file mode 100644 index e985f831..00000000 --- a/tests/mysql/usage/PreparedTest.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2013 - 2016, 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 "TabSample.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -const auto library_raii = sqlpp::mysql::scoped_library_initializer_t{0, nullptr, nullptr}; - -SQLPP_ALIAS_PROVIDER(left) - -namespace sql = sqlpp::mysql; -const auto tab = TabSample{}; - -void testPreparedStatementResult (sql::connection& db) -{ - auto preparedSelectAll = db.prepare(sqlpp::select(count(tab.alpha)).from(tab).unconditionally()); - auto preparedUpdateAll = db.prepare(sqlpp::update(tab).set(tab.gamma = false).unconditionally()); - - { - // explicit result scope - // if results are released update should execute without exception - auto result = db(preparedSelectAll); - std::ignore = result.front().count; - } - - db(preparedUpdateAll); -} - -int main() -{ - auto config = std::make_shared(); - config->user = "root"; - config->database = "sqlpp_mysql"; - config->debug = true; - try - { - sql::connection db(config); - } - catch (const sqlpp::exception& e) - { - std::cerr << "For testing, you'll need to create a database sqlpp_mysql for user root (no password)" << std::endl; - std::cerr << e.what() << std::endl; - return 1; - } - try - { - sql::connection db(config); - db.execute(R"(DROP TABLE IF EXISTS tab_sample)"); - db.execute(R"(CREATE TABLE tab_sample ( - alpha bigint(20) AUTO_INCREMENT, - beta varchar(255) DEFAULT NULL, - gamma bool DEFAULT NULL, - PRIMARY KEY (alpha) - ))"); - db.execute(R"(DROP TABLE IF EXISTS tab_foo)"); - db.execute(R"(CREATE TABLE tab_foo ( - omega bigint(20) DEFAULT NULL - ))"); - - testPreparedStatementResult(db); - } - catch (const std::exception& e) - { - std::cerr << "Exception: " << e.what() << std::endl; - return 1; - } -} diff --git a/tests/mysql/usage/RemoveTest.cpp b/tests/mysql/usage/Remove.cpp similarity index 98% rename from tests/mysql/usage/RemoveTest.cpp rename to tests/mysql/usage/Remove.cpp index a759b774..1fd67072 100644 --- a/tests/mysql/usage/RemoveTest.cpp +++ b/tests/mysql/usage/Remove.cpp @@ -34,7 +34,7 @@ const auto tab = TabSample{}; namespace sql = sqlpp::mysql; -int main() +int Remove(int, char*[]) { auto config = std::make_shared(); config->user = "root"; @@ -75,5 +75,6 @@ int main() std::cerr << "Exception: " << e.what() << std::endl; return 1; } + return 0; } diff --git a/tests/mysql/usage/SampleTest.cpp b/tests/mysql/usage/Sample.cpp similarity index 99% rename from tests/mysql/usage/SampleTest.cpp rename to tests/mysql/usage/Sample.cpp index b547cddf..a317d1c8 100644 --- a/tests/mysql/usage/SampleTest.cpp +++ b/tests/mysql/usage/Sample.cpp @@ -35,7 +35,7 @@ SQLPP_ALIAS_PROVIDER(left) SQLPP_ALIAS_PROVIDER(right) namespace mysql = sqlpp::mysql; -int main() +int Sample(int, char*[]) { sqlpp::mysql::global_library_init(); @@ -209,4 +209,5 @@ int main() std::cerr << "Exception: " << e.what() << std::endl; return 1; } + return 0; } diff --git a/tests/mysql/usage/SelectTest.cpp b/tests/mysql/usage/Select.cpp similarity index 99% rename from tests/mysql/usage/SelectTest.cpp rename to tests/mysql/usage/Select.cpp index 65cb994e..d7787065 100644 --- a/tests/mysql/usage/SelectTest.cpp +++ b/tests/mysql/usage/Select.cpp @@ -83,7 +83,7 @@ void testSelectAll(sql::connection& db, int expectedRowCount) std::cerr << "--------------------------------------" << std::endl; } -int main() +int Select(int, char*[]) { auto config = std::make_shared(); config->user = "root"; @@ -171,4 +171,5 @@ int main() std::cerr << "Exception: " << e.what() << std::endl; return 1; } + return 0; } diff --git a/tests/mysql/usage/TruncatedTest.cpp b/tests/mysql/usage/Truncated.cpp similarity index 98% rename from tests/mysql/usage/TruncatedTest.cpp rename to tests/mysql/usage/Truncated.cpp index cb57f10c..267b429d 100644 --- a/tests/mysql/usage/TruncatedTest.cpp +++ b/tests/mysql/usage/Truncated.cpp @@ -42,7 +42,7 @@ const auto library_raii = sqlpp::mysql::scoped_library_initializer_t{0, nullptr, namespace sql = sqlpp::mysql; const auto tab = TabSample{}; -int main() +int Truncated(int, char*[]) { auto config = std::make_shared(); config->user = "root"; @@ -105,4 +105,5 @@ int main() std::cerr << "Exception: " << e.what() << std::endl; return 1; } + return 0; } diff --git a/tests/mysql/usage/UnionTest.cpp b/tests/mysql/usage/Union.cpp similarity index 98% rename from tests/mysql/usage/UnionTest.cpp rename to tests/mysql/usage/Union.cpp index 5e58c7f1..6411c84c 100644 --- a/tests/mysql/usage/UnionTest.cpp +++ b/tests/mysql/usage/Union.cpp @@ -34,7 +34,7 @@ const auto library_raii = sqlpp::mysql::scoped_library_initializer_t{0, nullptr, namespace sql = sqlpp::mysql; const auto tab = TabSample{}; -int main() +int Union(int, char*[]) { auto config = std::make_shared(); config->user = "root"; @@ -78,4 +78,5 @@ int main() std::cerr << "Exception: " << e.what() << std::endl; return 1; } + return 0; } diff --git a/tests/mysql/usage/UpdateTest.cpp b/tests/mysql/usage/Update.cpp similarity index 98% rename from tests/mysql/usage/UpdateTest.cpp rename to tests/mysql/usage/Update.cpp index 20780ea3..d7aff71a 100644 --- a/tests/mysql/usage/UpdateTest.cpp +++ b/tests/mysql/usage/Update.cpp @@ -34,7 +34,7 @@ const auto tab = TabSample{}; namespace sql = sqlpp::mysql; -int main() +int Update(int, char*[]) { auto config = std::make_shared(); config->user = "root"; @@ -75,5 +75,6 @@ int main() std::cerr << "Exception: " << e.what() << std::endl; return 1; } + return 0; }