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:
parent
d0a8ea21af
commit
2e683a4b69
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2013-2016, Roland Bock
|
||||
# Copyright (c) 2013-2021, Roland Bock
|
||||
# Copyright (c) 2016 Christian Dávid
|
||||
# All rights reserved.
|
||||
#
|
||||
@ -27,6 +27,35 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
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
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||
|
||||
@ -44,10 +73,13 @@ endif()
|
||||
### Dependencies
|
||||
add_subdirectory(dependencies)
|
||||
|
||||
### Main targets
|
||||
### Core targets
|
||||
add_library(sqlpp11 INTERFACE)
|
||||
add_library(sqlpp11::sqlpp11 ALIAS sqlpp11)
|
||||
|
||||
# Connector targets
|
||||
add_subdirectory(src)
|
||||
|
||||
target_link_libraries(sqlpp11 INTERFACE date::date)
|
||||
|
||||
target_include_directories(sqlpp11 INTERFACE
|
||||
@ -127,8 +159,5 @@ install(
|
||||
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
|
||||
add_subdirectory(tests)
|
||||
add_subdirectory(test_types)
|
||||
add_subdirectory(test_serializer)
|
||||
add_subdirectory(test_static_asserts)
|
||||
add_subdirectory(test_constraints)
|
||||
add_subdirectory(test_scripts)
|
||||
endif()
|
||||
|
109
include/sqlpp11/sqlite3/bind_result.h
Normal file
109
include/sqlpp11/sqlite3/bind_result.h
Normal 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
|
359
include/sqlpp11/sqlite3/connection.h
Normal file
359
include/sqlpp11/sqlite3/connection.h
Normal 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
|
71
include/sqlpp11/sqlite3/connection_config.h
Normal file
71
include/sqlpp11/sqlite3/connection_config.h
Normal 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
|
237
include/sqlpp11/sqlite3/dynamic_libsqlite3.h
Normal file
237
include/sqlpp11/sqlite3/dynamic_libsqlite3.h
Normal 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
|
18
include/sqlpp11/sqlite3/export.h
Normal file
18
include/sqlpp11/sqlite3/export.h
Normal 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
|
154
include/sqlpp11/sqlite3/insert_or.h
Normal file
154
include/sqlpp11/sqlite3/insert_or.h
Normal 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
|
88
include/sqlpp11/sqlite3/prepared_statement.h
Normal file
88
include/sqlpp11/sqlite3/prepared_statement.h
Normal 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
|
140
include/sqlpp11/sqlite3/serializer.h
Normal file
140
include/sqlpp11/sqlite3/serializer.h
Normal 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
|
33
include/sqlpp11/sqlite3/sqlite3.h
Normal file
33
include/sqlpp11/sqlite3/sqlite3.h
Normal 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
35
src/CMakeLists.txt
Normal 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()
|
||||
|
96
src/sqlite3/CMakeLists.txt
Normal file
96
src/sqlite3/CMakeLists.txt
Normal 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
249
src/sqlite3/bind_result.cpp
Normal 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
280
src/sqlite3/connection.cpp
Normal 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};
|
||||
}
|
||||
}
|
||||
}
|
85
src/sqlite3/detail/connection_handle.cpp
Normal file
85
src/sqlite3/detail/connection_handle.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
61
src/sqlite3/detail/connection_handle.h
Normal file
61
src/sqlite3/detail/connection_handle.h
Normal 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
|
466
src/sqlite3/detail/dynamic_libsqlite3.cpp
Normal file
466
src/sqlite3/detail/dynamic_libsqlite3.cpp
Normal 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
|
96
src/sqlite3/detail/prepared_statement_handle.h
Normal file
96
src/sqlite3/detail/prepared_statement_handle.h
Normal 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
|
245
src/sqlite3/prepared_statement.cpp
Normal file
245
src/sqlite3/prepared_statement.cpp
Normal 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
|
@ -1,15 +1,15 @@
|
||||
# Copyright (c) 2013-2016, Roland Bock
|
||||
# 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:
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
# 1. 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.
|
||||
# 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
|
||||
@ -21,59 +21,17 @@
|
||||
# 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(core/)
|
||||
|
||||
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)
|
||||
if(MYSQL_CONNECTOR)
|
||||
add_subdirectory(mysql)
|
||||
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)
|
||||
if(POSTGRESQL_CONNECTOR)
|
||||
add_subdirectory(postgresql)
|
||||
endif()
|
||||
|
||||
foreach(test IN LISTS test_names)
|
||||
add_test(NAME sqlpp11.tests.${test}
|
||||
COMMAND sqlpp11_tests ${test}
|
||||
)
|
||||
endforeach()
|
||||
if(SQLITE3_CONNECTOR OR SQLCIPHER_CONNECTOR)
|
||||
add_subdirectory(sqlite3)
|
||||
endif()
|
||||
|
||||
# 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
29
tests/core/CMakeLists.txt
Normal 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)
|
||||
|
||||
|
79
tests/core/usage/CMakeLists.txt
Normal file
79
tests/core/usage/CMakeLists.txt
Normal 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)
|
26
tests/sqlite3/CMakeLists.txt
Normal file
26
tests/sqlite3/CMakeLists.txt
Normal 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)
|
||||
|
||||
|
75
tests/sqlite3/usage/AttachTest.cpp
Normal file
75
tests/sqlite3/usage/AttachTest.cpp
Normal 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;
|
||||
}
|
69
tests/sqlite3/usage/AutoIncrementTest.cpp
Normal file
69
tests/sqlite3/usage/AutoIncrementTest.cpp
Normal 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;
|
||||
}
|
78
tests/sqlite3/usage/BlobSample.h
Normal file
78
tests/sqlite3/usage/BlobSample.h
Normal 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
|
4
tests/sqlite3/usage/BlobSample.sql
Normal file
4
tests/sqlite3/usage/BlobSample.sql
Normal file
@ -0,0 +1,4 @@
|
||||
CREATE TABLE blob_sample (
|
||||
id INTEGER PRIMARY KEY,
|
||||
data blob
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
102
tests/sqlite3/usage/BlobTest.cpp
Normal file
102
tests/sqlite3/usage/BlobTest.cpp
Normal 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;
|
||||
}
|
60
tests/sqlite3/usage/CMakeLists.txt
Normal file
60
tests/sqlite3/usage/CMakeLists.txt
Normal 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()
|
130
tests/sqlite3/usage/DateTimeTest.cpp
Normal file
130
tests/sqlite3/usage/DateTimeTest.cpp
Normal 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;
|
||||
}
|
88
tests/sqlite3/usage/DynamicLoadingTest.cpp
Normal file
88
tests/sqlite3/usage/DynamicLoadingTest.cpp
Normal 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;
|
||||
}
|
86
tests/sqlite3/usage/DynamicSelectTest.cpp
Normal file
86
tests/sqlite3/usage/DynamicSelectTest.cpp
Normal 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;
|
||||
}
|
126
tests/sqlite3/usage/FloatingPointTest.cpp
Normal file
126
tests/sqlite3/usage/FloatingPointTest.cpp
Normal 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;
|
||||
}
|
79
tests/sqlite3/usage/FpSample.h
Normal file
79
tests/sqlite3/usage/FpSample.h
Normal 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
|
4
tests/sqlite3/usage/FpSample.sql
Normal file
4
tests/sqlite3/usage/FpSample.sql
Normal file
@ -0,0 +1,4 @@
|
||||
CREATE TABLE fp_sample (
|
||||
id INTEGER PRIMARY KEY,
|
||||
fp DOUBLE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
79
tests/sqlite3/usage/IntegralSample.h
Normal file
79
tests/sqlite3/usage/IntegralSample.h
Normal 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
|
119
tests/sqlite3/usage/IntegralTest.cpp
Normal file
119
tests/sqlite3/usage/IntegralTest.cpp
Normal 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;
|
||||
}
|
210
tests/sqlite3/usage/SampleTest.cpp
Normal file
210
tests/sqlite3/usage/SampleTest.cpp
Normal 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;
|
||||
}
|
173
tests/sqlite3/usage/SelectTest.cpp
Normal file
173
tests/sqlite3/usage/SelectTest.cpp
Normal 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;
|
||||
}
|
250
tests/sqlite3/usage/TabSample.h
Normal file
250
tests/sqlite3/usage/TabSample.h
Normal 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
|
5
tests/sqlite3/usage/TabSample.sql
Normal file
5
tests/sqlite3/usage/TabSample.sql
Normal 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;
|
84
tests/sqlite3/usage/TransactionTest.cpp
Normal file
84
tests/sqlite3/usage/TransactionTest.cpp
Normal 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;
|
||||
}
|
67
tests/sqlite3/usage/UnionTest.cpp
Normal file
67
tests/sqlite3/usage/UnionTest.cpp
Normal 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
Loading…
Reference in New Issue
Block a user