0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-15 20:31:16 +08:00

Fix missing inline attributes for mysql connector

Changed mysql usage tests to be linked into one executable.
This provokes multiple definition errors for non-inlined free
functions.
This commit is contained in:
Roland Bock 2021-10-11 09:04:57 +02:00
parent caee00e849
commit bde010351d
16 changed files with 199 additions and 147 deletions

View File

@ -71,7 +71,7 @@ namespace sqlpp
const auto date_digits = std::vector<char>{1, 1, 1, 1, 0, 1, 1, 0, 1, 1}; // 2015-10-28 const auto date_digits = std::vector<char>{1, 1, 1, 1, 0, 1, 1, 0, 1, 1}; // 2015-10-28
const auto time_digits = std::vector<char>{0, 1, 1, 0, 1, 1, 0, 1, 1}; // T23:00:12 const auto time_digits = std::vector<char>{0, 1, 1, 0, 1, 1, 0, 1, 1}; // T23:00:12
auto check_digits(const char* text, const std::vector<char>& digitFlags) -> bool inline auto check_digits(const char* text, const std::vector<char>& digitFlags) -> bool
{ {
for (const auto digitFlag : digitFlags) for (const auto digitFlag : digitFlags)
{ {

View File

@ -63,12 +63,12 @@ namespace sqlpp
} }
}; };
void thread_init() inline void thread_init()
{ {
thread_local MySqlThreadInitializer threadInitializer; 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(), if (!mysql_real_connect(mysql, config.host.empty() ? nullptr : config.host.c_str(),
config.user.empty() ? nullptr : config.user.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); 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(); 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(); thread_init();
@ -171,7 +171,7 @@ namespace sqlpp
} }
} }
std::shared_ptr<detail::prepared_statement_handle_t> prepare_statement(detail::connection_handle_t& handle, inline std::shared_ptr<detail::prepared_statement_handle_t> prepare_statement(detail::connection_handle_t& handle,
const std::string& statement, const std::string& statement,
size_t no_of_parameters, size_t no_of_parameters,
size_t no_of_columns) size_t no_of_columns)
@ -213,7 +213,7 @@ namespace sqlpp
}; };
// This will also cleanup when the program shuts down // 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); static const auto global_init_and_end = scoped_library_initializer_t(argc, argv, groups);
} }

View File

@ -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) find_package(Threads REQUIRED)
macro(build_and_run arg) add_library(sqlpp11_mysql_testing INTERFACE)
add_executable(Sqlpp11MySQL${arg} ${arg}.cpp) target_include_directories(sqlpp11_mysql_testing INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(Sqlpp11MySQL${arg} PRIVATE Threads::Threads)
target_link_libraries(Sqlpp11MySQL${arg} PRIVATE sqlpp11::sqlpp11) set(test_names
target_link_libraries(Sqlpp11MySQL${arg} PRIVATE MySQL::MySQL) Json
target_link_libraries(Sqlpp11MySQL${arg} PRIVATE date::date) CustomQuery
if(${arg} STREQUAL "JsonTest") DateTime
target_link_libraries(Sqlpp11MySQL${arg} PRIVATE MySQL::MySQL) Sample
endif() Select
if(NOT MSVC) Union
target_compile_options(Sqlpp11MySQL${arg} PRIVATE -Wall -Wextra -pedantic) DynamicSelect
endif() MoveConstructor
add_test(${arg} Sqlpp11MySQL${arg}) Prepared
endmacro() 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)

View File

@ -62,7 +62,7 @@ namespace
const auto tab = TabSample{}; const auto tab = TabSample{};
namespace mysql = sqlpp::mysql; namespace mysql = sqlpp::mysql;
int main() int CustomQuery(int, char*[])
{ {
mysql::global_library_init(); mysql::global_library_init();

View File

@ -69,7 +69,7 @@ namespace
} }
namespace mysql = sqlpp::mysql; namespace mysql = sqlpp::mysql;
int main() int DateTime(int, char*[])
{ {
auto config = std::make_shared<mysql::connection_config>(); auto config = std::make_shared<mysql::connection_config>();
config->user = "root"; config->user = "root";
@ -164,4 +164,5 @@ int main()
{ {
std::cerr << "Unkown exception" << std::endl; std::cerr << "Unkown exception" << std::endl;
} }
return 0;
} }

View File

@ -39,7 +39,7 @@
const auto library_raii = sqlpp::mysql::scoped_library_initializer_t{}; const auto library_raii = sqlpp::mysql::scoped_library_initializer_t{};
namespace mysql = sqlpp::mysql; namespace mysql = sqlpp::mysql;
int main() int DynamicSelect(int, char*[])
{ {
auto config = std::make_shared<mysql::connection_config>(); auto config = std::make_shared<mysql::connection_config>();
config->user = "root"; config->user = "root";
@ -87,4 +87,5 @@ int main()
std::cerr << "Exception: " << e.what() << std::endl; std::cerr << "Exception: " << e.what() << std::endl;
return 1; return 1;
} }
return 0;
} }

View File

@ -28,16 +28,18 @@
// JSON support only in MYSQL 5.7.8 and later // JSON support only in MYSQL 5.7.8 and later
#if !USE_MARIADB && (LIBMYSQL_VERSION_ID < 50708) #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; std::cerr << "Warning: not testing Json, because the MySQL version id is less than 50708" << std::endl;
return 0;
} }
#else #else
// JSON support only in MariaDB 10.2.7 and later // JSON support only in MariaDB 10.2.7 and later
#if USE_MARIADB && (MARIADB_VERSION_ID < 100207) #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; std::cerr << "Warning: not testing Json, because the MariaDB version id is less than 100207" << std::endl;
return 0;
} }
#else #else
@ -51,7 +53,7 @@ namespace test
} }
namespace mysql = sqlpp::mysql; namespace mysql = sqlpp::mysql;
int main() int Json(int, char*[])
{ {
mysql::global_library_init(); mysql::global_library_init();
@ -99,6 +101,7 @@ int main()
std::cerr << "Exception: " << e.what() << std::endl; std::cerr << "Exception: " << e.what() << std::endl;
return 1; return 1;
} }
return 0;
} }
#endif #endif
#endif #endif

View File

@ -38,7 +38,7 @@
#include <vector> #include <vector>
namespace mysql = sqlpp::mysql; namespace mysql = sqlpp::mysql;
int main() int MoveConstructor(int, char*[])
{ {
mysql::global_library_init(); mysql::global_library_init();
@ -93,4 +93,5 @@ int main()
std::cerr << "Exception: " << e.what() << std::endl; std::cerr << "Exception: " << e.what() << std::endl;
return 1; return 1;
} }
return 0;
} }

View File

@ -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 <cassert>
#include <sqlpp11/alias_provider.h>
#include <sqlpp11/functions.h>
#include <sqlpp11/insert.h>
#include <sqlpp11/mysql/connection.h>
#include <sqlpp11/remove.h>
#include <sqlpp11/select.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/update.h>
#include <iostream>
#include <vector>
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<sql::connection_config>();
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;
}

View File

@ -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 <cassert>
#include <sqlpp11/alias_provider.h>
#include <sqlpp11/functions.h>
#include <sqlpp11/insert.h>
#include <sqlpp11/mysql/connection.h>
#include <sqlpp11/remove.h>
#include <sqlpp11/select.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/update.h>
#include <iostream>
#include <vector>
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<sql::connection_config>();
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;
}
}

View File

@ -34,7 +34,7 @@ const auto tab = TabSample{};
namespace sql = sqlpp::mysql; namespace sql = sqlpp::mysql;
int main() int Remove(int, char*[])
{ {
auto config = std::make_shared<sql::connection_config>(); auto config = std::make_shared<sql::connection_config>();
config->user = "root"; config->user = "root";
@ -75,5 +75,6 @@ int main()
std::cerr << "Exception: " << e.what() << std::endl; std::cerr << "Exception: " << e.what() << std::endl;
return 1; return 1;
} }
return 0;
} }

View File

@ -35,7 +35,7 @@ SQLPP_ALIAS_PROVIDER(left)
SQLPP_ALIAS_PROVIDER(right) SQLPP_ALIAS_PROVIDER(right)
namespace mysql = sqlpp::mysql; namespace mysql = sqlpp::mysql;
int main() int Sample(int, char*[])
{ {
sqlpp::mysql::global_library_init(); sqlpp::mysql::global_library_init();
@ -209,4 +209,5 @@ int main()
std::cerr << "Exception: " << e.what() << std::endl; std::cerr << "Exception: " << e.what() << std::endl;
return 1; return 1;
} }
return 0;
} }

View File

@ -83,7 +83,7 @@ void testSelectAll(sql::connection& db, int expectedRowCount)
std::cerr << "--------------------------------------" << std::endl; std::cerr << "--------------------------------------" << std::endl;
} }
int main() int Select(int, char*[])
{ {
auto config = std::make_shared<sql::connection_config>(); auto config = std::make_shared<sql::connection_config>();
config->user = "root"; config->user = "root";
@ -171,4 +171,5 @@ int main()
std::cerr << "Exception: " << e.what() << std::endl; std::cerr << "Exception: " << e.what() << std::endl;
return 1; return 1;
} }
return 0;
} }

View File

@ -42,7 +42,7 @@ const auto library_raii = sqlpp::mysql::scoped_library_initializer_t{0, nullptr,
namespace sql = sqlpp::mysql; namespace sql = sqlpp::mysql;
const auto tab = TabSample{}; const auto tab = TabSample{};
int main() int Truncated(int, char*[])
{ {
auto config = std::make_shared<sql::connection_config>(); auto config = std::make_shared<sql::connection_config>();
config->user = "root"; config->user = "root";
@ -105,4 +105,5 @@ int main()
std::cerr << "Exception: " << e.what() << std::endl; std::cerr << "Exception: " << e.what() << std::endl;
return 1; return 1;
} }
return 0;
} }

View File

@ -34,7 +34,7 @@ const auto library_raii = sqlpp::mysql::scoped_library_initializer_t{0, nullptr,
namespace sql = sqlpp::mysql; namespace sql = sqlpp::mysql;
const auto tab = TabSample{}; const auto tab = TabSample{};
int main() int Union(int, char*[])
{ {
auto config = std::make_shared<sql::connection_config>(); auto config = std::make_shared<sql::connection_config>();
config->user = "root"; config->user = "root";
@ -78,4 +78,5 @@ int main()
std::cerr << "Exception: " << e.what() << std::endl; std::cerr << "Exception: " << e.what() << std::endl;
return 1; return 1;
} }
return 0;
} }

View File

@ -34,7 +34,7 @@ const auto tab = TabSample{};
namespace sql = sqlpp::mysql; namespace sql = sqlpp::mysql;
int main() int Update(int, char*[])
{ {
auto config = std::make_shared<sql::connection_config>(); auto config = std::make_shared<sql::connection_config>();
config->user = "root"; config->user = "root";
@ -75,5 +75,6 @@ int main()
std::cerr << "Exception: " << e.what() << std::endl; std::cerr << "Exception: " << e.what() << std::endl;
return 1; return 1;
} }
return 0;
} }