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

Fix missing inline attributes for sqlite3 connector

Changed sqlite3 usage tests to be linked into one executable.
This provokes multiple definition errors for non-inlined free
functions.
Also ran clang-format on the changed headers.
This commit is contained in:
Roland Bock 2021-10-11 08:23:36 +02:00
parent a3c2b186fb
commit caee00e849
17 changed files with 511 additions and 503 deletions

View File

@ -49,7 +49,7 @@ namespace sqlpp
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
const auto ms_digits = std::vector<char>{0, 1, 1, 1}; // .123 const auto ms_digits = std::vector<char>{0, 1, 1, 1}; // .123
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)
{ {
@ -79,11 +79,11 @@ namespace sqlpp
public: public:
bind_result_t() = default; bind_result_t() = default;
bind_result_t(const std::shared_ptr<detail::prepared_statement_handle_t>& handle) : _handle(handle) bind_result_t(const std::shared_ptr<detail::prepared_statement_handle_t>& handle) : _handle(handle)
{ {
if (_handle and _handle->debug) if (_handle and _handle->debug)
std::cerr << "Sqlite3 debug: Constructing bind result, using handle at " << _handle.get() << std::endl; std::cerr << "Sqlite3 debug: Constructing bind result, using handle at " << _handle.get() << std::endl;
} }
bind_result_t(const bind_result_t&) = delete; bind_result_t(const bind_result_t&) = delete;
bind_result_t(bind_result_t&& rhs) = default; bind_result_t(bind_result_t&& rhs) = default;
@ -120,172 +120,172 @@ namespace sqlpp
} }
} }
void _bind_boolean_result(size_t index, signed char* value, bool* is_null) void _bind_boolean_result(size_t index, signed char* value, bool* is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding boolean result " << *value << " at index: " << index << std::endl;
*value = static_cast<signed char>(sqlite3_column_int(_handle->sqlite_statement, static_cast<int>(index)));
*is_null = sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)) == SQLITE_NULL;
}
void _bind_floating_point_result(size_t index, double* value, bool* is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding floating_point result " << *value << " at index: " << index << std::endl;
switch (sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)))
{
case (SQLITE3_TEXT):
*value = atof(
reinterpret_cast<const char*>(sqlite3_column_text(_handle->sqlite_statement, static_cast<int>(index))));
break;
default:
*value = sqlite3_column_double(_handle->sqlite_statement, static_cast<int>(index));
}
*is_null = sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)) == SQLITE_NULL;
}
void _bind_integral_result(size_t index, int64_t* value, bool* is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding integral result " << *value << " at index: " << index << std::endl;
*value = sqlite3_column_int64(_handle->sqlite_statement, static_cast<int>(index));
*is_null = sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)) == SQLITE_NULL;
}
void _bind_unsigned_integral_result(size_t index, uint64_t* value, bool* is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding unsigned integral result " << *value << " at index: " << index
<< std::endl;
*value = static_cast<uint64_t>(sqlite3_column_int64(_handle->sqlite_statement, static_cast<int>(index)));
*is_null = sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)) == SQLITE_NULL;
}
void _bind_text_result(size_t index, const char** value, size_t* len)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding text result at index: " << index << std::endl;
*value = (reinterpret_cast<const char*>(sqlite3_column_text(_handle->sqlite_statement, static_cast<int>(index))));
*len = sqlite3_column_bytes(_handle->sqlite_statement, static_cast<int>(index));
}
void _bind_blob_result(size_t index, const uint8_t** value, size_t* len)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding text result at index: " << index << std::endl;
*value =
(reinterpret_cast<const uint8_t*>(sqlite3_column_blob(_handle->sqlite_statement, static_cast<int>(index))));
*len = sqlite3_column_bytes(_handle->sqlite_statement, static_cast<int>(index));
}
void _bind_date_result(size_t index, ::sqlpp::chrono::day_point* value, bool* is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding date result at index: " << index << std::endl;
*is_null = sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)) == SQLITE_NULL;
if (*is_null)
{
*value = {};
return;
}
const auto date_string =
reinterpret_cast<const char*>(sqlite3_column_text(_handle->sqlite_statement, static_cast<int>(index)));
if (_handle->debug)
std::cerr << "Sqlite3 debug: date string: " << date_string << std::endl;
if (detail::check_digits(date_string, detail::date_digits))
{
const auto ymd = ::date::year(std::atoi(date_string)) / atoi(date_string + 5) / atoi(date_string + 8);
*value = ::sqlpp::chrono::day_point(ymd);
}
else
{ {
if (_handle->debug) if (_handle->debug)
std::cerr << "Sqlite3 debug: invalid date result: " << date_string << std::endl; std::cerr << "Sqlite3 debug: binding boolean result " << *value << " at index: " << index << std::endl;
*value = {};
}
}
void _bind_date_time_result(size_t index, ::sqlpp::chrono::microsecond_point* value, bool* is_null) *value = static_cast<signed char>(sqlite3_column_int(_handle->sqlite_statement, static_cast<int>(index)));
{ *is_null = sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)) == SQLITE_NULL;
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding date result at index: " << index << std::endl;
*is_null = sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)) == SQLITE_NULL;
if (*is_null)
{
*value = {};
return;
} }
const auto date_time_string = void _bind_floating_point_result(size_t index, double* value, bool* is_null)
reinterpret_cast<const char*>(sqlite3_column_text(_handle->sqlite_statement, static_cast<int>(index)));
if (_handle->debug)
std::cerr << "Sqlite3 debug: date_time string: " << date_time_string << std::endl;
if (detail::check_digits(date_time_string, detail::date_digits))
{
const auto ymd =
::date::year(std::atoi(date_time_string)) / atoi(date_time_string + 5) / atoi(date_time_string + 8);
*value = ::sqlpp::chrono::day_point(ymd);
}
else
{ {
if (_handle->debug) if (_handle->debug)
std::cerr << "Sqlite3 debug: invalid date_time result: " << date_time_string << std::endl; std::cerr << "Sqlite3 debug: binding floating_point result " << *value << " at index: " << index << std::endl;
*value = {};
return; switch (sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)))
{
case (SQLITE3_TEXT):
*value = atof(
reinterpret_cast<const char*>(sqlite3_column_text(_handle->sqlite_statement, static_cast<int>(index))));
break;
default:
*value = sqlite3_column_double(_handle->sqlite_statement, static_cast<int>(index));
}
*is_null = sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)) == SQLITE_NULL;
} }
const auto time_string = date_time_string + 10; void _bind_integral_result(size_t index, int64_t* value, bool* is_null)
if (detail::check_digits(time_string, detail::time_digits))
{ {
*value += ::std::chrono::hours(std::atoi(time_string + 1)) + std::chrono::minutes(std::atoi(time_string + 4)) + if (_handle->debug)
std::chrono::seconds(std::atoi(time_string + 7)); std::cerr << "Sqlite3 debug: binding integral result " << *value << " at index: " << index << std::endl;
*value = sqlite3_column_int64(_handle->sqlite_statement, static_cast<int>(index));
*is_null = sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)) == SQLITE_NULL;
} }
else
void _bind_unsigned_integral_result(size_t index, uint64_t* value, bool* is_null)
{ {
return; if (_handle->debug)
std::cerr << "Sqlite3 debug: binding unsigned integral result " << *value << " at index: " << index
<< std::endl;
*value = static_cast<uint64_t>(sqlite3_column_int64(_handle->sqlite_statement, static_cast<int>(index)));
*is_null = sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)) == SQLITE_NULL;
} }
const auto ms_string = time_string + 9;
if (detail::check_digits(ms_string, detail::ms_digits) and ms_string[4] == '\0') void _bind_text_result(size_t index, const char** value, size_t* len)
{ {
*value += ::std::chrono::milliseconds(std::atoi(ms_string + 1)); if (_handle->debug)
std::cerr << "Sqlite3 debug: binding text result at index: " << index << std::endl;
*value =
(reinterpret_cast<const char*>(sqlite3_column_text(_handle->sqlite_statement, static_cast<int>(index))));
*len = sqlite3_column_bytes(_handle->sqlite_statement, static_cast<int>(index));
} }
else
void _bind_blob_result(size_t index, const uint8_t** value, size_t* len)
{ {
return; if (_handle->debug)
std::cerr << "Sqlite3 debug: binding text result at index: " << index << std::endl;
*value =
(reinterpret_cast<const uint8_t*>(sqlite3_column_blob(_handle->sqlite_statement, static_cast<int>(index))));
*len = sqlite3_column_bytes(_handle->sqlite_statement, static_cast<int>(index));
}
void _bind_date_result(size_t index, ::sqlpp::chrono::day_point* value, bool* is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding date result at index: " << index << std::endl;
*is_null = sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)) == SQLITE_NULL;
if (*is_null)
{
*value = {};
return;
}
const auto date_string =
reinterpret_cast<const char*>(sqlite3_column_text(_handle->sqlite_statement, static_cast<int>(index)));
if (_handle->debug)
std::cerr << "Sqlite3 debug: date string: " << date_string << std::endl;
if (detail::check_digits(date_string, detail::date_digits))
{
const auto ymd = ::date::year(std::atoi(date_string)) / atoi(date_string + 5) / atoi(date_string + 8);
*value = ::sqlpp::chrono::day_point(ymd);
}
else
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: invalid date result: " << date_string << std::endl;
*value = {};
}
}
void _bind_date_time_result(size_t index, ::sqlpp::chrono::microsecond_point* value, bool* is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding date result at index: " << index << std::endl;
*is_null = sqlite3_column_type(_handle->sqlite_statement, static_cast<int>(index)) == SQLITE_NULL;
if (*is_null)
{
*value = {};
return;
}
const auto date_time_string =
reinterpret_cast<const char*>(sqlite3_column_text(_handle->sqlite_statement, static_cast<int>(index)));
if (_handle->debug)
std::cerr << "Sqlite3 debug: date_time string: " << date_time_string << std::endl;
if (detail::check_digits(date_time_string, detail::date_digits))
{
const auto ymd =
::date::year(std::atoi(date_time_string)) / atoi(date_time_string + 5) / atoi(date_time_string + 8);
*value = ::sqlpp::chrono::day_point(ymd);
}
else
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: invalid date_time result: " << date_time_string << std::endl;
*value = {};
return;
}
const auto time_string = date_time_string + 10;
if (detail::check_digits(time_string, detail::time_digits))
{
*value += ::std::chrono::hours(std::atoi(time_string + 1)) +
std::chrono::minutes(std::atoi(time_string + 4)) + std::chrono::seconds(std::atoi(time_string + 7));
}
else
{
return;
}
const auto ms_string = time_string + 9;
if (detail::check_digits(ms_string, detail::ms_digits) and ms_string[4] == '\0')
{
*value += ::std::chrono::milliseconds(std::atoi(ms_string + 1));
}
else
{
return;
}
} }
}
private: private:
bool next_impl() bool next_impl()
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: Accessing next row of handle at " << _handle.get() << std::endl;
auto rc = sqlite3_step(_handle->sqlite_statement);
switch (rc)
{ {
case SQLITE_ROW: if (_handle->debug)
return true; std::cerr << "Sqlite3 debug: Accessing next row of handle at " << _handle.get() << std::endl;
case SQLITE_DONE:
return false; auto rc = sqlite3_step(_handle->sqlite_statement);
default:
throw sqlpp::exception("Sqlite3 error: Unexpected return value for sqlite3_step()"); switch (rc)
{
case SQLITE_ROW:
return true;
case SQLITE_DONE:
return false;
default:
throw sqlpp::exception("Sqlite3 error: Unexpected return value for sqlite3_step()");
}
} }
}
}; };
} // namespace sqlite3 } // namespace sqlite3
} // namespace sqlpp } // namespace sqlpp

View File

@ -51,7 +51,7 @@
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4251) #pragma warning(disable : 4251)
#endif #endif
namespace sqlpp namespace sqlpp
@ -59,7 +59,7 @@ namespace sqlpp
namespace sqlite3 namespace sqlite3
{ {
#ifdef SQLPP_DYNAMIC_LOADING #ifdef SQLPP_DYNAMIC_LOADING
using namespace dynamic; using namespace dynamic;
#endif #endif
namespace detail namespace detail
@ -111,8 +111,8 @@ namespace sqlpp
connection_handle& operator=(connection_handle&&) = delete; connection_handle& operator=(connection_handle&&) = delete;
}; };
detail::prepared_statement_handle_t prepare_statement(detail::connection_handle& handle, inline detail::prepared_statement_handle_t prepare_statement(detail::connection_handle& handle,
const std::string& statement) const std::string& statement)
{ {
if (handle.config.debug) if (handle.config.debug)
std::cerr << "Sqlite3 debug: Preparing: '" << statement << "'" << std::endl; std::cerr << "Sqlite3 debug: Preparing: '" << statement << "'" << std::endl;
@ -124,16 +124,15 @@ namespace sqlpp
if (rc != SQLITE_OK) if (rc != SQLITE_OK)
{ {
throw sqlpp::exception("Sqlite3 error: Could not prepare statement: " + throw sqlpp::exception(
std::string(sqlite3_errmsg(handle.sqlite)) + " (statement was >>" + "Sqlite3 error: Could not prepare statement: " + std::string(sqlite3_errmsg(handle.sqlite)) +
(rc == SQLITE_TOOBIG ? statement.substr(0, 128) + "..." : statement) + " (statement was >>" + (rc == SQLITE_TOOBIG ? statement.substr(0, 128) + "..." : statement) + "<<\n");
"<<\n");
} }
return result; return result;
} }
void execute_statement(detail::connection_handle& handle, detail::prepared_statement_handle_t& prepared) inline void execute_statement(detail::connection_handle& handle, detail::prepared_statement_handle_t& prepared)
{ {
auto rc = sqlite3_step(prepared.sqlite_statement); auto rc = sqlite3_step(prepared.sqlite_statement);
switch (rc) switch (rc)
@ -143,13 +142,13 @@ namespace sqlpp
case SQLITE_DONE: case SQLITE_DONE:
return; return;
default: default:
if(handle.config.debug) if (handle.config.debug)
std::cerr << "Sqlite3 debug: sqlite3_step return code: " << rc << std::endl; std::cerr << "Sqlite3 debug: sqlite3_step return code: " << rc << std::endl;
throw sqlpp::exception("Sqlite3 error: Could not execute statement: " + throw sqlpp::exception("Sqlite3 error: Could not execute statement: " +
std::string(sqlite3_errmsg(handle.sqlite))); std::string(sqlite3_errmsg(handle.sqlite)));
} }
} }
} } // namespace detail
class connection; class connection;
@ -200,81 +199,79 @@ namespace sqlpp
transaction_status_type _transaction_status = transaction_status_type::none; transaction_status_type _transaction_status = transaction_status_type::none;
// direct execution // direct execution
bind_result_t select_impl(const std::string& statement) bind_result_t select_impl(const std::string& statement)
{
std::unique_ptr<detail::prepared_statement_handle_t> prepared(
new detail::prepared_statement_handle_t(prepare_statement(*_handle, statement)));
if (!prepared)
{ {
throw sqlpp::exception("Sqlite3 error: Could not store result set"); std::unique_ptr<detail::prepared_statement_handle_t> prepared(
new detail::prepared_statement_handle_t(prepare_statement(*_handle, statement)));
if (!prepared)
{
throw sqlpp::exception("Sqlite3 error: Could not store result set");
}
return {std::move(prepared)};
} }
return {std::move(prepared)}; size_t insert_impl(const std::string& statement)
} {
auto prepared = prepare_statement(*_handle, statement);
execute_statement(*_handle, prepared);
size_t insert_impl(const std::string& statement) return sqlite3_last_insert_rowid(_handle->sqlite);
{ }
auto prepared = prepare_statement(*_handle, statement);
execute_statement(*_handle, prepared);
return sqlite3_last_insert_rowid(_handle->sqlite); size_t update_impl(const std::string& statement)
} {
auto prepared = prepare_statement(*_handle, statement);
size_t update_impl(const std::string& statement) execute_statement(*_handle, prepared);
{ return sqlite3_changes(_handle->sqlite);
auto prepared = prepare_statement(*_handle, statement); }
execute_statement(*_handle, prepared);
return sqlite3_changes(_handle->sqlite);
}
size_t remove_impl(const std::string& statement)
{
auto prepared = prepare_statement(*_handle, statement);
execute_statement(*_handle, prepared);
return sqlite3_changes(_handle->sqlite);
}
size_t remove_impl(const std::string& statement)
{
auto prepared = prepare_statement(*_handle, statement);
execute_statement(*_handle, prepared);
return sqlite3_changes(_handle->sqlite);
}
// prepared execution // prepared execution
prepared_statement_t prepare_impl(const std::string& statement) prepared_statement_t prepare_impl(const std::string& statement)
{ {
return {std::unique_ptr<detail::prepared_statement_handle_t>( return {std::unique_ptr<detail::prepared_statement_handle_t>(
new detail::prepared_statement_handle_t(prepare_statement(*_handle, statement)))}; new detail::prepared_statement_handle_t(prepare_statement(*_handle, statement)))};
} }
bind_result_t run_prepared_select_impl(prepared_statement_t& prepared_statement) bind_result_t run_prepared_select_impl(prepared_statement_t& prepared_statement)
{ {
return {prepared_statement._handle}; return {prepared_statement._handle};
} }
size_t run_prepared_insert_impl(prepared_statement_t& prepared_statement) size_t run_prepared_insert_impl(prepared_statement_t& prepared_statement)
{ {
execute_statement(*_handle, *prepared_statement._handle.get()); execute_statement(*_handle, *prepared_statement._handle.get());
return sqlite3_last_insert_rowid(_handle->sqlite); return sqlite3_last_insert_rowid(_handle->sqlite);
} }
size_t run_prepared_update_impl(prepared_statement_t& prepared_statement) size_t run_prepared_update_impl(prepared_statement_t& prepared_statement)
{ {
execute_statement(*_handle, *prepared_statement._handle.get()); execute_statement(*_handle, *prepared_statement._handle.get());
return sqlite3_changes(_handle->sqlite); return sqlite3_changes(_handle->sqlite);
} }
size_t run_prepared_remove_impl(prepared_statement_t& prepared_statement) size_t run_prepared_remove_impl(prepared_statement_t& prepared_statement)
{ {
execute_statement(*_handle, *prepared_statement._handle.get()); execute_statement(*_handle, *prepared_statement._handle.get());
return sqlite3_changes(_handle->sqlite); return sqlite3_changes(_handle->sqlite);
} }
size_t run_prepared_execute_impl(prepared_statement_t& prepared_statement) size_t run_prepared_execute_impl(prepared_statement_t& prepared_statement)
{ {
execute_statement(*_handle, *prepared_statement._handle.get()); execute_statement(*_handle, *prepared_statement._handle.get());
return sqlite3_changes(_handle->sqlite);
}
return sqlite3_changes(_handle->sqlite);
}
public: public:
using _prepared_statement_t = prepared_statement_t; using _prepared_statement_t = prepared_statement_t;
@ -299,14 +296,14 @@ namespace sqlpp
return ::sqlpp::serialize(t, context); return ::sqlpp::serialize(t, context);
} }
connection(connection_config config) : _handle(new detail::connection_handle(std::move(config))) connection(connection_config config) : _handle(new detail::connection_handle(std::move(config)))
{ {
} }
connection(connection&&) noexcept = default; connection(connection&&) noexcept = default;
connection& operator=(connection&&) noexcept = default; connection& operator=(connection&&) noexcept = default;
~connection() = default; ~connection() = default;
connection(const connection&) = delete; connection(const connection&) = delete;
connection& operator=(const connection&) = delete; connection& operator=(const connection&) = delete;
@ -412,12 +409,12 @@ namespace sqlpp
} }
//! execute arbitrary command (e.g. create a table) //! execute arbitrary command (e.g. create a table)
size_t execute(const std::string& statement) size_t execute(const std::string& statement)
{ {
auto prepared = prepare_statement(*_handle, statement); auto prepared = prepare_statement(*_handle, statement);
execute_statement(*_handle, prepared); execute_statement(*_handle, prepared);
return sqlite3_changes(_handle->sqlite); return sqlite3_changes(_handle->sqlite);
} }
template < template <
typename Execute, typename Execute,
@ -446,20 +443,20 @@ namespace sqlpp
} }
//! escape given string (does not quote, though) //! escape given string (does not quote, though)
std::string escape(const std::string& s) const std::string escape(const std::string& s) const
{
std::string t;
t.reserve(s.size());
for (const char c : s)
{ {
if (c == '\'') std::string t;
t.push_back(c); t.reserve(s.size());
t.push_back(c);
}
return t; for (const char c : s)
} {
if (c == '\'')
t.push_back(c);
t.push_back(c);
}
return t;
}
//! call run on the argument //! call run on the argument
template <typename T> template <typename T>
@ -496,98 +493,99 @@ namespace sqlpp
} }
//! set the transaction isolation level for this connection //! set the transaction isolation level for this connection
void set_default_isolation_level(isolation_level level) void set_default_isolation_level(isolation_level level)
{
if (level == sqlpp::isolation_level::read_uncommitted)
{ {
execute("pragma read_uncommitted = true"); if (level == sqlpp::isolation_level::read_uncommitted)
} else { {
execute("pragma read_uncommitted = false"); execute("pragma read_uncommitted = true");
}
else
{
execute("pragma read_uncommitted = false");
}
} }
}
//! get the currently active transaction isolation level //! get the currently active transaction isolation level
sqlpp::isolation_level get_default_isolation_level() sqlpp::isolation_level get_default_isolation_level()
{ {
auto stmt = prepare_statement(*_handle, "pragma read_uncommitted"); auto stmt = prepare_statement(*_handle, "pragma read_uncommitted");
execute_statement(*_handle, stmt); execute_statement(*_handle, stmt);
int level = sqlite3_column_int(stmt.sqlite_statement, 0); int level = sqlite3_column_int(stmt.sqlite_statement, 0);
return level == 0 ? sqlpp::isolation_level::serializable : return level == 0 ? sqlpp::isolation_level::serializable : sqlpp::isolation_level::read_uncommitted;
sqlpp::isolation_level::read_uncommitted; }
}
//! start transaction //! start transaction
void start_transaction() void start_transaction()
{
if (_transaction_status == transaction_status_type::active)
{ {
throw sqlpp::exception("Sqlite3 error: Cannot have more than one open transaction per connection"); if (_transaction_status == transaction_status_type::active)
} {
throw sqlpp::exception("Sqlite3 error: Cannot have more than one open transaction per connection");
}
_transaction_status = transaction_status_type::maybe; _transaction_status = transaction_status_type::maybe;
auto prepared = prepare_statement(*_handle, "BEGIN"); auto prepared = prepare_statement(*_handle, "BEGIN");
execute_statement(*_handle, prepared); execute_statement(*_handle, prepared);
_transaction_status = transaction_status_type::active; _transaction_status = transaction_status_type::active;
} }
//! commit transaction (or throw if the transaction has been finished already) //! commit transaction (or throw if the transaction has been finished already)
void commit_transaction() void commit_transaction()
{
if (_transaction_status == transaction_status_type::none)
{ {
throw sqlpp::exception("Sqlite3 error: Cannot commit a finished or failed transaction"); if (_transaction_status == transaction_status_type::none)
{
throw sqlpp::exception("Sqlite3 error: Cannot commit a finished or failed transaction");
}
_transaction_status = transaction_status_type::maybe;
auto prepared = prepare_statement(*_handle, "COMMIT");
execute_statement(*_handle, prepared);
_transaction_status = transaction_status_type::none;
} }
_transaction_status = transaction_status_type::maybe;
auto prepared = prepare_statement(*_handle, "COMMIT");
execute_statement(*_handle, prepared);
_transaction_status = transaction_status_type::none;
}
//! rollback transaction with or without reporting the rollback (or throw if the transaction has been finished //! rollback transaction with or without reporting the rollback (or throw if the transaction has been finished
// already) // already)
void rollback_transaction(bool report) void rollback_transaction(bool report)
{
if (_transaction_status == transaction_status_type::none)
{ {
throw sqlpp::exception("Sqlite3 error: Cannot rollback a finished or failed transaction"); if (_transaction_status == transaction_status_type::none)
{
throw sqlpp::exception("Sqlite3 error: Cannot rollback a finished or failed transaction");
}
if (report)
{
std::cerr << "Sqlite3 warning: Rolling back unfinished transaction" << std::endl;
}
_transaction_status = transaction_status_type::maybe;
auto prepared = prepare_statement(*_handle, "ROLLBACK");
execute_statement(*_handle, prepared);
_transaction_status = transaction_status_type::none;
} }
if (report)
{
std::cerr << "Sqlite3 warning: Rolling back unfinished transaction" << std::endl;
}
_transaction_status = transaction_status_type::maybe;
auto prepared = prepare_statement(*_handle, "ROLLBACK");
execute_statement(*_handle, prepared);
_transaction_status = transaction_status_type::none;
}
//! report a rollback failure (will be called by transactions in case of a rollback failure in the destructor) //! 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; std::cerr << "Sqlite3 message:" << message << std::endl;
} }
//! get the last inserted id //! get the last inserted id
uint64_t last_insert_id() noexcept uint64_t last_insert_id() noexcept
{ {
return sqlite3_last_insert_rowid(_handle->sqlite); return sqlite3_last_insert_rowid(_handle->sqlite);
} }
::sqlite3* native_handle() ::sqlite3* native_handle()
{ {
return _handle->sqlite; return _handle->sqlite;
} }
schema_t attach(const connection_config& config, const std::string name) schema_t attach(const connection_config& config, const std::string name)
{ {
auto prepared = auto prepared =
prepare_statement(*_handle, "ATTACH '" + escape(config.path_to_database) + "' AS " + escape(name)); prepare_statement(*_handle, "ATTACH '" + escape(config.path_to_database) + "' AS " + escape(name));
execute_statement(*_handle, prepared); execute_statement(*_handle, prepared);
return {name}; return {name};
} }
}; };
inline std::string serializer_t::escape(std::string arg) inline std::string serializer_t::escape(std::string arg)

View File

@ -50,7 +50,7 @@ namespace sqlpp
{ {
namespace detail namespace detail
{ {
void check_bind_result(int result, const char* const type) inline void check_bind_result(int result, const char* const type)
{ {
switch (result) switch (result)
{ {
@ -78,12 +78,11 @@ namespace sqlpp
public: public:
prepared_statement_t() = default; prepared_statement_t() = default;
prepared_statement_t(std::shared_ptr<detail::prepared_statement_handle_t>&& handle) prepared_statement_t(std::shared_ptr<detail::prepared_statement_handle_t>&& handle) : _handle(std::move(handle))
: _handle(std::move(handle)) {
{ if (_handle and _handle->debug)
if (_handle and _handle->debug) std::cerr << "Sqlite3 debug: Constructing prepared_statement, using handle at " << _handle.get() << std::endl;
std::cerr << "Sqlite3 debug: Constructing prepared_statement, using handle at " << _handle.get() << std::endl; }
}
prepared_statement_t(const prepared_statement_t&) = delete; prepared_statement_t(const prepared_statement_t&) = delete;
prepared_statement_t(prepared_statement_t&& rhs) = default; prepared_statement_t(prepared_statement_t&& rhs) = default;
prepared_statement_t& operator=(const prepared_statement_t&) = delete; prepared_statement_t& operator=(const prepared_statement_t&) = delete;
@ -95,158 +94,157 @@ namespace sqlpp
return _handle == rhs._handle; return _handle == rhs._handle;
} }
void _reset() void _reset()
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: resetting prepared statement" << std::endl;
sqlite3_reset(_handle->sqlite_statement);
}
void _bind_boolean_parameter(size_t index, const signed char* value, bool is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding boolean parameter " << (*value ? "true" : "false")
<< " at index: " << index << ", being " << (is_null ? "" : "not ") << "null" << std::endl;
int result;
if (not is_null)
result = sqlite3_bind_int(_handle->sqlite_statement, static_cast<int>(index + 1), *value);
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "boolean");
}
void _bind_floating_point_parameter(size_t index, const double* value, bool is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding floating_point parameter " << *value << " at index: " << index
<< ", being " << (is_null ? "" : "not ") << "null" << std::endl;
int result;
if (not is_null)
{ {
if (std::isnan(*value)) if (_handle->debug)
result = sqlite3_bind_text(_handle->sqlite_statement, static_cast<int>(index + 1), "NaN", 3, SQLITE_STATIC); std::cerr << "Sqlite3 debug: resetting prepared statement" << std::endl;
else if (std::isinf(*value)) sqlite3_reset(_handle->sqlite_statement);
}
void _bind_boolean_parameter(size_t index, const signed char* value, bool is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding boolean parameter " << (*value ? "true" : "false")
<< " at index: " << index << ", being " << (is_null ? "" : "not ") << "null" << std::endl;
int result;
if (not is_null)
result = sqlite3_bind_int(_handle->sqlite_statement, static_cast<int>(index + 1), *value);
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "boolean");
}
void _bind_floating_point_parameter(size_t index, const double* value, bool is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding floating_point parameter " << *value << " at index: " << index
<< ", being " << (is_null ? "" : "not ") << "null" << std::endl;
int result;
if (not is_null)
{ {
if (*value > std::numeric_limits<double>::max()) if (std::isnan(*value))
result = sqlite3_bind_text(_handle->sqlite_statement, static_cast<int>(index + 1), "Inf", 3, SQLITE_STATIC); result = sqlite3_bind_text(_handle->sqlite_statement, static_cast<int>(index + 1), "NaN", 3, SQLITE_STATIC);
else if (std::isinf(*value))
{
if (*value > std::numeric_limits<double>::max())
result =
sqlite3_bind_text(_handle->sqlite_statement, static_cast<int>(index + 1), "Inf", 3, SQLITE_STATIC);
else
result =
sqlite3_bind_text(_handle->sqlite_statement, static_cast<int>(index + 1), "-Inf", 4, SQLITE_STATIC);
}
else else
result = result = sqlite3_bind_double(_handle->sqlite_statement, static_cast<int>(index + 1), *value);
sqlite3_bind_text(_handle->sqlite_statement, static_cast<int>(index + 1), "-Inf", 4, SQLITE_STATIC);
} }
else else
result = sqlite3_bind_double(_handle->sqlite_statement, static_cast<int>(index + 1), *value); result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "floating_point");
} }
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "floating_point");
}
void _bind_integral_parameter(size_t index, const int64_t* value, bool is_null) void _bind_integral_parameter(size_t index, const int64_t* value, bool is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding integral parameter " << *value << " at index: " << index << ", being "
<< (is_null ? "" : "not ") << "null" << std::endl;
int result;
if (not is_null)
result = sqlite3_bind_int64(_handle->sqlite_statement, static_cast<int>(index + 1), *value);
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "integral");
}
void _bind_unsigned_integral_parameter(size_t index, const uint64_t* value, bool is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding unsigned integral parameter " << *value << " at index: " << index
<< ", being " << (is_null ? "" : "not ") << "null" << std::endl;
int result;
if (not is_null)
result =
sqlite3_bind_int64(_handle->sqlite_statement, static_cast<int>(index + 1), static_cast<int64_t>(*value));
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "integral");
}
void _bind_text_parameter(size_t index, const std::string* value, bool is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding text parameter " << *value << " at index: " << index << ", being "
<< (is_null ? "" : "not ") << "null" << std::endl;
int result;
if (not is_null)
result = sqlite3_bind_text(_handle->sqlite_statement, static_cast<int>(index + 1), value->data(),
static_cast<int>(value->size()), SQLITE_STATIC);
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "text");
}
void _bind_date_parameter(size_t index, const ::sqlpp::chrono::day_point* value, bool is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding date parameter "
<< " at index: " << index << ", being " << (is_null ? "" : "not ") << "null" << std::endl;
int result;
if (not is_null)
{ {
std::ostringstream os; if (_handle->debug)
const auto ymd = ::date::year_month_day{*value}; std::cerr << "Sqlite3 debug: binding integral parameter " << *value << " at index: " << index << ", being "
os << ymd; << (is_null ? "" : "not ") << "null" << std::endl;
const auto text = os.str();
result = sqlite3_bind_text(_handle->sqlite_statement, static_cast<int>(index + 1), text.data(), int result;
static_cast<int>(text.size()), SQLITE_TRANSIENT); if (not is_null)
result = sqlite3_bind_int64(_handle->sqlite_statement, static_cast<int>(index + 1), *value);
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "integral");
} }
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "date");
}
void _bind_date_time_parameter(size_t index, void _bind_unsigned_integral_parameter(size_t index, const uint64_t* value, bool is_null)
const ::sqlpp::chrono::microsecond_point* value,
bool is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding date_time parameter "
<< " at index: " << index << ", being " << (is_null ? "" : "not ") << "null" << std::endl;
int result;
if (not is_null)
{ {
const auto dp = ::sqlpp::chrono::floor<::date::days>(*value); if (_handle->debug)
const auto time = ::date::make_time(::sqlpp::chrono::floor<::std::chrono::milliseconds>(*value - dp)); std::cerr << "Sqlite3 debug: binding unsigned integral parameter " << *value << " at index: " << index
const auto ymd = ::date::year_month_day{dp}; << ", being " << (is_null ? "" : "not ") << "null" << std::endl;
std::ostringstream os; // gcc-4.9 does not support auto os = std::ostringstream{};
os << ymd << ' ' << time; int result;
const auto text = os.str(); if (not is_null)
result = sqlite3_bind_text(_handle->sqlite_statement, static_cast<int>(index + 1), text.data(), result =
static_cast<int>(text.size()), SQLITE_TRANSIENT); sqlite3_bind_int64(_handle->sqlite_statement, static_cast<int>(index + 1), static_cast<int64_t>(*value));
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "integral");
} }
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "date");
}
void _bind_blob_parameter(size_t index, const std::vector<uint8_t>* value, bool is_null) void _bind_text_parameter(size_t index, const std::string* value, bool is_null)
{ {
if (_handle->debug) if (_handle->debug)
std::cerr << "Sqlite3 debug: binding vector parameter size of " << value->size() << " at index: " << index std::cerr << "Sqlite3 debug: binding text parameter " << *value << " at index: " << index << ", being "
<< ", being " << (is_null ? "" : "not ") << "null" << std::endl; << (is_null ? "" : "not ") << "null" << std::endl;
int result; int result;
if (not is_null) if (not is_null)
result = sqlite3_bind_blob(_handle->sqlite_statement, static_cast<int>(index + 1), value->data(), result = sqlite3_bind_text(_handle->sqlite_statement, static_cast<int>(index + 1), value->data(),
static_cast<int>(value->size()), SQLITE_STATIC); static_cast<int>(value->size()), SQLITE_STATIC);
else else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1)); result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "blob"); detail::check_bind_result(result, "text");
} }
void _bind_date_parameter(size_t index, const ::sqlpp::chrono::day_point* value, bool is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding date parameter "
<< " at index: " << index << ", being " << (is_null ? "" : "not ") << "null" << std::endl;
int result;
if (not is_null)
{
std::ostringstream os;
const auto ymd = ::date::year_month_day{*value};
os << ymd;
const auto text = os.str();
result = sqlite3_bind_text(_handle->sqlite_statement, static_cast<int>(index + 1), text.data(),
static_cast<int>(text.size()), SQLITE_TRANSIENT);
}
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "date");
}
void _bind_date_time_parameter(size_t index, const ::sqlpp::chrono::microsecond_point* value, bool is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding date_time parameter "
<< " at index: " << index << ", being " << (is_null ? "" : "not ") << "null" << std::endl;
int result;
if (not is_null)
{
const auto dp = ::sqlpp::chrono::floor<::date::days>(*value);
const auto time = ::date::make_time(::sqlpp::chrono::floor<::std::chrono::milliseconds>(*value - dp));
const auto ymd = ::date::year_month_day{dp};
std::ostringstream os; // gcc-4.9 does not support auto os = std::ostringstream{};
os << ymd << ' ' << time;
const auto text = os.str();
result = sqlite3_bind_text(_handle->sqlite_statement, static_cast<int>(index + 1), text.data(),
static_cast<int>(text.size()), SQLITE_TRANSIENT);
}
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "date");
}
void _bind_blob_parameter(size_t index, const std::vector<uint8_t>* value, bool is_null)
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: binding vector parameter size of " << value->size() << " at index: " << index
<< ", being " << (is_null ? "" : "not ") << "null" << std::endl;
int result;
if (not is_null)
result = sqlite3_bind_blob(_handle->sqlite_statement, static_cast<int>(index + 1), value->data(),
static_cast<int>(value->size()), SQLITE_STATIC);
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
detail::check_bind_result(result, "blob");
}
}; };
} // namespace sqlite3 } // namespace sqlite3
} // namespace sqlpp } // namespace sqlpp

View File

@ -85,18 +85,18 @@ namespace sqlpp
{ {
static_assert(wrong_t<Lhs, Rhs>::value, "Sqlite3: No support for outer join"); static_assert(wrong_t<Lhs, Rhs>::value, "Sqlite3: No support for outer join");
return context; return context;
}; }
template <typename Lhs, typename Rhs> template <typename Lhs, typename Rhs>
sqlite3::serializer_t& serialize(const pre_join_t<right_outer_join_t, Lhs, Rhs>&, sqlite3::serializer_t& context) sqlite3::serializer_t& serialize(const pre_join_t<right_outer_join_t, Lhs, Rhs>&, sqlite3::serializer_t& context)
{ {
static_assert(wrong_t<Lhs, Rhs>::value, "Sqlite3: No support for right_outer join"); static_assert(wrong_t<Lhs, Rhs>::value, "Sqlite3: No support for right_outer join");
return context; return context;
}; }
// Some special treatment of data types // Some special treatment of data types
template <typename Period> template <typename Period>
sqlite3::serializer_t& serialize(const time_point_operand<Period>& t, sqlite3::serializer_t& context) sqlite3::serializer_t& serialize(const time_point_operand<Period>& t, sqlite3::serializer_t& context)
{ {
const auto dp = ::sqlpp::chrono::floor<::date::days>(t._t); const auto dp = ::sqlpp::chrono::floor<::date::days>(t._t);
const auto time = ::date::make_time(t._t - dp); const auto time = ::date::make_time(t._t - dp);
@ -105,14 +105,14 @@ namespace sqlpp
return context; return context;
} }
inline sqlite3::serializer_t& serialize(const day_point_operand& t, sqlite3::serializer_t& context) inline sqlite3::serializer_t& serialize(const day_point_operand& t, sqlite3::serializer_t& context)
{ {
const auto ymd = ::date::year_month_day{t._t}; const auto ymd = ::date::year_month_day{t._t};
context << "DATE('" << ymd << "')"; context << "DATE('" << ymd << "')";
return context; return context;
} }
inline sqlite3::serializer_t& serialize(const floating_point_operand& t, sqlite3::serializer_t& context) inline sqlite3::serializer_t& serialize(const floating_point_operand& t, sqlite3::serializer_t& context)
{ {
if (std::isnan(t._t)) if (std::isnan(t._t))
context << "'NaN'"; context << "'NaN'";
@ -130,11 +130,11 @@ namespace sqlpp
// sqlite3 accepts only signed integers, // sqlite3 accepts only signed integers,
// so we MUST perform a conversion from unsigned to signed // 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::serializer_t& serialize(const unsigned_integral_operand& t, sqlite3::serializer_t& context)
{ {
context << static_cast<typename integral_operand::_value_t>(t._t); context << static_cast<typename integral_operand::_value_t>(t._t);
return context; return context;
} }
} } // namespace sqlpp
#endif #endif

View File

@ -38,7 +38,7 @@
namespace sql = sqlpp::sqlite3; namespace sql = sqlpp::sqlite3;
int main() int Attach(int, char*[])
{ {
sql::connection_config config; sql::connection_config config;
config.path_to_database = ":memory:"; config.path_to_database = ":memory:";

View File

@ -38,7 +38,7 @@
#include <set> #include <set>
namespace sql = sqlpp::sqlite3; namespace sql = sqlpp::sqlite3;
int main() int AutoIncrement(int, char*[])
{ {
sql::connection_config config; sql::connection_config config;
config.path_to_database = ":memory:"; config.path_to_database = ":memory:";

View File

@ -54,7 +54,7 @@ void verify_blob(sql::connection& db, const std::vector<uint8_t>& data, uint64_t
} }
} }
int main() int Blob(int, char*[])
{ {
sql::connection_config config; sql::connection_config config;
config.path_to_database = ":memory:"; config.path_to_database = ":memory:";

View File

@ -1,4 +1,4 @@
# Copyright (c) 2013 - 2016, Roland Bock # Copyright (c) 2013 - 2021, Roland Bock
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without modification, # Redistribution and use in source and binary forms, with or without modification,
@ -22,38 +22,50 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) add_library(sqlpp11_sqlite3_testing INTERFACE)
target_include_directories(sqlpp11_sqlite3_testing INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
macro (build_and_run arg) set(test_names
# Add headers to sources to enable file browsing in IDEs DateTime
add_executable(Sqlpp11Sqlite3${arg} ${arg}.cpp) Sample
Select
Union
With
Attach
DynamicSelect
AutoIncrement
Transaction
FloatingPoint
Integral
Blob
)
target_link_libraries(Sqlpp11Sqlite3${arg} PRIVATE sqlpp11::sqlpp11) create_test_sourcelist(test_sources test_main.cpp ${test_names})
if (SQLCIPHER) add_executable(sqlpp11_sqlite3_tests ${test_sources})
target_compile_definitions(Sqlpp11Sqlite3${arg} PRIVATE SQLPP_USE_SQLCIPHER) target_link_libraries(sqlpp11_sqlite3_tests PRIVATE sqlpp11 sqlpp11_testing sqlpp11_sqlite3_testing)
target_link_libraries(Sqlpp11Sqlite3${arg} PRIVATE SQLCipher::SQLCipher) target_link_libraries(sqlpp11_sqlite3_tests PRIVATE sqlpp11::sqlpp11)
if (SQLPP_DYNAMIC_LOADING) if (SQLCIPHER)
target_include_directories(Sqlpp11Sqlite3${arg} PRIVATE ${SQLCIPHER_INCLUDE_DIRS}) target_compile_definitions(sqlpp11_sqlite3_tests PRIVATE SQLPP_USE_SQLCIPHER)
endif() target_link_libraries(sqlpp11_sqlite3_tests PRIVATE SQLCipher::SQLCipher)
else() if (SQLPP_DYNAMIC_LOADING)
target_link_libraries(Sqlpp11Sqlite3${arg} PRIVATE SQLite::SQLite3) target_include_directories(sqlpp11_sqlite3_tests PRIVATE ${SQLCIPHER_INCLUDE_DIRS})
endif() endif()
else()
target_link_libraries(sqlpp11_sqlite3_tests PRIVATE SQLite::SQLite3)
endif()
add_test(NAME Sqlpp11Sqlite3${arg} COMMAND Sqlpp11Sqlite3${arg}) # conditionally bump to a higher C++ standard to test compatibility
endmacro () if (SQLPP11_TESTS_CXX_STD)
set_property(TARGET sqlpp11_sqlite3_tests PROPERTY CXX_STANDARD ${SQLPP11_TESTS_CXX_STD})
set_property(TARGET sqlpp11_sqlite3_tests PROPERTY CXX_STANDARD_REQUIRED yes)
set_property(TARGET sqlpp11_sqlite3_tests PROPERTY CXX_EXTENSIONS no)
endif()
build_and_run(DateTimeTest) foreach(test IN LISTS test_names)
build_and_run(SampleTest) add_test(NAME sqlpp11.sqlite3.tests.${test}
build_and_run(SelectTest) COMMAND sqlpp11_sqlite3_tests ${test}
build_and_run(UnionTest) )
build_and_run(WithTest) endforeach()
build_and_run(AttachTest)
build_and_run(DynamicSelectTest)
build_and_run(AutoIncrementTest)
build_and_run(TransactionTest)
build_and_run(FloatingPointTest)
build_and_run(IntegralTest)
build_and_run(BlobTest)
# the dynamic loading test needs the extra option "SQLPP_DYNAMIC_LOADING" and does NOT link the sqlite libs # the dynamic loading test needs the extra option "SQLPP_DYNAMIC_LOADING" and does NOT link the sqlite libs
if (SQLPP_DYNAMIC_LOADING) if (SQLPP_DYNAMIC_LOADING)

View File

@ -58,7 +58,7 @@ namespace
} // namespace } // namespace
namespace sql = sqlpp::sqlite3; namespace sql = sqlpp::sqlite3;
int main() int DateTime(int, char*[])
{ {
try try
{ {

View File

@ -44,7 +44,7 @@
SQLPP_ALIAS_PROVIDER(left) SQLPP_ALIAS_PROVIDER(left)
namespace sql = sqlpp::sqlite3; namespace sql = sqlpp::sqlite3;
int main() int DynamicSelect(int, char*[])
{ {
sql::connection_config config; sql::connection_config config;
config.path_to_database = ":memory:"; config.path_to_database = ":memory:";

View File

@ -61,7 +61,7 @@ static auto require(int line, bool condition) -> void
} }
} }
int main() int FloatingPoint(int, char*[])
{ {
sql::connection_config config; sql::connection_config config;
config.path_to_database = ":memory:"; config.path_to_database = ":memory:";

View File

@ -52,7 +52,7 @@ auto require_equal(int line, const L& l, const R& r) -> void
} }
} }
int main() int Integral(int, char*[])
{ {
sql::connection_config config; sql::connection_config config;
config.path_to_database = ":memory:"; config.path_to_database = ":memory:";
@ -107,7 +107,7 @@ int main()
require_equal(__LINE__, rows.front().unsignedValue.value(), uint64_t_value_unsupported); require_equal(__LINE__, rows.front().unsignedValue.value(), uint64_t_value_unsupported);
rows.pop_front(); rows.pop_front();
require_equal(__LINE__, rows.front().signedValue.value(), size_t_value_min); require_equal(__LINE__, rows.front().signedValue.value(), int64_t_value_min);
require_equal(__LINE__, rows.front().unsignedValue.value(), size_t_value_max); require_equal(__LINE__, rows.front().unsignedValue.value(), size_t_value_max);
rows.pop_front(); rows.pop_front();

View File

@ -42,7 +42,7 @@ SQLPP_ALIAS_PROVIDER(pragma)
SQLPP_ALIAS_PROVIDER(sub) SQLPP_ALIAS_PROVIDER(sub)
namespace sql = sqlpp::sqlite3; namespace sql = sqlpp::sqlite3;
int main() int Sample(int, char*[])
{ {
sql::connection_config config; sql::connection_config config;
config.path_to_database = ":memory:"; config.path_to_database = ":memory:";

View File

@ -89,7 +89,7 @@ namespace string_util
} }
} }
int main() int Select(int, char*[])
{ {
sql::connection db({":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "", true}); sql::connection db({":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "", true});
db.execute(R"(CREATE TABLE tab_sample ( db.execute(R"(CREATE TABLE tab_sample (

View File

@ -47,7 +47,7 @@ namespace sql = sqlpp::sqlite3;
SQLPP_ALIAS_PROVIDER(pragma) SQLPP_ALIAS_PROVIDER(pragma)
int main() int Transaction(int, char*[])
{ {
sql::connection db({":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "", true}); sql::connection db({":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "", true});

View File

@ -37,7 +37,7 @@
namespace sql = sqlpp::sqlite3; namespace sql = sqlpp::sqlite3;
const auto tab = TabSample{}; const auto tab = TabSample{};
int main() int Union(int, char*[])
{ {
sql::connection_config config; sql::connection_config config;
config.path_to_database = ":memory:"; config.path_to_database = ":memory:";

View File

@ -39,7 +39,7 @@
namespace sql = sqlpp::sqlite3; namespace sql = sqlpp::sqlite3;
const auto tab = TabSample{}; const auto tab = TabSample{};
int main() int With(int, char*[])
{ {
#if SQLITE_VERSION_NUMBER >= 3008003 #if SQLITE_VERSION_NUMBER >= 3008003
sql::connection_config config; sql::connection_config config;