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

Moved sqlite3 over here.

This commit is contained in:
Roland Bock 2021-08-01 20:37:36 +02:00
parent d0a8ea21af
commit 2e683a4b69
101 changed files with 4963 additions and 61 deletions

View File

@ -1,4 +1,4 @@
# Copyright (c) 2013-2016, Roland Bock # Copyright (c) 2013-2021, Roland Bock
# Copyright (c) 2016 Christian Dávid # Copyright (c) 2016 Christian Dávid
# All rights reserved. # All rights reserved.
# #
@ -27,6 +27,35 @@
cmake_minimum_required(VERSION 3.14) cmake_minimum_required(VERSION 3.14)
project(sqlpp11 VERSION 0.1 LANGUAGES CXX) project(sqlpp11 VERSION 0.1 LANGUAGES CXX)
option(MYSQL_CONNECTOR "Build MySQL Connector" OFF)
option(POSTGRESQL_CONNECTOR "Build PostgreSQL Connector" OFF)
option(SQLITE3_CONNECTOR "Build SQLite3 Connector" OFF)
option(SQLCIPHER_CONNECTOR "Build SQLite3 Connector with SQLCipher" OFF)
if(MYSQL_CONNECTOR)
find_package(MySQL REQUIRED)
else()
message(STATUS "Not building MYSQL_CONNECTOR")
endif()
if(POSTGRESQL_CONNECTOR)
find_package(PostgreSQL REQUIRED)
else()
message(STATUS "Not building POSTGRESQL_CONNECTOR")
endif()
if(SQLITE3_CONNECTOR)
find_package(SQLite3 REQUIRED)
else()
message(STATUS "Not building SQLITE3_CONNECTOR")
endif()
if(SQLCIPHER_CONNECTOR)
find_package(SQLCipher REQUIRED)
else()
message(STATUS "Not building SQLCIPHER_CONNECTOR")
endif()
### Project Wide Setup ### Project Wide Setup
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
@ -44,10 +73,13 @@ endif()
### Dependencies ### Dependencies
add_subdirectory(dependencies) add_subdirectory(dependencies)
### Main targets ### Core targets
add_library(sqlpp11 INTERFACE) add_library(sqlpp11 INTERFACE)
add_library(sqlpp11::sqlpp11 ALIAS sqlpp11) add_library(sqlpp11::sqlpp11 ALIAS sqlpp11)
# Connector targets
add_subdirectory(src)
target_link_libraries(sqlpp11 INTERFACE date::date) target_link_libraries(sqlpp11 INTERFACE date::date)
target_include_directories(sqlpp11 INTERFACE target_include_directories(sqlpp11 INTERFACE
@ -127,8 +159,5 @@ install(
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
add_subdirectory(tests) add_subdirectory(tests)
add_subdirectory(test_types) add_subdirectory(test_types)
add_subdirectory(test_serializer)
add_subdirectory(test_static_asserts)
add_subdirectory(test_constraints)
add_subdirectory(test_scripts) add_subdirectory(test_scripts)
endif() endif()

View File

@ -0,0 +1,109 @@
/*
* Copyright (c) 2013 - 2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SQLPP_SQLITE3_BIND_RESULT_H
#define SQLPP_SQLITE3_BIND_RESULT_H
#include <memory>
#include <sqlpp11/chrono.h>
#include <sqlpp11/sqlite3/export.h>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4251)
#endif
namespace sqlpp
{
namespace sqlite3
{
namespace detail
{
struct prepared_statement_handle_t;
}
class SQLPP11_SQLITE3_EXPORT bind_result_t
{
std::shared_ptr<detail::prepared_statement_handle_t> _handle;
public:
bind_result_t() = default;
bind_result_t(const std::shared_ptr<detail::prepared_statement_handle_t>& handle);
bind_result_t(const bind_result_t&) = delete;
bind_result_t(bind_result_t&& rhs) = default;
bind_result_t& operator=(const bind_result_t&) = delete;
bind_result_t& operator=(bind_result_t&&) = default;
~bind_result_t() = default;
bool operator==(const bind_result_t& rhs) const
{
return _handle == rhs._handle;
}
template <typename ResultRow>
void next(ResultRow& result_row)
{
if (!_handle)
{
result_row._invalidate();
return;
}
if (next_impl())
{
if (not result_row)
{
result_row._validate();
}
result_row._bind(*this);
}
else
{
if (result_row)
result_row._invalidate();
}
}
void _bind_boolean_result(size_t index, signed char* value, bool* is_null);
void _bind_floating_point_result(size_t index, double* value, bool* is_null);
void _bind_integral_result(size_t index, int64_t* value, bool* is_null);
void _bind_unsigned_integral_result(size_t index, uint64_t* value, bool* is_null);
void _bind_text_result(size_t index, const char** text, size_t* len);
void _bind_blob_result(size_t index, const uint8_t** text, size_t* len);
void _bind_date_result(size_t index, ::sqlpp::chrono::day_point* value, bool* is_null);
void _bind_date_time_result(size_t index, ::sqlpp::chrono::microsecond_point* value, bool* is_null);
private:
bool next_impl();
};
} // namespace sqlite3
} // namespace sqlpp
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif

View File

@ -0,0 +1,359 @@
/*
* 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.
*/
#ifndef SQLPP_SQLITE3_CONNECTION_H
#define SQLPP_SQLITE3_CONNECTION_H
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <sqlpp11/connection.h>
#include <sqlpp11/schema.h>
#include <sqlpp11/serialize.h>
#include <sqlpp11/sqlite3/bind_result.h>
#include <sqlpp11/sqlite3/connection_config.h>
#include <sqlpp11/sqlite3/prepared_statement.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/sqlite3/export.h>
#include <sstream>
#include <string>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4251)
#endif
namespace sqlpp
{
namespace sqlite3
{
namespace detail
{
struct connection_handle;
}
class connection;
struct serializer_t
{
serializer_t(const connection& db) : _db(db), _count(1)
{
}
template <typename T>
std::ostream& operator<<(T t)
{
return _os << t;
}
std::string escape(std::string arg);
std::string str() const
{
return _os.str();
}
size_t count() const
{
return _count;
}
void pop_count()
{
++_count;
}
const connection& _db;
std::stringstream _os;
size_t _count;
};
class SQLPP11_SQLITE3_EXPORT connection : public sqlpp::connection
{
std::unique_ptr<detail::connection_handle> _handle;
enum class transaction_status_type
{
none,
maybe,
active
};
transaction_status_type _transaction_status = transaction_status_type::none;
// direct execution
bind_result_t select_impl(const std::string& statement);
size_t insert_impl(const std::string& statement);
size_t update_impl(const std::string& statement);
size_t remove_impl(const std::string& statement);
// prepared execution
prepared_statement_t prepare_impl(const std::string& statement);
bind_result_t run_prepared_select_impl(prepared_statement_t& prepared_statement);
size_t run_prepared_execute_impl(prepared_statement_t& prepared_statement);
size_t run_prepared_insert_impl(prepared_statement_t& prepared_statement);
size_t run_prepared_update_impl(prepared_statement_t& prepared_statement);
size_t run_prepared_remove_impl(prepared_statement_t& prepared_statement);
public:
using _prepared_statement_t = prepared_statement_t;
using _context_t = serializer_t;
using _serializer_context_t = _context_t;
using _interpreter_context_t = _context_t;
struct _tags
{
using _null_result_is_trivial_value = std::true_type;
};
template <typename T>
static _context_t& _serialize_interpretable(const T& t, _context_t& context)
{
return ::sqlpp::serialize(t, context);
}
template <typename T>
static _context_t& _interpret_interpretable(const T& t, _context_t& context)
{
return ::sqlpp::serialize(t, context);
}
connection(connection_config config);
connection(connection&&) noexcept;
connection& operator=(connection&&) noexcept;
~connection();
connection(const connection&) = delete;
connection& operator=(const connection&) = delete;
//! select returns a result (which can be iterated row by row)
template <typename Select>
bind_result_t select(const Select& s)
{
_context_t context(*this);
serialize(s, context);
return select_impl(context.str());
}
template <typename Select>
_prepared_statement_t prepare_select(Select& s)
{
_context_t context(*this);
serialize(s, context);
return prepare_impl(context.str());
}
template <typename PreparedSelect>
bind_result_t run_prepared_select(const PreparedSelect& s)
{
s._prepared_statement._reset();
s._bind_params();
return run_prepared_select_impl(s._prepared_statement);
}
//! insert returns the last auto_incremented id (or zero, if there is none)
template <typename Insert>
size_t insert(const Insert& i)
{
_context_t context(*this);
serialize(i, context);
return insert_impl(context.str());
}
template <typename Insert>
_prepared_statement_t prepare_insert(Insert& i)
{
_context_t context(*this);
serialize(i, context);
return prepare_impl(context.str());
}
template <typename PreparedInsert>
size_t run_prepared_insert(const PreparedInsert& i)
{
i._prepared_statement._reset();
i._bind_params();
return run_prepared_insert_impl(i._prepared_statement);
}
//! update returns the number of affected rows
template <typename Update>
size_t update(const Update& u)
{
_context_t context(*this);
serialize(u, context);
return update_impl(context.str());
}
template <typename Update>
_prepared_statement_t prepare_update(Update& u)
{
_context_t context(*this);
serialize(u, context);
return prepare_impl(context.str());
}
template <typename PreparedUpdate>
size_t run_prepared_update(const PreparedUpdate& u)
{
u._prepared_statement._reset();
u._bind_params();
return run_prepared_update_impl(u._prepared_statement);
}
//! remove returns the number of removed rows
template <typename Remove>
size_t remove(const Remove& r)
{
_context_t context(*this);
serialize(r, context);
return remove_impl(context.str());
}
template <typename Remove>
_prepared_statement_t prepare_remove(Remove& r)
{
_context_t context(*this);
serialize(r, context);
return prepare_impl(context.str());
}
template <typename PreparedRemove>
size_t run_prepared_remove(const PreparedRemove& r)
{
r._prepared_statement._reset();
r._bind_params();
return run_prepared_remove_impl(r._prepared_statement);
}
//! execute arbitrary command (e.g. create a table)
size_t execute(const std::string& command);
template <
typename Execute,
typename Enable = typename std::enable_if<not std::is_convertible<Execute, std::string>::value, void>::type>
size_t execute(const Execute& x)
{
_context_t context(*this);
serialize(x, context);
return execute(context.str());
}
template <typename Execute>
_prepared_statement_t prepare_execute(Execute& x)
{
_context_t context(*this);
serialize(x, context);
return prepare_impl(context.str());
}
template <typename PreparedExecute>
size_t run_prepared_execute(const PreparedExecute& x)
{
x._prepared_statement._reset();
x._bind_params();
return run_prepared_execute_impl(x._prepared_statement);
}
//! escape given string (does not quote, though)
std::string escape(const std::string& s) const;
//! call run on the argument
template <typename T>
auto _run(const T& t, ::sqlpp::consistent_t) -> decltype(t._run(*this))
{
return t._run(*this);
}
template <typename Check, typename T>
auto _run(const T& t, Check) -> Check;
template <typename T>
auto operator()(const T& t) -> decltype(this->_run(t, sqlpp::run_check_t<_serializer_context_t, T>{}))
{
return _run(t, sqlpp::run_check_t<_serializer_context_t, T>{});
}
//! call prepare on the argument
template <typename T>
auto _prepare(const T& t, const std::true_type&) -> decltype(t._prepare(*this))
{
return t._prepare(*this);
}
template <typename T>
auto _prepare(const T& t, const std::false_type&) -> void;
template <typename T>
auto prepare(const T& t)
-> decltype(this->_prepare(t, typename sqlpp::prepare_check_t<_serializer_context_t, T>::type{}))
{
sqlpp::prepare_check_t<_serializer_context_t, T>{};
return _prepare(t, sqlpp::prepare_check_t<_serializer_context_t, T>{});
}
//! set the transaction isolation level for this connection
void set_default_isolation_level(isolation_level level);
//! get the currently active transaction isolation level
isolation_level get_default_isolation_level();
//! start transaction
void start_transaction();
//! commit transaction (or throw if the transaction has been finished already)
void commit_transaction();
//! rollback transaction with or without reporting the rollback (or throw if the transaction has been finished
// already)
void rollback_transaction(bool report);
//! 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;
//! get the last inserted id
uint64_t last_insert_id() noexcept;
::sqlite3* native_handle();
auto attach(const connection_config&, const std::string name) -> schema_t;
};
inline std::string serializer_t::escape(std::string arg)
{
return _db.escape(arg);
}
} // namespace sqlite3
} // namespace sqlpp
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#include <sqlpp11/sqlite3/serializer.h>
#endif

View File

@ -0,0 +1,71 @@
/*
* 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.
*/
#ifndef SQLPP_SQLITE3_CONNECTION_CONFIG_H
#define SQLPP_SQLITE3_CONNECTION_CONFIG_H
#include <string>
#include <iostream>
namespace sqlpp
{
namespace sqlite3
{
struct connection_config
{
connection_config() : path_to_database(), flags(0), vfs(), debug(false),password("")
{
}
connection_config(const connection_config&) = default;
connection_config(connection_config&&) = default;
connection_config(std::string path, int fl = 0, std::string vf = "", bool dbg = false,std::string password="")
: path_to_database(std::move(path)), flags(fl), vfs(std::move(vf)), debug(dbg),password(password)
{
}
bool operator==(const connection_config& other) const
{
return (other.path_to_database == path_to_database && other.flags == flags && other.vfs == vfs &&
other.debug == debug && other.password==password);
}
bool operator!=(const connection_config& other) const
{
return !operator==(other);
}
std::string path_to_database;
int flags;
std::string vfs;
bool debug;
std::string password;
};
}
}
#endif

View File

@ -0,0 +1,237 @@
/*
* Copyright (c) 2017, Volker Aßmann
* 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.
*/
#ifndef DYNAMIC_LIBSQLITE3_H
#define DYNAMIC_LIBSQLITE3_H
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <stdexcept>
// namespace for internal sqlite function wrappers - when using this instead of sqlite3 direct linking
// do this:
// using namespace sqlpp::sqlite3::dyn;
// to override the libsqlite3 functions with these function pointers
#ifdef SQLPP_DYNAMIC_LOADING
namespace sqlpp
{
namespace sqlite3
{
namespace dynamic
{
/// load the SQLite libraries, optionally providing the filename (leave empty for default)
void init_sqlite(std::string libname);
#define DYNDEFINE(NAME) extern decltype(::NAME)* NAME
DYNDEFINE(sqlite3_open_v2);
DYNDEFINE(sqlite3_open);
DYNDEFINE(sqlite3_prepare_v2);
DYNDEFINE(sqlite3_exec);
DYNDEFINE(sqlite3_step);
DYNDEFINE(sqlite3_bind_int);
DYNDEFINE(sqlite3_close);
DYNDEFINE(sqlite3_initialize);
DYNDEFINE(sqlite3_os_init);
DYNDEFINE(sqlite3_os_end);
DYNDEFINE(sqlite3_bind_blob);
DYNDEFINE(sqlite3_bind_double);
DYNDEFINE(sqlite3_bind_int64);
DYNDEFINE(sqlite3_bind_null);
DYNDEFINE(sqlite3_bind_text);
DYNDEFINE(sqlite3_bind_value);
DYNDEFINE(sqlite3_libversion_number);
// DYNDEFINE(sqlite3_compileoption_used);
DYNDEFINE(sqlite3_threadsafe);
// DYNDEFINE(sqlite3_close_v2);
DYNDEFINE(sqlite3_shutdown);
DYNDEFINE(sqlite3_config);
DYNDEFINE(sqlite3_db_config);
DYNDEFINE(sqlite3_extended_result_codes);
DYNDEFINE(sqlite3_last_insert_rowid);
DYNDEFINE(sqlite3_changes);
DYNDEFINE(sqlite3_total_changes);
DYNDEFINE(sqlite3_interrupt);
DYNDEFINE(sqlite3_complete);
DYNDEFINE(sqlite3_complete16);
DYNDEFINE(sqlite3_busy_handler);
DYNDEFINE(sqlite3_busy_timeout);
DYNDEFINE(sqlite3_get_table);
DYNDEFINE(sqlite3_free_table);
// DYNDEFINE(sqlite3_realloc64);
DYNDEFINE(sqlite3_free);
// DYNDEFINE(sqlite3_msize);
DYNDEFINE(sqlite3_memory_used);
DYNDEFINE(sqlite3_memory_highwater);
DYNDEFINE(sqlite3_randomness);
DYNDEFINE(sqlite3_set_authorizer);
DYNDEFINE(sqlite3_progress_handler);
DYNDEFINE(sqlite3_open16);
// DYNDEFINE(sqlite3_uri_boolean);
// DYNDEFINE(sqlite3_uri_int64);
DYNDEFINE(sqlite3_errcode);
DYNDEFINE(sqlite3_errmsg);
DYNDEFINE(sqlite3_extended_errcode);
DYNDEFINE(sqlite3_limit);
DYNDEFINE(sqlite3_prepare);
DYNDEFINE(sqlite3_prepare16);
DYNDEFINE(sqlite3_prepare16_v2);
// DYNDEFINE(sqlite3_stmt_readonly);
// DYNDEFINE(sqlite3_stmt_busy);
// DYNDEFINE(sqlite3_bind_blob64);
DYNDEFINE(sqlite3_bind_text16);
// DYNDEFINE(sqlite3_bind_text64);
DYNDEFINE(sqlite3_bind_zeroblob);
DYNDEFINE(sqlite3_bind_parameter_count);
DYNDEFINE(sqlite3_bind_parameter_index);
DYNDEFINE(sqlite3_clear_bindings);
DYNDEFINE(sqlite3_column_count);
DYNDEFINE(sqlite3_data_count);
DYNDEFINE(sqlite3_column_bytes);
DYNDEFINE(sqlite3_column_bytes16);
DYNDEFINE(sqlite3_column_double);
DYNDEFINE(sqlite3_column_int);
DYNDEFINE(sqlite3_column_int64);
DYNDEFINE(sqlite3_column_text);
DYNDEFINE(sqlite3_column_type);
DYNDEFINE(sqlite3_column_value);
DYNDEFINE(sqlite3_column_blob);
DYNDEFINE(sqlite3_finalize);
DYNDEFINE(sqlite3_reset);
DYNDEFINE(sqlite3_create_function);
DYNDEFINE(sqlite3_create_function16);
// DYNDEFINE(sqlite3_create_function_v2);
DYNDEFINE(sqlite3_value_bytes);
DYNDEFINE(sqlite3_value_bytes16);
DYNDEFINE(sqlite3_value_double);
DYNDEFINE(sqlite3_value_int);
DYNDEFINE(sqlite3_value_int64);
DYNDEFINE(sqlite3_value_type);
DYNDEFINE(sqlite3_value_numeric_type);
DYNDEFINE(sqlite3_set_auxdata);
DYNDEFINE(sqlite3_result_blob);
// DYNDEFINE(sqlite3_result_blob64);
DYNDEFINE(sqlite3_result_double);
DYNDEFINE(sqlite3_result_error);
DYNDEFINE(sqlite3_result_error16);
DYNDEFINE(sqlite3_result_error_toobig);
DYNDEFINE(sqlite3_result_error_nomem);
DYNDEFINE(sqlite3_result_error_code);
DYNDEFINE(sqlite3_result_int);
DYNDEFINE(sqlite3_result_int64);
DYNDEFINE(sqlite3_result_null);
DYNDEFINE(sqlite3_result_text);
// DYNDEFINE(sqlite3_result_text64);
DYNDEFINE(sqlite3_result_text16);
DYNDEFINE(sqlite3_result_text16le);
DYNDEFINE(sqlite3_result_text16be);
DYNDEFINE(sqlite3_result_value);
DYNDEFINE(sqlite3_result_zeroblob);
DYNDEFINE(sqlite3_create_collation);
DYNDEFINE(sqlite3_create_collation_v2);
DYNDEFINE(sqlite3_create_collation16);
DYNDEFINE(sqlite3_collation_needed);
DYNDEFINE(sqlite3_collation_needed16);
#ifdef SQLITE_HAS_CODEC
DYNDEFINE(sqlite3_key);
DYNDEFINE(sqlite3_key_v2);
DYNDEFINE(sqlite3_rekey);
DYNDEFINE(sqlite3_rekey_v2);
DYNDEFINE(sqlite3_activate_see);
#endif
#ifdef SQLITE_ENABLE_CEROD
DYNDEFINE(sqlite3_activate_cerod);
#endif
DYNDEFINE(sqlite3_sleep);
DYNDEFINE(sqlite3_get_autocommit);
// DYNDEFINE(sqlite3_db_readonly);
DYNDEFINE(sqlite3_next_stmt);
DYNDEFINE(sqlite3_enable_shared_cache);
DYNDEFINE(sqlite3_release_memory);
// DYNDEFINE(sqlite3_db_release_memory);
// DYNDEFINE(sqlite3_soft_heap_limit64);
DYNDEFINE(sqlite3_table_column_metadata);
DYNDEFINE(sqlite3_load_extension);
DYNDEFINE(sqlite3_enable_load_extension);
DYNDEFINE(sqlite3_auto_extension);
// DYNDEFINE(sqlite3_cancel_auto_extension);
DYNDEFINE(sqlite3_reset_auto_extension);
DYNDEFINE(sqlite3_create_module);
DYNDEFINE(sqlite3_create_module_v2);
DYNDEFINE(sqlite3_declare_vtab);
DYNDEFINE(sqlite3_overload_function);
DYNDEFINE(sqlite3_blob_open);
DYNDEFINE(sqlite3_blob_close);
DYNDEFINE(sqlite3_blob_bytes);
DYNDEFINE(sqlite3_blob_read);
DYNDEFINE(sqlite3_blob_write);
DYNDEFINE(sqlite3_vfs_find);
DYNDEFINE(sqlite3_vfs_register);
DYNDEFINE(sqlite3_vfs_unregister);
DYNDEFINE(sqlite3_mutex_alloc);
DYNDEFINE(sqlite3_mutex_free);
DYNDEFINE(sqlite3_mutex_enter);
DYNDEFINE(sqlite3_mutex_try);
DYNDEFINE(sqlite3_mutex_leave);
// DYNDEFINE(sqlite3_mutex_held);
// DYNDEFINE(sqlite3_mutex_notheld);
DYNDEFINE(sqlite3_db_mutex);
DYNDEFINE(sqlite3_file_control);
DYNDEFINE(sqlite3_test_control);
DYNDEFINE(sqlite3_status);
DYNDEFINE(sqlite3_db_status);
DYNDEFINE(sqlite3_stmt_status);
DYNDEFINE(sqlite3_backup_init);
DYNDEFINE(sqlite3_backup_step);
DYNDEFINE(sqlite3_backup_finish);
DYNDEFINE(sqlite3_backup_remaining);
DYNDEFINE(sqlite3_backup_pagecount);
DYNDEFINE(sqlite3_unlock_notify);
// DYNDEFINE(sqlite3_stricmp);
// DYNDEFINE(sqlite3_strnicmp);
// DYNDEFINE(sqlite3_strglob);
// DYNDEFINE(sqlite3_log);
// DYNDEFINE(sqlite3_wal_autocheckpoint);
// DYNDEFINE(sqlite3_wal_checkpoint);
// DYNDEFINE(sqlite3_wal_checkpoint_v2);
// DYNDEFINE(sqlite3_vtab_config);
// DYNDEFINE(sqlite3_vtab_on_conflict);
// DYNDEFINE(sqlite3_rtree_geometry_callback);
// DYNDEFINE(sqlite3_rtree_query_callback);
} // namespace dynamic
} // namespace sqlite3
} // namespace sqlpp
#undef DYNDEFINE
#endif
#endif // DYNAMIC_LIBSQLITE3_H

View File

@ -0,0 +1,18 @@
#ifndef SQLPP_SQLITE3_EXPORT_H
#define SQLPP_SQLITE3_EXPORT_H
#ifdef _WIN32
#ifdef SQLPP11_SHARED
#ifdef SQLPP11_COMPILING_DLL
#define SQLPP11_SQLITE3_EXPORT __declspec(dllexport)
#else
#define SQLPP11_SQLITE3_EXPORT __declspec(dllimport)
#endif
#else
#define SQLPP11_SQLITE3_EXPORT
#endif
#else
#define SQLPP11_SQLITE3_EXPORT
#endif
#endif

View File

@ -0,0 +1,154 @@
/*
* Copyright (c) 2013 - 2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SQLPP_SQLITE3_INSERT_OR_H
#define SQLPP_SQLITE3_INSERT_OR_H
#include <sqlpp11/default_value.h>
#include <sqlpp11/insert_value_list.h>
#include <sqlpp11/into.h>
#include <sqlpp11/noop.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/prepared_insert.h>
#include <sqlpp11/statement.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
namespace sqlite3
{
struct insert_or_replace_name_t
{
};
struct insert_or_ignore_name_t
{
};
template <typename InsertOrAlternative>
struct insert_or_t : public statement_name_t<InsertOrAlternative>
{
using _traits = make_traits<no_value_t, tag::is_return_value>;
struct _alias_t
{
};
template <typename Statement>
struct _result_methods_t
{
using _statement_t = Statement;
const _statement_t& _get_statement() const
{
return static_cast<const _statement_t&>(*this);
}
template <typename Db>
auto _run(Db& db) const -> decltype(db.insert(this->_get_statement()))
{
return db.insert(_get_statement());
}
template <typename Db>
auto _prepare(Db& db) const -> prepared_insert_t<Db, _statement_t>
{
return {{}, db.prepare_insert(_get_statement())};
}
};
};
template <typename Database, typename InsertOrAlternative>
using blank_insert_or_t =
statement_t<Database, insert_or_t<InsertOrAlternative>, no_into_t, no_insert_value_list_t>;
template <typename Database>
using blank_insert_or_replace_t = blank_insert_or_t<Database, insert_or_replace_name_t>;
template <typename Database>
using blank_insert_or_ignore_t = blank_insert_or_t<Database, insert_or_ignore_name_t>;
inline auto insert_or_replace() -> blank_insert_or_replace_t<void>
{
return {blank_insert_or_replace_t<void>()};
}
template <typename Table>
constexpr auto insert_or_replace_into(Table table) -> decltype(blank_insert_or_replace_t<void>().into(table))
{
return {blank_insert_or_replace_t<void>().into(table)};
}
template <typename Database>
constexpr auto dynamic_insert_or_replace(const Database&) -> decltype(blank_insert_or_replace_t<Database>())
{
return {blank_insert_or_replace_t<Database>()};
}
template <typename Database, typename Table>
constexpr auto dynamic_insert_or_replace_into(const Database&, Table table)
-> decltype(blank_insert_or_replace_t<Database>().into(table))
{
return {blank_insert_or_replace_t<Database>().into(table)};
}
inline auto insert_or_ignore() -> blank_insert_or_ignore_t<void>
{
return {blank_insert_or_ignore_t<void>()};
}
template <typename Table>
constexpr auto insert_or_ignore_into(Table table) -> decltype(blank_insert_or_ignore_t<void>().into(table))
{
return {blank_insert_or_ignore_t<void>().into(table)};
}
template <typename Database>
constexpr auto dynamic_insert_or_ignore(const Database&) -> decltype(blank_insert_or_ignore_t<Database>())
{
return {blank_insert_or_ignore_t<Database>()};
}
template <typename Database, typename Table>
constexpr auto dynamic_insert_or_ignore_into(const Database&, Table table)
-> decltype(blank_insert_or_ignore_t<Database>().into(table))
{
return {blank_insert_or_ignore_t<Database>().into(table)};
}
inline sqlite3::serializer_t& serialize(const sqlite3::insert_or_replace_name_t&, sqlite3::serializer_t& context)
{
context << "INSERT OR REPLACE ";
return context;
}
inline sqlite3::serializer_t& serialize(const sqlite3::insert_or_ignore_name_t&, sqlite3::serializer_t& context)
{
context << "INSERT OR IGNORE ";
return context;
}
}
}
#endif

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2013 - 2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SQLPP_SQLITE3_PREPARED_STATEMENT_H
#define SQLPP_SQLITE3_PREPARED_STATEMENT_H
#include <memory>
#include <sqlpp11/chrono.h>
#include <sqlpp11/sqlite3/export.h>
#include <string>
#include <vector>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4251)
#endif
namespace sqlpp
{
namespace sqlite3
{
class connection;
namespace detail
{
struct prepared_statement_handle_t;
}
class SQLPP11_SQLITE3_EXPORT prepared_statement_t
{
friend ::sqlpp::sqlite3::connection;
std::shared_ptr<detail::prepared_statement_handle_t> _handle;
public:
prepared_statement_t() = default;
prepared_statement_t(std::shared_ptr<detail::prepared_statement_handle_t>&& handle);
prepared_statement_t(const prepared_statement_t&) = delete;
prepared_statement_t(prepared_statement_t&& rhs) = default;
prepared_statement_t& operator=(const prepared_statement_t&) = delete;
prepared_statement_t& operator=(prepared_statement_t&&) = default;
~prepared_statement_t() = default;
bool operator==(const prepared_statement_t& rhs) const
{
return _handle == rhs._handle;
}
void _reset();
void _bind_boolean_parameter(size_t index, const signed char* value, bool is_null);
void _bind_floating_point_parameter(size_t index, const double* value, bool is_null);
void _bind_integral_parameter(size_t index, const int64_t* value, bool is_null);
void _bind_unsigned_integral_parameter(size_t index, const uint64_t* value, bool is_null);
void _bind_text_parameter(size_t index, const std::string* value, bool is_null);
void _bind_date_parameter(size_t index, const ::sqlpp::chrono::day_point* value, bool is_null);
void _bind_date_time_parameter(size_t index, const ::sqlpp::chrono::microsecond_point* value, bool is_null);
void _bind_blob_parameter(size_t index, const std::vector<uint8_t>* value, bool is_null);
};
} // namespace sqlite3
} // namespace sqlpp
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif

View File

@ -0,0 +1,140 @@
/*
* 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.
*/
#ifndef SQLPP_SQLITE3_SERIALIZER_H
#define SQLPP_SQLITE3_SERIALIZER_H
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <sqlpp11/any.h>
#include <sqlpp11/data_types/day_point/operand.h>
#include <sqlpp11/data_types/floating_point/operand.h>
#include <sqlpp11/data_types/integral/operand.h>
#include <sqlpp11/data_types/time_point/operand.h>
#include <sqlpp11/data_types/unsigned_integral/operand.h>
#include <sqlpp11/parameter.h>
#include <sqlpp11/pre_join.h>
#include <sqlpp11/some.h>
#include <sqlpp11/with.h>
#include <cmath>
namespace sqlpp
{
// Serialize parameters
template <typename ValueType, typename NameType>
sqlite3::serializer_t& serialize(const parameter_t<ValueType, NameType>&, sqlite3::serializer_t& context)
{
context << "?" << context.count();
context.pop_count();
return context;
}
// disable some stuff that won't work with sqlite3
#if SQLITE_VERSION_NUMBER < 3008003
template <typename Database, typename... Expressions>
sqlite3::serializer_t& serialize(const with_data_t<Database, Expressions...>&, sqlite3::serializer_t& context)
{
static_assert(wrong_t<Expressions...>::value, "Sqlite3: No support for with before version 3.8.3");
return context;
}
#endif
template <typename Select>
sqlite3::serializer_t& serialize(const any_t<Select>&, sqlite3::serializer_t& context)
{
static_assert(wrong_t<Select>::value, "Sqlite3: No support for any()");
return context;
}
template <typename Select>
sqlite3::serializer_t& serialize(const some_t<Select>&, sqlite3::serializer_t& context)
{
static_assert(wrong_t<Select>::value, "Sqlite3: No support for some()");
return context;
}
template <typename Lhs, typename Rhs>
sqlite3::serializer_t& serialize(const pre_join_t<outer_join_t, Lhs, Rhs>&, sqlite3::serializer_t& context)
{
static_assert(wrong_t<Lhs, Rhs>::value, "Sqlite3: No support for outer join");
return context;
};
template <typename Lhs, typename Rhs>
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");
return context;
};
// Some special treatment of data types
template <typename Period>
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 time = ::date::make_time(t._t - dp);
const auto ymd = ::date::year_month_day{dp};
context << "STRFTIME('%Y-%m-%d %H:%M:%f', '" << ymd << ' ' << time << "')";
return context;
}
inline sqlite3::serializer_t& serialize(const day_point_operand& t, sqlite3::serializer_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)
{
if (std::isnan(t._t))
context << "'NaN'";
else if (std::isinf(t._t))
{
if (t._t > std::numeric_limits<double>::max())
context << "'Inf'";
else
context << "'-Inf'";
}
else
context << t._t;
return context;
}
// 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)
{
context << static_cast<typename integral_operand::_value_t>(t._t);
return context;
}
}
#endif

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2013 - 2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SQLPP_SQLITE3_H
#define SQLPP_SQLITE3_H
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/sqlite3/insert_or.h>
#endif

35
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,35 @@
# Copyright (c) 2021-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:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. 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.
if(MYSQL_CONNECTOR)
add_subdirectory(mysql)
endif()
if(POSTGRESQL_CONNECTOR)
add_subdirectory(postgresql)
endif()
if(SQLITE3_CONNECTOR OR SQLCIPHER_CONNECTOR)
add_subdirectory(sqlite3)
endif()

View File

@ -0,0 +1,96 @@
# 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.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
add_library(sqlpp11-connector-sqlite3)
add_library(sqlpp11::sqlite3 ALIAS sqlpp11-connector-sqlite3)
target_sources(sqlpp11-connector-sqlite3
PRIVATE
connection.cpp
bind_result.cpp
prepared_statement.cpp
detail/connection_handle.cpp
)
target_link_libraries(sqlpp11-connector-sqlite3 PUBLIC sqlpp11::sqlpp11)
if (SQLPP_DYNAMIC_LOADING)
add_library(sqlpp11-connector-sqlite3-dynamic
connection.cpp
bind_result.cpp
prepared_statement.cpp
detail/connection_handle.cpp
detail/dynamic_libsqlite3.cpp
)
add_library(sqlpp11::sqlite3-dynamic ALIAS sqlpp11-connector-sqlite3-dynamic)
get_filename_component(SQLite3_LIB_FILE ${SQLite3_LIBRARY} NAME)
if (WIN32)
# the import library (.lib) needs to be replaced by .dll
get_filename_component(SQLite3_LIB_FILE ${SQLite3_LIB_FILE} NAME_WE)
string(APPEND SQLite3_LIB_FILE ".dll")
endif()
set_target_properties(sqlpp11-connector-sqlite3 PROPERTIES DEFINE_SYMBOL SQLPP11_COMPILING_DLL)
set_target_properties(sqlpp11-connector-sqlite3-dynamic PROPERTIES DEFINE_SYMBOL SQLPP11_COMPILING_DLL)
target_compile_definitions(sqlpp11-connector-sqlite3-dynamic
PUBLIC SQLPP_DYNAMIC_LOADING
PRIVATE SQLPP_DYNAMIC_LOADING_FILENAME=${SQLite3_LIB_FILE})
target_include_directories(sqlpp11-connector-sqlite3-dynamic PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_link_libraries(sqlpp11-connector-sqlite3-dynamic PUBLIC sqlpp11::sqlpp11)
endif()
target_include_directories(sqlpp11-connector-sqlite3 PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
if (SQLCIPHER)
target_compile_definitions(sqlpp11-connector-sqlite3 PUBLIC SQLPP_USE_SQLCIPHER)
target_link_libraries(sqlpp11-connector-sqlite3 PUBLIC SQLCipher::SQLCipher)
if (SQLPP_DYNAMIC_LOADING)
target_compile_definitions(sqlpp11-connector-sqlite3-dynamic PUBLIC SQLPP_USE_SQLCIPHER)
target_include_directories(sqlpp11-connector-sqlite3-dynamic PUBLIC ${SQLCIPHER_INCLUDE_DIRS})
endif()
else()
target_link_libraries(sqlpp11-connector-sqlite3 PUBLIC SQLite::SQLite3)
endif()
install(TARGETS sqlpp11-connector-sqlite3
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
if (SQLPP_DYNAMIC_LOADING)
install(TARGETS sqlpp11-connector-sqlite3-dynamic
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
endif()

249
src/sqlite3/bind_result.cpp Normal file
View File

@ -0,0 +1,249 @@
/*
* 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 "detail/prepared_statement_handle.h"
#include <cctype>
#include <ciso646>
#include <date/date.h> // Howard Hinnant's date library
#include <iostream>
#include <sqlpp11/exception.h>
#include <sqlpp11/sqlite3/bind_result.h>
#include <vector>
#ifdef SQLPP_DYNAMIC_LOADING
#include <sqlpp11/sqlite3/dynamic_libsqlite3.h>
#endif
namespace sqlpp
{
namespace sqlite3
{
#ifdef SQLPP_DYNAMIC_LOADING
using namespace dynamic;
#endif
bind_result_t::bind_result_t(const std::shared_ptr<detail::prepared_statement_handle_t>& handle) : _handle(handle)
{
if (_handle and _handle->debug)
std::cerr << "Sqlite3 debug: Constructing bind result, using handle at " << _handle.get() << std::endl;
}
void bind_result_t::_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_result_t::_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_result_t::_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_result_t::_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_result_t::_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_result_t::_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));
}
namespace
{
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 ms_digits = std::vector<char>{0, 1, 1, 1}; // .123
auto check_digits(const char* text, const std::vector<char>& digitFlags) -> bool
{
for (const auto digitFlag : digitFlags)
{
if (digitFlag)
{
if (not std::isdigit(*text))
{
return false;
}
}
else
{
if (std::isdigit(*text) or *text == '\0')
{
return false;
}
}
++text;
}
return true;
}
} // namespace
void bind_result_t::_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 (check_digits(date_string, 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_result_t::_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 (check_digits(date_time_string, 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 (check_digits(time_string, 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 (check_digits(ms_string, ms_digits) and ms_string[4] == '\0')
{
*value += ::std::chrono::milliseconds(std::atoi(ms_string + 1));
}
else
{
return;
}
}
bool bind_result_t::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:
return true;
case SQLITE_DONE:
return false;
default:
throw sqlpp::exception("Sqlite3 error: Unexpected return value for sqlite3_step()");
}
}
} // namespace sqlite3
} // namespace sqlpp

280
src/sqlite3/connection.cpp Normal file
View File

@ -0,0 +1,280 @@
/*
* 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 "detail/connection_handle.h"
#include "detail/prepared_statement_handle.h"
#include <iostream>
#include <sqlpp11/exception.h>
#include <sqlpp11/sqlite3/connection.h>
#ifdef SQLPP_DYNAMIC_LOADING
#include <sqlpp11/sqlite3/dynamic_libsqlite3.h>
#endif
namespace sqlpp
{
namespace sqlite3
{
#ifdef SQLPP_DYNAMIC_LOADING
using namespace dynamic;
#endif
namespace
{
detail::prepared_statement_handle_t prepare_statement(detail::connection_handle& handle,
const std::string& statement)
{
if (handle.config.debug)
std::cerr << "Sqlite3 debug: Preparing: '" << statement << "'" << std::endl;
detail::prepared_statement_handle_t result(nullptr, handle.config.debug);
auto rc = sqlite3_prepare_v2(handle.sqlite, statement.c_str(), static_cast<int>(statement.size()),
&result.sqlite_statement, nullptr);
if (rc != SQLITE_OK)
{
throw sqlpp::exception("Sqlite3 error: Could not prepare statement: " +
std::string(sqlite3_errmsg(handle.sqlite)) + " (statement was >>" +
(rc == SQLITE_TOOBIG ? statement.substr(0, 128) + "..." : statement) +
"<<\n");
}
return result;
}
void execute_statement(detail::connection_handle& handle, detail::prepared_statement_handle_t& prepared)
{
auto rc = sqlite3_step(prepared.sqlite_statement);
switch (rc)
{
case SQLITE_OK:
case SQLITE_ROW: // might occur if execute is called with a select
case SQLITE_DONE:
return;
default:
if(handle.config.debug)
std::cerr << "Sqlite3 debug: sqlite3_step return code: " << rc << std::endl;
throw sqlpp::exception("Sqlite3 error: Could not execute statement: " +
std::string(sqlite3_errmsg(handle.sqlite)));
}
}
}
connection::connection(connection_config config) : _handle(new detail::connection_handle(std::move(config)))
{
}
connection::connection(connection&&) noexcept = default;
connection& connection::operator=(connection&&) noexcept = default;
connection::~connection()
{
}
::sqlite3* connection::native_handle()
{
return _handle->sqlite;
}
bind_result_t connection::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");
}
return {std::move(prepared)};
}
bind_result_t connection::run_prepared_select_impl(prepared_statement_t& prepared_statement)
{
return {prepared_statement._handle};
}
size_t connection::insert_impl(const std::string& statement)
{
auto prepared = prepare_statement(*_handle, statement);
execute_statement(*_handle, prepared);
return sqlite3_last_insert_rowid(_handle->sqlite);
}
prepared_statement_t connection::prepare_impl(const std::string& statement)
{
return {std::unique_ptr<detail::prepared_statement_handle_t>(
new detail::prepared_statement_handle_t(prepare_statement(*_handle, statement)))};
}
size_t connection::run_prepared_insert_impl(prepared_statement_t& prepared_statement)
{
execute_statement(*_handle, *prepared_statement._handle.get());
return sqlite3_last_insert_rowid(_handle->sqlite);
}
size_t connection::run_prepared_execute_impl(prepared_statement_t& prepared_statement)
{
execute_statement(*_handle, *prepared_statement._handle.get());
return sqlite3_changes(_handle->sqlite);
}
size_t connection::execute(const std::string& statement)
{
auto prepared = prepare_statement(*_handle, statement);
execute_statement(*_handle, prepared);
return sqlite3_changes(_handle->sqlite);
}
size_t connection::update_impl(const std::string& statement)
{
auto prepared = prepare_statement(*_handle, statement);
execute_statement(*_handle, prepared);
return sqlite3_changes(_handle->sqlite);
}
size_t connection::run_prepared_update_impl(prepared_statement_t& prepared_statement)
{
execute_statement(*_handle, *prepared_statement._handle.get());
return sqlite3_changes(_handle->sqlite);
}
size_t connection::remove_impl(const std::string& statement)
{
auto prepared = prepare_statement(*_handle, statement);
execute_statement(*_handle, prepared);
return sqlite3_changes(_handle->sqlite);
}
size_t connection::run_prepared_remove_impl(prepared_statement_t& prepared_statement)
{
execute_statement(*_handle, *prepared_statement._handle.get());
return sqlite3_changes(_handle->sqlite);
}
std::string connection::escape(const std::string& s) const
{
std::string t;
t.reserve(s.size());
for (const char c : s)
{
if (c == '\'')
t.push_back(c);
t.push_back(c);
}
return t;
}
void connection::set_default_isolation_level(isolation_level level)
{
if (level == sqlpp::isolation_level::read_uncommitted)
{
execute("pragma read_uncommitted = true");
} else {
execute("pragma read_uncommitted = false");
}
}
sqlpp::isolation_level connection::get_default_isolation_level()
{
auto stmt = prepare_statement(*_handle, "pragma read_uncommitted");
execute_statement(*_handle, stmt);
int level = sqlite3_column_int(stmt.sqlite_statement, 0);
return level == 0 ? sqlpp::isolation_level::serializable :
sqlpp::isolation_level::read_uncommitted;
}
void connection::start_transaction()
{
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;
auto prepared = prepare_statement(*_handle, "BEGIN");
execute_statement(*_handle, prepared);
_transaction_status = transaction_status_type::active;
}
void connection::commit_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;
}
void connection::rollback_transaction(bool report)
{
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;
}
void connection::report_rollback_failure(const std::string message) noexcept
{
std::cerr << "Sqlite3 message:" << message << std::endl;
}
uint64_t connection::last_insert_id() noexcept
{
return sqlite3_last_insert_rowid(_handle->sqlite);
}
auto connection::attach(const connection_config& config, const std::string name) -> schema_t
{
auto prepared =
prepare_statement(*_handle, "ATTACH '" + escape(config.path_to_database) + "' AS " + escape(name));
execute_statement(*_handle, prepared);
return {name};
}
}
}

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2013 - 2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <memory>
#include <sqlpp11/exception.h>
#include <sqlpp11/sqlite3/connection_config.h>
#include "connection_handle.h"
#ifdef SQLPP_DYNAMIC_LOADING
#include <sqlpp11/sqlite3/dynamic_libsqlite3.h>
#endif
namespace sqlpp
{
namespace sqlite3
{
#ifdef SQLPP_DYNAMIC_LOADING
using namespace dynamic;
#endif
namespace detail
{
connection_handle::connection_handle(connection_config conf) : config(conf), sqlite(nullptr)
{
#ifdef SQLPP_DYNAMIC_LOADING
init_sqlite("");
#endif
auto rc = sqlite3_open_v2(conf.path_to_database.c_str(), &sqlite, conf.flags,
conf.vfs.empty() ? nullptr : conf.vfs.c_str());
if (rc != SQLITE_OK)
{
const std::string msg = sqlite3_errmsg(sqlite);
sqlite3_close(sqlite);
throw sqlpp::exception("Sqlite3 error: Can't open database: " + msg);
}
#ifdef SQLITE_HAS_CODEC
if (conf.password.size()>0)
{
int ret = sqlite3_key(sqlite, conf.password.data(),conf.password.size());
if (ret!=SQLITE_OK)
{
const std::string msg = sqlite3_errmsg(sqlite);
sqlite3_close(sqlite);
throw sqlpp::exception("Sqlite3 error: Can't set password to database: " + msg);
}
}
#endif
}
connection_handle::~connection_handle()
{
auto rc = sqlite3_close(sqlite);
if (rc != SQLITE_OK)
{
std::cerr << "Sqlite3 error: Can't close database: " << sqlite3_errmsg(sqlite) << std::endl;
}
}
}
}
}

View File

@ -0,0 +1,61 @@
/*
* 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.
*/
#ifndef SQLPP_SQLITE3_CONNECTION_HANDLE_H
#define SQLPP_SQLITE3_CONNECTION_HANDLE_H
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <sqlpp11/sqlite3/connection_config.h>
namespace sqlpp
{
namespace sqlite3
{
struct connection_config;
namespace detail
{
struct connection_handle
{
connection_config config;
::sqlite3* sqlite;
connection_handle(connection_config config);
~connection_handle();
connection_handle(const connection_handle&) = delete;
connection_handle(connection_handle&&) = delete;
connection_handle& operator=(const connection_handle&) = delete;
connection_handle& operator=(connection_handle&&) = delete;
};
} // namespace detail
} // namespace sqlite3
} // namespace sqlpp
#endif

View File

@ -0,0 +1,466 @@
/*
* Copyright (c) 2017, Volker Assmann
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "sqlpp11/sqlite3/dynamic_libsqlite3.h"
#include "sqlpp11/exception.h"
#include <cassert>
#include <string>
#if defined(__linux__) || defined(__APPLE__)
#include <dlfcn.h>
#else
#include <Windows.h>
#endif
#ifdef SQLPP_DYNAMIC_LOADING
namespace sqlpp
{
namespace sqlite3
{
namespace dynamic
{
#define DYNDEFINE(NAME) decltype(::NAME)* NAME
#if defined(__linux__) || defined(__APPLE__)
#define DYNLOAD(HNDL, NAME) NAME = reinterpret_cast<decltype(NAME)>(dlsym(HNDL, #NAME))
#else
#define DYNLOAD(HNDL, NAME) NAME = reinterpret_cast<decltype(NAME)>(GetProcAddress(HNDL, #NAME))
#endif
DYNDEFINE(sqlite3_open_v2);
DYNDEFINE(sqlite3_open);
DYNDEFINE(sqlite3_prepare_v2);
DYNDEFINE(sqlite3_exec);
DYNDEFINE(sqlite3_step);
DYNDEFINE(sqlite3_bind_int);
DYNDEFINE(sqlite3_close);
DYNDEFINE(sqlite3_initialize);
DYNDEFINE(sqlite3_os_init);
DYNDEFINE(sqlite3_os_end);
DYNDEFINE(sqlite3_bind_blob);
DYNDEFINE(sqlite3_bind_double);
DYNDEFINE(sqlite3_bind_int64);
DYNDEFINE(sqlite3_bind_null);
DYNDEFINE(sqlite3_bind_text);
DYNDEFINE(sqlite3_bind_value);
DYNDEFINE(sqlite3_libversion_number);
// DYNDEFINE(sqlite3_compileoption_used);
DYNDEFINE(sqlite3_threadsafe);
// DYNDEFINE(sqlite3_close_v2);
DYNDEFINE(sqlite3_shutdown);
DYNDEFINE(sqlite3_config);
DYNDEFINE(sqlite3_db_config);
DYNDEFINE(sqlite3_extended_result_codes);
DYNDEFINE(sqlite3_last_insert_rowid);
DYNDEFINE(sqlite3_changes);
DYNDEFINE(sqlite3_total_changes);
DYNDEFINE(sqlite3_interrupt);
DYNDEFINE(sqlite3_complete);
DYNDEFINE(sqlite3_complete16);
DYNDEFINE(sqlite3_busy_handler);
DYNDEFINE(sqlite3_busy_timeout);
DYNDEFINE(sqlite3_get_table);
DYNDEFINE(sqlite3_free_table);
// DYNDEFINE(sqlite3_realloc64);
DYNDEFINE(sqlite3_free);
// DYNDEFINE(sqlite3_msize);
DYNDEFINE(sqlite3_memory_used);
DYNDEFINE(sqlite3_memory_highwater);
DYNDEFINE(sqlite3_randomness);
DYNDEFINE(sqlite3_set_authorizer);
DYNDEFINE(sqlite3_progress_handler);
DYNDEFINE(sqlite3_open16);
// DYNDEFINE(sqlite3_uri_boolean);
// DYNDEFINE(sqlite3_uri_int64);
DYNDEFINE(sqlite3_errcode);
DYNDEFINE(sqlite3_errmsg);
DYNDEFINE(sqlite3_extended_errcode);
DYNDEFINE(sqlite3_limit);
DYNDEFINE(sqlite3_prepare);
DYNDEFINE(sqlite3_prepare16);
DYNDEFINE(sqlite3_prepare16_v2);
// DYNDEFINE(sqlite3_stmt_readonly);
// DYNDEFINE(sqlite3_stmt_busy);
// DYNDEFINE(sqlite3_bind_blob64);
DYNDEFINE(sqlite3_bind_text16);
// DYNDEFINE(sqlite3_bind_text64);
DYNDEFINE(sqlite3_bind_zeroblob);
DYNDEFINE(sqlite3_bind_parameter_count);
DYNDEFINE(sqlite3_bind_parameter_index);
DYNDEFINE(sqlite3_clear_bindings);
DYNDEFINE(sqlite3_column_count);
DYNDEFINE(sqlite3_data_count);
DYNDEFINE(sqlite3_column_bytes);
DYNDEFINE(sqlite3_column_bytes16);
DYNDEFINE(sqlite3_column_double);
DYNDEFINE(sqlite3_column_int);
DYNDEFINE(sqlite3_column_int64);
DYNDEFINE(sqlite3_column_text);
DYNDEFINE(sqlite3_column_type);
DYNDEFINE(sqlite3_column_value);
DYNDEFINE(sqlite3_column_blob);
DYNDEFINE(sqlite3_finalize);
DYNDEFINE(sqlite3_reset);
DYNDEFINE(sqlite3_create_function);
DYNDEFINE(sqlite3_create_function16);
// DYNDEFINE(sqlite3_create_function_v2);
DYNDEFINE(sqlite3_value_bytes);
DYNDEFINE(sqlite3_value_bytes16);
DYNDEFINE(sqlite3_value_double);
DYNDEFINE(sqlite3_value_int);
DYNDEFINE(sqlite3_value_int64);
DYNDEFINE(sqlite3_value_type);
DYNDEFINE(sqlite3_value_numeric_type);
DYNDEFINE(sqlite3_set_auxdata);
DYNDEFINE(sqlite3_result_blob);
// DYNDEFINE(sqlite3_result_blob64);
DYNDEFINE(sqlite3_result_double);
DYNDEFINE(sqlite3_result_error);
DYNDEFINE(sqlite3_result_error16);
DYNDEFINE(sqlite3_result_error_toobig);
DYNDEFINE(sqlite3_result_error_nomem);
DYNDEFINE(sqlite3_result_error_code);
DYNDEFINE(sqlite3_result_int);
DYNDEFINE(sqlite3_result_int64);
DYNDEFINE(sqlite3_result_null);
DYNDEFINE(sqlite3_result_text);
// DYNDEFINE(sqlite3_result_text64);
DYNDEFINE(sqlite3_result_text16);
DYNDEFINE(sqlite3_result_text16le);
DYNDEFINE(sqlite3_result_text16be);
DYNDEFINE(sqlite3_result_value);
DYNDEFINE(sqlite3_result_zeroblob);
DYNDEFINE(sqlite3_create_collation);
DYNDEFINE(sqlite3_create_collation_v2);
DYNDEFINE(sqlite3_create_collation16);
DYNDEFINE(sqlite3_collation_needed);
DYNDEFINE(sqlite3_collation_needed16);
#ifdef SQLITE_HAS_CODEC
DYNDEFINE(sqlite3_key);
DYNDEFINE(sqlite3_key_v2);
DYNDEFINE(sqlite3_rekey);
DYNDEFINE(sqlite3_rekey_v2);
DYNDEFINE(sqlite3_activate_see);
#endif
#ifdef SQLITE_ENABLE_CEROD
DYNDEFINE(sqlite3_activate_cerod);
#endif
DYNDEFINE(sqlite3_sleep);
DYNDEFINE(sqlite3_get_autocommit);
// DYNDEFINE(sqlite3_db_readonly);
DYNDEFINE(sqlite3_next_stmt);
DYNDEFINE(sqlite3_enable_shared_cache);
DYNDEFINE(sqlite3_release_memory);
// DYNDEFINE(sqlite3_db_release_memory);
// DYNDEFINE(sqlite3_soft_heap_limit64);
DYNDEFINE(sqlite3_table_column_metadata);
DYNDEFINE(sqlite3_load_extension);
DYNDEFINE(sqlite3_enable_load_extension);
DYNDEFINE(sqlite3_auto_extension);
// DYNDEFINE(sqlite3_cancel_auto_extension);
DYNDEFINE(sqlite3_reset_auto_extension);
DYNDEFINE(sqlite3_create_module);
DYNDEFINE(sqlite3_create_module_v2);
DYNDEFINE(sqlite3_declare_vtab);
DYNDEFINE(sqlite3_overload_function);
DYNDEFINE(sqlite3_blob_open);
DYNDEFINE(sqlite3_blob_close);
DYNDEFINE(sqlite3_blob_bytes);
DYNDEFINE(sqlite3_blob_read);
DYNDEFINE(sqlite3_blob_write);
DYNDEFINE(sqlite3_vfs_find);
DYNDEFINE(sqlite3_vfs_register);
DYNDEFINE(sqlite3_vfs_unregister);
DYNDEFINE(sqlite3_mutex_alloc);
DYNDEFINE(sqlite3_mutex_free);
DYNDEFINE(sqlite3_mutex_enter);
DYNDEFINE(sqlite3_mutex_try);
DYNDEFINE(sqlite3_mutex_leave);
// DYNDEFINE(sqlite3_mutex_held);
// DYNDEFINE(sqlite3_mutex_notheld);
DYNDEFINE(sqlite3_db_mutex);
DYNDEFINE(sqlite3_file_control);
DYNDEFINE(sqlite3_test_control);
DYNDEFINE(sqlite3_status);
DYNDEFINE(sqlite3_db_status);
DYNDEFINE(sqlite3_stmt_status);
DYNDEFINE(sqlite3_backup_init);
DYNDEFINE(sqlite3_backup_step);
DYNDEFINE(sqlite3_backup_finish);
DYNDEFINE(sqlite3_backup_remaining);
DYNDEFINE(sqlite3_backup_pagecount);
DYNDEFINE(sqlite3_unlock_notify);
// DYNDEFINE(sqlite3_stricmp);
// DYNDEFINE(sqlite3_strnicmp);
// DYNDEFINE(sqlite3_strglob);
// DYNDEFINE(sqlite3_log);
// DYNDEFINE(sqlite3_wal_autocheckpoint);
// DYNDEFINE(sqlite3_wal_checkpoint);
// DYNDEFINE(sqlite3_wal_checkpoint_v2);
// DYNDEFINE(sqlite3_vtab_config);
// DYNDEFINE(sqlite3_vtab_on_conflict);
// DYNDEFINE(sqlite3_rtree_geometry_callback);
// DYNDEFINE(sqlite3_rtree_query_callback);
#define STR(x) #x
#define GET_STR(x) STR(x)
#ifndef SQLPP_DYNAMIC_LOADING_FILENAME
#ifdef __linux__
#define SQLPP_DYNAMIC_LOADING_FILENAME libsqlite3.so
#elif __APPLE__
#define SQLPP_DYNAMIC_LOADING_FILENAME libsqlite3.dylib
#endif
#endif
void init_sqlite(std::string libname)
{
if (libname.empty())
{
libname = GET_STR(SQLPP_DYNAMIC_LOADING_FILENAME);
}
#if defined(__linux__) || defined(__APPLE__)
void* handle = nullptr;
handle = dlopen(libname.c_str(), RTLD_LAZY | RTLD_GLOBAL);
#else
HINSTANCE handle = nullptr;
handle = LoadLibrary(libname.c_str());
#endif
#undef STR
#undef GET_STR
if (!handle)
{
#if defined(__linux__) || defined(__APPLE__)
throw sqlpp::exception(std::string("Could not load library " + libname + ": ").append(dlerror()));
#elif defined(_WIN32)
if (GetLastError() == 193)
{
throw sqlpp::exception(
"Could not load SQLite library - error code indicates you are mixing 32/64 bit DLLs (lib: " + libname +
")");
}
else
{
throw sqlpp::exception("Could not load lib using LoadLibrary (" + libname + ")");
}
#endif
}
DYNLOAD(handle, sqlite3_libversion_number);
// DYNLOAD(handle, sqlite3_compileoption_used);
DYNLOAD(handle, sqlite3_threadsafe);
DYNLOAD(handle, sqlite3_close);
// DYNLOAD(handle, sqlite3_close_v2);
DYNLOAD(handle, sqlite3_exec);
DYNLOAD(handle, sqlite3_initialize);
DYNLOAD(handle, sqlite3_shutdown);
DYNLOAD(handle, sqlite3_os_init);
DYNLOAD(handle, sqlite3_os_end);
DYNLOAD(handle, sqlite3_config);
DYNLOAD(handle, sqlite3_db_config);
DYNLOAD(handle, sqlite3_extended_result_codes);
DYNLOAD(handle, sqlite3_last_insert_rowid);
DYNLOAD(handle, sqlite3_changes);
DYNLOAD(handle, sqlite3_total_changes);
DYNLOAD(handle, sqlite3_interrupt);
DYNLOAD(handle, sqlite3_complete);
DYNLOAD(handle, sqlite3_complete16);
DYNLOAD(handle, sqlite3_busy_handler);
DYNLOAD(handle, sqlite3_busy_timeout);
DYNLOAD(handle, sqlite3_get_table);
DYNLOAD(handle, sqlite3_free_table);
// DYNLOAD(handle, sqlite3_realloc64);
DYNLOAD(handle, sqlite3_free);
// DYNLOAD(handle, sqlite3_msize);
DYNLOAD(handle, sqlite3_memory_used);
DYNLOAD(handle, sqlite3_memory_highwater);
DYNLOAD(handle, sqlite3_randomness);
DYNLOAD(handle, sqlite3_set_authorizer);
DYNLOAD(handle, sqlite3_progress_handler);
DYNLOAD(handle, sqlite3_open);
DYNLOAD(handle, sqlite3_open16);
DYNLOAD(handle, sqlite3_open_v2);
// DYNLOAD(handle, sqlite3_uri_boolean);
// DYNLOAD(handle, sqlite3_uri_int64);
DYNLOAD(handle, sqlite3_errcode);
DYNLOAD(handle, sqlite3_errmsg);
DYNLOAD(handle, sqlite3_extended_errcode);
DYNLOAD(handle, sqlite3_limit);
DYNLOAD(handle, sqlite3_prepare);
DYNLOAD(handle, sqlite3_prepare_v2);
DYNLOAD(handle, sqlite3_prepare16);
DYNLOAD(handle, sqlite3_prepare16_v2);
// DYNLOAD(handle, sqlite3_stmt_readonly);
// DYNLOAD(handle, sqlite3_stmt_busy);
DYNLOAD(handle, sqlite3_bind_blob);
// DYNLOAD(handle, sqlite3_bind_blob64);
DYNLOAD(handle, sqlite3_bind_double);
DYNLOAD(handle, sqlite3_bind_int);
DYNLOAD(handle, sqlite3_bind_int64);
DYNLOAD(handle, sqlite3_bind_null);
DYNLOAD(handle, sqlite3_bind_text);
DYNLOAD(handle, sqlite3_bind_text16);
// DYNLOAD(handle, sqlite3_bind_text64);
DYNLOAD(handle, sqlite3_bind_value);
DYNLOAD(handle, sqlite3_bind_zeroblob);
DYNLOAD(handle, sqlite3_bind_parameter_count);
DYNLOAD(handle, sqlite3_bind_parameter_index);
DYNLOAD(handle, sqlite3_clear_bindings);
DYNLOAD(handle, sqlite3_column_count);
DYNLOAD(handle, sqlite3_step);
DYNLOAD(handle, sqlite3_data_count);
DYNLOAD(handle, sqlite3_column_bytes);
DYNLOAD(handle, sqlite3_column_bytes16);
DYNLOAD(handle, sqlite3_column_double);
DYNLOAD(handle, sqlite3_column_int);
DYNLOAD(handle, sqlite3_column_int64);
DYNLOAD(handle, sqlite3_column_text);
DYNLOAD(handle, sqlite3_column_type);
DYNLOAD(handle, sqlite3_column_value);
DYNLOAD(handle, sqlite3_column_blob);
DYNLOAD(handle, sqlite3_finalize);
DYNLOAD(handle, sqlite3_reset);
DYNLOAD(handle, sqlite3_create_function);
DYNLOAD(handle, sqlite3_create_function16);
// DYNLOAD(handle, sqlite3_create_function_v2);
DYNLOAD(handle, sqlite3_value_bytes);
DYNLOAD(handle, sqlite3_value_bytes16);
DYNLOAD(handle, sqlite3_value_double);
DYNLOAD(handle, sqlite3_value_int);
DYNLOAD(handle, sqlite3_value_int64);
DYNLOAD(handle, sqlite3_value_type);
DYNLOAD(handle, sqlite3_value_numeric_type);
DYNLOAD(handle, sqlite3_set_auxdata);
DYNLOAD(handle, sqlite3_result_blob);
// DYNLOAD(handle, sqlite3_result_blob64);
DYNLOAD(handle, sqlite3_result_double);
DYNLOAD(handle, sqlite3_result_error);
DYNLOAD(handle, sqlite3_result_error16);
DYNLOAD(handle, sqlite3_result_error_toobig);
DYNLOAD(handle, sqlite3_result_error_nomem);
DYNLOAD(handle, sqlite3_result_error_code);
DYNLOAD(handle, sqlite3_result_int);
DYNLOAD(handle, sqlite3_result_int64);
DYNLOAD(handle, sqlite3_result_null);
DYNLOAD(handle, sqlite3_result_text);
// DYNLOAD(handle, sqlite3_result_text64);
DYNLOAD(handle, sqlite3_result_text16);
DYNLOAD(handle, sqlite3_result_text16le);
DYNLOAD(handle, sqlite3_result_text16be);
DYNLOAD(handle, sqlite3_result_value);
DYNLOAD(handle, sqlite3_result_zeroblob);
DYNLOAD(handle, sqlite3_create_collation);
DYNLOAD(handle, sqlite3_create_collation_v2);
DYNLOAD(handle, sqlite3_create_collation16);
DYNLOAD(handle, sqlite3_collation_needed);
DYNLOAD(handle, sqlite3_collation_needed16);
#ifdef SQLITE_HAS_CODEC
DYNLOAD(handle, sqlite3_key);
DYNLOAD(handle, sqlite3_key_v2);
DYNLOAD(handle, sqlite3_rekey);
DYNLOAD(handle, sqlite3_rekey_v2);
DYNLOAD(handle, sqlite3_activate_see);
#endif
#ifdef SQLITE_ENABLE_CEROD
DYNLOAD(handle, sqlite3_activate_cerod);
#endif
DYNLOAD(handle, sqlite3_sleep);
DYNLOAD(handle, sqlite3_get_autocommit);
// DYNLOAD(handle, sqlite3_db_readonly);
DYNLOAD(handle, sqlite3_next_stmt);
DYNLOAD(handle, sqlite3_enable_shared_cache);
DYNLOAD(handle, sqlite3_release_memory);
// DYNLOAD(handle, sqlite3_db_release_memory);
// DYNLOAD(handle, sqlite3_soft_heap_limit64);
DYNLOAD(handle, sqlite3_table_column_metadata);
DYNLOAD(handle, sqlite3_load_extension);
DYNLOAD(handle, sqlite3_enable_load_extension);
DYNLOAD(handle, sqlite3_auto_extension);
// DYNLOAD(handle, sqlite3_cancel_auto_extension);
DYNLOAD(handle, sqlite3_reset_auto_extension);
DYNLOAD(handle, sqlite3_create_module);
DYNLOAD(handle, sqlite3_create_module_v2);
DYNLOAD(handle, sqlite3_declare_vtab);
DYNLOAD(handle, sqlite3_overload_function);
DYNLOAD(handle, sqlite3_blob_open);
DYNLOAD(handle, sqlite3_blob_close);
DYNLOAD(handle, sqlite3_blob_bytes);
DYNLOAD(handle, sqlite3_blob_read);
DYNLOAD(handle, sqlite3_blob_write);
DYNLOAD(handle, sqlite3_vfs_find);
DYNLOAD(handle, sqlite3_vfs_register);
DYNLOAD(handle, sqlite3_vfs_unregister);
DYNLOAD(handle, sqlite3_mutex_alloc);
DYNLOAD(handle, sqlite3_mutex_free);
DYNLOAD(handle, sqlite3_mutex_enter);
DYNLOAD(handle, sqlite3_mutex_try);
DYNLOAD(handle, sqlite3_mutex_leave);
// DYNLOAD(handle, sqlite3_mutex_held);
// DYNLOAD(handle, sqlite3_mutex_notheld);
DYNLOAD(handle, sqlite3_db_mutex);
DYNLOAD(handle, sqlite3_file_control);
DYNLOAD(handle, sqlite3_test_control);
DYNLOAD(handle, sqlite3_status);
DYNLOAD(handle, sqlite3_db_status);
DYNLOAD(handle, sqlite3_stmt_status);
DYNLOAD(handle, sqlite3_backup_init);
DYNLOAD(handle, sqlite3_backup_step);
DYNLOAD(handle, sqlite3_backup_finish);
DYNLOAD(handle, sqlite3_backup_remaining);
DYNLOAD(handle, sqlite3_backup_pagecount);
DYNLOAD(handle, sqlite3_unlock_notify);
// DYNLOAD(handle, sqlite3_stricmp);
// DYNLOAD(handle, sqlite3_strnicmp);
// DYNLOAD(handle, sqlite3_strglob);
// DYNLOAD(handle, sqlite3_log);
// DYNLOAD(handle, sqlite3_wal_autocheckpoint);
// DYNLOAD(handle, sqlite3_wal_checkpoint);
// DYNLOAD(handle, sqlite3_wal_checkpoint_v2);
// DYNLOAD(handle, sqlite3_vtab_config);
// DYNLOAD(handle, sqlite3_vtab_on_conflict);
// DYNLOAD(handle, sqlite3_rtree_geometry_callback);
// DYNLOAD(handle, sqlite3_rtree_query_callback);
// check some functions for nullptr to verify if loading worked, otherwise throw
if (sqlite3_shutdown == nullptr || sqlite3_exec == nullptr)
{
throw sqlpp::exception("Initializing dynamically loaded SQLite3 functions failed");
}
}
} // dynamic
} // sqlite3
} // sqlpp
#undef DYNDEFINE
#undef DYNLOAD
#endif

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2013 - 2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SQLPP_SQLITE3_DETAIL_PREPARED_STATEMENT_HANDLE_H
#define SQLPP_SQLITE3_DETAIL_PREPARED_STATEMENT_HANDLE_H
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#ifdef SQLPP_DYNAMIC_LOADING
#include <sqlpp11/sqlite3/dynamic_libsqlite3.h>
#endif
namespace sqlpp
{
namespace sqlite3
{
#ifdef SQLPP_DYNAMIC_LOADING
using namespace dynamic;
#endif
namespace detail
{
struct prepared_statement_handle_t
{
sqlite3_stmt* sqlite_statement;
bool debug;
prepared_statement_handle_t(sqlite3_stmt* statement, bool debug_) : sqlite_statement(statement), debug(debug_)
{
}
prepared_statement_handle_t(const prepared_statement_handle_t&) = delete;
prepared_statement_handle_t(prepared_statement_handle_t&& rhs)
{
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)
{
if (sqlite_statement != rhs.sqlite_statement)
{
sqlite_statement = rhs.sqlite_statement;
rhs.sqlite_statement = nullptr;
}
debug = rhs.debug;
return *this;
}
~prepared_statement_handle_t()
{
if (sqlite_statement)
{
sqlite3_finalize(sqlite_statement);
}
}
bool operator!() const
{
return !sqlite_statement;
}
};
} // namespace detail
} // namespace sqlite3
} // namespace sqlpp
#endif

View File

@ -0,0 +1,245 @@
/*
* 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 "detail/prepared_statement_handle.h"
#include <ciso646>
#include <cmath>
#include <date/date.h>
#include <iostream>
#include <sqlpp11/exception.h>
#include <sqlpp11/sqlite3/prepared_statement.h>
#include <sstream>
#include <string>
#if defined(__CYGWIN__)
#include <sstream>
// Workaround because cygwin gcc does not define to_string
namespace std
{
template <typename T>
std::string to_string(T t)
{
std::ostringstream stream;
stream << t;
return stream.str();
}
} // namespace std
#endif
#ifdef SQLPP_DYNAMIC_LOADING
#include <sqlpp11/sqlite3/dynamic_libsqlite3.h>
#endif
namespace sqlpp
{
namespace sqlite3
{
#ifdef SQLPP_DYNAMIC_LOADING
using namespace dynamic;
#endif
namespace
{
void check_bind_result(int result, const char* const type)
{
switch (result)
{
case SQLITE_OK:
return;
case SQLITE_RANGE:
throw sqlpp::exception("Sqlite3 error: " + std::string(type) + " bind value out of range");
case SQLITE_NOMEM:
throw sqlpp::exception("Sqlite3 error: " + std::string(type) + " bind out of memory");
case SQLITE_TOOBIG:
throw sqlpp::exception("Sqlite3 error: " + std::string(type) + " bind too big");
default:
throw sqlpp::exception("Sqlite3 error: " + std::string(type) +
" bind returned unexpected value: " + std::to_string(result));
}
}
} // namespace
prepared_statement_t::prepared_statement_t(std::shared_ptr<detail::prepared_statement_handle_t>&& handle)
: _handle(std::move(handle))
{
if (_handle and _handle->debug)
std::cerr << "Sqlite3 debug: Constructing prepared_statement, using handle at " << _handle.get() << std::endl;
}
void prepared_statement_t::_reset()
{
if (_handle->debug)
std::cerr << "Sqlite3 debug: resetting prepared statement" << std::endl;
sqlite3_reset(_handle->sqlite_statement);
}
void prepared_statement_t::_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));
check_bind_result(result, "boolean");
}
void prepared_statement_t::_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))
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
result = sqlite3_bind_double(_handle->sqlite_statement, static_cast<int>(index + 1), *value);
}
else
result = sqlite3_bind_null(_handle->sqlite_statement, static_cast<int>(index + 1));
check_bind_result(result, "floating_point");
}
void prepared_statement_t::_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));
check_bind_result(result, "integral");
}
void prepared_statement_t::_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));
check_bind_result(result, "integral");
}
void prepared_statement_t::_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));
check_bind_result(result, "text");
}
void prepared_statement_t::_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));
check_bind_result(result, "date");
}
void prepared_statement_t::_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));
check_bind_result(result, "date");
}
void prepared_statement_t::_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));
check_bind_result(result, "blob");
}
} // namespace sqlite3
} // namespace sqlpp

View File

@ -1,13 +1,13 @@
# Copyright (c) 2013-2016, Roland Bock # Copyright (c) 2021-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,
# are permitted provided that the following conditions are met: # are permitted provided that the following conditions are met:
# #
# Redistributions of source code must retain the above copyright notice, this # 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer. # list of conditions and the following disclaimer.
# #
# Redistributions in binary form must reproduce the above copyright notice, this # 2. Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or # list of conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution. # other materials provided with the distribution.
# #
@ -21,59 +21,17 @@
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # 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 # (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.
add_subdirectory(core/)
add_library(sqlpp11_testing INTERFACE) if(MYSQL_CONNECTOR)
target_include_directories(sqlpp11_testing INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(mysql)
if (NOT MSVC)
target_compile_options(sqlpp11_testing INTERFACE -Wall -Wextra -pedantic)
endif ()
set(test_names
BooleanExpression
CustomQuery
DateTime
Interpret
Insert
Remove
Update
Select
SelectType
Function
Prepared
Minimalistic
Result
Union
With
)
find_package(Boost 1.50)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
list(APPEND test_names Ppgen)
endif() endif()
if(POSTGRESQL_CONNECTOR)
create_test_sourcelist(test_sources test_main.cpp ${test_names}) add_subdirectory(postgresql)
add_executable(sqlpp11_tests ${test_sources})
target_link_libraries(sqlpp11_tests PRIVATE sqlpp11 sqlpp11_testing)
# conditionally bump to a higher C++ standard to test compatibility
if (SQLPP11_TESTS_CXX_STD)
set_property(TARGET sqlpp11_tests PROPERTY CXX_STANDARD ${SQLPP11_TESTS_CXX_STD})
set_property(TARGET sqlpp11_tests PROPERTY CXX_STANDARD_REQUIRED yes)
set_property(TARGET sqlpp11_tests PROPERTY CXX_EXTENSIONS no)
endif() endif()
foreach(test IN LISTS test_names) if(SQLITE3_CONNECTOR OR SQLCIPHER_CONNECTOR)
add_test(NAME sqlpp11.tests.${test} add_subdirectory(sqlite3)
COMMAND sqlpp11_tests ${test} endif()
)
endforeach()
# if you want to use the generator, you can do something like this:
#find_package(PythonInterp REQUIRED)
#add_custom_command(
# OUTPUT "${CMAKE_CURRENT_LIST_DIR}/Sample.h"
# COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/scripts/ddl2cpp" "${CMAKE_CURRENT_LIST_DIR}/sample.sql" Sample test
# DEPENDS "${CMAKE_CURRENT_LIST_DIR}/sample.sql"
# VERBATIM)

29
tests/core/CMakeLists.txt Normal file
View File

@ -0,0 +1,29 @@
# Copyright (c) 2021-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:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. 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.
add_subdirectory(usage)
add_subdirectory(serialize)
add_subdirectory(constraints)
add_subdirectory(static_asserts)

View File

@ -0,0 +1,79 @@
# 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.
add_library(sqlpp11_testing INTERFACE)
target_include_directories(sqlpp11_testing INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
if (NOT MSVC)
target_compile_options(sqlpp11_testing INTERFACE -Wall -Wextra -pedantic)
endif ()
set(test_names
BooleanExpression
CustomQuery
DateTime
Interpret
Insert
Remove
Update
Select
SelectType
Function
Prepared
Minimalistic
Result
Union
With
)
find_package(Boost 1.50)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
list(APPEND test_names Ppgen)
endif()
create_test_sourcelist(test_sources test_main.cpp ${test_names})
add_executable(sqlpp11_tests ${test_sources})
target_link_libraries(sqlpp11_tests PRIVATE sqlpp11 sqlpp11_testing)
# conditionally bump to a higher C++ standard to test compatibility
if (SQLPP11_TESTS_CXX_STD)
set_property(TARGET sqlpp11_tests PROPERTY CXX_STANDARD ${SQLPP11_TESTS_CXX_STD})
set_property(TARGET sqlpp11_tests PROPERTY CXX_STANDARD_REQUIRED yes)
set_property(TARGET sqlpp11_tests PROPERTY CXX_EXTENSIONS no)
endif()
foreach(test IN LISTS test_names)
add_test(NAME sqlpp11.tests.${test}
COMMAND sqlpp11_tests ${test}
)
endforeach()
# if you want to use the generator, you can do something like this:
#find_package(PythonInterp REQUIRED)
#add_custom_command(
# OUTPUT "${CMAKE_CURRENT_LIST_DIR}/Sample.h"
# COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/scripts/ddl2cpp" "${CMAKE_CURRENT_LIST_DIR}/sample.sql" Sample test
# DEPENDS "${CMAKE_CURRENT_LIST_DIR}/sample.sql"
# VERBATIM)

View File

@ -0,0 +1,26 @@
# Copyright (c) 2021-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:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. 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.
add_subdirectory(usage)

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2015 - 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/sqlite3/connection.h>
#include <sqlpp11/sqlpp11.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
#include <vector>
namespace sql = sqlpp::sqlite3;
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
// Opening a connection to an in-memory database and creating a table in it
sql::connection db(config);
db.execute(R"(CREATE TABLE tab_sample (
alpha INTEGER PRIMARY KEY,
beta varchar(255) DEFAULT NULL,
gamma bool DEFAULT NULL
))");
// Attaching another in-memory database and creating the same table in it
auto other = db.attach(config, "other");
db.execute(R"(CREATE TABLE other.tab_sample (
alpha INTEGER PRIMARY KEY,
beta varchar(255) DEFAULT NULL,
gamma bool DEFAULT NULL
))");
auto left = TabSample{};
auto right =
schema_qualified_table(other, TabSample{}).as(sqlpp::alias::right); // this is a table in the attached database
// inserting in one tab_sample
db(insert_into(left).default_values());
// selecting from the other tab_sample
assert(db(select(all_of(right)).from(right).unconditionally()).empty());
return 0;
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2015 - 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 <sqlpp11/custom_query.h>
#include <sqlpp11/sqlite3/sqlite3.h>
#include <sqlpp11/sqlpp11.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <cassert>
#include <iostream>
#include <set>
namespace sql = sqlpp::sqlite3;
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE tab_sample (
alpha INTEGER PRIMARY KEY AUTOINCREMENT,
beta bool DEFAULT NULL,
gamma varchar(255) DEFAULT NULL
))");
const auto tab = TabSample{};
db(insert_into(tab).default_values());
db(insert_into(tab).default_values());
db(insert_into(tab).default_values());
std::set<int64_t> results;
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
results.insert(row.alpha);
};
const auto expected = std::set<int64_t>{1, 2, 3};
assert(results == expected);
return 0;
}

View File

@ -0,0 +1,78 @@
// generated by ../../sqlpp11/scripts/ddl2cpp -fail-on-parse BlobSample.sql BlobSample blob
#ifndef BLOB_BLOBSAMPLE_H
#define BLOB_BLOBSAMPLE_H
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/data_types.h>
#include <sqlpp11/table.h>
namespace BlobSample_
{
struct Id
{
struct _alias_t
{
static constexpr const char _literal[] = "id";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T id;
T& operator()()
{
return id;
}
const T& operator()() const
{
return id;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::integer, sqlpp::tag::can_be_null>;
};
struct Data
{
struct _alias_t
{
static constexpr const char _literal[] = "data";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T data;
T& operator()()
{
return data;
}
const T& operator()() const
{
return data;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::blob, sqlpp::tag::can_be_null>;
};
} // namespace BlobSample_
struct BlobSample : sqlpp::table_t<BlobSample, BlobSample_::Id, BlobSample_::Data>
{
struct _alias_t
{
static constexpr const char _literal[] = "blob_sample";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T blobSample;
T& operator()()
{
return blobSample;
}
const T& operator()() const
{
return blobSample;
}
};
};
};
#endif

View File

@ -0,0 +1,4 @@
CREATE TABLE blob_sample (
id INTEGER PRIMARY KEY,
data blob
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

View File

@ -0,0 +1,102 @@
#include "BlobSample.h"
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/sqlpp11.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <functional>
#include <iostream>
#include <random>
namespace sql = sqlpp::sqlite3;
const auto blob = BlobSample{};
/*
* max default blob/text is 1,000,000,000
* But 999,999,993 is the biggest one SQLITE will accept
* without throwing SQLITE_TOOBIG
* But it takes too long (over 5s) to generate and check
*/
constexpr size_t blob_size = 1000 * 1000ul;
constexpr size_t blob_small_size = 999;
void verify_blob(sql::connection& db, const std::vector<uint8_t>& data, uint64_t id)
{
auto result = db(select(blob.data).from(blob).where(blob.id == id));
const auto& result_row = result.front();
std::cerr << "Insert size: " << data.size() << std::endl;
std::cerr << "Select size: " << result_row.data.len << std::endl;
if (data.size() != result_row.data.len)
{
std::cerr << "Size mismatch" << std::endl;
throw std::runtime_error("Size mismatch " + std::to_string(data.size()) +
" != " + std::to_string(result_row.data.len));
}
std::cerr << "Verifying content" << std::endl;
std::vector<uint8_t> result_blob(result_row.data.blob, result_row.data.blob + result_row.data.len);
if (data != result_blob)
{
std::cout << "Content mismatch ([row] original -> received)" << std::endl;
for (size_t i = 0; i < data.size(); i++)
{
if (data[i] != result_row.data.blob[i])
{
std::cerr << "[" << i << "] " << static_cast<int>(data.at(i)) << " -> " << static_cast<int>(result_blob.at(i))
<< std::endl;
}
}
throw std::runtime_error("Content mismatch");
}
}
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE blob_sample (
id INTEGER PRIMARY KEY,
data blob
))");
std::cerr << "Generating data " << blob_size << std::endl;
std::vector<uint8_t> data(blob_size);
std::uniform_int_distribution<unsigned short> distribution(0, 255);
std::mt19937 engine;
auto generator = std::bind(distribution, engine);
std::generate_n(data.begin(), blob_size, generator);
std::vector<uint8_t> data_smaller(blob_small_size);
std::generate_n(data_smaller.begin(), blob_small_size, generator);
// If we use the bigger blob it will trigger SQLITE_TOOBIG for the query
auto id = db(insert_into(blob).set(blob.data = data_smaller));
auto prepared_insert = db.prepare(insert_into(blob).set(blob.data = parameter(blob.data)));
prepared_insert.params.data = data;
auto prep_id = db(prepared_insert);
prepared_insert.params.data.set_null();
auto null_id = db(prepared_insert);
verify_blob(db, data_smaller, id);
verify_blob(db, data, prep_id);
{
auto result = db(select(blob.data).from(blob).where(blob.id == null_id));
const auto& result_row = result.front();
std::cerr << "Null blob is_null:\t" << std::boolalpha << result_row.data.is_null() << std::endl;
std::cerr << "Null blob len == 0:\t" << std::boolalpha << (result_row.data.len == 0) << std::endl;
std::cerr << "Null blob blob == nullptr:\t" << std::boolalpha << (result_row.data.blob == nullptr) << std::endl;
if (!result_row.data.is_null() || result_row.data.len != 0 || result_row.data.blob != nullptr)
{
throw std::runtime_error("Null blob has incorrect values");
}
}
return 0;
}

View File

@ -0,0 +1,60 @@
# 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.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
macro (build_and_run arg)
# Add headers to sources to enable file browsing in IDEs
add_executable(Sqlpp11Sqlite3${arg} ${arg}.cpp)
target_link_libraries(Sqlpp11Sqlite3${arg} PRIVATE sqlpp11-connector-sqlite3)
if (NOT MSVC)
target_compile_options(Sqlpp11Sqlite3${arg} INTERFACE -Wall -Wextra -pedantic)
endif ()
add_test(NAME Sqlpp11Sqlite3${arg} COMMAND Sqlpp11Sqlite3${arg})
endmacro ()
build_and_run(DateTimeTest)
build_and_run(SampleTest)
build_and_run(SelectTest)
build_and_run(UnionTest)
build_and_run(WithTest)
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
if (SQLPP_DYNAMIC_LOADING)
add_executable(Sqlpp11Sqlite3DynamicLoadingTest "DynamicLoadingTest.cpp" ${sqlpp_headers})
target_link_libraries(Sqlpp11Sqlite3DynamicLoadingTest sqlpp11-connector-sqlite3-dynamic)
if (NOT MSVC)
target_link_libraries(Sqlpp11Sqlite3DynamicLoadingTest dl)
target_compile_options(Sqlpp11Sqlite3DynamicLoadingTest INTERFACE -Wall -Wextra -pedantic)
endif ()
add_test(NAME Sqlpp11Sqlite3DynamicLoadingTest COMMAND Sqlpp11Sqlite3DynamicLoadingTest)
endif()

View File

@ -0,0 +1,130 @@
/*
* 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 <sqlpp11/custom_query.h>
#include <sqlpp11/sqlite3/sqlite3.h>
#include <sqlpp11/sqlpp11.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <cassert>
#include <iostream>
#include <vector>
namespace
{
const auto now = ::sqlpp::chrono::floor<::std::chrono::milliseconds>(std::chrono::system_clock::now());
const auto today = ::sqlpp::chrono::floor<::sqlpp::chrono::days>(now);
const auto yesterday = today - ::sqlpp::chrono::days{1};
template <typename L, typename R>
auto require_equal(int line, const L& l, const R& r) -> void
{
if (l != r)
{
std::cerr << line << ": ";
serialize(::sqlpp::wrap_operand_t<L>{l}, std::cerr);
std::cerr << " != ";
serialize(::sqlpp::wrap_operand_t<R>{r}, std::cerr);
throw std::runtime_error("Unexpected result");
}
}
} // namespace
namespace sql = sqlpp::sqlite3;
int main()
{
try
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE tab_date_time (
col_day_point DATE,
col_time_point DATETIME
))");
const auto tab = TabDateTime{};
db(insert_into(tab).default_values());
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
require_equal(__LINE__, row.colDayPoint.is_null(), true);
require_equal(__LINE__, row.colDayPoint.value(), ::sqlpp::chrono::day_point{});
require_equal(__LINE__, row.colTimePoint.is_null(), true);
require_equal(__LINE__, row.colTimePoint.value(), ::sqlpp::chrono::microsecond_point{});
}
db(update(tab).set(tab.colDayPoint = today, tab.colTimePoint = now).unconditionally());
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
require_equal(__LINE__, row.colDayPoint.value(), today);
require_equal(__LINE__, row.colTimePoint.value(), now);
}
db(update(tab).set(tab.colDayPoint = yesterday, tab.colTimePoint = today).unconditionally());
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
require_equal(__LINE__, row.colDayPoint.value(), yesterday);
require_equal(__LINE__, row.colTimePoint.value(), today);
}
auto prepared_update = db.prepare(
update(tab)
.set(tab.colDayPoint = parameter(tab.colDayPoint), tab.colTimePoint = parameter(tab.colTimePoint))
.unconditionally());
prepared_update.params.colDayPoint = today;
prepared_update.params.colTimePoint = now;
std::cout << "---- running prepared update ----" << std::endl;
db(prepared_update);
std::cout << "---- finished prepared update ----" << std::endl;
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
require_equal(__LINE__, row.colDayPoint.value(), today);
require_equal(__LINE__, row.colTimePoint.value(), now);
}
}
catch (const std::exception& e)
{
std::cerr << "Exception: " << e.what() << std::endl;
return 1;
}
catch (...)
{
std::cerr << "Unknown exception: " << std::endl;
return 1;
}
return 0;
}

View File

@ -0,0 +1,88 @@
/*
* 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 <sqlpp11/alias_provider.h>
#include <sqlpp11/functions.h>
#include <sqlpp11/insert.h>
#include <sqlpp11/remove.h>
#include <sqlpp11/select.h>
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/update.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
#include <vector>
#include <sqlpp11/sqlite3/dynamic_libsqlite3.h>
SQLPP_ALIAS_PROVIDER(left)
namespace sql = sqlpp::sqlite3;
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute("CREATE TABLE tab_sample (\
alpha bigint(20) DEFAULT NULL,\
beta varchar(255) DEFAULT NULL,\
gamma bool DEFAULT NULL\
)");
const auto tab = TabSample{};
auto i = insert_into(tab).columns(tab.beta, tab.gamma);
i.values.add(tab.beta = "rhabarbertorte", tab.gamma = false);
// i.values.add(tab.beta = "cheesecake", tab.gamma = false)
// i.values.add(tab.beta = "kaesekuchen", tab.gamma = true)
auto last_insert_rowid = db(i);
std::cerr << "last insert rowid: " << last_insert_rowid << std::endl;
// Just to demonstrate that you can call basically any function
std::cerr << "last insert rowid: "
<< db(select(sqlpp::verbatim<sqlpp::integer>("last_insert_rowid()").as(tab.alpha))).front().alpha
<< std::endl;
// select a static (alpha) and a dynamic column (beta)
auto s = dynamic_select(db).dynamic_columns(tab.alpha.as(left)).from(tab).unconditionally();
s.selected_columns.add(tab.beta);
s.selected_columns.add(tab.gamma);
for (const auto& row : db(s))
{
std::cerr << "row.alpha: " << row.left << ", row.beta: " << row.at("beta") << ", row.gamma: " << row.at("gamma")
<< std::endl;
};
return 0;
}

View File

@ -0,0 +1,86 @@
/*
* 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 <sqlpp11/alias_provider.h>
#include <sqlpp11/functions.h>
#include <sqlpp11/insert.h>
#include <sqlpp11/remove.h>
#include <sqlpp11/select.h>
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/update.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
#include <vector>
SQLPP_ALIAS_PROVIDER(left)
namespace sql = sqlpp::sqlite3;
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute("CREATE TABLE tab_sample (\
alpha bigint(20) DEFAULT NULL,\
beta varchar(255) DEFAULT NULL,\
gamma bool DEFAULT NULL\
)");
const auto tab = TabSample{};
auto i = insert_into(tab).columns(tab.beta, tab.gamma);
i.values.add(tab.beta = "rhabarbertorte", tab.gamma = false);
// i.values.add(tab.beta = "cheesecake", tab.gamma = false)
// i.values.add(tab.beta = "kaesekuchen", tab.gamma = true)
auto last_insert_rowid = db(i);
std::cerr << "last insert rowid: " << last_insert_rowid << std::endl;
// Just to demonstrate that you can call basically any function
std::cerr << "last insert rowid: "
<< db(select(sqlpp::verbatim<sqlpp::integer>("last_insert_rowid()").as(tab.alpha))).front().alpha
<< std::endl;
// select a static (alpha) and a dynamic column (beta)
auto s = dynamic_select(db).dynamic_columns(tab.alpha.as(left)).from(tab).unconditionally();
s.selected_columns.add(tab.beta);
s.selected_columns.add(tab.gamma);
for (const auto& row : db(s))
{
std::cerr << "row.alpha: " << row.left << ", row.beta: " << row.at("beta") << ", row.gamma: " << row.at("gamma")
<< std::endl;
};
return 0;
}

View File

@ -0,0 +1,126 @@
/*
* 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 <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/sqlpp11.h>
#include "FpSample.h"
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
#include <limits>
namespace sql = sqlpp::sqlite3;
const auto fp = FpSample{};
template <typename L, typename R>
auto require_equal(int line, const L& l, const R& r) -> void
{
if (l != r)
{
std::cerr << line << ": ";
serialize(::sqlpp::wrap_operand_t<L>{l}, std::cerr);
std::cerr << " != ";
serialize(::sqlpp::wrap_operand_t<R>{r}, std::cerr);
throw std::runtime_error("Unexpected result");
}
}
static auto require(int line, bool condition) -> void
{
if (!condition)
{
std::cerr << line << " condition violated";
throw std::runtime_error("Unexpected result");
}
}
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE fp_sample (
id INTEGER PRIMARY KEY AUTOINCREMENT,
fp REAL
))");
db.execute("INSERT into fp_sample (id, fp) values(NULL, 1.0)");
db.execute("INSERT into fp_sample (id, fp) values(NULL, 'Inf')");
db.execute("INSERT into fp_sample (id, fp) values(NULL, 'Nan')");
db.execute("INSERT into fp_sample (id, fp) values(NULL, 'SomeString')");
db(insert_into(fp).set(fp.fp = std::numeric_limits<double>::quiet_NaN()));
db(insert_into(fp).set(fp.fp = std::numeric_limits<double>::infinity()));
db(insert_into(fp).set(fp.fp = -std::numeric_limits<double>::infinity()));
auto prepared_insert = db.prepare(insert_into(fp).set(fp.fp = parameter(fp.fp)));
prepared_insert.params.fp = std::numeric_limits<double>::quiet_NaN();
db(prepared_insert);
prepared_insert.params.fp = std::numeric_limits<double>::infinity();
db(prepared_insert);
prepared_insert.params.fp = -std::numeric_limits<double>::infinity();
db(prepared_insert);
auto q = select(fp.fp).from(fp).unconditionally();
auto rows = db(q);
// raw string inserts
require_equal(__LINE__, rows.front().fp, 1.0);
rows.pop_front();
require(__LINE__, std::isinf(rows.front().fp.value()));
rows.pop_front();
require(__LINE__, std::isnan(rows.front().fp.value()));
rows.pop_front();
require_equal(__LINE__, rows.front().fp, 0.0);
rows.pop_front();
// dsl inserts
require(__LINE__, std::isnan(rows.front().fp.value()));
rows.pop_front();
require(__LINE__, std::isinf(rows.front().fp.value()));
require(__LINE__, rows.front().fp.value() > std::numeric_limits<double>::max());
rows.pop_front();
require(__LINE__, std::isinf(rows.front().fp.value()));
require(__LINE__, rows.front().fp.value() < std::numeric_limits<double>::lowest());
// prepared dsl inserts
rows.pop_front();
require(__LINE__, std::isnan(rows.front().fp.value()));
rows.pop_front();
require(__LINE__, std::isinf(rows.front().fp.value()));
require(__LINE__, rows.front().fp.value() > std::numeric_limits<double>::max());
rows.pop_front();
require(__LINE__, std::isinf(rows.front().fp.value()));
require(__LINE__, rows.front().fp.value() < std::numeric_limits<double>::lowest());
return 0;
}

View File

@ -0,0 +1,79 @@
// generated by ../../sqlpp11/scripts/ddl2cpp -fail-on-parse FpSample.sql FpSample fp
#ifndef FP_FPSAMPLE_H
#define FP_FPSAMPLE_H
#include <sqlpp11/table.h>
#include <sqlpp11/data_types.h>
#include <sqlpp11/char_sequence.h>
namespace FpSample_
{
struct Id
{
struct _alias_t
{
static constexpr const char _literal[] = "id";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T id;
T& operator()()
{
return id;
}
const T& operator()() const
{
return id;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::integer, sqlpp::tag::can_be_null>;
};
struct Fp
{
struct _alias_t
{
static constexpr const char _literal[] = "fp";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T fp;
T& operator()()
{
return fp;
}
const T& operator()() const
{
return fp;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::floating_point, sqlpp::tag::can_be_null>;
};
}
struct FpSample : sqlpp::table_t<FpSample, FpSample_::Id, FpSample_::Fp>
{
struct _alias_t
{
static constexpr const char _literal[] = "fp_sample";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T fpSample;
T& operator()()
{
return fpSample;
}
const T& operator()() const
{
return fpSample;
}
};
};
};
#endif

View File

@ -0,0 +1,4 @@
CREATE TABLE fp_sample (
id INTEGER PRIMARY KEY,
fp DOUBLE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

View File

@ -0,0 +1,79 @@
#ifndef INTEGRAL_SAMPLE_H
#define INTEGRAL_SAMPLE_H
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/data_types.h>
#include <sqlpp11/table.h>
namespace IntegralSample_
{
struct SignedValue
{
struct _alias_t
{
static constexpr const char _literal[] = "signed_value";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T signedValue;
T& operator()()
{
return signedValue;
}
const T& operator()() const
{
return signedValue;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::integer, sqlpp::tag::can_be_null>;
};
struct UnsignedValue
{
struct _alias_t
{
static constexpr const char _literal[] = "unsigned_value";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T unsignedValue;
T& operator()()
{
return unsignedValue;
}
const T& operator()() const
{
return unsignedValue;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::integer_unsigned, sqlpp::tag::can_be_null>;
};
} // namespace IntegralSample_
struct IntegralSample : sqlpp::table_t<IntegralSample, IntegralSample_::SignedValue, IntegralSample_::UnsignedValue>
{
struct _alias_t
{
static constexpr const char _literal[] = "integral_sample";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T fpSample;
T& operator()()
{
return fpSample;
}
const T& operator()() const
{
return fpSample;
}
};
};
};
#endif

View File

@ -0,0 +1,119 @@
/*
* 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 <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/sqlpp11.h>
#include "IntegralSample.h"
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
#include <limits>
namespace sql = sqlpp::sqlite3;
const auto intSample = IntegralSample{};
template <typename L, typename R>
auto require_equal(int line, const L& l, const R& r) -> void
{
if (l != r)
{
std::cerr << line << ": ";
serialize(::sqlpp::wrap_operand_t<L>{l}, std::cerr);
std::cerr << " != ";
serialize(::sqlpp::wrap_operand_t<R>{r}, std::cerr);
throw std::runtime_error("Unexpected result");
}
}
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE integral_sample (
signed_value INTEGER,
unsigned_value INTEGER
))");
// The connector supports uint64_t values and will always retrieve the correct value from the database.
// Sqlite3 stores the values as int64_t internally though, so big uint64_t values will be converted
// and the library has to intepret the int64_t values correctly as uint64_t.
// Therefore, we test uint64_t values in an out of the range of int64_t and test if they are retrieved
// correctly from the database in both cases.
uint64_t uint64_t_value_supported = std::numeric_limits<int64_t>::max();
int64_t int64_t_value_max = std::numeric_limits<int64_t>::max();
uint64_t uint64_t_value_unsupported = std::numeric_limits<uint64_t>::max();
int64_t int64_t_value_min = std::numeric_limits<int64_t>::min();
std::size_t size_t_value_max = std::numeric_limits<std::size_t>::max();
std::size_t size_t_value_min = std::numeric_limits<std::size_t>::min();
uint32_t uint32_t_value = std::numeric_limits<uint32_t>::max();
int32_t int32_t_value = std::numeric_limits<int32_t>::max();
db(insert_into(intSample).set(intSample.signedValue = int64_t_value_max,
intSample.unsignedValue = uint64_t_value_supported));
auto prepared_insert =
db.prepare(insert_into(intSample).set(intSample.signedValue = parameter(intSample.signedValue),
intSample.unsignedValue = parameter(intSample.unsignedValue)));
prepared_insert.params.signedValue = int64_t_value_min;
prepared_insert.params.unsignedValue = uint64_t_value_unsupported;
db(prepared_insert);
db(insert_into(intSample).set(intSample.signedValue = size_t_value_min, intSample.unsignedValue = size_t_value_max));
db(insert_into(intSample).set(intSample.signedValue = int32_t_value, intSample.unsignedValue = uint32_t_value));
auto q = select(intSample.signedValue, intSample.unsignedValue).from(intSample).unconditionally();
auto rows = db(q);
require_equal(__LINE__, rows.front().signedValue.value(), int64_t_value_max);
require_equal(__LINE__, rows.front().unsignedValue.value(), uint64_t_value_supported);
rows.pop_front();
require_equal(__LINE__, rows.front().signedValue.value(), int64_t_value_min);
require_equal(__LINE__, rows.front().unsignedValue.value(), uint64_t_value_unsupported);
rows.pop_front();
require_equal(__LINE__, rows.front().signedValue.value(), size_t_value_min);
require_equal(__LINE__, rows.front().unsignedValue.value(), size_t_value_max);
rows.pop_front();
require_equal(__LINE__, rows.front().signedValue.value(), int32_t_value);
require_equal(__LINE__, rows.front().unsignedValue.value(), uint32_t_value);
rows.pop_front();
return 0;
}

View File

@ -0,0 +1,210 @@
/*
* 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 <sqlpp11/custom_query.h>
#include <sqlpp11/sqlite3/sqlite3.h>
#include <sqlpp11/sqlpp11.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <cassert>
#include <iostream>
#include <vector>
SQLPP_ALIAS_PROVIDER(left)
SQLPP_ALIAS_PROVIDER(pragma)
SQLPP_ALIAS_PROVIDER(sub)
namespace sql = sqlpp::sqlite3;
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE tab_sample (
alpha INTEGER PRIMARY KEY,
beta varchar(255) DEFAULT NULL,
gamma bool DEFAULT NULL
))");
db.execute(R"(CREATE TABLE tab_foo (
omega bigint(20) DEFAULT NULL
))");
const auto tab = TabSample{};
// clear the table
db(remove_from(tab).unconditionally());
// explicit all_of(tab)
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
std::cerr << "row.alpha: " << row.alpha << ", row.beta: " << row.beta << ", row.gamma: " << row.gamma << std::endl;
};
std::cerr << __FILE__ << ": " << __LINE__ << std::endl;
// selecting a table implicitly expands to all_of(tab)
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
std::cerr << "row.alpha: " << row.alpha << ", row.beta: " << row.beta << ", row.gamma: " << row.gamma << std::endl;
};
// insert
std::cerr << "no of required columns: " << TabSample::_required_insert_columns::size::value << std::endl;
db(insert_into(tab).default_values());
std::cout << "Last Insert ID: " << db.last_insert_id() << "\n";
db(insert_into(tab).set(tab.gamma = true));
std::cout << "Last Insert ID: " << db.last_insert_id() << "\n";
auto di = dynamic_insert_into(db, tab).dynamic_set(tab.gamma = true);
di.insert_list.add(tab.beta = "");
db(di);
// update
db(update(tab).set(tab.gamma = false).where(tab.alpha.in(1)));
db(update(tab).set(tab.gamma = false).where(tab.alpha.in(sqlpp::value_list(std::vector<int>{1, 2, 3, 4}))));
// remove
db(remove_from(tab).where(tab.alpha == tab.alpha + 3));
auto result = db(select(all_of(tab)).from(tab).unconditionally());
std::cerr << "Accessing a field directly from the result (using the current row): " << result.begin()->alpha
<< std::endl;
std::cerr << "Can do that again, no problem: " << result.begin()->alpha << std::endl;
auto tx = start_transaction(db);
TabFoo foo;
for (const auto& row : db(select(all_of(tab), select(max(foo.omega)).from(foo).where(foo.omega > tab.alpha))
.from(tab)
.unconditionally()))
{
int x = row.alpha;
int a = row.max;
std::cout << x << ", " << a << std::endl;
}
tx.commit();
for (const auto& row : db(select(tab.alpha).from(tab.join(foo).on(tab.alpha == foo.omega)).unconditionally()))
{
std::cerr << row.alpha << std::endl;
}
for (const auto& row :
db(select(tab.alpha).from(tab.left_outer_join(foo).on(tab.alpha == foo.omega)).unconditionally()))
{
std::cerr << row.alpha << std::endl;
}
auto ps = db.prepare(select(all_of(tab))
.from(tab)
.where(tab.alpha != parameter(tab.alpha) and tab.beta != parameter(tab.beta) and
tab.gamma != parameter(tab.gamma)));
ps.params.alpha = 7;
ps.params.beta = "wurzelbrunft";
ps.params.gamma = true;
for (const auto& row : db(ps))
{
std::cerr << "bound result: alpha: " << row.alpha << std::endl;
std::cerr << "bound result: beta: " << row.beta << std::endl;
std::cerr << "bound result: gamma: " << row.gamma << std::endl;
}
std::cerr << "--------" << std::endl;
ps.params.alpha = sqlpp::eval<sqlpp::integer>(db, "last_insert_rowid()");
ps.params.gamma = "false";
for (const auto& row : db(ps))
{
std::cerr << "bound result: alpha: " << row.alpha << std::endl;
std::cerr << "bound result: beta: " << row.beta << std::endl;
std::cerr << "bound result: gamma: " << row.gamma << std::endl;
}
std::cerr << "--------" << std::endl;
ps.params.beta = "kaesekuchen";
for (const auto& row : db(ps))
{
std::cerr << "bound result: alpha: " << row.alpha << std::endl;
std::cerr << "bound result: beta: " << row.beta << std::endl;
std::cerr << "bound result: gamma: " << row.gamma << std::endl;
}
auto pi = db.prepare(insert_into(tab).set(tab.beta = parameter(tab.beta), tab.gamma = true));
pi.params.beta = "prepared cake";
std::cerr << "Inserted: " << db(pi) << std::endl;
auto pu = db.prepare(update(tab).set(tab.gamma = parameter(tab.gamma)).where(tab.beta == "prepared cake"));
pu.params.gamma = false;
std::cerr << "Updated: " << db(pu) << std::endl;
auto pr = db.prepare(remove_from(tab).where(tab.beta != parameter(tab.beta)));
pr.params.beta = "prepared cake";
std::cerr << "Deleted lines: " << db(pr) << std::endl;
// Check that a prepared select is default-constructible
{
auto s = select(all_of(tab))
.from(tab)
.where((tab.beta.like(parameter(tab.beta)) and tab.alpha == parameter(tab.alpha)) or
tab.gamma != parameter(tab.gamma));
using P = decltype(db.prepare(s));
P p; // You must not use this one yet!
p = db.prepare(s);
}
auto i = db(sqlpp::sqlite3::insert_or_replace_into(tab).set(tab.beta = "test", tab.gamma = true));
std::cerr << i << std::endl;
i = db(sqlpp::sqlite3::insert_or_ignore_into(tab).set(tab.beta = "test", tab.gamma = true));
std::cerr << i << std::endl;
assert(db(select(count(tab.alpha)).from(tab).unconditionally()).begin()->count);
assert(
db(select(all_of(tab)).from(tab).where(tab.alpha.not_in(select(tab.alpha).from(tab).unconditionally()))).empty());
auto x = custom_query(sqlpp::verbatim("PRAGMA user_version = "), 1);
db(x);
int pragmaValue =
db(custom_query(sqlpp::verbatim("PRAGMA user_version")).with_result_type_of(select(sqlpp::value(1).as(pragma))))
.front()
.pragma;
std::cerr << pragmaValue << std::endl;
// Testing sub select tables and unconditional joins
const auto subQuery = select(tab.alpha).from(tab).unconditionally().as(sub);
for (const auto& row : db(select(subQuery.alpha).from(subQuery).unconditionally()))
{
std::cerr << row.alpha;
}
for (const auto& row : db(select(subQuery.alpha).from(tab.inner_join(subQuery).unconditionally()).unconditionally()))
{
std::cerr << row.alpha;
}
return 0;
}

View File

@ -0,0 +1,173 @@
/*
* Copyright (c) 2013 - 2016, Roland Bock
* Copyright (c) 2017, Juan Dent
* 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/remove.h>
#include <sqlpp11/select.h>
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/update.h>
#include <iostream>
#include <vector>
SQLPP_ALIAS_PROVIDER(left)
namespace sql = sqlpp::sqlite3;
const auto tab = TabSample{};
void testSelectAll(sql::connection& db, size_t expectedRowCount)
{
std::cerr << "--------------------------------------" << std::endl;
size_t i = 0;
for (const auto& row : db(sqlpp::select(all_of(tab)).from(tab).unconditionally()))
{
++i;
std::cerr << ">>> row.alpha: " << row.alpha << ", row.beta: " << row.beta << ", row.gamma: " << row.gamma
<< std::endl;
assert(static_cast<size_t>(row.alpha) == i);
};
assert(i == expectedRowCount);
auto preparedSelectAll = db.prepare(sqlpp::select(all_of(tab)).from(tab).unconditionally());
i = 0;
for (const auto& row : db(preparedSelectAll))
{
++i;
std::cerr << ">>> row.alpha: " << row.alpha << ", row.beta: " << row.beta << ", row.gamma: " << row.gamma
<< std::endl;
assert(static_cast<size_t>(row.alpha) == i);
};
assert(i == expectedRowCount);
std::cerr << "--------------------------------------" << std::endl;
}
namespace string_util
{
std::string ltrim(std::string str, const std::string& chars = "\t\n\v\f\r ")
{
str.erase(0, str.find_first_not_of(chars));
return str;
}
std::string rtrim(std::string str, const std::string& chars = "\t\n\v\f\r ")
{
str.erase(str.find_last_not_of(chars) + 1);
return str;
}
std::string trim(std::string str, const std::string& chars = "\t\n\v\f\r ")
{
return ltrim(rtrim(str, chars), chars);
}
}
int main()
{
sql::connection db({":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "", true});
db.execute(R"(CREATE TABLE tab_sample (
alpha INTEGER PRIMARY KEY,
beta varchar(255) DEFAULT NULL,
gamma bool DEFAULT NULL
))");
testSelectAll(db, 0);
db(insert_into(tab).default_values());
testSelectAll(db, 1);
db(insert_into(tab).set(tab.gamma = true, tab.beta = " cheesecake "));
testSelectAll(db, 2);
db(insert_into(tab).set(tab.gamma = true, tab.beta = " cheesecake "));
testSelectAll(db, 3);
// test functions and operators
db(select(all_of(tab)).from(tab).where(tab.alpha.is_null()));
db(select(all_of(tab)).from(tab).where(tab.alpha.is_not_null()));
db(select(all_of(tab)).from(tab).where(tab.alpha.in(1, 2, 3)));
db(select(all_of(tab)).from(tab).where(tab.alpha.in(sqlpp::value_list(std::vector<int>{1, 2, 3, 4}))));
db(select(all_of(tab)).from(tab).where(tab.alpha.not_in(1, 2, 3)));
db(select(all_of(tab)).from(tab).where(tab.alpha.not_in(sqlpp::value_list(std::vector<int>{1, 2, 3, 4}))));
db(select(count(tab.alpha)).from(tab).unconditionally());
db(select(avg(tab.alpha)).from(tab).unconditionally());
db(select(max(tab.alpha)).from(tab).unconditionally());
db(select(min(tab.alpha)).from(tab).unconditionally());
db(select(exists(select(tab.alpha).from(tab).where(tab.alpha > 7))).from(tab).unconditionally());
db(select(trim(tab.beta)).from(tab).unconditionally());
// db(select(not_exists(select(tab.alpha).from(tab).where(tab.alpha > 7))).from(tab));
// db(select(all_of(tab)).from(tab).where(tab.alpha == any(select(tab.alpha).from(tab).where(tab.alpha < 3))));
db(select(all_of(tab)).from(tab).where((tab.alpha + tab.alpha) > 3));
db(select(all_of(tab)).from(tab).where((tab.beta + tab.beta) == ""));
db(select(all_of(tab)).from(tab).where((tab.beta + tab.beta).like(R"(%'\"%)")));
// update
db(update(tab).set(tab.gamma = false).where(tab.alpha.in(1)));
db(update(tab).set(tab.gamma = false).where(tab.alpha.in(sqlpp::value_list(std::vector<int>{1, 2, 3, 4}))));
// remove
db(remove_from(tab).where(tab.alpha == tab.alpha + 3));
auto result = db(select(all_of(tab)).from(tab).unconditionally());
std::cerr << "Accessing a field directly from the result (using the current row): " << result.begin()->alpha
<< std::endl;
std::cerr << "Can do that again, no problem: " << result.begin()->alpha << std::endl;
std::cerr << "--------------------------------------" << std::endl;
auto tx = start_transaction(db);
for (const auto& row : db(select(all_of(tab), select(max(tab.alpha)).from(tab)).from(tab).unconditionally()))
{
int x = row.alpha;
int a = row.max;
std::cout << ">>>" << x << ", " << a << std::endl;
}
for (const auto& row :
db(select(tab.alpha, tab.beta, tab.gamma, trim(tab.beta))
.from(tab)
.unconditionally()))
{
std::cerr << ">>> row.alpha: " << row.alpha << ", row.beta: " << row.beta << ", row.gamma: " << row.gamma
<< ", row.trim: '" << row.trim << "'" << std::endl;
// check trim
assert(string_util::trim(row.beta.value()) == row.trim.value());
// end
};
for (const auto& row : db(select(all_of(tab), select(trim(tab.beta)).from(tab)).from(tab).unconditionally()))
{
int x = row.alpha;
std::string a = row.trim;
std::cout << ">>>" << x << ", " << a << std::endl;
}
tx.commit();
std::cerr << "--------------------------------------" << std::endl;
return 0;
}

View File

@ -0,0 +1,250 @@
/*
* Copyright (c) 2013 - 2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SQLPP_TAB_SAMPLE_H
#define SQLPP_TAB_SAMPLE_H
#include <sqlpp11/table.h>
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/column_types.h>
namespace TabFoo_
{
struct Omega
{
struct _alias_t
{
static constexpr const char _literal[] = "omega";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T omega;
T& operator()()
{
return omega;
}
const T& operator()() const
{
return omega;
}
};
};
using _traits = ::sqlpp::make_traits<::sqlpp::bigint>;
};
}
struct TabFoo : sqlpp::table_t<TabFoo, TabFoo_::Omega>
{
using _value_type = sqlpp::no_value_t;
struct _alias_t
{
static constexpr const char _literal[] = "tab_foo";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T tabFoo;
T& operator()()
{
return tabFoo;
}
const T& operator()() const
{
return tabFoo;
}
};
};
};
namespace TabSample_
{
struct Alpha
{
struct _alias_t
{
static constexpr const char _literal[] = "alpha";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T alpha;
T& operator()()
{
return alpha;
}
const T& operator()() const
{
return alpha;
}
};
};
using _traits = ::sqlpp::make_traits<::sqlpp::bigint,
::sqlpp::tag::must_not_insert,
::sqlpp::tag::must_not_update,
::sqlpp::tag::can_be_null>;
};
struct Beta
{
struct _alias_t
{
static constexpr const char _literal[] = "beta";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T beta;
T& operator()()
{
return beta;
}
const T& operator()() const
{
return beta;
}
};
};
using _traits = ::sqlpp::make_traits<::sqlpp::varchar, ::sqlpp::tag::must_not_update, ::sqlpp::tag::can_be_null>;
};
struct Gamma
{
struct _alias_t
{
static constexpr const char _literal[] = "gamma";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T gamma;
T& operator()()
{
return gamma;
}
const T& operator()() const
{
return gamma;
}
};
};
using _traits = ::sqlpp::make_traits<::sqlpp::boolean>;
};
}
struct TabSample : sqlpp::table_t<TabSample, TabSample_::Alpha, TabSample_::Beta, TabSample_::Gamma>
{
using _value_type = sqlpp::no_value_t;
struct _alias_t
{
static constexpr const char _literal[] = "tab_sample";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T tabSample;
T& operator()()
{
return tabSample;
}
const T& operator()() const
{
return tabSample;
}
};
};
};
namespace TabDateTime_
{
struct ColDayPoint
{
struct _alias_t
{
static constexpr const char _literal[] = "col_day_point";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T colDayPoint;
T& operator()()
{
return colDayPoint;
}
const T& operator()() const
{
return colDayPoint;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::day_point, sqlpp::tag::can_be_null>;
};
struct ColTimePoint
{
struct _alias_t
{
static constexpr const char _literal[] = "col_time_point";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T colTimePoint;
T& operator()()
{
return colTimePoint;
}
const T& operator()() const
{
return colTimePoint;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::time_point, sqlpp::tag::can_be_null>;
};
}
struct TabDateTime : sqlpp::table_t<TabDateTime, TabDateTime_::ColDayPoint, TabDateTime_::ColTimePoint>
{
struct _alias_t
{
static constexpr const char _literal[] = "tab_date_time";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T tabDateTime;
T& operator()()
{
return tabDateTime;
}
const T& operator()() const
{
return tabDateTime;
}
};
};
};
#endif

View File

@ -0,0 +1,5 @@
CREATE TABLE tab_sample (
alpha bigint(20) DEFAULT NULL,
beta tinyint(1) DEFAULT NULL,
gamma varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

View File

@ -0,0 +1,84 @@
/*
* 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/custom_query.h>
#include <sqlpp11/functions.h>
#include <sqlpp11/insert.h>
#include <sqlpp11/remove.h>
#include <sqlpp11/select.h>
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/update.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
#include <vector>
namespace sql = sqlpp::sqlite3;
SQLPP_ALIAS_PROVIDER(pragma)
int main()
{
sql::connection db({":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "", true});
std::cerr << "--------------------------------------" << std::endl;
auto current_level = db.get_default_isolation_level();
std::cout << "Expecting default isolation level = 1, is " << static_cast<int>(current_level) << std::endl;
assert(current_level == sqlpp::isolation_level::serializable);
int pragmaValue = db(custom_query(sqlpp::verbatim("PRAGMA read_uncommitted"))
.with_result_type_of(select(sqlpp::value(1).as(pragma))))
.front()
.pragma;
assert(pragmaValue == 0);
std::cerr << "Expecting read_uncommitted = 0, is: " << pragmaValue << std::endl;
db.set_default_isolation_level(sqlpp::isolation_level::read_uncommitted);
auto tx = start_transaction(db);
pragmaValue = db(custom_query(sqlpp::verbatim("PRAGMA read_uncommitted"))
.with_result_type_of(select(sqlpp::value(1).as(pragma))))
.front()
.pragma;
std::cerr << "Now expecting read_uncommitted = 1, is: " << pragmaValue << std::endl;
assert(pragmaValue == 1);
current_level = db.get_default_isolation_level();
std::cout << "Now expecting default isolation level = 4, is " << static_cast<int>(current_level) << std::endl;
assert(current_level == sqlpp::isolation_level::read_uncommitted);
tx.commit();
std::cerr << "--------------------------------------" << std::endl;
return 0;
}

View File

@ -0,0 +1,67 @@
/*
* 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 <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/sqlpp11.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
namespace sql = sqlpp::sqlite3;
const auto tab = TabSample{};
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE tab_sample (
alpha INTEGER PRIMARY KEY,
beta varchar(255) DEFAULT NULL,
gamma bool DEFAULT NULL
))");
auto u = select(all_of(tab)).from(tab).unconditionally().union_all(select(all_of(tab)).from(tab).unconditionally());
for (const auto& row : db(u))
{
std::cout << row.alpha << row.beta << row.gamma << std::endl;
}
for (const auto& row : db(u.union_distinct(select(all_of(tab)).from(tab).unconditionally())))
{
std::cout << row.alpha << row.beta << row.gamma << std::endl;
}
return 0;
}

Some files were not shown because too many files have changed in this diff Show More