summaryrefslogtreecommitdiff
path: root/include/boost
diff options
context:
space:
mode:
Diffstat (limited to 'include/boost')
-rw-r--r--include/boost/sqlite.hpp38
-rw-r--r--include/boost/sqlite/allocator.hpp48
-rw-r--r--include/boost/sqlite/backup.hpp74
-rw-r--r--include/boost/sqlite/blob.hpp156
-rw-r--r--include/boost/sqlite/collation.hpp140
-rw-r--r--include/boost/sqlite/connection.hpp210
-rw-r--r--include/boost/sqlite/cstring_ref.hpp223
-rw-r--r--include/boost/sqlite/detail/aggregate_function.hpp166
-rw-r--r--include/boost/sqlite/detail/catch.hpp169
-rw-r--r--include/boost/sqlite/detail/config.hpp83
-rw-r--r--include/boost/sqlite/detail/exception.hpp48
-rw-r--r--include/boost/sqlite/detail/scalar_function.hpp172
-rw-r--r--include/boost/sqlite/detail/vtable.hpp611
-rw-r--r--include/boost/sqlite/detail/window_function.hpp238
-rw-r--r--include/boost/sqlite/error.hpp178
-rw-r--r--include/boost/sqlite/extension.hpp67
-rw-r--r--include/boost/sqlite/field.hpp85
-rw-r--r--include/boost/sqlite/function.hpp452
-rw-r--r--include/boost/sqlite/hooks.hpp370
-rw-r--r--include/boost/sqlite/json.hpp140
-rw-r--r--include/boost/sqlite/memory.hpp105
-rw-r--r--include/boost/sqlite/meta_data.hpp58
-rw-r--r--include/boost/sqlite/mutex.hpp55
-rw-r--r--include/boost/sqlite/result.hpp147
-rw-r--r--include/boost/sqlite/resultset.hpp150
-rw-r--r--include/boost/sqlite/row.hpp167
-rw-r--r--include/boost/sqlite/statement.hpp651
-rw-r--r--include/boost/sqlite/static_resultset.hpp497
-rw-r--r--include/boost/sqlite/string.hpp49
-rw-r--r--include/boost/sqlite/transaction.hpp198
-rw-r--r--include/boost/sqlite/value.hpp130
-rw-r--r--include/boost/sqlite/vtable.hpp615
32 files changed, 0 insertions, 6490 deletions
diff --git a/include/boost/sqlite.hpp b/include/boost/sqlite.hpp
deleted file mode 100644
index 474102a..0000000
--- a/include/boost/sqlite.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2022 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_HPP
-#define BOOST_SQLITE_HPP
-
-/** @defgroup reference Reference
- *
- * This page contains the documentation of the sqlite high-level API.
- */
-
-#include <boost/sqlite/backup.hpp>
-#include <boost/sqlite/blob.hpp>
-#include <boost/sqlite/collation.hpp>
-#include <boost/sqlite/connection.hpp>
-#include <boost/sqlite/cstring_ref.hpp>
-#include <boost/sqlite/error.hpp>
-#include <boost/sqlite/field.hpp>
-#include <boost/sqlite/function.hpp>
-#include <boost/sqlite/meta_data.hpp>
-#include <boost/sqlite/memory.hpp>
-#include <boost/sqlite/hooks.hpp>
-#include <boost/sqlite/json.hpp>
-#include <boost/sqlite/resultset.hpp>
-#include <boost/sqlite/row.hpp>
-#include <boost/sqlite/statement.hpp>
-#include <boost/sqlite/static_resultset.hpp>
-#include <boost/sqlite/string.hpp>
-#include <boost/sqlite/transaction.hpp>
-#include <boost/sqlite/value.hpp>
-#include <boost/sqlite/vtable.hpp>
-
-#if defined(BOOST_SQLITE_COMPILE_EXTENSION)
-#include <boost/sqlite/extension.hpp>
-#endif
-
-#endif //BOOST_SQLITE_HPP
diff --git a/include/boost/sqlite/allocator.hpp b/include/boost/sqlite/allocator.hpp
deleted file mode 100644
index f449475..0000000
--- a/include/boost/sqlite/allocator.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_ALLOCATOR_HPP
-#define BOOST_SQLITE_ALLOCATOR_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-
-#include <cstddef>
-#include <cstdint>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-template<typename T>
-struct allocator
-{
- constexpr allocator() noexcept {}
- constexpr allocator( const allocator& other ) noexcept {}
- template< class U >
- constexpr allocator( const allocator<U>& other ) noexcept {}
-
-#if defined(SQLITE_4_BYTE_ALIGNED_MALLOC)
- constexpr static std::size_t alignment = 4u;
-#else
- constexpr static std::size_t alignment = 8u;
-#endif
-
- static_assert(alignof(T) <= alignment, "T alignment can't be fulfilled by sqlite");
- [[nodiscard]] T* allocate( std::size_t n )
- {
- auto p = static_cast<T*>(sqlite3_malloc64(n * sizeof(T)));
- if (p == nullptr)
- boost::throw_exception(std::bad_alloc());
- return p;
- }
- void deallocate( T* p, std::size_t)
- {
- return sqlite3_free(p);
- }
-};
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_ALLOCATOR_HPP
diff --git a/include/boost/sqlite/backup.hpp b/include/boost/sqlite/backup.hpp
deleted file mode 100644
index 737a28e..0000000
--- a/include/boost/sqlite/backup.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_BACKUP_HPP
-#define BOOST_SQLITE_BACKUP_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/cstring_ref.hpp>
-#include <boost/sqlite/error.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-struct connection ;
-
-///@{
-/**
- @brief Backup a database
- @ingroup reference
-
- This function will create a backup of an existing database.
- This can be useful to write an in memory database to disk et vice versa.
-
- @param source The source database to backup
- @param target The target of the backup
- @param source_name The source database to read the backup from. Default is 'main'.
- @param target_name The target database to write the backup to. Default is 'main'.
-
- @par Error Handling
-
- @throws system_error from overload without `ec` & `ei`
-
- or you need to pass
-
- @param ec The system::error_code to capture any possibly errors
- @param ei Additional error_info when error occurs.
-
- @par Example
-
- @code{.cpp}
-
- sqlite::connection conn{":memory:"};
- {
- sqlite::connection read{"./read_only_db.db", SQLITE_READONLY};
- backup(read, target);
- }
-
- @endcode
- */
-BOOST_SQLITE_DECL
-void
-backup(connection & source,
- connection & target,
- cstring_ref source_name,
- cstring_ref target_name,
- system::error_code & ec,
- error_info & ei);
-
-BOOST_SQLITE_DECL
-void
-backup(connection & source,
- connection & target,
- cstring_ref source_name = "main",
- cstring_ref target_name = "main");
-
-///@}
-
-BOOST_SQLITE_END_NAMESPACE
-
-
-#endif //BOOST_SQLITE_BACKUP_HPP
diff --git a/include/boost/sqlite/blob.hpp b/include/boost/sqlite/blob.hpp
deleted file mode 100644
index cd82363..0000000
--- a/include/boost/sqlite/blob.hpp
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright (c) 2022 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_BLOB_HPP
-#define BOOST_SQLITE_BLOB_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/memory.hpp>
-#include <boost/sqlite/error.hpp>
-#include <type_traits>
-#include <memory>
-#include <cstring>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-struct connection ;
-
-/// @brief a view to a binary large object @ingroup reference
-struct blob_view
-{
- /// The data in the blob
- const void * data() const {return data_;}
- /// The size of the data int he blob, in bytes
- std::size_t size() const {return size_;}
- /// Construct a blob
- blob_view(const void * data, std::size_t size) : data_(data), size_(size) {}
-
- /// Construct an empty blob
- blob_view() = default;
- /// Construct a blob from some other blob-like structure.
- template<typename T>
- explicit blob_view(const T & value,
- typename std::enable_if<
- std::is_pointer<decltype(std::declval<T>().data())>::value
- && std::is_convertible<decltype(std::declval<T>().size()), std::size_t>::value
- >::type * = nullptr) : data_(value.data()), size_(value.size()) {}
-
- inline blob_view(const struct blob & b);
- private:
- const void * data_{nullptr};
- std::size_t size_{0u};
-};
-
-/// @brief Helper type to pass a blob full of zeroes without allocating extra memory. @ingroup reference
-enum class zero_blob : sqlite3_uint64 {};
-
-/// @brief An object that owns a binary large object. @ingroup reference
-struct blob
-{
- /// The data in the blob
- void * data() const {return impl_.get();}
- /// The size of the data int he blob, in bytes
- std::size_t size() const {return size_;}
-
- /// Create a blob from a blob_view
- explicit blob(blob_view bv)
- {
- impl_.reset(sqlite3_malloc(static_cast<int>(bv.size())));
- size_ = bv.size();
- std::memcpy(impl_.get(), bv.data(), size_);
- }
- /// Create an empty blob with size `n`.
- explicit blob(std::size_t n) : impl_(sqlite3_malloc(static_cast<int>(n))), size_(n) {}
-
- /// Construct an empty blob
- constexpr blob() = default;
- /// Release & take ownership of the blob.
- void * release() && {return std::move(impl_).release(); }
- private:
- unique_ptr<void> impl_;
- std::size_t size_{0u};
-};
-
-blob_view::blob_view(const blob & b) : data_(b.data()), size_(b.size()) {}
-
-/// @brief an object that holds a binary large object. Can be obtained by using @ref blob_handle. @ingroup reference
-struct blob_handle
-{
- /// Default constructor
- blob_handle() = default;
-
- /// Construct from a handle. Takes owner ship
- explicit blob_handle(sqlite3_blob * blob) : blob_(blob) {}
-
- ///@{
- /// @brief Reopen on another row
- BOOST_SQLITE_DECL
- void reopen(sqlite3_int64 row_id, system::error_code & ec);
- BOOST_SQLITE_DECL
- void reopen(sqlite3_int64 row_id);
- ///@}
-
- ///@{
- /// @brief Read data from the blob
- BOOST_SQLITE_DECL
- void read_at(void *data, int len, int offset, system::error_code &ec);
- BOOST_SQLITE_DECL
- void read_at(void *data, int len, int offset);
- ///@}
-
- ///@{
- /// @brief Write data to the blob
- BOOST_SQLITE_DECL
- void write_at(const void *data, int len, int offset, system::error_code &ec);
- BOOST_SQLITE_DECL
- void write_at(const void *data, int len, int offset);
- ///@}
-
- /// The size of the blob
- std::size_t size() const {return static_cast<std::size_t>(sqlite3_blob_bytes(blob_.get()));}
-
- /// The handle of the blob
- using handle_type = sqlite3_blob*;
- /// Returns the handle of the blob
- handle_type handle() { return blob_.get(); }
- /// Release the owned handle.
- handle_type release() && { return blob_.release(); }
- private:
- struct deleter_
- {
- void operator()(sqlite3_blob *impl)
- {
- sqlite3_blob_close(impl);
- }
- };
- std::unique_ptr<sqlite3_blob, deleter_> blob_;
-};
-
-///@{
-/// Open a blob for incremental access
-BOOST_SQLITE_DECL
-blob_handle open_blob(connection & conn,
- cstring_ref db,
- cstring_ref table,
- cstring_ref column,
- sqlite3_int64 row,
- bool read_only,
- system::error_code &ec,
- error_info &ei);
-
-BOOST_SQLITE_DECL
-blob_handle open_blob(connection & conn,
- cstring_ref db,
- cstring_ref table,
- cstring_ref column,
- sqlite3_int64 row,
- bool read_only = false);
-///}@
-
-
-
-BOOST_SQLITE_END_NAMESPACE
-
-
-#endif //BOOST_SQLITE_BLOB_HPP
diff --git a/include/boost/sqlite/collation.hpp b/include/boost/sqlite/collation.hpp
deleted file mode 100644
index a4624c4..0000000
--- a/include/boost/sqlite/collation.hpp
+++ /dev/null
@@ -1,140 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_COLLATION_HPP
-#define BOOST_SQLITE_COLLATION_HPP
-
-#include <boost/sqlite/connection.hpp>
-#include <boost/sqlite/detail/exception.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-///@{
-/** Define a custom collation function
- @ingroup reference
-
- @param conn A connection to the database in which to install the collation.
- @param name The name of the collation.
- @param func The function
-
- The function must be callable with two `string_view` and return an int, indicating the comparison results.
-
- @par Example
-
- @code{.cpp}
-
- // a case insensitive string omparison, e.g. from boost.urls
- int ci_compare(string_view s0, string_view s1) noexcept;
-
- extern sqlite::connection conn;
-
- // Register the collation
- sqlite::create_collation(conn, "iequal", &ci_compare);
-
- // use the collation to get by name, case insensitively
- conn.query("select first_name, last_name from people where first_name = 'Klemens' collate iequal;");
-
- // order by names case insensitively
- conn.query("select * from people order by last_name collate iequal asc;");
-
- @endcode
-
- */
-
-template<typename Func>
-void create_collation(
- connection & conn,
- cstring_ref name,
- Func && func,
- typename std::enable_if<
- std::is_convertible<
- decltype(func(string_view(), string_view())),
- int>::value,
- system::error_code>::type & ec)
-{
- using func_type = typename std::decay<Func>::type;
- unique_ptr<func_type> f{new (memory_tag{}) func_type(std::forward<Func>(func))};
- if (f == nullptr)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_NOMEM);
- return;
- }
- auto res = sqlite3_create_collation_v2(
- conn.handle(),
- name.c_str(),
- SQLITE_UTF8,
- f.get(),
- +[](void * data, int len_l, const void * str_l, int len_r, const void * str_r) -> int
- {
- string_view l(static_cast<const char*>(str_l), len_l);
- string_view r(static_cast<const char*>(str_r), len_r);
- auto & impl = (*static_cast<func_type*>(data));
- static_assert(noexcept(impl(l, r)),
- "Collation function must be noexcept");
- return impl(l, r);
- },
- +[](void * p) { delete_(static_cast<func_type*>(p)); }
- );
-
- if (res != SQLITE_OK)
- BOOST_SQLITE_ASSIGN_EC(ec, res);
- else
- f.release();
-}
-
-
-template<typename Func>
-auto create_collation(
- connection & conn,
- cstring_ref name,
- Func && func)
-#if !defined(BOOST_SQLITE_GENERATING_DOCS)
- -> typename std::enable_if<
- std::is_convertible<
- decltype(func(string_view(), string_view())),
- int>::value>::type
-#endif
-{
- system::error_code ec;
- create_collation(conn, name, std::forward<Func>(func), ec);
- if (ec)
- detail::throw_error_code(ec, BOOST_CURRENT_LOCATION);
-}
-
-
-inline void delete_collation(
- connection & conn,
- cstring_ref name,
- system::error_code & ec)
-{
- auto res = sqlite3_create_collation_v2(
- conn.handle(),
- name.c_str(),
- SQLITE_UTF8,
- nullptr, nullptr, nullptr);
- if (res != SQLITE_OK)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, res);
- }
-}
-
-
-inline auto delete_collation(
- connection & conn,
- cstring_ref name)
-{
- system::error_code ec;
- delete_collation(conn, name, ec);
- if (ec)
- detail::throw_error_code(ec, BOOST_CURRENT_LOCATION);
-}
-
-/// @}
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_COLLATION_HPP
diff --git a/include/boost/sqlite/connection.hpp b/include/boost/sqlite/connection.hpp
deleted file mode 100644
index 0f6ccf8..0000000
--- a/include/boost/sqlite/connection.hpp
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright (c) 2022 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_CONNECTION_HPP
-#define BOOST_SQLITE_CONNECTION_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/error.hpp>
-#include <boost/sqlite/resultset.hpp>
-#include <boost/sqlite/statement.hpp>
-#include <memory>
-#include <boost/system/system_error.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-template<typename T, bool Strict>
-struct static_resultset;
-
-constexpr static cstring_ref in_memory = ":memory:";
-
-/** @brief main object for a connection to a database.
- @ingroup reference
-
- @par Example
- @code{.cpp}
- sqlite::connection conn;
- conn.connect("./my-database.db");
- conn.prepare("insert into log (text) values ($1)").execute(std::make_tuple("booting up"));
- @endcode
-
- */
-struct connection
-{
- /// The handle of the connection
- using handle_type = sqlite3*;
- /// Returns the handle
- handle_type handle() const { return impl_.get(); }
- /// Release the owned handle.
- handle_type release() && { return impl_.release(); }
-
- ///Default constructor
- connection() = default;
- /// Construct the connection from a handle.
- explicit connection(handle_type handle, bool take_ownership = true) : impl_(handle, take_ownership) {}
- /// Move constructor.
- connection(connection && ) = default;
- /// Move assign operator.
- connection& operator=(connection && ) = default;
-
- /// Construct a connection and connect it to `filename`. `flags` is set by `SQLITE_OPEN_*` flags. @see https://www.sqlite.org/c3ref/c_open_autoproxy.html
- connection(cstring_ref filename,
- int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) { connect(filename, flags); }
-
-#if defined(BOOST_WINDOWS_API)
- template<typename Path,
- typename = std::enable_if_t<
- std::is_same<typename Path::string_type, std::wstring>::value &&
- std::is_constructible<cstring_ref, decltype(std::declval<Path>().string())>::value
- >>
- explicit connection(const Path & pth) : connection(pth.string()) {}
-#endif
- ///@{
- /// Connect the database to `filename`. `flags` is set by `SQLITE_OPEN_*` flags.
- BOOST_SQLITE_DECL void connect(cstring_ref filename, int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
- BOOST_SQLITE_DECL void connect(cstring_ref filename, int flags, system::error_code & ec);
- ///@}
-
-#if defined(BOOST_WINDOWS_API)
- template<typename Path,
- typename = std::enable_if_t<
- std::is_same<typename Path::string_type, std::wstring>::value &&
- std::is_constructible<cstring_ref, decltype(std::declval<Path>().string())>::value
- >>
- void connect(const Path & pth, int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)
- {
- connect(pth.string(), flags);
- }
-
-
- template<typename Path,
- typename = std::enable_if_t<
- std::is_same<typename Path::string_type, std::wstring>::value &&
- std::is_constructible<cstring_ref, decltype(std::declval<Path>().string())>::value
- >>
- void connect(const Path & pth, int flags, system::error_code & ec)
- {
- connect(pth.string(), flags, ec);
- }
-#endif
-
- ///@{
- /// Close the database connection.
- BOOST_SQLITE_DECL void close();
- BOOST_SQLITE_DECL void close(system::error_code & ec, error_info & ei);
- ///@}
-
- /// Check if the database holds a valid handle.
- bool valid() const {return impl_ != nullptr;}
-
-
- ///@{
- /// Perform a query without parameters. Can only execute a single statement.
- BOOST_SQLITE_DECL resultset query(
- core::string_view q,
- system::error_code & ec,
- error_info & ei);
-
- BOOST_SQLITE_DECL resultset query(core::string_view q);
-
- template<typename T, bool Strict = false>
- static_resultset<T, Strict> query(
- core::string_view q,
- system::error_code & ec,
- error_info & ei)
- {
- static_resultset<T, Strict> tmp = query(q, ec, ei);
- if (ec)
- return {};
- tmp.check_columns_(ec, ei);
- if (ec)
- return {};
-
- return tmp;
- }
-
- template<typename T, bool Strict = false>
- static_resultset<T, Strict> query(core::string_view q)
- {
- system::error_code ec;
- error_info ei;
- auto tmp = query<T, Strict>(q, ec, ei);
- if (ec)
- throw_exception(system::system_error(ec, ei.message()));
- return tmp;
- }
- ///@}
-
- ///@{
- /// Perform a query without parametert, It execute a multiple statement.
- BOOST_SQLITE_DECL void execute(
- cstring_ref q,
- system::error_code & ec,
- error_info & ei);
-
- BOOST_SQLITE_DECL void execute(cstring_ref q);
-
- template<typename StringLike,
- typename = decltype(std::declval<const StringLike&>().c_str())>
- void execute(
- const StringLike& q,
- system::error_code & ec,
- error_info & ei)
- {
- execute(q.c_str(), ec, ei);
- }
- template<typename StringLike,
- typename = decltype(std::declval<const StringLike&>().c_str())>
- void execute(const StringLike & q) { execute(q.c_str());}
- ///@}
-
- ///@{
- /// Perform a query with parameters. Can only execute a single statement.
- BOOST_SQLITE_DECL statement prepare(
- core::string_view q,
- system::error_code & ec,
- error_info & ei);
-
- BOOST_SQLITE_DECL statement prepare(core::string_view q);
- ///@}
-
- /// Check if the database has the table
- bool has_table(
- cstring_ref table,
- cstring_ref db_name = "main") const
- {
- return sqlite3_table_column_metadata(impl_.get(), db_name.c_str(), table.c_str(),
- nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)
- == SQLITE_OK;
- }
-
- /// Check if the database has the table
- bool has_column(
- cstring_ref table,
- cstring_ref column,
- cstring_ref db_name = "main") const
- {
- return sqlite3_table_column_metadata(impl_.get(), db_name.c_str(), table.c_str(), column.c_str(),
- nullptr, nullptr, nullptr, nullptr, nullptr)
- == SQLITE_OK;
- }
- private:
- struct deleter_
- {
- deleter_(bool owned = true) : owned_(owned) {}
- bool owned_ = true;
- void operator()(sqlite3 *impl)
- {
- if (owned_)
- sqlite3_close_v2(impl);
- }
- };
-
- std::unique_ptr<sqlite3, deleter_> impl_{nullptr, deleter_{}};
-};
-
-BOOST_SQLITE_END_NAMESPACE
-
-
-#endif //BOOST_SQLITE_CONNECTION_HPP
diff --git a/include/boost/sqlite/cstring_ref.hpp b/include/boost/sqlite/cstring_ref.hpp
deleted file mode 100644
index 6747f45..0000000
--- a/include/boost/sqlite/cstring_ref.hpp
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright (c) 2022 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-// based on boost.process
-#ifndef BOOST_SQLITE_CSTRING_REF_HPP
-#define BOOST_SQLITE_CSTRING_REF_HPP
-
-#include <boost/config.hpp>
-#include <boost/core/detail/string_view.hpp>
-
-#include <cstddef>
-#include <type_traits>
-#include <string>
-
-
-#if __cplusplus >= 201702L
-#include <string_view>
-#endif
-
-namespace boost
-{
-namespace sqlite
-{
-
-/// Small wrapper for a null-terminated string that can be directly passed to C APIS
-/** This ref can only be modified by moving the front pointer. It does not store the
- * size, but can detect values that can directly be passed to system APIs.
- *
- * It can be constructed from a `char*` pointer or any class that has a `c_str()`
- * member function, e.g. std::string or boost::static_string.
- *
- */
-struct cstring_ref
-{
- using value_type = char;
- using traits_type = std::char_traits<char>;
- BOOST_CONSTEXPR cstring_ref() noexcept : view_("") {}
- BOOST_CONSTEXPR cstring_ref(std::nullptr_t) = delete;
-
- BOOST_CONSTEXPR cstring_ref( const value_type* s ) : view_(s) {}
-
- template<typename Source,
- typename =
- typename std::enable_if<
- std::is_same<const value_type,
- typename std::remove_pointer<decltype(std::declval<Source>().c_str())>::type
- >::value>::type>
- BOOST_CONSTEXPR cstring_ref(Source && src) : view_(src.c_str()) {}
-
- BOOST_CONSTEXPR const char * c_str() const BOOST_NOEXCEPT
- {
- return this->data();
- }
-
- using string_view_type = core::string_view;
- constexpr operator string_view_type() const {return view_;}
-
-#if __cplusplus >= 201702L
- constexpr operator std::string_view() const {return view_;}
-#endif
-
- using pointer = char *;
- using const_pointer = const char *;
- using reference = char &;
- using const_reference = const char &;
- using const_iterator = const_pointer;
- using iterator = const_iterator;
- using const_reverse_iterator = typename std::reverse_iterator<const_iterator>;
- using reverse_iterator = typename std::reverse_iterator<iterator>;
- using size_type = std::size_t;
- using difference_type = std::ptrdiff_t;
-
- static BOOST_CONSTEXPR size_type npos = -1;
-
- BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT {return view_;};
- BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT {return view_ + length();};
- BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT {return view_;};
- BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT {return view_ + length();};
-
-#if defined(BOOST_NO_CXX17)
- const_reverse_iterator rbegin() const BOOST_NOEXCEPT {return reverse_iterator(end());};
- const_reverse_iterator rend() const BOOST_NOEXCEPT {return reverse_iterator(begin());};
- const_reverse_iterator crbegin() const BOOST_NOEXCEPT {return reverse_iterator(end());};
- const_reverse_iterator crend() const BOOST_NOEXCEPT {return reverse_iterator(begin());};
-#else
- BOOST_CONSTEXPR const_reverse_iterator rbegin() const BOOST_NOEXCEPT {return reverse_iterator(end());};
- BOOST_CONSTEXPR const_reverse_iterator rend() const BOOST_NOEXCEPT {return reverse_iterator(begin());};
- BOOST_CONSTEXPR const_reverse_iterator crbegin() const BOOST_NOEXCEPT {return reverse_iterator(end());};
- BOOST_CONSTEXPR const_reverse_iterator crend() const BOOST_NOEXCEPT {return reverse_iterator(begin());};
-#endif
-
- BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT {return length(); }
- BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT {return length_impl_(); }
- BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT {return static_cast<std::size_t>(-1); }
- BOOST_ATTRIBUTE_NODISCARD BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT {return *view_ == '\0'; }
-
- BOOST_CONSTEXPR const_reference operator[](size_type pos) const {return view_[pos] ;}
- BOOST_CXX14_CONSTEXPR const_reference at(size_type pos) const
- {
- if (pos >= size())
- throw_exception(std::out_of_range("cstring-view out of range"));
- return view_[pos];
- }
- BOOST_CONSTEXPR const_reference front() const {return *view_;}
- BOOST_CONSTEXPR const_reference back() const {return view_[length() - 1];}
- BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT {return view_;}
- BOOST_CXX14_CONSTEXPR void remove_prefix(size_type n) {view_ = view_ + n;}
- void swap(cstring_ref& s) BOOST_NOEXCEPT {std::swap(view_, s.view_);}
-
- size_type copy(value_type* s, size_type n, size_type pos = 0) const
- {
- return traits_type::copy(s, view_ + pos, n) - view_;
- }
- BOOST_CONSTEXPR cstring_ref substr(size_type pos = 0) const
- {
- return cstring_ref(view_ + pos);
- }
-
- BOOST_CXX14_CONSTEXPR string_view_type substr(size_type pos, size_type length) const
- {
- return string_view_type(view_).substr(pos, length);
- }
-
- BOOST_CXX14_CONSTEXPR int compare(cstring_ref x) const BOOST_NOEXCEPT
- {
- auto idx = 0u;
- for (; view_[idx] != null_char_()[0] && x[idx] != null_char_()[0]; idx++)
- if (!traits_type::eq(view_[idx], x[idx]))
- return traits_type::lt(view_[idx], x[idx]) ? -1 : 1;
-
- return traits_type::to_int_type(view_[idx]) -
- traits_type::to_int_type(x[idx]); // will compare to null char of either.
- }
-
- BOOST_CXX14_CONSTEXPR bool starts_with(string_view_type x) const BOOST_NOEXCEPT
- {
- if (x.empty())
- return true;
-
- auto idx = 0u;
- for (; view_[idx] != null_char_()[0] && idx < x.size(); idx++)
- if (!traits_type::eq(view_[idx], x[idx]))
- return false;
-
- return idx == x.size() || view_[idx] != null_char_()[0];
- }
- BOOST_CONSTEXPR bool starts_with(value_type x) const BOOST_NOEXCEPT
- {
- return traits_type::eq(view_[0], x);
- }
-
- BOOST_CXX14_CONSTEXPR size_type find( char ch, size_type pos = 0 ) const BOOST_NOEXCEPT
- {
- for (auto p = view_ + pos; *p != *null_char_(); p++)
- if (traits_type::eq(*p, ch))
- return p - view_;
- return npos;
- }
-
-
- friend BOOST_CXX14_CONSTEXPR bool operator==(cstring_ref x, cstring_ref y) BOOST_NOEXCEPT
- {
- std::size_t idx = 0u;
- for (idx = 0u; x[idx] != null_char_()[0] && y[idx] != null_char_()[0]; idx++)
- if (!traits_type::eq(x[idx], y[idx]))
- return false;
- return x[idx] == y[idx];
- }
- friend BOOST_CXX14_CONSTEXPR bool operator!=(cstring_ref x, cstring_ref y) BOOST_NOEXCEPT
- {
- std::size_t idx = 0u;
- for (idx = 0u; x[idx] != null_char_()[0] &&
- y[idx] != null_char_()[0]; idx++)
- if (!traits_type::eq(x[idx], y[idx]))
- return true;
- return x[idx] != y[idx];
- }
- friend BOOST_CXX14_CONSTEXPR bool operator< (cstring_ref x, cstring_ref y) BOOST_NOEXCEPT {return x.compare(y) < 0;}
- friend BOOST_CXX14_CONSTEXPR bool operator> (cstring_ref x, cstring_ref y) BOOST_NOEXCEPT {return x.compare(y) > 0;}
- friend BOOST_CXX14_CONSTEXPR bool operator<=(cstring_ref x, cstring_ref y) BOOST_NOEXCEPT {return x.compare(y) <= 0;}
- friend BOOST_CXX14_CONSTEXPR bool operator>=(cstring_ref x, cstring_ref y) BOOST_NOEXCEPT {return x.compare(y) >= 0;}
-
- // modifiers
- void clear() BOOST_NOEXCEPT { view_ = null_char_(); } // Boost extension
-
- std::basic_string<value_type, traits_type> to_string() const
- {
- return std::basic_string<char, traits_type>(begin(), end());
- }
-
- template<typename Allocator>
- std::basic_string<value_type, traits_type, Allocator> to_string(const Allocator& a) const
- {
- return std::basic_string<value_type, traits_type, Allocator>(begin(), end(), a);
- }
-
- template<class A> operator std::basic_string<char, std::char_traits<char>, A>() const
- {
- return std::basic_string<char, std::char_traits<char>, A>( view_ );
- }
-
- private:
- BOOST_CONSTEXPR static const_pointer null_char_() {return "\0";}
- constexpr std::size_t length_impl_(std::size_t n = 0) const BOOST_NOEXCEPT
- {
- return view_[n] == null_char_()[0] ? n : length_impl_(n+1);
- }
- const_pointer view_;
-};
-
-template<typename Char>
-inline std::basic_ostream<Char>& operator<<( std::basic_ostream<Char> & os, cstring_ref str )
-{
- return os << core::string_view(str);
-}
-
-
-}
-}
-
-
-#endif //BOOST_SQLITE_CSTRING_REF_HPP
diff --git a/include/boost/sqlite/detail/aggregate_function.hpp b/include/boost/sqlite/detail/aggregate_function.hpp
deleted file mode 100644
index de0c447..0000000
--- a/include/boost/sqlite/detail/aggregate_function.hpp
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright (c) 2023 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_DETAIL_AGGREGATE_FUNCTION_HPP
-#define BOOST_SQLITE_DETAIL_AGGREGATE_FUNCTION_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/detail/catch.hpp>
-#include <boost/sqlite/error.hpp>
-#include <boost/sqlite/cstring_ref.hpp>
-#include <boost/sqlite/memory.hpp>
-#include <boost/sqlite/result.hpp>
-#include <boost/sqlite/value.hpp>
-
-#include <boost/callable_traits/args.hpp>
-#include <boost/callable_traits/return_type.hpp>
-#include <boost/callable_traits/has_void_return.hpp>
-#include <boost/core/span.hpp>
-
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-namespace detail
-{
-
-template<typename Func>
-struct aggregate_function_maker
-{
- void * mem;
-
- template<typename ... Args>
- Func* operator()(Args && ... args)
- {
- return new (mem) Func(std::forward<Args>(args)...);
- }
-};
-
-template<typename Func, typename Args>
-int create_aggregate_function(sqlite3 * db, cstring_ref name, Args && args, int flags,
- std::true_type /* void return */)
-{
- using args_type = callable_traits::args_t<decltype(&Func::step)>;
- using span_type = typename std::tuple_element<1U, args_type>::type;
- using func_type = typename std::decay<Func>::type;
- using func_args_type = typename std::decay<Args>::type;
-
- return sqlite3_create_function_v2(
- db, name.c_str(),
- span_type::extent == boost::dynamic_extent ? -1 : static_cast<int>(span_type::extent),
- SQLITE_UTF8 | flags,
- new (memory_tag{}) func_args_type(std::forward<Args>(args)),
- nullptr,
- +[](sqlite3_context* ctx, int len, sqlite3_value** args)
- {
- auto aa = reinterpret_cast<value*>(args);
- auto fa = reinterpret_cast<func_args_type*>(sqlite3_user_data(ctx));
- auto c = static_cast<func_type*>(sqlite3_aggregate_context(ctx, 0));
-
- execute_context_function(
- ctx,
- [&]() -> result<void>
- {
- if (c == nullptr)
- {
- auto p = sqlite3_aggregate_context(ctx, sizeof(func_type));
- if (!p)
- return error(SQLITE_NOMEM);
- c = mp11::tuple_apply(aggregate_function_maker<func_type>{p}, *fa);
- }
- c->step(span_type{aa, static_cast<std::size_t>(len)});
- return {};
- });
- },
- [](sqlite3_context* ctx)
- {
- auto fa = reinterpret_cast<func_args_type*>(sqlite3_user_data(ctx));
- auto c = static_cast<func_type*>(sqlite3_aggregate_context(ctx, 0));
-
- execute_context_function(
- ctx,
- [&]() -> result<decltype(c->final())>
- {
- if (c == nullptr)
- {
- auto p = sqlite3_aggregate_context(ctx, sizeof(func_type));
- if (!p)
- return error(SQLITE_NOMEM);
- c = mp11::tuple_apply(aggregate_function_maker<func_type>{p}, *fa);
- }
- struct reaper {void operator()(func_type * c) { c->~func_type();}};
- std::unique_ptr<func_type, reaper> cl{c};
- return c->final();
- });
- },
- [](void * ptr) noexcept { delete_(static_cast<func_type*>(ptr));}
- );
-}
-
-
-template<typename Func, typename Args>
-int create_aggregate_function(sqlite3 * db, cstring_ref name, Args && args, int flags,
- std::false_type /* void return */)
-{
- using args_type = callable_traits::args_t<decltype(&Func::step)>;
- using span_type = typename std::tuple_element<1U, args_type>::type;
- using func_type = typename std::decay<Func>::type;
- using func_args_type = typename std::decay<Args>::type;
-
- return sqlite3_create_function_v2(
- db, name.c_str(),
- span_type::extent == boost::dynamic_extent ? -1 : static_cast<int>(span_type::extent),
- SQLITE_UTF8 | flags,
- new (memory_tag{}) func_args_type(std::forward<Args>(args)),
- nullptr,
- +[](sqlite3_context* ctx, int len, sqlite3_value** args)
- {
- auto aa = reinterpret_cast<value*>(args);
- auto fa = reinterpret_cast<func_args_type*>(sqlite3_user_data(ctx));
- auto c = static_cast<func_type*>(sqlite3_aggregate_context(ctx, 0));
-
- execute_context_function(
- ctx,
- [&]() -> result<void>
- {
- if (c == nullptr)
- {
- auto p = sqlite3_aggregate_context(ctx, sizeof(func_type));
- if (!p)
- return {system::in_place_error, error(SQLITE_NOMEM)};
- c = mp11::tuple_apply(aggregate_function_maker<func_type>{p}, *fa);
- }
- return c->step(span_type{aa, static_cast<std::size_t>(len)});
- });
- },
- [](sqlite3_context* ctx)
- {
- auto fa = reinterpret_cast<func_args_type*>(sqlite3_user_data(ctx));
- auto c = static_cast<func_type*>(sqlite3_aggregate_context(ctx, 0));
-
- execute_context_function(
- ctx,
- [&]() -> result<decltype(c->final())>
- {
- if (c == nullptr)
- {
- auto p = sqlite3_aggregate_context(ctx, sizeof(func_type));
- if (!p)
- return {system::in_place_error, error(SQLITE_NOMEM)};
- c = mp11::tuple_apply(aggregate_function_maker<func_type>{p}, *fa);
- }
- struct reaper {void operator()(func_type * c) { c->~func_type();}};
- std::unique_ptr<func_type, reaper> cl{c};
- return c->final();
- });
- },
- [](void * ptr) noexcept { delete_(static_cast<func_type*>(ptr));}
- );
-}
-
-}
-
-BOOST_SQLITE_END_NAMESPACE
-
-
-#endif //BOOST_SQLITE_DETAIL_AGGREGATE_FUNCTION_HPP
diff --git a/include/boost/sqlite/detail/catch.hpp b/include/boost/sqlite/detail/catch.hpp
deleted file mode 100644
index e5b053f..0000000
--- a/include/boost/sqlite/detail/catch.hpp
+++ /dev/null
@@ -1,169 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_DETAIL_CATCH_HPP
-#define BOOST_SQLITE_DETAIL_CATCH_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/detail/exception.hpp>
-#include <boost/sqlite/error.hpp>
-#include <boost/sqlite/result.hpp>
-
-#include <boost/system/system_error.hpp>
-
-#include <stdexcept>
-
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-namespace detail
-{
-
-template<typename Func, typename ... Args>
-void execute_context_function_impl(std::false_type /* is_void */,
- sqlite3_context * ctx,
- Func && func, Args && ... args)
- noexcept(noexcept(std::forward<Func>(func)(std::forward<Args>(args)...)))
-{
- set_result(ctx, std::forward<Func>(func)(std::forward<Args>(args)...));
-}
-
-template<typename Func, typename ... Args>
-void execute_context_function_impl(std::true_type /* is_void */,
- sqlite3_context * ctx,
- Func && func, Args && ... args)
- noexcept(noexcept(std::forward<Func>(func)(std::forward<Args>(args)...)))
-{
- std::forward<Func>(func)(std::forward<Args>(args)...);
-}
-
-template<typename T>
-int extract_error(char * &errMsg, result<T> & res)
-{
- error err = std::move(res).error();
- if (err.info)
- errMsg = err.info.release();
- return err.code;
-}
-
-
-template<typename Func, typename ... Args>
-void execute_context_function(sqlite3_context * ctx,
- Func && func, Args && ... args) noexcept
-{
- using return_type = decltype(func(std::forward<Args>(args)...));
-#if !defined(BOOST_NO_EXCEPTIONS)
- try
- {
-#endif
- execute_context_function_impl(std::is_void<return_type>{}, ctx,
- std::forward<Func>(func),
- std::forward<Args>(args)...);
-#if !defined(BOOST_NO_EXCEPTIONS)
- }
- catch(boost::system::system_error & se)
- {
- const auto msg = boost::sqlite::detail::get_message(se);
- if (!msg.empty())
- sqlite3_result_error(ctx, msg.data(), msg.size());
- if (se.code().category() == boost::sqlite::sqlite_category())
- sqlite3_result_error_code(ctx, se.code().value());
- }
- catch(std::bad_alloc &) { sqlite3_result_error_nomem(ctx); }
- catch(std::length_error &) { sqlite3_result_error_toobig(ctx); }
- catch(std::out_of_range &) { sqlite3_result_error_code(ctx, SQLITE_RANGE);}
- catch(std::logic_error &le)
- {
- sqlite3_result_error(ctx, le.what(), std::strlen(le.what()));
- sqlite3_result_error_code(ctx, SQLITE_MISUSE);
- }
- catch(std::exception & ex)
- {
- sqlite3_result_error(ctx, ex.what(), std::strlen(ex.what()));
- }
- catch(...) {sqlite3_result_error_code(ctx, SQLITE_ERROR); }
-#endif
-}
-
-}
-BOOST_SQLITE_END_NAMESPACE
-
-#if defined(BOOST_NO_EXCEPTIONS)
-#define BOOST_SQLITE_TRY
-#define BOOST_SQLITE_CATCH_RESULT(ctx)
-#define BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(msg)
-#define BOOST_SQLITE_CATCH_AND_RETURN()
-
-#else
-
-#define BOOST_SQLITE_TRY try
-#define BOOST_SQLITE_CATCH_RESULT(ctx) \
-catch(boost::system::system_error & se) \
-{ \
- if (se.code().category() == boost::sqlite::sqlite_category()) \
- sqlite3_result_error_code(ctx, se.code().value()); \
- const auto msg = boost::sqlite::detail::get_message(se); \
- if (!msg.empty()) \
- sqlite3_result_error(ctx, msg.data(), msg.size()); \
-} \
-catch(std::bad_alloc &) { sqlite3_result_error_nomem(ctx); } \
-catch(std::length_error &) { sqlite3_result_error_toobig(ctx); } \
-catch(std::out_of_range &) { sqlite3_result_error_code(ctx, SQLITE_RANGE);} \
-catch(std::logic_error &le) \
-{ \
- sqlite3_result_error(ctx, le.what(), std::strlen(le.what())); \
- sqlite3_result_error_code(ctx, SQLITE_MISUSE); \
-} \
-catch(std::exception & ex) \
-{ \
- sqlite3_result_error(ctx, ex.what(), std::strlen(ex.what())); \
-} \
-catch(...) {sqlite3_result_error_code(ctx, SQLITE_ERROR); }
-
-
-#define BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(msg) \
-catch (boost::system::system_error & se) \
-{ \
- auto code = SQLITE_ERROR; \
- if (se.code().category() == boost::sqlite::sqlite_category()) \
- code = se.code().value(); \
- const auto pre = boost::sqlite::detail::get_message(se); \
- msg = boost::sqlite::error_info(pre).release(); \
- return code; \
-} \
-catch(std::bad_alloc &) { return SQLITE_NOMEM; } \
-catch(std::length_error &) { return SQLITE_TOOBIG; } \
-catch(std::out_of_range &) { return SQLITE_RANGE;} \
-catch(std::logic_error &le) \
-{ \
- msg = boost::sqlite::error_info(le.what()).release(); \
- return SQLITE_MISUSE; \
-} \
-catch(std::exception & ex) \
-{ \
- msg = boost::sqlite::error_info(ex.what()).release(); \
- return SQLITE_ERROR; \
-} \
-catch(...) {return SQLITE_ERROR; } \
-
-
-#define BOOST_SQLITE_CATCH_AND_RETURN() \
-catch (boost::system::system_error & se) \
-{ \
- auto code = SQLITE_ERROR; \
- if (se.code().category() == boost::sqlite::sqlite_category()) \
- code = se.code().value(); \
- return code; \
-} \
-catch(std::bad_alloc &) { return SQLITE_NOMEM; } \
-catch(std::length_error &) { return SQLITE_TOOBIG; } \
-catch(std::out_of_range &) { return SQLITE_RANGE;} \
-catch(std::logic_error &) { return SQLITE_MISUSE;} \
-catch(...) { return SQLITE_ERROR; } \
-
-#endif
-
-#endif //BOOST_SQLITE_DETAIL_CATCH_HPP
diff --git a/include/boost/sqlite/detail/config.hpp b/include/boost/sqlite/detail/config.hpp
deleted file mode 100644
index 2126f60..0000000
--- a/include/boost/sqlite/detail/config.hpp
+++ /dev/null
@@ -1,83 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_DETAIL_CONFIG_HPP
-#define BOOST_SQLITE_DETAIL_CONFIG_HPP
-
-#include <boost/config.hpp>
-#include <boost/core/detail/string_view.hpp>
-
-#if defined(BOOST_SQLITE_COMPILE_EXTENSION)
-#include <sqlite3ext.h>
-#define BOOST_SQLITE_COMPILING_EXTENSION 1
-#define BOOST_SQLITE_BEGIN_NAMESPACE namespace boost { namespace sqlite { inline namespace ext {
-#define BOOST_SQLITE_END_NAMESPACE } } }
-#else
-#include <sqlite3.h>
-#define BOOST_SQLITE_BEGIN_NAMESPACE namespace boost { namespace sqlite {
-#define BOOST_SQLITE_END_NAMESPACE } }
-#endif
-
-// copied from boost.json
-#if defined(BOOST_SQLITE_DOCS)
-# define BOOST_SQLITE_DECL
-#else
-# if (defined(BOOST_SQLITE_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_SQLITE_STATIC_LINK)
-# if defined(BOOST_SQLITE_SOURCE)
-# define BOOST_SQLITE_DECL BOOST_SYMBOL_EXPORT
-# else
-# define BOOST_SQLITE_DECL BOOST_SYMBOL_IMPORT
-# endif
-# endif // static lib
-# ifndef BOOST_SQLITE_DECL
-# define BOOST_SQLITE_DECL
-# endif
-# if !defined(BOOST_SQLITE_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SQLITE_NO_LIB)
-# define BOOST_LIB_NAME boost_sqlite
-# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SQLITE_DYN_LINK)
-# define BOOST_DYN_LINK
-# endif
-# include <boost/config/auto_link.hpp>
-# endif
-#endif
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-
-#if defined(BOOST_SQLITE_COMPILE_EXTENSION)
-extern const sqlite3_api_routines *sqlite3_api;
-#endif
-
-using string_view = boost::core::string_view;
-
-BOOST_SQLITE_END_NAMESPACE
-
-#define BOOST_SQLITE_RETURN_EC(ev) \
-do \
-{ \
- static constexpr auto loc##__LINE__((BOOST_CURRENT_LOCATION)); \
- return ::boost::system::error_code(ev, boost::sqlite::sqlite_category(), &loc##__LINE__); \
-} \
-while (false)
-
-#define BOOST_SQLITE_ASSIGN_EC(ec, ev) \
-do \
-{ \
- static constexpr auto loc##__LINE__((BOOST_CURRENT_LOCATION)); \
- ec.assign(ev, boost::sqlite::sqlite_category(), &loc##__LINE__); \
-} \
-while (false)
-
-#if defined(BOOST_SQLITE_NO_VIRTUAL)
-#define BOOST_SQLITE_VIRTUAL
-#define BOOST_SQLITE_PURE
-#else
-#define BOOST_SQLITE_VIRTUAL virtual
-#define BOOST_SQLITE_PURE = 0
-#endif
-
-#endif // BOOST_SQLITE_DETAIL_HPP \ No newline at end of file
diff --git a/include/boost/sqlite/detail/exception.hpp b/include/boost/sqlite/detail/exception.hpp
deleted file mode 100644
index 9f29cbe..0000000
--- a/include/boost/sqlite/detail/exception.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2023 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_DETAIL_EXCEPTION_HPP
-#define BOOST_SQLITE_DETAIL_EXCEPTION_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/error.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-namespace detail
-{
-
-BOOST_SQLITE_DECL
-BOOST_NORETURN void throw_error_code(const boost::system::error_code & ec,
- const boost::source_location & loc = BOOST_CURRENT_LOCATION);
-
-BOOST_SQLITE_DECL
-BOOST_NORETURN void throw_error_code(const boost::system::error_code & ec,
- const error_info & ei,
- const boost::source_location & loc = BOOST_CURRENT_LOCATION);
-
-BOOST_SQLITE_DECL
-BOOST_NORETURN void throw_out_of_range(const char * msg,
- const boost::source_location & loc);
-
-BOOST_SQLITE_DECL
-BOOST_NORETURN void throw_invalid_argument(const char * msg,
- const boost::source_location & loc);
-
-inline core::string_view get_message(const system::system_error & se)
-{
- auto ec_len = se.code().what().size();
- auto se_len = std::strlen(se.what());
-
- if (ec_len == se_len)
- return core::string_view();
- else
- return core::string_view(se.what(), se_len - (ec_len + 2));
-}
-
-
-}
-BOOST_SQLITE_END_NAMESPACE
-
-
-#endif //BOOST_SQLITE_DETAIL_EXCEPTION_HPP
diff --git a/include/boost/sqlite/detail/scalar_function.hpp b/include/boost/sqlite/detail/scalar_function.hpp
deleted file mode 100644
index ee16a23..0000000
--- a/include/boost/sqlite/detail/scalar_function.hpp
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright (c) 2023 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_DETAIL_SCALAR_FUNCTION_HPP
-#define BOOST_SQLITE_DETAIL_SCALAR_FUNCTION_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/cstring_ref.hpp>
-#include <boost/sqlite/memory.hpp>
-#include <boost/sqlite/result.hpp>
-#include <boost/sqlite/value.hpp>
-
-#include <boost/callable_traits/args.hpp>
-#include <boost/callable_traits/return_type.hpp>
-#include <boost/callable_traits/has_void_return.hpp>
-#include <boost/core/span.hpp>
-
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-template<typename ... Args>
-struct context;
-
-namespace detail
-{
-
-template<typename Func, typename ... Args, std::size_t Extent>
-auto create_scalar_function_impl(sqlite3 * db,
- cstring_ref name,
- Func && func,
- int flags,
- std::tuple<context<Args...>, boost::span<value, Extent>> * ,
- std::false_type /* void return */,
- std::false_type /* is pointer */) -> int
-{
- using func_type = typename std::decay<Func>::type;
- return sqlite3_create_function_v2(
- db, name.c_str(),
- Extent == boost::dynamic_extent ? -1 : static_cast<int>(Extent),
- SQLITE_UTF8 | flags,
- new (memory_tag{}) func_type(std::forward<Func>(func)),
- +[](sqlite3_context* ctx, int len, sqlite3_value** args)
- {
- auto cc = context<Args...>(ctx);
- auto aa = reinterpret_cast<value*>(args);
- auto &f = *reinterpret_cast<func_type*>(sqlite3_user_data(ctx));
- boost::span<value, Extent> vals{aa, static_cast<std::size_t>(len)};
-
- execute_context_function(ctx, f, cc, vals);
- }, nullptr, nullptr,
- +[](void * ptr) noexcept {delete_(static_cast<func_type*>(ptr));}
- );
-}
-
-template<typename Func, typename ... Args, std::size_t Extent>
-auto create_scalar_function_impl(sqlite3 * db,
- cstring_ref name,
- Func && func, int flags,
- std::tuple<context<Args...>, boost::span<value, Extent>> * ,
- std::true_type /* void return */,
- std::false_type /* is pointer */) -> int
-{
- using func_type = typename std::decay<Func>::type;
- return sqlite3_create_function_v2(
- db,
- name.c_str(),
- (Extent == boost::dynamic_extent) ? -1 : static_cast<int>(Extent),
- SQLITE_UTF8 | flags,
- new (memory_tag{}) func_type(std::forward<Func>(func)),
- +[](sqlite3_context* ctx, int len, sqlite3_value** args)
- {
- auto cc = context<Args...>(ctx);
- auto aa = reinterpret_cast<value*>(args);
- auto &f = *reinterpret_cast<func_type*>(sqlite3_user_data(ctx));
- boost::span<value, Extent> vals{aa, static_cast<std::size_t>(len)};
-
- execute_context_function(
- ctx,
- [&]()
- {
- f(cc, vals);
- return result<void>();
- });
-
- }, nullptr, nullptr,
- +[](void * ptr){delete_(static_cast<func_type*>(ptr));}
- );
-}
-
-
-template<typename Func, typename ... Args, std::size_t Extent>
-auto create_scalar_function_impl(sqlite3 * db,
- cstring_ref name,
- Func * func, int flags,
- std::tuple<context<Args...>, boost::span<value, Extent>> * ,
- std::false_type /* void return */,
- std::true_type /* is pointer */) -> int
-{
- return sqlite3_create_function_v2(
- db, name.c_str(),
- Extent == boost::dynamic_extent ? -1 : static_cast<int>(Extent),
- SQLITE_UTF8 | flags,
- reinterpret_cast<void*>(func),
- +[](sqlite3_context* ctx, int len, sqlite3_value** args)
- {
- auto cc = context<Args...>(ctx);
- auto aa = reinterpret_cast<value*>(args);
- auto f = reinterpret_cast<Func*>(sqlite3_user_data(ctx));
-
- boost::span<value, Extent> vals{aa, static_cast<std::size_t>(len)};
-
- execute_context_function(
- ctx, f, cc, vals);
- }, nullptr, nullptr, nullptr);
-}
-
-template<typename Func, typename ... Args, std::size_t Extent>
-auto create_scalar_function_impl(sqlite3 * db,
- cstring_ref name,
- Func * func, int flags,
- std::tuple<context<Args...>, boost::span<value, Extent>> * ,
- std::true_type /* void return */,
- std::true_type /* is pointer */) -> int
-{
- return sqlite3_create_function_v2(
- db,
- name.c_str(),
- (Extent == boost::dynamic_extent) ? -1 : static_cast<int>(Extent),
- SQLITE_UTF8 | flags,
- reinterpret_cast<void*>(func),
- +[](sqlite3_context* ctx, int len, sqlite3_value** args)
- {
- auto cc = context<Args...>(ctx);
- auto aa = reinterpret_cast<value*>(args);
- auto f = *reinterpret_cast<Func*>(sqlite3_user_data(ctx));
- boost::span<value, Extent> vals{aa, static_cast<std::size_t>(len)};
- execute_context_function(
- ctx,
- [&]()
- {
- f(cc, vals);
- return result<void>();
- });
-
- }, nullptr, nullptr, nullptr);
-}
-
-template<typename Func>
-auto create_scalar_function(sqlite3 * db,
- cstring_ref name,
- Func && func,
- int flags)
- -> decltype(create_scalar_function_impl(
- db, name, std::forward<Func>(func), flags,
- static_cast<callable_traits::args_t<Func>*>(nullptr),
- callable_traits::has_void_return<Func>{},
- std::is_pointer<typename std::decay<Func>::type>{}
- ))
-{
- return create_scalar_function_impl(db, name, std::forward<Func>(func), flags,
- static_cast<callable_traits::args_t<Func>*>(nullptr),
- callable_traits::has_void_return<Func>{},
- std::is_pointer<typename std::decay<Func>::type>{});
-}
-
-
-}
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_DETAIL_SCALAR_FUNCTION_HPP
diff --git a/include/boost/sqlite/detail/vtable.hpp b/include/boost/sqlite/detail/vtable.hpp
deleted file mode 100644
index f85f44c..0000000
--- a/include/boost/sqlite/detail/vtable.hpp
+++ /dev/null
@@ -1,611 +0,0 @@
-// Copyright (c) 2023 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_DETAIL_VTABLE_HPP
-#define BOOST_SQLITE_DETAIL_VTABLE_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/detail/catch.hpp>
-#include <boost/sqlite/vtable.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-namespace detail
-{
-struct vtab_impl
-{
-
-template<typename Module>
-static int connect(sqlite3 * db, void * pAux, int argc, const char * const * argv,
- sqlite3_vtab **ppVTab, char** errMsg)
-{
- using table_type = typename Module::table_type;
- auto &impl = *static_cast<Module*>(pAux);
- BOOST_SQLITE_TRY
- {
- result<table_type> rtab = impl.connect(
- sqlite::connection(db, false),
- argc, argv);
-
- if (rtab.has_error())
- return extract_error(*errMsg, rtab);
-
- auto tab = make_unique<table_type>(std::move(*rtab));
- tab->db_ = db;
- auto code = sqlite3_declare_vtab(db, tab->declaration());
- if (code != SQLITE_OK)
- return code;
-
- sqlite::vtab::module_config cfg{db};
- auto r = tab->config(cfg);
- if (r.has_error())
- return extract_error(*errMsg, r);
-
- *ppVTab = tab.release();
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(*errMsg)
-}
-
-
-template<typename Module>
-static int create(sqlite3 * db, void * pAux, int argc, const char * const * argv,
- sqlite3_vtab **ppVTab, char** errMsg)
-{
- using table_type = typename Module::table_type;
- auto &impl = *static_cast<Module*>(pAux);
- BOOST_SQLITE_TRY
- {
- result<table_type> rtab = impl.create(
- sqlite::connection(db, false),
- argc, argv);
-
- if (rtab.has_error())
- return extract_error(*errMsg, rtab);
-
- auto tab = make_unique<table_type>(std::move(*rtab));
- tab->db_ = db;
-
- auto code = sqlite3_declare_vtab(db, tab->declaration());
- if (code != SQLITE_OK)
- return code;
-
- sqlite::vtab::module_config mc{db};
- auto r = tab->config(mc);
- if (r.has_error())
- return extract_error(*errMsg, r);
-
- *ppVTab = tab.release();
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(*errMsg)
-}
-
-template<typename Table>
-static int disconnect(sqlite3_vtab * tab)
-{
- BOOST_SQLITE_TRY
- {
- auto tb = static_cast<Table*>(tab);
- tb->~Table();
- sqlite3_free(tb);
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(tab->zErrMsg);
-}
-
-template<typename Table>
-static int destroy(sqlite3_vtab * tab)
-{
- BOOST_SQLITE_TRY
- {
- auto tb = static_cast<Table*>(tab);
- auto res = tb->destroy();
- tb->~Table();
- sqlite3_free(tb);
- if (res.has_error())
- return std::move(res).error().code;
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(tab->zErrMsg);
-}
-
-template<typename Module, typename Table>
-static void assign_create(sqlite3_module & md, const Module &,
- const sqlite::vtab::eponymous_module<Table> & base)
-{
- md.xConnect = md.xCreate = &connect<Module>;
- md.xDisconnect = md.xDestroy = &disconnect<Table>;
- if (base.eponymous_only())
- md.xCreate = nullptr;
-}
-
-template<typename Module, typename Table>
-static void assign_create(sqlite3_module & md, const Module &,
- const sqlite::vtab::module<Table> &)
-{
- md.xConnect = &connect<Module>;
- md.xDisconnect = &disconnect<Table>;
- md.xCreate = &create<Module>;
- md.xDestroy = &destroy<Table>;
-}
-
-template<typename Table>
-static int open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor)
-{
- auto tab = static_cast<Table *>(pVTab);
-
- BOOST_SQLITE_TRY
- {
- auto res = tab->open();
- if (res.has_error())
- return extract_error(pVTab->zErrMsg, res);
- *ppCursor = new (memory_tag{}) typename Table::cursor_type(std::move(*res));
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_AND_RETURN();
-}
-
-template<typename Cursor>
-static int close(sqlite3_vtab_cursor * cursor)
-{
- auto p = static_cast<Cursor *>(cursor);
-
- BOOST_SQLITE_TRY
- {
- p->~Cursor();
- }
- BOOST_SQLITE_CATCH_AND_RETURN();
-
- sqlite3_free(p);
- return SQLITE_OK;
-
-}
-
-template<typename Table>
-static int best_index(sqlite3_vtab *pVTab, sqlite3_index_info* info)
-{
- BOOST_SQLITE_TRY
- {
- auto tb = static_cast<Table*>(pVTab);
-
- sqlite::vtab::index_info ii(tb->db_, info);
- auto r = tb->best_index(ii);
- if (r.has_error())
- return extract_error(pVTab->zErrMsg, r);
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pVTab->zErrMsg);
-}
-
-
-template<typename Cursor>
-static int filter(sqlite3_vtab_cursor* pCursor,
- int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv)
-{
- BOOST_SQLITE_TRY
- {
- auto cr = static_cast<Cursor*>(pCursor);
-
- auto r = cr->filter(idxNum, idxStr,
- boost::span<value>{reinterpret_cast<value*>(argv),
- static_cast<std::size_t>(argc)});
- if (r.has_error())
- return extract_error(pCursor->pVtab->zErrMsg, r);
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pCursor->pVtab->zErrMsg);
-}
-
-
-template<typename Cursor>
-static int next(sqlite3_vtab_cursor* pCursor)
-{
- BOOST_SQLITE_TRY
- {
- auto cr = static_cast<Cursor*>(pCursor);
-
- auto r = cr->next();
- if (r.has_error())
- return extract_error(pCursor->pVtab->zErrMsg, r);
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pCursor->pVtab->zErrMsg);
-}
-
-
-template<typename Cursor>
-static int eof(sqlite3_vtab_cursor* pCursor)
-{
- return static_cast<Cursor*>(pCursor)->eof() ? 1 : 0;
-}
-
-template<typename Cursor>
-static auto column(sqlite3_vtab_cursor* pCursor,
- sqlite3_context * ctx, int idx)
- -> typename std::enable_if<!std::is_void<typename Cursor::column_type>::value, int>::type
-{
-#if SQLITE_VERSION_NUMBER >= 3032000
- bool no_change = sqlite3_vtab_nochange(ctx) != 0;
-#else
- bool no_change = false;
-#endif
- auto cr = static_cast<Cursor*>(pCursor);
- execute_context_function(
- ctx,
- [&]{
- return cr->column(idx, no_change);
- });
-
- return SQLITE_OK;
-}
-
-
-template<typename Cursor>
-static auto column(sqlite3_vtab_cursor* pCursor,
- sqlite3_context * ctx, int idx)
- -> typename std::enable_if<std::is_void<typename Cursor::column_type>::value, int>::type
-{
-#if SQLITE_VERSION_NUMBER >= 3032000
- bool no_change = sqlite3_vtab_nochange(ctx) != 0;
-#else
- bool no_change = false;
-#endif
- auto cr = static_cast<Cursor*>(pCursor);
- BOOST_SQLITE_TRY
- {
- cr->column(context<>{ctx}, idx, no_change);
- }
- BOOST_SQLITE_CATCH_RESULT(ctx);
- return SQLITE_OK;
-}
-
-template<typename Cursor>
-static int row_id(sqlite3_vtab_cursor* pCursor, sqlite3_int64 *pRowid)
-{
- BOOST_SQLITE_TRY
- {
- auto cr = static_cast<Cursor*>(pCursor);
-
- auto r = cr->row_id();
- if (r.has_error())
- return extract_error(pCursor->pVtab->zErrMsg, r);
- *pRowid = *r;
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pCursor->pVtab->zErrMsg);
-}
-
-template<typename Table>
-static int update(sqlite3_vtab * pVTab, int argc, sqlite3_value ** argv, sqlite3_int64 * pRowid)
-{
- using table_type = Table;
- BOOST_SQLITE_TRY
- {
- auto & mod = *static_cast<table_type *>(pVTab);
- auto db = mod.db_;
- if (argc == 1 && sqlite3_value_type(argv[0]) != SQLITE_NULL)
- {
- auto r = mod.delete_(sqlite::value(*argv));
- if (r.has_error())
- return extract_error(pVTab->zErrMsg, r);
- }
- else if (argc > 1 && sqlite3_value_type(argv[0]) == SQLITE_NULL)
- {
- auto r = mod.insert(value{argv[1]},
- boost::span<value>{reinterpret_cast<value *>(argv + 2),
- static_cast<std::size_t>(argc - 2)},
- sqlite3_vtab_on_conflict(db));
- if (r.has_error())
- return extract_error(pVTab->zErrMsg, r);
- *pRowid = r.value();
- }
- else if (argc > 1 && sqlite3_value_type(argv[0]) != SQLITE_NULL)
- {
- auto r = mod.update(sqlite::value(*argv), value{argv[1]}, // ID
- boost::span<value>{reinterpret_cast<value *>(argv + 2),
- static_cast<std::size_t>(argc - 2)},
- sqlite3_vtab_on_conflict(db));
-
- if (r.has_error())
- return extract_error(pVTab->zErrMsg, r);
- *pRowid = r.value();
- }
- else
- {
- pVTab->zErrMsg = sqlite3_mprintf("Misuse of update api");
- return SQLITE_MISUSE;
- }
-
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pVTab->zErrMsg)
- return SQLITE_OK;
-}
-
-template<typename Module>
-static void assign_update(sqlite3_module & md, const Module &,
- std::true_type /* modifiable */)
-{
- md.xUpdate = &update<typename Module::table_type>;
-}
-
-template<typename Module>
-static void assign_update(sqlite3_module & /*md*/, const Module &,
- std::false_type /* modifiable */)
-{
-}
-
-template<typename Table>
-static int begin(sqlite3_vtab* pVTab)
-{
- BOOST_SQLITE_TRY
- {
- auto cr = static_cast<Table*>(pVTab);
-
- auto r = cr->begin();
- if (r.has_error())
- return extract_error(pVTab->zErrMsg, r);
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pVTab->zErrMsg);
-}
-
-template<typename Table>
-static int sync(sqlite3_vtab* pVTab)
-{
- BOOST_SQLITE_TRY
- {
- auto cr = static_cast<Table*>(pVTab);
-
- auto r = cr->sync();
- if (r.has_error())
- return extract_error(pVTab->zErrMsg, r);
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pVTab->zErrMsg);
-}
-
-template<typename Table>
-static int commit(sqlite3_vtab* pVTab)
-{
- BOOST_SQLITE_TRY
- {
- auto cr = static_cast<Table*>(pVTab);
-
- auto r = cr->commit();
- if (r.has_error())
- return extract_error(pVTab->zErrMsg, r);
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pVTab->zErrMsg);
-}
-
-template<typename Table>
-static int rollback(sqlite3_vtab* pVTab)
-{
- BOOST_SQLITE_TRY
- {
- auto cr = static_cast<Table*>(pVTab);
-
- auto r = cr->rollback();
- if (r.has_error())
- return extract_error(pVTab->zErrMsg, r);
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pVTab->zErrMsg);
-}
-
-template<typename Module>
-static void assign_transaction(sqlite3_module & /*md*/, const Module &,
- std::false_type /* modifiable */)
-{
-}
-
-template<typename Module>
-static void assign_transaction(sqlite3_module & md, const Module &,
- std::true_type /* modifiable */)
-{
- md.xBegin = &begin <typename Module::table_type>;
- md.xSync = &sync <typename Module::table_type>;
- md.xCommit = &commit <typename Module::table_type>;
- md.xRollback = &rollback<typename Module::table_type>;
-}
-
-template<typename Table>
-static int find_function(sqlite3_vtab *pVtab, int nArg, const char *zName,
- void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
- void **ppArg)
-{
- BOOST_SQLITE_TRY
- {
- auto cr = static_cast<Table*>(pVtab);
-
- auto r = cr->find_function(
- nArg, zName, sqlite::vtab::function_setter(pxFunc, ppArg));
- if (r.has_error())
- return extract_error(pVtab->zErrMsg, r);
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pVtab->zErrMsg);
-}
-
-template<typename Module>
-static void assign_find_function(sqlite3_module & /*md*/, const Module &,
- std::false_type /* overloadable */)
-{
-}
-
-template<typename Module>
-static void assign_find_function(sqlite3_module & md, const Module &,
- std::true_type /* overloadable */)
-{
- md.xFindFunction = &find_function<typename Module::table_type>;
-}
-
-template<typename Table>
-static int rename(sqlite3_vtab* pVTab, const char * name)
-{
- BOOST_SQLITE_TRY
- {
- auto cr = static_cast<Table*>(pVTab);
-
- auto r = cr->rename(name);
- if (r.has_error())
- return extract_error(pVTab->zErrMsg, r);
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pVTab->zErrMsg);
-}
-
-template<typename Module>
-static void assign_rename(sqlite3_module & /*md*/, const Module &,
- std::false_type /* renamable */)
-{
-}
-
-template<typename Module>
-static void assign_rename(sqlite3_module & md, const Module &,
- std::true_type /* renamable */)
-{
- md.xRename = &rename<typename Module::table_type>;
-}
-#if SQLITE_VERSION_NUMBER >= 3007007
-
-template<typename Table>
-static int savepoint(sqlite3_vtab* pVTab, int i)
-{
- BOOST_SQLITE_TRY
- {
- auto cr = static_cast<Table*>(pVTab);
-
- auto r = cr->savepoint(i);
- if (r.has_error())
- return extract_error(pVTab->zErrMsg, r);
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pVTab->zErrMsg);
-}
-
-template<typename Table>
-static int release(sqlite3_vtab* pVTab, int i)
-{
- BOOST_SQLITE_TRY
- {
- auto cr = static_cast<Table*>(pVTab);
-
- auto r = cr->release(i);
- if (r.has_error())
- return extract_error(pVTab->zErrMsg, r);
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pVTab->zErrMsg);
-}
-
-template<typename Table>
-static int rollback_to(sqlite3_vtab* pVTab, int i)
-{
- BOOST_SQLITE_TRY
- {
- auto cr = static_cast<Table*>(pVTab);
-
- auto r = cr->rollback_to(i);
- if (r.has_error())
- return extract_error(pVTab->zErrMsg, r);
-
- return SQLITE_OK;
- }
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(pVTab->zErrMsg);
-}
-
-template<typename Module>
-static void assign_recursive_transaction(sqlite3_module & /*md*/, const Module &,
- std::false_type /* recursive_transaction */)
-{
-}
-
-template<typename Module>
-static void assign_recursive_transaction(sqlite3_module & md, const Module &,
- std::true_type /* recursive_transaction */)
-{
- md.xSavepoint = &savepoint <typename Module::table_type>;
- md.xRelease = &release <typename Module::table_type>;
- md.xRollbackTo = &rollback_to<typename Module::table_type>;
-}
-
-#endif
-
-#if SQLITE_VERSION_NUMBER >= 3026000
-
-template<typename Table>
-static void assign_shadow_name(sqlite3_module & /*md*/, const sqlite::vtab::module<Table> &) {}
-
-template<typename Table>
-static void assign_shadow_name(sqlite3_module & /*md*/, const sqlite::vtab::eponymous_module<Table> &) {}
-
-template<typename Module,
- bool (*Func)(const char *) = &Module::shadow_name>
-static void assign_shadow_name(sqlite3_module & md, const Module & mod)
-{
- md.xShadowName = +[](const char * name){return Func(name) != 0;};
-}
-
-#endif
-
-};
-
-template<typename Module>
-const sqlite3_module make_module(const Module & mod)
-{
- sqlite3_module md;
- std::memset(&md, 0, sizeof(sqlite3_module));
-
-#if SQLITE_VERSION_NUMBER < 3007007
- md.iVersion = 1;
-#elif SQLITE_VERSION_NUMBER < 3026000
- md.iVersion = 2;
-#else
- md.iVersion = 3;
-#endif
- using table_type = typename Module::table_type;
- using cursor_type = typename table_type::cursor_type;
- vtab_impl::assign_create(md, mod, mod);
- md.xBestIndex = &vtab_impl::best_index<table_type>;
- md.xOpen = &vtab_impl::open <table_type>;
- md.xClose = &vtab_impl::close <cursor_type>;
- md.xFilter = &vtab_impl::filter <cursor_type>;
- md.xNext = &vtab_impl::next <cursor_type>;
- md.xEof = &vtab_impl::eof <cursor_type>;
- md.xColumn = &vtab_impl::column <cursor_type>;
- md.xRowid = &vtab_impl::row_id <cursor_type>;
- vtab_impl::assign_update (md, mod, std::is_base_of<sqlite::vtab::modifiable, table_type>{});
- vtab_impl::assign_transaction (md, mod, std::is_base_of<sqlite::vtab::transaction, table_type>{});
- vtab_impl::assign_find_function(md, mod, std::is_base_of<sqlite::vtab::overload_functions, table_type>{});
- vtab_impl::assign_rename (md, mod, std::is_base_of<sqlite::vtab::renamable, table_type>{});
-#if SQLITE_VERSION_NUMBER >= 3007007
- vtab_impl::assign_recursive_transaction(md, mod, std::is_base_of<sqlite::vtab::recursive_transaction, table_type>{});
-#endif
-#if SQLITE_VERSION_NUMBER >= 3026000
- vtab_impl::assign_shadow_name(md, mod);
-#endif
- return md;
-}
-
-}
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_DETAIL_VTABLE_HPP
diff --git a/include/boost/sqlite/detail/window_function.hpp b/include/boost/sqlite/detail/window_function.hpp
deleted file mode 100644
index df8475c..0000000
--- a/include/boost/sqlite/detail/window_function.hpp
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright (c) 2023 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_IMPL_WINDOW_FUNCTION_HPP
-#define BOOST_SQLITE_IMPL_WINDOW_FUNCTION_HPP
-#if SQLITE_VERSION_NUMBER >= 3025000
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/cstring_ref.hpp>
-#include <boost/sqlite/memory.hpp>
-#include <boost/sqlite/result.hpp>
-#include <boost/sqlite/value.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-namespace detail
-{
-
-template<typename Func>
-struct window_function_maker
-{
- void * mem;
-
- template<typename ... Args>
- Func* operator()(Args && ... args)
- {
- return new (mem) Func(std::forward<Args>(args)...);
- }
-};
-
-template<typename Func, typename Args>
-int create_window_function(sqlite3 * db, cstring_ref name, Args && args, int flags,
- std::true_type /* is void */)
-{
- using args_type = callable_traits::args_t<decltype(&Func::step)>;
- using span_type = typename std::tuple_element<1U, args_type>::type;
- using func_type = typename std::decay<Func>::type;
- using func_args_type = typename std::decay<Args>::type;
-
- return sqlite3_create_window_function(
- db, name.c_str(),
- span_type::extent == boost::dynamic_extent ? -1 : static_cast<int>(span_type::extent),
- SQLITE_UTF8 | flags,
- new (memory_tag{}) func_args_type(std::forward<Args>(args)),
- +[](sqlite3_context* ctx, int len, sqlite3_value** args) noexcept //xStep
- {
- auto aa = reinterpret_cast<value*>(args);
- auto fa = reinterpret_cast<func_args_type*>(sqlite3_user_data(ctx));
- auto c = static_cast<func_type*>(sqlite3_aggregate_context(ctx, 0));
-
- execute_context_function(
- ctx,
- [&]() -> result<void>
- {
- if (c == nullptr)
- {
- auto p = sqlite3_aggregate_context(ctx, sizeof(func_type));
- if (!p)
- return error(SQLITE_NOMEM);
- c = mp11::tuple_apply(window_function_maker<func_type>{p}, *fa);
- }
- c->step(span_type{aa, static_cast<std::size_t>(len)});
- return {};
- });
-
- },
- [](sqlite3_context* ctx) // xFinal
- {
- auto fa = reinterpret_cast<func_args_type*>(sqlite3_user_data(ctx));
- auto c = static_cast<func_type*>(sqlite3_aggregate_context(ctx, 0));
-
- execute_context_function(
- ctx,
- [&]() -> result<decltype(c->value())>
- {
- if (c == nullptr)
- {
- auto p = sqlite3_aggregate_context(ctx, sizeof(func_type));
- if (!p)
- return error(SQLITE_NOMEM);
- c = mp11::tuple_apply(window_function_maker<func_type>{p}, *fa);
- }
- struct reaper {void operator()(func_type * c) { c->~func_type();}};
- std::unique_ptr<func_type, reaper> cl{c};
-
- return c->value();
- });
- },
- [](sqlite3_context* ctx) //xValue
- {
- auto fa = reinterpret_cast<func_args_type*>(sqlite3_user_data(ctx));
- auto c = static_cast<func_type*>(sqlite3_aggregate_context(ctx, 0));
- execute_context_function(
- ctx,
- [&]() -> result<decltype(c->value())>
- {
- if (c == nullptr)
- {
- auto p = sqlite3_aggregate_context(ctx, sizeof(func_type));
- if (!p)
- return error(SQLITE_NOMEM);
- c = mp11::tuple_apply(window_function_maker<func_type>{p}, *fa);
- }
- return c->value();
- });
-
- },
- +[](sqlite3_context* ctx, int len, sqlite3_value** args) // xInverse
- {
- auto aa = reinterpret_cast<value*>(args);
- auto fa = reinterpret_cast<func_args_type*>(sqlite3_user_data(ctx));
- auto c = static_cast<func_type*>(sqlite3_aggregate_context(ctx, 0));
- execute_context_function(
- ctx,
- [&]() -> result<decltype(c->inverse(span_type{aa, static_cast<std::size_t>(len)}))>
- {
- if (c == nullptr)
- {
- auto p = sqlite3_aggregate_context(ctx, sizeof(func_type));
- if (!p)
- return error(SQLITE_NOMEM);
- c = mp11::tuple_apply(window_function_maker<func_type>{p}, *fa);
- }
- c->inverse(span_type{aa, static_cast<std::size_t>(len)});
- return {};
- });
-
- },
- [](void * ptr) /* xDestroy */ { delete_(static_cast<func_type*>(ptr));}
- );
-}
-
-template<typename Func, typename Args>
-int create_window_function(sqlite3 * db, cstring_ref name, Args && args, int flags,
- std::false_type /* is void */)
-{
- using args_type = callable_traits::args_t<decltype(&Func::step)>;
- using span_type = typename std::tuple_element<1U, args_type>::type;
- using func_type = typename std::decay<Func>::type;
- using func_args_type = typename std::decay<Args>::type;
-
- return sqlite3_create_window_function(
- db, name.c_str(),
- span_type::extent == boost::dynamic_extent ? -1 : static_cast<int>(span_type::extent),
- SQLITE_UTF8 | flags,
- new (memory_tag{}) func_args_type(std::forward<Args>(args)),
- +[](sqlite3_context* ctx, int len, sqlite3_value** args) noexcept //xStep
- {
- auto aa = reinterpret_cast<value*>(args);
- auto fa = reinterpret_cast<func_args_type*>(sqlite3_user_data(ctx));
- auto c = static_cast<func_type*>(sqlite3_aggregate_context(ctx, 0));
-
- execute_context_function(
- ctx,
- [&]() -> result<decltype(c->step(span_type{aa, static_cast<std::size_t>(len)}))>
- {
- if (c == nullptr)
- {
- auto p = sqlite3_aggregate_context(ctx, sizeof(func_type));
- if (!p)
- return {system::in_place_error, error(SQLITE_NOMEM)};
- c = mp11::tuple_apply(window_function_maker<func_type>{p}, *fa);
- }
- return c->step(span_type{aa, static_cast<std::size_t>(len)});
- });
-
- },
- [](sqlite3_context* ctx) // xFinal
- {
- auto fa = reinterpret_cast<func_args_type*>(sqlite3_user_data(ctx));
- auto c = static_cast<func_type*>(sqlite3_aggregate_context(ctx, 0));
- execute_context_function(
- ctx,
- [&]() -> result<decltype(c->value())>
- {
- if (c == nullptr)
- {
- auto p = sqlite3_aggregate_context(ctx, sizeof(func_type));
- if (!p)
- return {system::in_place_error, error(SQLITE_NOMEM)};
- c = mp11::tuple_apply(window_function_maker<func_type>{p}, *fa);
- }
-
- struct reaper {void operator()(func_type * c) { c->~func_type();}};
- std::unique_ptr<func_type, reaper> cl{c};
- return c->value();
- });
- },
- [](sqlite3_context* ctx) //xValue
- {
- auto fa = reinterpret_cast<func_args_type*>(sqlite3_user_data(ctx));
- auto c = static_cast<func_type*>(sqlite3_aggregate_context(ctx, 0));
- execute_context_function(
- ctx,
- [&]() -> result<decltype(c->value())>
- {
- if (c == nullptr)
- {
- auto p = sqlite3_aggregate_context(ctx, sizeof(func_type));
- if (!p)
- return {system::in_place_error, error(SQLITE_NOMEM)};
- c = mp11::tuple_apply(window_function_maker<func_type>{p}, *fa);
- }
- return c->value();
- });
-
- },
- +[](sqlite3_context* ctx, int len, sqlite3_value** args) // xInverse
- {
- auto aa = reinterpret_cast<value*>(args);
- auto fa = reinterpret_cast<func_args_type*>(sqlite3_user_data(ctx));
- auto c = static_cast<func_type*>(sqlite3_aggregate_context(ctx, 0));
- execute_context_function(
- ctx,
- [&]() -> result<decltype(c->inverse(span_type{aa, static_cast<std::size_t>(len)}))>
- {
- if (c == nullptr)
- {
- auto p = sqlite3_aggregate_context(ctx, sizeof(func_type));
- if (!p)
- return {system::in_place_error, error(SQLITE_NOMEM)};
- c = mp11::tuple_apply(window_function_maker<func_type>{p}, *fa);
- }
- return c->inverse(span_type{aa, static_cast<std::size_t>(len)});
- });
-
- },
- [](void * ptr) /* xDestroy */ { delete_(static_cast<func_type*>(ptr));}
- );
-}
-
-
-}
-
-BOOST_SQLITE_END_NAMESPACE
-#endif // SQLITE_VERSION
-#endif //BOOST_SQLITE_IMPL_WINDOW_FUNCTION_HPP
diff --git a/include/boost/sqlite/error.hpp b/include/boost/sqlite/error.hpp
deleted file mode 100644
index 9fe6211..0000000
--- a/include/boost/sqlite/error.hpp
+++ /dev/null
@@ -1,178 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_ERROR_HPP
-#define BOOST_SQLITE_ERROR_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/cstring_ref.hpp>
-#include <boost/sqlite/memory.hpp>
-#include <boost/system/error_code.hpp>
-#include <boost/system/error_category.hpp>
-#include <boost/system/result.hpp>
-
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-BOOST_SQLITE_DECL
-system::error_category & sqlite_category();
-
-
-/**
- * \brief Additional information about error conditions stored in an sqlite-allocate string
- * \ingroup reference
- * \details Contains an error message describing what happened. Not all error
- * conditions are able to generate this extended information - those that
- * can't have an empty error message.
- */
-struct error_info
-{
- /// Default constructor.
- error_info() = default;
-
- /// Initialization constructor.
- error_info(core::string_view msg) noexcept : msg_(new (memory_tag{}) char[msg.size() + 1u])
- {
- std::memcpy(msg_.get(), msg.data(), (std::min)(msg.size() + 1, capacity()));
- }
-
- /// set the message by copy
- void set_message(core::string_view msg)
- {
- reserve(msg.size() + 1u);
- std::memcpy(msg_.get(), msg.data(), (std::min)(msg.size() + 1, capacity()));
- }
- /// transfer ownership into the message
- void reset(char * c = nullptr)
- {
- msg_.reset(c);
- }
-
- /// use sqlite_mprintf to generate a message
-#if defined(__GNUC__)
- cstring_ref format(const char * fmt, ...) __attribute__((format (printf, 2, 3)))
- {
- va_list args;
- va_start(args, fmt);
- msg_.reset(sqlite3_vmprintf(fmt, args));
- va_end(args);
- return msg_.get();
- }
-
-#endif
- cstring_ref format(cstring_ref fmt, ...)
- {
- va_list args;
- va_start(args, fmt);
- msg_.reset(sqlite3_vmprintf(fmt.c_str(), args));
- va_end(args);
- return msg_.get();
- }
-
- /// use sqlite_snprintf to generate a message
-#if defined(__GNUC__)
- cstring_ref snformat(const char * fmt, ...) __attribute__((format (printf, 2, 3)))
- {
- if (capacity() == 0)
- return "";
- va_list args;
- va_start(args, fmt);
- sqlite3_vsnprintf(static_cast<int>(capacity()), msg_.get(), fmt, args);
- va_end(args);
- return msg_.get();
- }
-
-#endif
- cstring_ref snformat(cstring_ref fmt, ...)
- {
- if (capacity() == 0)
- return "";
- va_list args;
- va_start(args, fmt);
- sqlite3_vsnprintf(static_cast<int>(capacity()), msg_.get(), fmt.c_str(), args);
- va_end(args);
- return msg_.get();
- }
- /// reserve data in the buffer i.e. allocate
- void reserve(std::size_t sz)
- {
- if (msg_)
- {
- if (sqlite3_msize(msg_.get()) < sz)
- msg_.reset(static_cast<char*>(sqlite3_realloc64(msg_.release(), sz)));
- }
- else
- msg_.reset(static_cast<char*>(sqlite3_malloc64(sz)));
- }
-
- /// Get the allocated memory
- std::size_t capacity() const {return msg_ ? sqlite3_msize(msg_.get()) : 0u;}
-
- /// Gets the error message.
- cstring_ref message() const noexcept { return msg_ ? msg_.get() : ""; }
-
- char * release()
- {
- return msg_.release();
- }
- /// Restores the object to its initial state.
- void clear() noexcept { if (msg_) *msg_ = '\0'; }
-
-
- operator bool() const {return msg_.operator bool();}
- private:
- unique_ptr<char> msg_;
-};
-
-
-/**
- * \brief An error containing both a code & optional message.
- * \ingroup reference
- * \details Contains an error .
- */
-struct error
-{
- /// The code of the error.
- int code;
- /// The additional information of the error
- error_info info;
-
- error(int code, error_info info) : code(code), info(std::move(info)) {}
- explicit error(int code) : code(code) {}
- error(int code, core::string_view info)
- : code(code),
- info(info) {}
-
- error(system::error_code code, error_info info)
- : code(code.category() == sqlite_category() ? code.value() : SQLITE_FAIL),
- info(std::move(info)) {}
-
- error(system::error_code code) : code(code.category() == sqlite_category() ? code.value() : SQLITE_FAIL)
- {
- if (code.category() == sqlite_category())
- info = error_info{code.what()};
- }
- error() = default;
- error(error && ) noexcept = default;
-};
-
-BOOST_NORETURN BOOST_SQLITE_DECL void throw_exception_from_error( error const & e, boost::source_location const & loc );
-
-template<typename T = void>
-using result = system::result<T, error>;
-
-template<typename T>
-struct is_result_type : std::false_type {};
-
-template<typename T>
-struct is_result_type<result<T>> : std::true_type {};
-
-
-BOOST_SQLITE_END_NAMESPACE
-
-
-#endif // BOOST_SQLITE_ERROR_HPP
diff --git a/include/boost/sqlite/extension.hpp b/include/boost/sqlite/extension.hpp
deleted file mode 100644
index 32553fa..0000000
--- a/include/boost/sqlite/extension.hpp
+++ /dev/null
@@ -1,67 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_EXTENSION_HPP
-#define BOOST_SQLITE_EXTENSION_HPP
-
-#define BOOST_SQLITE_COMPILE_EXTENSION 1
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/connection.hpp>
-#include <boost/sqlite/detail/catch.hpp>
-#include <boost/config.hpp>
-
-
-/** @brief Declare a sqlite module.
- @ingroup reference
-
- @param Name The name of the module
- @param Conn The parameter name of the connection
-
- This macro can be used to create an sqlite extension.
-
- @note When defining BOOST_SQLITE_COMPILE_EXTENSION (was is done in extension.hpp)
- sqlite will use an inline namespace to avoid symbol clashes.
-
- @par Examples
-
- @code{.cpp}
-
- BOOST_SQLITE_EXTENSION(extension, conn)
- {
- create_scalar_function(
- conn, "assert",
- [](boost::sqlite::context<>, boost::span<boost::sqlite::value, 1u> sp)
- {
- if (sp.front().get_int() == 0)
- throw std::logic_error("assertion failed");
- });
- }
-
- @endcode{.cpp}
-
- */
-#define BOOST_SQLITE_EXTENSION(Name, Conn) \
-void sqlite_##Name##_impl (boost::sqlite::connection Conn); \
-extern "C" BOOST_SYMBOL_EXPORT \
-int sqlite3_##Name##_init( \
- sqlite3 *db, \
- char **pzErrMsg, \
- const sqlite3_api_routines *pApi) \
-{ \
- using boost::sqlite::sqlite3_api; \
- SQLITE_EXTENSION_INIT2(pApi); \
- \
- BOOST_SQLITE_TRY \
- { \
- sqlite_##Name##_impl(boost::sqlite::connection{db, false}); \
- return SQLITE_OK; \
- } \
- BOOST_SQLITE_CATCH_ASSIGN_STR_AND_RETURN(*pzErrMsg); \
-} \
-void sqlite_##Name##_impl(boost::sqlite::connection Conn)
-
-#endif //BOOST_SQLITE_EXTENSION_HPP
diff --git a/include/boost/sqlite/field.hpp b/include/boost/sqlite/field.hpp
deleted file mode 100644
index 20fe4bd..0000000
--- a/include/boost/sqlite/field.hpp
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2022 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_FIELD_HPP
-#define BOOST_SQLITE_FIELD_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/blob.hpp>
-#include <boost/sqlite/cstring_ref.hpp>
-#include <boost/sqlite/value.hpp>
-
-#include <boost/core/detail/string_view.hpp>
-
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-/** @brief A holder for a sqlite field, i.e. something returned from a query.
- @ingroup reference
- */
-struct field
-{
- typedef sqlite_int64 int64;
-
- /// The type of the value
- value_type type() const
- {
- return static_cast<value_type>( sqlite3_column_type(stm_, col_));
- }
- /// Is the held value null
- bool is_null() const
- {
- return type() == value_type::null;
- }
- /// Is the held value is not null
- explicit operator bool () const
- {
- return type() != value_type::null;
- }
- /// Returns the value as an `int64`.
- int64 get_int() const
- {
- return sqlite3_column_int64(stm_, col_);
- }
- /// Returns the value as an `double`.
- double get_double() const
- {
- return sqlite3_column_double(stm_, col_);
- }
- /// Returns the value as text, i.e. a string_view. Note that this value may be invalidated`.
- BOOST_SQLITE_DECL
- cstring_ref get_text() const;
- /// Returns the value as blob, i.e. raw memory. Note that this value may be invalidated`.
- BOOST_SQLITE_DECL
- blob_view get_blob() const;
- /// Returns the field as a value.
- value get_value() const
- {
- return value(sqlite3_column_value(stm_, col_));
- }
- /// Returns the name of the column.
- cstring_ref column_name() const
- {
- return sqlite3_column_name(stm_, col_);
- }
- /// Returns the name of the table.
- cstring_ref table_name() const
- {
- return sqlite3_column_table_name(stm_, col_);
- }
- /// Returns the name of the original data source.
- cstring_ref column_origin_name() const
- {
- return sqlite3_column_origin_name(stm_, col_);
- }
-
- private:
- friend struct row;
- sqlite3_stmt * stm_;
- int col_ = -1;
-};
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_FIELD_HPP
diff --git a/include/boost/sqlite/function.hpp b/include/boost/sqlite/function.hpp
deleted file mode 100644
index 14060b6..0000000
--- a/include/boost/sqlite/function.hpp
+++ /dev/null
@@ -1,452 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_FUNCTION_HPP
-#define BOOST_SQLITE_FUNCTION_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/detail/aggregate_function.hpp>
-#include <boost/sqlite/detail/scalar_function.hpp>
-#include <boost/sqlite/detail/window_function.hpp>
-#include <boost/sqlite/connection.hpp>
-#include <boost/sqlite/result.hpp>
-#include <boost/sqlite/value.hpp>
-#include <boost/sqlite/detail/exception.hpp>
-#include <boost/sqlite/cstring_ref.hpp>
-
-#include <boost/core/span.hpp>
-#include <boost/callable_traits/args.hpp>
-#include <boost/callable_traits/has_void_return.hpp>
-#include <boost/callable_traits/return_type.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-enum function_flags
-{
- deterministic = SQLITE_DETERMINISTIC,
- directonly = SQLITE_DIRECTONLY,
- subtype = SQLITE_SUBTYPE,
- innocuous = SQLITE_INNOCUOUS,
- result_subtype = SQLITE_RESULT_SUBTYPE,
-#if defined(SQLITE_SELFORDER1)
- selforder1 = SQLITE_SELFORDER1,
-#else
- selforder1 = 0
-#endif
-};
-
-
-/** @brief A context that can be passed into scalar functions.
- @ingroup reference
-
- @tparam Args The argument that can be stored in the context.
-
- @code{.cpp}
- extern sqlite::connection conn;
-
- sqlite::create_scalar_function(
- conn, "my_sum",
- [](sqlite::context<std::size_t> ctx,
- boost::span<sqlite::value, 1u> args) -> std::size_t
- {
- auto value = args[0].get_int();
- auto p = ctx.get_if<0>();
- if (p != nullptr) // increment the counter
- return (*p) += value;
- else // set the initial value
- ctx.set<0>(value);
- return value;
- });
- @endcode
-
-*/
-template<typename ... Args>
-struct context
-{
- template<std::size_t N>
- using element = mp11::mp_take_c<mp11::mp_list<Args...>, N>;
-
- /// Set the value in the context at position `Idx`
- template<std::size_t Idx>
- void set(element<Idx> value)
- {
- sqlite3_set_auxdata(ctx_, Idx, *static_cast<void**>(&value),
- new (memory_tag{}) element<Idx>(std::move(value)),
- +[](void * ptr)
- {
- delete_(static_cast<element<Idx> *>(ptr));
- });
- }
-
- /// Returns the value in the context at position `Idx`. Throws if the value isn't set.
- template<std::size_t Idx>
- auto get() -> element<Idx> &
- {
- using type = element<Idx> ;
- auto p = static_cast<type*>(sqlite3_get_auxdata(ctx_, Idx));
- if (p == nullptr)
- detail::throw_invalid_argument("argument not set",
- BOOST_CURRENT_LOCATION);
- return *p;
- }
-
- /// Returns the value in the context at position `Idx`. Returns nullptr .value isn't set.
- template<std::size_t Idx>
- auto get_if() -> element<Idx> *
- {
- using type = element<Idx> ;
- return static_cast<type*>(sqlite3_get_auxdata(ctx_, Idx));
- }
-
-
- explicit context(sqlite3_context * ctx) noexcept : ctx_(ctx) {}
-
- /// Set the result through the context, instead of returning it.
- template<typename T>
- auto set_result(T && val)
-#if !defined(BOOST_SQLITE_GENERATING_DOCS)
- -> decltype(detail::set_result(static_cast<sqlite3_context*>(nullptr), std::forward<T>(val)))
-#endif
- {
- detail::set_result(ctx_, std::forward<T>(val));
- }
- /// Set the an error through the context, instead of throwing it.
- void set_error(cstring_ref message, int code = SQLITE_ERROR)
- {
- sqlite3_result_error(ctx_, message.c_str(), -1);
- sqlite3_result_error_code(ctx_, code);
- }
- /// Returns the connection of the context.
- connection get_connection() const
- {
- return connection{sqlite3_context_db_handle(ctx_), false};
- }
-
- private:
- sqlite3_context * ctx_;
-};
-
-
-///@{
-/** @brief create a scalar function
- @ingroup reference
-
- @param conn The connection to add the function to.
- @param name The name of the function
- @param func The function to be added
- @param ec The system::error_code
-
- @throws `system::system_error` when the overload without `ec` is used.
-
- `func` must take `context<Args...>` as the first and a `span<value, N>` as the second value.
- If `N` is not `dynamic_extent` it will be used to deduce the number of arguments for the function.
-
- @par Example
-
- @code{.cpp}
- extern sqlite::connection conn;
-
- sqlite::create_function(
- conn, "my_sum",
- [](sqlite::context<std::size_t> ctx,
- boost::span<sqlite::value, 1u> args) -> std::size_t
- {
- auto value = args[0].get_int();
- auto p = ctx.get_if<0>();
- if (p != nullptr) // increment the counter
- return (*p) += value;
- else // set the initial value
- ctx.set<0>(value);
- return value;
- });
- @endcode
-
- */
-template<typename Func>
-auto create_scalar_function(
- connection & conn,
- cstring_ref name,
- Func && func,
- function_flags flags,
- system::error_code & ec,
- error_info & ei)
-#if !defined(BOOST_SQLITE_GENERATING_DOCS)
- -> typename std::enable_if<
- std::is_same<
- decltype(
- detail::create_scalar_function(
- static_cast<sqlite3*>(nullptr), name,
- std::declval<Func>(), flags)
- ), int>::value>::type
-#endif
-{
- auto res = detail::create_scalar_function(conn.handle(), name,
- std::forward<Func>(func), static_cast<int>(flags));
- if (res != 0)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, res);
- ei.set_message(sqlite3_errmsg(conn.handle()));
- }
-}
-
-///@{
-/** @brief create a scalar function
- @ingroup reference
-
- @param conn The connection to add the function to.
- @param name The name of the function
- @param func The function to be added
- @param ec The system::error_code
-
- @throws `system::system_error` when the overload without `ec` is used.
-
- `func` must take `context<Args...>` as the first and a `span<value, N>` as the second value.
- If `N` is not `dynamic_extent` it will be used to deduce the number of arguments for the function.
-
- @par Example
-
- @code{.cpp}
- extern sqlite::connection conn;
-
- sqlite::create_function(
- conn, "to_upper",
- [](sqlite::context<> ctx,
- boost::span<sqlite::value, 1u> args) -> std::string
- {
- std::string res;
- auto txt = val[0].get_text();
- res.resize(txt.size());
- std::transform(txt.begin(), txt.end(), res.begin(),
- [](char c){return std::toupper(c);});
- return value;
- });
- @endcode
-
- */
-template<typename Func>
-auto create_scalar_function(
- connection & conn,
- cstring_ref name,
- Func && func,
- function_flags flags = {})
- -> typename std::enable_if<
- std::is_same<
- decltype(
- detail::create_scalar_function(
- static_cast<sqlite3*>(nullptr), name,
- std::declval<Func>(), flags)
- ), int>::value>::type
-{
- system::error_code ec;
- error_info ei;
- create_scalar_function(conn, name, std::forward<Func>(func), flags, ec, ei);
- if (ec)
- detail::throw_error_code(ec, ei);
-}
-///@}
-
-
-///@{
-/** @brief create a aggregate function
- @ingroup reference
-
- @param conn The connection to add the function to.
- @param name The name of the function
- @param args
- @param ec The system::error_code
-
-@tparam Func The function to be added
-
- @throws `system::system_error` when the overload without `ec` is used.
-
-
- `func` needs to be an object with two functions:
-
- @code{.cpp}
- void step(boost::span<sqlite::value, N> args);
- T final();
- @endcode
-
-
-
- An aggregrate function will create a new `Func` for a new `aggregate` from the args tuple and call `step` for every step.
- When the aggregation is done `final` is called and the result is returned to sqlite.
-
- @par Example
-
- @code{.cpp}
- extern sqlite::connection conn;
-
- struct aggregate_func
- {
- aggregate_func(std::size_t init) : counter(init) {}
- std::size_t counter;
- void step(, boost::span<sqlite::value, 1u> val)
- {
- counter += val[0].get_text().size();
- }
-
- std::size_t final()
- {
- return counter;
- }
- };
-
- sqlite::create_function<aggregate_func>(
- conn, "char_counter", std::make_tuple(42));
-
- @endcode
-
- */
-template<typename Func, typename Args = std::tuple<>>
-void create_aggregate_function(
- connection & conn,
- cstring_ref name,
- Args && args,
- function_flags flags,
- system::error_code & ec,
- error_info & ei)
-{
- using func_type = typename std::decay<Func>::type;
- auto res = detail::create_aggregate_function<Func>(
- conn.handle(), name, std::forward<Args>(args), static_cast<int>(flags),
- callable_traits::has_void_return<decltype(&func_type::step)>{}
- );
- if (res != 0)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, res);
- ei.set_message(sqlite3_errmsg(conn.handle()));
- }
-}
-
-template<typename Func, typename Args = std::tuple<>>
-void create_aggregate_function(
- connection & conn,
- cstring_ref name,
- Args && args= {},
- function_flags flags = {})
-{
- system::error_code ec;
- error_info ei;
- create_aggregate_function<Func>(conn, name, std::forward<Args>(args), flags, ec, ei);
- if (ec)
- detail::throw_error_code(ec, ei);
-}
-///@}
-
-#if SQLITE_VERSION_NUMBER >= 3025000
-
-///@{
-/** @brief create a aggregate window function
- @ingroup reference
-
- @param conn The connection to add the function to.
- @param name The name of the function
- @param args The arguments to construct Func from.
- @param ec The system::error_code
-
-@tparam Func The function to be added
-
- @throws `system::system_error` when the overload without `ec` is used.
-
- `func` needs to be an object with three functions:
-
- @code{.cpp}
- void step(boost::span<sqlite::value, N> args);
- void inverse(boost::span<sqlite::value, N> args);
- T final();
- @endcode
-
- `State` can be any type and will get deduced together with `N`.
- An aggregrate function will create a new `State` for a new `aggregate` and call `step` for every step.
- When an element is removed from the window `inverse` is called.
- When the aggregation is done `final` is called and the result is returned to sqlite.
-
- @par Example
-
- @code{.cpp}
- extern sqlite::connection conn;
-
- struct window_func
- {
- std::size_t counter;
- void step(boost::span<sqlite::value, 1u> val)
- {
- counter += val[0].get_text().size();
- }
- void inverse(boost::span<sqlite::value, 1u> val)
- {
- counter -= val[0].get_text().size();
- }
-
- std::size_t final()
- {
- return counter;
- }
- };
-
- sqlite::create_function(
- conn, "win_char_counter",
- aggregate_func{});
- @endcode
- */
-template<typename Func, typename Args = std::tuple<>>
-void create_window_function(
- connection & conn,
- cstring_ref name,
- Args && args,
- function_flags flags,
- system::error_code & ec)
-{
- using func_type = typename std::decay<Func>::type;
- auto res = detail::create_window_function<Func>(
- conn.handle(), name, std::forward<Args>(args), static_cast<int>(flags),
- callable_traits::has_void_return<decltype(&func_type::step)>{});
- if (res != 0)
- BOOST_SQLITE_ASSIGN_EC(ec, res);
-}
-
-template<typename Func, typename Args = std::tuple<>>
-void create_window_function(
- connection & conn,
- cstring_ref name,
- Args && args = {},
- function_flags flags = {})
-{
- system::error_code ec;
- create_window_function<Func>(conn, name, std::forward<Args>(args), flags, ec);
- if (ec)
- detail::throw_error_code(ec);
-}
-
-///@}
-
-///@{
-/// Delete function
-
-inline void delete_function(connection & conn, cstring_ref name, int argc, system::error_code &ec)
-{
- auto res = sqlite3_create_function_v2(conn.handle(), name.c_str(), argc, 0, nullptr, nullptr, nullptr, nullptr, nullptr);
- if (res != 0)
- BOOST_SQLITE_ASSIGN_EC(ec, res);
-
-}
-
-inline void delete_function(connection & conn, cstring_ref name, int argc = -1)
-{
- system::error_code ec;
- delete_function(conn, name, argc, ec);
- if (ec)
- detail::throw_error_code(ec);
-}
-
-///@}
-#endif
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_FUNCTION_HPP
diff --git a/include/boost/sqlite/hooks.hpp b/include/boost/sqlite/hooks.hpp
deleted file mode 100644
index 50cb4fc..0000000
--- a/include/boost/sqlite/hooks.hpp
+++ /dev/null
@@ -1,370 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_HOOKS_HPP
-#define BOOST_SQLITE_HOOKS_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/function.hpp>
-#include <boost/system/result.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-
-#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
-/** The context for pre-update events
-
- @note This is only available if sqlite was compiled with `SQLITE_ENABLE_PREUPDATE_HOOK` enabled.
-
- */
-struct preupdate_context
-{
- /// Returns the old value, i.e. the value before the update.
- system::result<value> old(int column) const
- {
- sqlite3_value * val;
- int res = sqlite3_preupdate_old(db_, column, &val);
- if (res != 0)
- BOOST_SQLITE_RETURN_EC(res);
- return value(val);
- }
- /// The count of colums to be updated
- int count() const { return sqlite3_preupdate_count(db_); }
- /// The nesting depth of the update.
- int depth() const { return sqlite3_preupdate_depth(db_); }
- /// The new value to be written to column
- system::result<value> new_(int column) const
- {
- sqlite3_value * val;
- int res = sqlite3_preupdate_new(db_, column, &val);
- if (res != 0)
- BOOST_SQLITE_RETURN_EC(res);
- return value(val);
- }
-
- /// @brief Query the status of blob access, e.g. when using @ref blob_handle
- /// @see https://www.sqlite.org/c3ref/preupdate_blobwrite.html
- int blob_write() const { return sqlite3_preupdate_blobwrite(db_); }
-
- explicit preupdate_context(sqlite3 * db) noexcept : db_(db) {}
- private:
- sqlite3 * db_;
-};
-
-#endif
-
-namespace detail
-{
-
-
-template<typename Func>
-bool commit_hook_impl(sqlite3 * db,
- Func * func,
- std::true_type)
-{
- static_assert(noexcept(func()), "hook must be noexcept");
- return sqlite3_commit_hook( db, func, [](void * data) { return (*static_cast<Func *>(data))() ? 1 : 0; }, nullptr) != nullptr;
-}
-
-
-template<typename Func>
-bool commit_hook_impl(sqlite3 * db,
- Func && func,
- std::false_type)
-{
- static_assert(noexcept(func()), "hook must be noexcept");
- return sqlite3_commit_hook(
- db,
- [](void * data) { return (*static_cast<Func *>(data))() ? 1 : 0; },
- &func) != nullptr;
-}
-
-inline bool commit_hook(sqlite3 * db, std::nullptr_t, std::false_type)
-{
- return sqlite3_commit_hook(db, nullptr, nullptr);
-}
-
-
-
-template<typename Func>
-bool commit_hook(sqlite3 * db,
- Func && func)
-{
- using func_type = typename std::decay<Func>::type;
- return commit_hook_impl(db, std::forward<Func>(func), std::is_pointer<func_type>{});
-}
-
-
-
-template<typename Func>
-bool rollback_hook_impl(sqlite3 * db,
- Func * func,
- std::true_type)
-{
- static_assert(noexcept(func()), "hook must be noexcept");
- return sqlite3_rollback_hook( db, func, [](void * data) { (*static_cast<Func *>(data))(); }, nullptr) != nullptr;
-}
-
-
-template<typename Func>
-bool rollback_hook_impl(sqlite3 * db,
- Func && func,
- std::false_type)
-{
- static_assert(noexcept(func()), "hook must be noexcept");
- return sqlite3_rollback_hook(
- db,
- [](void * data) { (*static_cast<Func *>(data))(); },
- &func) != nullptr;
-}
-
-inline bool rollback_hook_impl(sqlite3 * db, std::nullptr_t, std::false_type)
-{
- return sqlite3_rollback_hook(db, nullptr, nullptr);
-}
-
-template<typename Func>
-bool rollback_hook(sqlite3 * db,
- Func && func)
-{
- using func_type = typename std::decay<Func>::type;
- return rollback_hook_impl(db, std::forward<Func>(func), std::is_pointer<func_type>{});
-}
-
-#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
-
-template<typename Func>
-bool preupdate_hook_impl(sqlite3 * db,
- Func * func,
- std::true_type)
-{
- static_assert(noexcept(func(preupdate_context(nullptr), SQLITE_SELECT, "", "", 0, 0)), "hook must be noexcept");
- return sqlite3_preupdate_hook(
- db, func,
- [](void * data,
- sqlite3* db,
- int op,
- const char * db_name,
- const char * table_name,
- sqlite_int64 key1,
- sqlite_int64 key2)
- {
- (*static_cast<Func *>(data))(preupdate_context(db), op, db_name, table_name, key1, key2);
- }, nullptr) != nullptr;
-}
-
-
-template<typename Func>
-bool preupdate_hook_impl(sqlite3 * db,
- Func & func,
- std::false_type)
-{
- static_assert(noexcept(func(preupdate_context(nullptr), SQLITE_SELECT, "", "", 0, 0)),
- "hooks but be noexcept");
- using func_type = typename std::decay<Func>::type;
-
- return sqlite3_preupdate_hook(
- db,
- [](void * data,
- sqlite3* db,
- int op,
- const char * db_name,
- const char * table_name,
- sqlite_int64 key1,
- sqlite_int64 key2)
- {
- (*static_cast<Func *>(data))(preupdate_context(db), op, db_name, table_name, key1, key2);
- }, &func) != nullptr;
-}
-
-inline bool preupdate_hook_impl(sqlite3 * db, std::nullptr_t, std::false_type)
-{
- return sqlite3_preupdate_hook(db, nullptr, nullptr);
-}
-
-template<typename Func>
-bool preupdate_hook(sqlite3 * db,
- Func && func)
-{
- using func_type = typename std::decay<Func>::type;
- return preupdate_hook_impl(db, std::forward<Func>(func), std::is_pointer<func_type>{});
-}
-
-#endif
-
-template<typename Func>
-bool update_hook_impl(sqlite3 * db,
- Func * func,
- std::true_type)
-{
- static_assert(noexcept(func(SQLITE_SELECT, "", "", 0)), "hook must be noexcept");
- return sqlite3_update_hook(
- db, func,
- [](void * data,
- sqlite3*,
- int op,
- const char * db,
- const char * name,
- sqlite_int64 key)
- {
- (*static_cast<Func *>(data))(op, db, name, key);
- }, nullptr) != nullptr;
-}
-
-
-template<typename Func>
-bool update_hook_impl(sqlite3 * db,
- Func & func,
- std::false_type)
-{
- static_assert(noexcept(func(SQLITE_SELECT, "", "", 0)), "hook must be noexcept");
- using func_type = typename std::decay<Func>::type;
-
- return sqlite3_update_hook(
- db,
- [](void * data,
- int op,
- const char * db,
- const char * name,
- sqlite_int64 key)
- {
- (*static_cast<func_type*>(data))(op, db, name, key);
- }, &func) != nullptr;
-}
-
-inline
-bool update_hook_impl(sqlite3 * db,
- std::nullptr_t,
- std::false_type)
-{
- return sqlite3_update_hook(db, nullptr, nullptr);
-}
-
-template<typename Func>
-bool update_hook(sqlite3 * db,
- Func && func)
-{
- using func_type = typename std::decay<Func>::type;
- return update_hook_impl(db, std::forward<Func>(func), std::is_pointer<func_type>{});
-}
-
-
-}
-
-/**
- @brief Install a commit hook
- @ingroup reference
-
- @see [related sqlite documentation](https://www.sqlite.org/c3ref/commit_hook.html)
-
- The commit hook gets called before a commit gets performed.
- If `func` returns true, the commit goes, otherwise it gets rolled back.
-
- @note If the function is not a free function pointer, this function will *NOT* take ownership.
-
- @note If `func` is a `nullptr` the hook gets reset.
-
- @param conn The database connection to install the hook in
- @param func The hook function
- @return true if an hook has been replaced.
- */
-template<typename Func>
-bool commit_hook(connection & conn, Func && func)
-{
- return detail::commit_hook(conn.handle(), std::forward<Func>(func));
-}
-
-/**
- @brief Install a rollback hook
- @ingroup reference
-
- @see [related sqlite documentation](https://www.sqlite.org/c3ref/commit_hook.html)
-
- The rollback hook gets called when a rollback gets performed.
-
- @note If the function is not a free function pointer, this function will *NOT* take ownership.
-
- @note If `func` is a `nullptr` the hook gets reset.
-
- @param conn The database connection to install the hook in
- @param func The hook function
- @return true if an hook has been replaced.
- */
-template<typename Func>
-bool rollback_hook(connection & conn, Func && func)
-{
- return detail::rollback_hook(conn.handle(), std::forward<Func>(func));
-}
-
-#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
-/** A hook for pre-update events.
-
- @note This is only available if sqlite was compiled with `SQLITE_ENABLE_PREUPDATE_HOOK` enabled.
- @ingroup reference
-
- @see [related sqlite documentation](https://sqlite.org/c3ref/preupdate_count.html)
-
- The function will get called
-
- @note If the function is not a free function pointer, this function will *NOT* take ownership.
-
- @note If `func` is a `nullptr` the hook gets reset.
-
- @param conn The database connection to install the hook in
- @param func The hook function
- @return true if an hook has been replaced.
-
- The signature of the handler is as following (it must noexcept):
-
- @code{.cpp}
- void preupdate_hook(sqlite::preupdate_context ctx,
- int op,
- const char * db_name,
- const char * table_name,
- sqlite3_int64 current_key,
- sqlite3_int64 new_key);
- @endcode
-
-
-
-*/
-template<typename Func>
-bool preupdate_hook(connection & conn, Func && func)
-{
- return detail::preupdate_hook(conn.handle(), std::forward<Func>(func));
-}
-
-#endif
-
-/**
- @brief Install an update hook
- @ingroup reference
-
- @see [related sqlite documentation](https://www.sqlite.org/c3ref/update_hook.html)
-
- The update hook gets called when an update was performed.
-
- @note If the function is not a free function pointer, this function will *NOT* take ownership.
-
- The signature of the function is `void(int op, core::string_view db, core::string_view table, sqlite3_int64 id)`.
- `op` is either `SQLITE_INSERT`, `SQLITE_DELETE` and `SQLITE_UPDATE`.
-
- @note If `func` is a `nullptr` the hook gets reset.
-
- @param conn The database connection to install the hook in
- @param func The hook function
- @return true if an hook has been replaced.
- */
-template<typename Func>
-bool update_hook(connection & conn, Func && func)
-{
- return detail::update_hook(conn.handle(), std::forward<Func>(func));
-}
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_HOOKS_HPP
diff --git a/include/boost/sqlite/json.hpp b/include/boost/sqlite/json.hpp
deleted file mode 100644
index 3409e56..0000000
--- a/include/boost/sqlite/json.hpp
+++ /dev/null
@@ -1,140 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_JSON_HPP
-#define BOOST_SQLITE_JSON_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/field.hpp>
-#include <boost/sqlite/resultset.hpp>
-#include <boost/sqlite/value.hpp>
-#include <boost/json/parse.hpp>
-#include <boost/json/serializer.hpp>
-#include <boost/json/storage_ptr.hpp>
-#include <boost/json/value_from.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-struct resultset;
-struct field;
-struct value;
-
-/// @brief The subtype value used by the sqlite json extension. See the [sqlite reference](https://www.sqlite.org/json1.html)
-constexpr int json_subtype = static_cast<int>('J');
-
-inline void tag_invoke(const struct set_result_tag &, sqlite3_context * ctx, const json::value & value)
-{
- json::serializer ser;
- ser.reset(&value);
-
- sqlite3_int64 len = 4096;
- unique_ptr<char> c{static_cast<char*>(sqlite3_malloc64(len))};
-
- len = sqlite3_msize(c.get());
- auto v = ser.read(c.get(), len);
-
- while (!ser.done())
- {
- auto l = v.size();
- len *= 2;
- c.reset(static_cast<char*>(sqlite3_realloc(c.release(), len)));
- v = ser.read(c.get() + l, len);
- }
-
- sqlite3_result_text(ctx, c.release(), v.size(), sqlite3_free);
- sqlite3_result_subtype(ctx, json_subtype);
-}
-
-///@{
-/// @brief Check if the value or field is a json. @ingroup reference
-inline bool is_json(const value & v) { return v.type() == value_type::text && v.subtype() == json_subtype; }
-inline bool is_json(const field & f) { return f.type() == value_type::text && f.get_value().subtype() == json_subtype; }
-///@}
-
-///@{
-/// @brief Convert the value or field to a json. @ingroup reference
-inline json::value as_json(const value & v, json::storage_ptr ptr = {})
-{
- return json::parse(v.get_text(), ptr);
-}
-inline json::value as_json(const field & f, json::storage_ptr ptr = {})
-{
- return json::parse(f.get_text(), ptr);
-}
-///@}
-
-
-inline void tag_invoke( const json::value_from_tag &, json::value& val, const value & f)
-{
- switch (f.type())
- {
- case value_type::integer:
- val.emplace_int64() = f.get_int();
- break;
- case value_type::floating:
- val.emplace_double() = f.get_double();
- break;
- case value_type::text:
- {
- auto txt = f.get_text();
- if (f.subtype() == json_subtype)
- val = json::parse(txt, val.storage());
- else
- val.emplace_string() = txt;
- }
- break;
- case value_type::blob:
- throw_exception(std::invalid_argument("cannot convert blob to json"));
- case value_type::null:
- default:
- val.emplace_null();
- }
-}
-
-inline void tag_invoke( const json::value_from_tag &, json::value& val, const field & f)
-{
- switch (f.type())
- {
- case value_type::integer:
- val.emplace_int64() = f.get_int();
- break;
- case value_type::floating:
- val.emplace_double() = f.get_double();
- break;
- case value_type::text:
- {
- auto txt = f.get_text();
- if (f.get_value().subtype() == json_subtype)
- val = json::parse(txt, val.storage());
- else
- val.emplace_string() = txt;
- }
- break;
- case value_type::blob:
- throw_exception(std::invalid_argument("cannot convert blob to json"));
- case value_type::null:
- default:
- val.emplace_null();
- }
-}
-
-inline void tag_invoke( const json::value_from_tag &, json::value& val, resultset && rs)
-{
- auto & obj = val.emplace_array();
-
- for (auto r : rs)
- {
- auto & row = obj.emplace_back(json::object(obj.storage())).get_object();
- for (auto c : r)
- row[c.column_name()] = json::value_from(c, row.storage());
- }
-}
-
-BOOST_SQLITE_END_NAMESPACE
-
-
-#endif //BOOST_SQLITE_JSON_HPP
diff --git a/include/boost/sqlite/memory.hpp b/include/boost/sqlite/memory.hpp
deleted file mode 100644
index e136a0e..0000000
--- a/include/boost/sqlite/memory.hpp
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2023 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_MEMORY_HPP
-#define BOOST_SQLITE_MEMORY_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-
-#include <memory>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-/// A tag to allow `operator new`
-/// @ingroup reference
-struct memory_tag {};
-BOOST_SQLITE_END_NAMESPACE
-
-
-inline void *operator new ( std::size_t size, boost::sqlite::memory_tag) noexcept
-{
- using namespace boost::sqlite;
- return sqlite3_malloc64(size);
-}
-inline void *operator new[]( std::size_t size, boost::sqlite::memory_tag) noexcept
-{
- using namespace boost::sqlite;
- return sqlite3_malloc64(size);
-}
-
-inline void operator delete ( void* ptr, boost::sqlite::memory_tag) noexcept
-{
- using namespace boost::sqlite;
- return sqlite3_free(ptr);
-}
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-template<typename T>
-void delete_(T * t)
-{
- struct scoped_free
- {
- void * p;
- ~scoped_free()
- {
- sqlite3_free(p);
- }
- };
- scoped_free _{t};
- t->~T();
-}
-
-namespace detail
-{
-
-template<typename T>
-struct deleter
-{
- void operator()(T* t)
- {
- delete_(t);
- }
-};
-
-template<typename T>
-struct deleter<T[]>
-{
- static_assert(std::is_trivially_destructible<T>::value, "T[] needs to be trivially destructible");
- void operator()(T* t)
- {
- sqlite3_free(t);
- }
-};
-
-template<>
-struct deleter<void>
-{
- void operator()(void* t)
- {
- sqlite3_free(t);
- }
-};
-}
-
-template<typename T>
-using unique_ptr = std::unique_ptr<T, detail::deleter<T>>;
-
-template<typename T>
-inline std::size_t msize(const unique_ptr<T> & ptr)
-{
- return sqlite3_msize(ptr.get());
-}
-
-template<typename T, typename ... Args>
-unique_ptr<T> make_unique(Args && ... args)
-{
- unique_ptr<void> up{sqlite3_malloc64(sizeof(T))};
- unique_ptr<T> res{new (up.get()) T(std::forward<Args>(args)...)};
- up.release();
- return res;
-}
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_MEMORY_HPP
diff --git a/include/boost/sqlite/meta_data.hpp b/include/boost/sqlite/meta_data.hpp
deleted file mode 100644
index 00f6527..0000000
--- a/include/boost/sqlite/meta_data.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_META_DATA_HPP
-#define BOOST_SQLITE_META_DATA_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/connection.hpp>
-#include <boost/sqlite/cstring_ref.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-
-struct connection ;
-
-/// The metadata of a column
-struct column_meta_data
-{
- /// Data type fo the column
- cstring_ref data_type;
- /// Name of default collation sequence
- cstring_ref collation;
- /// true if column has a NOT NULL constraint
- bool not_null;
- /// true if column is part of the PRIMARY KEY
- bool primary_key;
- /// true if column is AUTOINCREMENT
- bool auto_increment;
-};
-
-///@{
-/// get the meta-data of one colum
-BOOST_SQLITE_DECL
-column_meta_data table_column_meta_data(connection & conn,
- cstring_ref db_name, cstring_ref table_name, cstring_ref column_name,
- system::error_code & ec, error_info &ei);
-BOOST_SQLITE_DECL
-column_meta_data table_column_meta_data(connection & conn,
- cstring_ref table_name, cstring_ref column_name,
- system::error_code & ec, error_info &ei);
-
-BOOST_SQLITE_DECL
-column_meta_data table_column_meta_data(connection & conn,
- cstring_ref db_name, cstring_ref table_name, cstring_ref column_name);
-BOOST_SQLITE_DECL
-column_meta_data table_column_meta_data(connection & conn,
- cstring_ref table_name, cstring_ref column_name);
-///@}
-
-///
-BOOST_SQLITE_END_NAMESPACE
-
-
-#endif //BOOST_SQLITE_META_DATA_HPP
diff --git a/include/boost/sqlite/mutex.hpp b/include/boost/sqlite/mutex.hpp
deleted file mode 100644
index 63caf0e..0000000
--- a/include/boost/sqlite/mutex.hpp
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_MUTEX_HPP
-#define BOOST_SQLITE_MUTEX_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <memory>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-/// A mutex class that maybe a noop depending on the mode sqlite3 was compiled as.
-struct mutex
-{
- bool try_lock()
- {
- if (!impl_)
- return false;
- return sqlite3_mutex_try(impl_.get()) == SQLITE_OK;
- }
- void lock() { sqlite3_mutex_enter(impl_.get()); }
- void unlock() { sqlite3_mutex_leave(impl_.get()); }
-
- mutex() : impl_(sqlite3_mutex_alloc(SQLITE_MUTEX_FAST)) {}
- mutex(mutex && ) = delete;
- private:
- struct deleter_ {void operator()(sqlite3_mutex *mtx) {sqlite3_mutex_free(mtx);}};
- std::unique_ptr<sqlite3_mutex, deleter_> impl_;
-};
-
-/// A recursive mutex class that maybe a noop depending on the mode sqlite3 was compiled as.
-struct recursive_mutex
-{
- bool try_lock()
- {
- if (!impl_)
- return false;
- return sqlite3_mutex_try(impl_.get()) == SQLITE_OK;
- }
- void lock() { sqlite3_mutex_enter(impl_.get()); }
- void unlock() { sqlite3_mutex_leave(impl_.get()); }
-
- recursive_mutex() : impl_(sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE)) {}
- recursive_mutex(recursive_mutex && ) = delete;
- private:
- struct deleter_ {void operator()(sqlite3_mutex *mtx) {sqlite3_mutex_free(mtx);}};
- std::unique_ptr<sqlite3_mutex, deleter_> impl_;
-};
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_MUTEX_HPP
diff --git a/include/boost/sqlite/result.hpp b/include/boost/sqlite/result.hpp
deleted file mode 100644
index b609eb4..0000000
--- a/include/boost/sqlite/result.hpp
+++ /dev/null
@@ -1,147 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_RESULT_HPP
-#define BOOST_SQLITE_RESULT_HPP
-
-#include <boost/sqlite/blob.hpp>
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/value.hpp>
-
-#include <boost/variant2/variant.hpp>
-
-#include <type_traits>
-
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-
-struct set_result_tag {};
-
-
-inline void tag_invoke(set_result_tag, sqlite3_context * ctx, blob b)
-{
- auto sz = b.size();
- sqlite3_result_blob(ctx, std::move(b).release(), sz, &operator delete);
-}
-
-
-inline void tag_invoke(set_result_tag, sqlite3_context * ctx, zero_blob zb)
-{
- sqlite3_result_zeroblob64(ctx, static_cast<sqlite3_uint64>(zb));
-}
-
-inline void tag_invoke(set_result_tag, sqlite3_context * ctx, double dbl) { sqlite3_result_double(ctx, dbl); }
-
-inline void tag_invoke(set_result_tag, sqlite3_context * ctx, sqlite3_int64 value)
-{
- sqlite3_result_int64(ctx, static_cast<sqlite3_int64>(value));
-}
-
-template<typename = std::enable_if_t<!std::is_same<std::int64_t, sqlite3_int64>::value>>
-inline void tag_invoke(set_result_tag, sqlite3_context * ctx, std::int64_t value)
-
-{
- sqlite3_result_int64(ctx, static_cast<sqlite3_int64>(value));
-}
-
-inline void tag_invoke(set_result_tag, sqlite3_context * ctx, std::nullptr_t) { sqlite3_result_null(ctx); }
-inline void tag_invoke(set_result_tag, sqlite3_context * ctx, string_view str)
-{
- sqlite3_result_text(ctx, str.data(), str.size(), SQLITE_TRANSIENT);
-}
-template<typename String>
-inline auto tag_invoke(set_result_tag, sqlite3_context * ctx, String && str)
- -> typename std::enable_if<std::is_convertible<String, string_view>::value>::type
-{
- return tag_invoke(set_result_tag{}, ctx, string_view(str));
-}
-
-
-inline void tag_invoke(set_result_tag, sqlite3_context * , variant2::monostate) { }
-inline void tag_invoke(set_result_tag, sqlite3_context * ctx, const value & val)
-{
- sqlite3_result_value(ctx, val.handle());
-}
-
-struct set_variant_result
-{
- sqlite3_context * ctx;
- template<typename T>
- void operator()(T && val)
- {
- tag_invoke(set_result_tag{}, ctx, std::forward<T>(val));
- }
-};
-
-template<typename ... Args>
-inline void tag_invoke(set_result_tag, sqlite3_context * ctx, const variant2::variant<Args...> & var)
-{
- visit(set_variant_result{ctx}, var);
-}
-
-template<typename T>
-inline void tag_invoke(set_result_tag, sqlite3_context * ctx, std::unique_ptr<T> ptr)
-{
- sqlite3_result_pointer(ctx, ptr.release(), typeid(T).name(), +[](void * ptr){delete static_cast<T*>(ptr);});
-}
-
-template<typename T>
-inline void tag_invoke(set_result_tag, sqlite3_context * ctx, std::unique_ptr<T, void(*)(T*)> ptr)
-{
- sqlite3_result_pointer(ctx, ptr.release(), typeid(T).name(), static_cast<void(*)(void*)>(ptr.get_deleter()));
-}
-
-template<typename T, typename Deleter>
-inline auto tag_invoke(set_result_tag, sqlite3_context * ctx, std::unique_ptr<T, Deleter> ptr)
- -> typename std::enable_if<std::is_empty<Deleter>::value &&
- std::is_default_constructible<Deleter>::value>::type
-{
- sqlite3_result_pointer(ctx, ptr.release(), typeid(T).name(), +[](void * ptr){Deleter()(static_cast<T*>(ptr));});
-}
-
-inline void tag_invoke(set_result_tag, sqlite3_context * ctx, error err)
-{
- if (err.info)
- sqlite3_result_error(ctx, err.info.message().c_str(), -1);
- sqlite3_result_error_code(ctx, err.code);
-}
-
-
-template<typename T>
-inline void tag_invoke(set_result_tag tag, sqlite3_context * ctx, result<T> res)
-{
- if (res.has_value())
- tag_invoke(tag, ctx, std::move(res).value());
- else
- tag_invoke(tag, ctx, std::move(res).error());
-}
-
-inline void tag_invoke(set_result_tag tag, sqlite3_context * ctx, result<void> res)
-{
- if (res.has_error())
- tag_invoke(tag, ctx, std::move(res).error());
-}
-
-
-namespace detail
-{
-
-template<typename Value>
-inline auto set_result(sqlite3_context * ctx, Value && value)
- -> decltype(tag_invoke(set_result_tag{}, ctx, std::forward<Value>(value)))
-{
- tag_invoke(set_result_tag{}, ctx, std::forward<Value>(value));
-}
-
-
-}
-
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_RESULT_HPP
diff --git a/include/boost/sqlite/resultset.hpp b/include/boost/sqlite/resultset.hpp
deleted file mode 100644
index 7c514f0..0000000
--- a/include/boost/sqlite/resultset.hpp
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright (c) 2022 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_RESULTSET_HPP
-#define BOOST_SQLITE_RESULTSET_HPP
-
-#include <memory>
-#include <boost/sqlite/row.hpp>
-#include <boost/describe/members.hpp>
-
-#include <boost/system/result.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-struct connection ;
-/**
- @brief Representation of a result from a database.
- @ingroup reference
-
- If is a forward-range with output iterators.
-
- @par Example
-
- @code{.cpp}
-
- extern sqlite::connection conn;
-
- sqlite::resultset rs = conn.query("select * from users;");
-
- do
- {
- handle_row(r.current());
- }
- while (rs.read_next()) // read it line by line
-
-
- @endcode
-
-*/
-struct resultset
-{
- /// Returns the current row.
- row current() const &
- {
- row r;
- r.stm_ = impl_.get();
- return r;
- }
- /// Checks if the last row has been reached.
- bool done() const {return done_;}
-
- ///@{
- /// Read the next row. Returns false if there's nothing more to read.
- BOOST_SQLITE_DECL bool read_next(system::error_code & ec, error_info & ei);
- BOOST_SQLITE_DECL bool read_next();
- ///@}
-
- ///
- std::size_t column_count() const
- {
- return sqlite3_column_count(impl_.get());
- }
- /// Returns the name of the column idx.
- cstring_ref column_name(std::size_t idx) const
- {
- return sqlite3_column_name(impl_.get(), static_cast<int>(idx));
- }
- /// Returns the name of the source table for column idx.
- cstring_ref table_name(std::size_t idx) const
- {
- return sqlite3_column_table_name(impl_.get(), static_cast<int>(idx));
- }
- /// Returns the origin name of the column for column idx.
- cstring_ref column_origin_name(std::size_t idx) const
- {
- return sqlite3_column_origin_name(impl_.get(), static_cast<int>(idx));
- }
-
- /// The input iterator can be used to read every row in a for-loop
- struct iterator
- {
- using value_type = value;
- using difference_type = int;
- using reference = value&;
- using iterator_category = std::forward_iterator_tag;
-
- iterator() {}
- explicit iterator(sqlite3_stmt * stmt, bool sentinel) : sentinel_(sentinel )
- {
- row_.stm_ = stmt;
- }
-
- bool operator!=(iterator rhs) const
- {
- return sentinel_ != rhs.sentinel_;
- }
-
- row &operator*() { return row_; }
- row *operator->() { return &row_; }
-
- BOOST_SQLITE_DECL
- iterator operator++();
-
- iterator operator++(int)
- {
- auto l = *this;
- ++(*this);
- return l;
- }
-
- private:
- row row_;
- bool sentinel_ = true;
- };
-
- /// Return an input iterator to the currently unread row
- iterator begin() { return iterator(impl_.get(), done_);}
- /// Sentinel iterator.
- iterator end() { return iterator(impl_.get(), true); }
-
- private:
- friend struct connection;
- friend struct statement;
-
- struct deleter_
- {
- constexpr deleter_() noexcept {}
- bool delete_ = true;
- void operator()(sqlite3_stmt * sm)
- {
- if (sqlite3_data_count(sm) > 0)
- while ( sqlite3_step(sm) == SQLITE_ROW);
- if (delete_)
- sqlite3_finalize(sm);
- else
- {
- sqlite3_clear_bindings(sm);
- sqlite3_reset(sm);
- }
-
- }
- };
- std::unique_ptr<sqlite3_stmt, deleter_> impl_;
- bool done_ = false;
-};
-
-BOOST_SQLITE_END_NAMESPACE
-
-
-#endif //BOOST_SQLITE_RESULTSET_HPP
diff --git a/include/boost/sqlite/row.hpp b/include/boost/sqlite/row.hpp
deleted file mode 100644
index 6893f96..0000000
--- a/include/boost/sqlite/row.hpp
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (c) 2022 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_ROW_HPP
-#define BOOST_SQLITE_ROW_HPP
-
-#include <boost/sqlite/field.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-/** @brief Representation of a row in a database.
- @ingroup reference
-
- Is a random-access range.
-
- All values that are obtained by view are valid until the next row is read.
-
- */
-struct row
-{
- /// The size of the row
- std::size_t size() const
- {
- return sqlite3_column_count(stm_);
- }
- /// Returns the field at `idx`, @throws std::out_of_range
- BOOST_SQLITE_DECL
- field at(std::size_t idx) const;
- /// Returns the field at `idx`.
- field operator[](std::size_t idx) const
- {
- field f;
- f.stm_ = stm_;
- f.col_ = static_cast<int>(idx);
- return f;
- }
- /// Random access iterator used to iterate over the columns.
- struct const_iterator
- {
- using difference_type = int;
- using reference = field&;
- using iterator_category = std::random_access_iterator_tag;
-
- const_iterator & operator++()
- {
- f_.col_++;
- return *this;
- }
-
- const_iterator operator++(int)
- {
- auto last = *this;
- ++(*this);
- return last;
- }
-
- const_iterator & operator--()
- {
- f_.col_--;
- return *this;
- }
-
- const_iterator operator--(int)
- {
- auto last = *this;
- --(*this);
- return last;
- }
-
- field operator[](int i) const
- {
- auto f = f_;
- f.col_ += i;
- return f;
- }
-
- const_iterator operator+(int i) const
- {
- auto r = *this;
- r.f_.col_ += i;
- return r;
- }
-
- const_iterator operator-(int i) const
- {
- auto r = *this;
- r.f_.col_ -= i;
- return r;
- }
-
- const_iterator & operator+=(int i)
- {
- f_.col_ += i;
- return *this;
- }
-
- const_iterator & operator-=(int i)
- {
- f_.col_ -= i;
- return *this;
- }
-
- const field & operator*() const
- {
- return f_;
- }
-
- const field * operator->() const
- {
- return &f_;
- }
-
- bool operator==(const const_iterator& other) const
- {
- return f_.col_ == other.f_.col_
- && f_.stm_ == other.f_.stm_;
- }
-
- bool operator!=(const const_iterator& other) const
- {
- return f_.col_ != other.f_.col_
- || f_.stm_ != other.f_.stm_;
- }
-
- bool operator<(const const_iterator& other) const
- {
- return f_.col_ < other.f_.col_
- && f_.stm_ < other.f_.stm_;
- }
-
- bool operator>(const const_iterator& other) const
- {
- return f_.col_ > other.f_.col_
- && f_.stm_ > other.f_.stm_;
- }
-
- const_iterator() = default;
- private:
- friend struct row;
- field f_;
- };
- /// Returns the begin of the column-range.
- const_iterator begin() const
- {
- const_iterator ci;
- ci.f_.col_ = 0;
- ci.f_.stm_ = stm_;
- return ci;
- }
- /// Returns the end of the column-range.
- const_iterator end() const
- {
- const_iterator ci;
- ci.f_.col_ = sqlite3_column_count(stm_);
- ci.f_.stm_ = stm_;
- return ci;
- }
- private:
- friend struct resultset;
- sqlite3_stmt * stm_;
-
-};
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_ROW_HPP
diff --git a/include/boost/sqlite/statement.hpp b/include/boost/sqlite/statement.hpp
deleted file mode 100644
index b77bbe8..0000000
--- a/include/boost/sqlite/statement.hpp
+++ /dev/null
@@ -1,651 +0,0 @@
-// Copyright (c) 2022 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_STATEMENT_HPP
-#define BOOST_SQLITE_STATEMENT_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/detail/exception.hpp>
-#include <boost/sqlite/blob.hpp>
-#include <boost/sqlite/resultset.hpp>
-
-#include <boost/mp11/algorithm.hpp>
-#include <boost/core/ignore_unused.hpp>
-#include <boost/variant2/variant.hpp>
-
-
-#include <tuple>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-struct connection;
-template<typename, bool>
-struct static_resultset;
-
-/// @brief A reference to a value to temporary bind for an execute statement. Most values are captures by reference.
-/// @ingroup reference
-struct param_ref
-{
- /// Default construct a parameter, gives `null`.
- param_ref() = default;
- /// Bind null
- param_ref(variant2::monostate) : impl_{variant2::in_place_type_t<variant2::monostate>{}} {}
- /// Bind null
- param_ref(std::nullptr_t) : impl_{variant2::in_place_type_t<variant2::monostate>{}} {}
- /// Bind an integer.
- template<typename I,
- typename = typename std::enable_if<std::is_integral<I>::value>::type>
- param_ref(I value)
- {
- BOOST_IF_CONSTEXPR ((sizeof(I) == sizeof(int) && std::is_unsigned<I>::value)
- || (sizeof(I) > sizeof(int)))
- impl_.emplace<sqlite3_int64>(static_cast<sqlite3_int64>(value));
- else
- impl_.emplace<int>(static_cast<int>(value));
- }
- /// Bind a blob.
- param_ref(blob_view blob) : impl_(blob) { }
- /// Bind a string.
- param_ref(string_view text) : impl_(text) { }
-
- template<typename StringLike>
- param_ref(StringLike && text,
- typename std::enable_if<std::is_constructible<string_view, StringLike>::value>::type * = nullptr)
- : impl_(variant2::in_place_type_t<string_view>{}, text) {}
-
- template<typename BlobLike>
- param_ref(BlobLike && text,
- typename std::enable_if<
- !std::is_constructible<string_view, BlobLike>::value
- && std::is_constructible<blob_view, BlobLike>::value>::type * = nullptr)
- : impl_(variant2::in_place_type_t<blob_view>{}, text) {}
-
- /// Bind a floating point value.
- param_ref(double value) : impl_(value) { }
- /// Bind a zero_blob value, i.e. a blob that initialized by zero.
- param_ref(zero_blob zb) : impl_(zb) { }
-
-#if SQLITE_VERSION_NUMBER >= 3020000
- /// Bind pointer value to the parameter. @see https://www.sqlite.org/bindptr.html
- template<typename T>
- param_ref(std::unique_ptr<T> ptr)
- : impl_(variant2::in_place_index_t<7>{},
- std::unique_ptr<void, void(*)(void*)>(
- static_cast<void*>(ptr.release()),
- +[](void * ptr){delete static_cast<T*>(ptr);}),
- typeid(T).name())
- {
- }
-
- /// Bind pointer value with a function as deleter to the parameter. @see https://www.sqlite.org/bindptr.html
- template<typename T>
- param_ref(std::unique_ptr<T, void(*)(T*)> ptr)
- : impl_(variant2::in_place_index_t<7>{},
- std::unique_ptr<void, void(*)(void*)>(
- static_cast<void*>(ptr.release()),
- +[](void * ptr){delete static_cast<T*>(ptr);}),
- typeid(T).name())
- {
- }
-
- /// @brief Bind pointer value with a function custom deleter to the parameter.
- /// The deleter needs to be default constructible. @see https://www.sqlite.org/bindptr.html
- template<typename T, typename Deleter>
- param_ref(std::unique_ptr<T, Deleter> ptr,
- typename std::enable_if<std::is_empty<Deleter>::value &&
- std::is_default_constructible<Deleter>::value, int>::type * = nullptr)
- : impl_(variant2::in_place_index_t<7>{},
- std::unique_ptr<void, void(*)(void*)>(
- static_cast<void*>(ptr.release()),
- +[](void * ptr){delete static_cast<T*>(ptr);}),
- typeid(T).name())
- {
- }
-#endif
-
- /// Apply the param_ref to a statement.
- int apply(sqlite3_stmt * stmt, int c) const
- {
- return variant2::visit(visitor{stmt, c}, impl_);
- }
-
- private:
- struct make_visitor
- {
- template<typename T>
- auto operator()(T&& t) const -> typename std::enable_if<std::is_constructible<param_ref, T&&>::value, param_ref>::type
- {
- return param_ref(std::forward<T>(t));
- }
- };
-
- public:
- /// Construct param_ref from a variant
- template<typename T>
- param_ref(T && t,
- decltype(variant2::visit(make_visitor(), std::forward<T>(t))) * = nullptr)
- : param_ref(variant2::visit(make_visitor(), std::forward<T>(t)))
- {}
- private:
-
- struct visitor
- {
- sqlite3_stmt * stmt;
- int col;
-
- int operator()(variant2::monostate )
- {
- return sqlite3_bind_null(stmt, col);
- }
- int operator()(int i )
- {
- return sqlite3_bind_int(stmt, col, i);
- }
- int operator()(sqlite3_int64 i64 )
- {
- return sqlite3_bind_int64(stmt, col, i64);
- }
-
- int operator()(blob_view blob)
- {
- if (blob.size() > static_cast<std::size_t>(std::numeric_limits<int>::max()))
- return sqlite3_bind_blob64(stmt, col, blob.data(), blob.size(), SQLITE_STATIC);
- else
- return sqlite3_bind_blob(stmt, col, blob.data(), static_cast<int>(blob.size()), SQLITE_STATIC);
- }
-
- int operator()(string_view text)
- {
- if (text.size() > std::numeric_limits<int>::max())
- return sqlite3_bind_text64(stmt, col, text.data(), text.size(), SQLITE_STATIC, SQLITE_UTF8);
- else
- return sqlite3_bind_text(stmt, col, text.data(), static_cast<int>(text.size()), SQLITE_STATIC);
- }
- int operator()(double value)
- {
- return sqlite3_bind_double(stmt, col, value);
- }
- int operator()(zero_blob zb)
- {
- if (static_cast<std::size_t>(zb) > static_cast<std::size_t>(std::numeric_limits<int>::max()))
- return sqlite3_bind_zeroblob64(stmt, col, static_cast<sqlite3_uint64>(zb));
- else
- return sqlite3_bind_zeroblob(stmt, col, static_cast<int>(zb));
- }
-#if SQLITE_VERSION_NUMBER >= 3020000
- int operator()(std::pair<std::unique_ptr<void, void(*)(void*)>, const char*> & p)
- {
- auto d =p.first.get_deleter();
- return sqlite3_bind_pointer(stmt, col, p.first.release(), p.second, d);
- }
-#endif
- };
-
- mutable // so we can use it with
- variant2::variant<variant2::monostate, int, sqlite3_int64,
- blob_view, string_view, double, zero_blob
-#if SQLITE_VERSION_NUMBER >= 3020000
- , std::pair<std::unique_ptr<void, void(*)(void*)>, const char*>
-#endif
- > impl_;
-};
-
-
-/** @brief A statement used for a prepared-statement.
- @ingroup reference
-
- */
-struct statement
-{
- ///@{
- /** @brief execute the prepared statement once.
-
- @param params The arguments to be passed to the prepared statement. This can be a map or a vector of param_ref.
- @param ec The system::error_code used to deliver errors for the exception less overload.
- @param info The error_info used to deliver errors for the exception less overload.
- @return The resultset of the query.
-
- @code{.cpp}
- extern sqlite::connection conn;
- statement st = conn.prepare("select id from users where name = $1;");
- resultset q = std::move(st).execute(std::make_tuple("peter"));
- @endcode
-
- */
- template <typename ArgRange = std::initializer_list<param_ref>>
- resultset execute(
- ArgRange && params,
- system::error_code& ec,
- error_info& info) &&
- {
- bind_impl(std::forward<ArgRange>(params), ec, info);
- resultset rs;
- rs.impl_.reset(impl_.release());
- if (!ec)
- rs.read_next(ec, info);
- return rs;
- }
-
- template <typename ArgRange = std::initializer_list<param_ref>>
- resultset execute(ArgRange && params) &&
- {
- system::error_code ec;
- error_info ei;
- auto tmp = std::move(*this).execute(std::forward<ArgRange>(params), ec, ei);
- if (ec)
- detail::throw_error_code(ec, ei);
- return tmp;
- }
-
- resultset execute(
- std::initializer_list<std::pair<string_view, param_ref>> params,
- system::error_code& ec,
- error_info& info) &&
- {
- bind_impl(std::move(params), ec, info);
- resultset rs;
- rs.impl_.reset(impl_.release());
- if (!ec)
- rs.read_next(ec, info);
- return rs;
- }
-
- resultset execute(std::initializer_list<std::pair<string_view, param_ref>> params) &&
- {
- system::error_code ec;
- error_info ei;
- auto tmp = std::move(*this).execute(std::move(params), ec, ei);
- if (ec)
- detail::throw_error_code(ec, ei);
- return tmp;
- }
-
- template<typename T, bool Strict = false, typename ArgRange = std::initializer_list<param_ref>>
- static_resultset<T, Strict> execute(
- ArgRange && params,
- system::error_code & ec,
- error_info & ei) &&
- {
- static_resultset<T, Strict> tmp = std::move(*this).execute(std::forward<ArgRange>(params), ec, ei);
- if (ec)
- return {};
- tmp.check_columns_(ec, ei);
- if (ec)
- return {};
-
- return tmp;
- }
-
- template<typename T, bool Strict = false, typename ArgRange = std::initializer_list<param_ref>>
- static_resultset<T, Strict> execute(ArgRange && params) &&
- {
- system::error_code ec;
- error_info ei;
- auto tmp = std::move(*this).execute<T>(std::forward<ArgRange>(params), ec, ei);
- if (ec)
- throw_exception(system::system_error(ec, ei.message()));
- return tmp;
- }
-
- template<typename T, bool Strict = false>
- static_resultset<T, Strict> execute(
- std::initializer_list<std::pair<string_view, param_ref>> params,
- system::error_code & ec,
- error_info & ei) &&
- {
- static_resultset<T, Strict> tmp = std::move(*this).execute(std::move(params), ec, ei);
- if (ec)
- return {};
- tmp.check_columns_(ec, ei);
- if (ec)
- return {};
-
- return tmp;
- }
-
- template<typename T, bool Strict = false>
- static_resultset<T, Strict> execute(std::initializer_list<std::pair<string_view, param_ref>> params) &&
- {
- system::error_code ec;
- error_info ei;
- auto tmp = std::move(*this).execute<T, Strict>(std::move(params), ec, ei);
- if (ec)
- throw_exception(system::system_error(ec, ei.message()));
- return tmp;
- }
-
- ///@}
-
- ///@{
- /** @brief execute the prepared statement and reset it afterwards.
-
- @warning The handle is shared between the statement & resultset. The statemens need to be kept alive.
-
- @param params The arguments to be passed to the prepared statement. This can be a map, a vector or a stuple of param_ref.
- @param ec The system::error_code used to deliver errors for the exception less overload.
- @param info The error_info used to deliver errors for the exception less overload.
- @return The resultset of the query.
-
- @code{.cpp}
- extern sqlite::connection conn;
- statement st = conn.prepare("select id from users where name = $1;");
- resultset q = std::move(st).execute(std::make_tuple("peter"));
- @endcode
-
-
-
- */
- template <typename ArgRange = std::initializer_list<param_ref>>
- resultset execute(
- ArgRange && params,
- system::error_code& ec,
- error_info& info) &
- {
- bind_impl(std::forward<ArgRange>(params), ec, info);
- resultset rs;
- rs.impl_.get_deleter().delete_ = false;
- rs.impl_.reset(impl_.get());
- if (!ec)
- rs.read_next(ec, info);
- return rs;
- }
-
-
- template <typename ArgRange = std::initializer_list<param_ref>>
- resultset execute(ArgRange && params) &
- {
- system::error_code ec;
- error_info ei;
- auto tmp = execute(std::forward<ArgRange>(params), ec, ei);
- if (ec)
- detail::throw_error_code(ec, ei);
- return tmp;
- }
-
-
- resultset execute(
- std::initializer_list<std::pair<string_view, param_ref>> params,
- system::error_code& ec,
- error_info& info) &
- {
- bind_impl(std::move(params), ec, info);
- resultset rs;
- rs.impl_.get_deleter().delete_ = false;
- rs.impl_.reset(impl_.get());
- if (!ec)
- rs.read_next(ec, info);
- return rs;
- }
-
- resultset execute(std::initializer_list<std::pair<string_view, param_ref>> params) &
- {
- system::error_code ec;
- error_info ei;
- auto tmp = execute(std::move(params), ec, ei);
- if (ec)
- detail::throw_error_code(ec, ei);
- return tmp;
- }
-
- template<typename T, bool Strict = false, typename ArgRange = std::initializer_list<param_ref>>
- static_resultset<T, Strict> execute(
- ArgRange && params,
- system::error_code & ec,
- error_info & ei) &
- {
- static_resultset<T, Strict> tmp = execute(std::forward<ArgRange>(params), ec, ei);
- if (ec)
- return {};
- tmp.check_columns_(ec, ei);
- if (ec)
- return {};
-
- return tmp;
- }
-
- template<typename T, bool Strict = false, typename ArgRange = std::initializer_list<param_ref>>
- static_resultset<T, Strict> execute(ArgRange && params) &
- {
- system::error_code ec;
- error_info ei;
- auto tmp = execute<T, Strict>(std::forward<ArgRange>(params), ec, ei);
- if (ec)
- throw_exception(system::system_error(ec, ei.message()));
- return tmp;
- }
-
- template<typename T, bool Strict = false>
- static_resultset<T, Strict> execute(
- std::initializer_list<std::pair<string_view, param_ref>> params,
- system::error_code & ec,
- error_info & ei) &
- {
- static_resultset<T, Strict> tmp = execute(std::move(params), ec, ei);
- if (ec)
- return {};
- tmp.check_columns_(ec, ei);
- if (ec)
- return {};
-
- return tmp;
- }
-
- template<typename T, bool Strict = false>
- static_resultset<T, Strict> execute(std::initializer_list<std::pair<string_view, param_ref>> params) &
- {
- system::error_code ec;
- error_info ei;
- auto tmp = execute<T, Strict>(std::move(params), ec, ei);
- if (ec)
- throw_exception(system::system_error(ec, ei.message()));
- return tmp;
- }
-
- ///@}
-
-
- /// Returns the sql used to construct the prepared statement.
- core::string_view sql()
- {
- return sqlite3_sql(impl_.get());
- }
-
-#if SQLITE_VERSION_NUMBER >= 3014000
- /// Returns the expanded sql used to construct the prepared statement.
- core::string_view expanded_sql()
- {
- return sqlite3_expanded_sql(impl_.get());
- }
-#endif
-
- /// Returns the expanded sql used to construct the prepared statement.
-#ifdef SQLITE_ENABLE_NORMALIZE
- core::string_view normalized_sql()
- {
- return sqlite3_normalized_sql(impl_.get());
- }
-#endif
-
- /// Returns the declared type of the column
- core::string_view declared_type(int id) const
- {
- return sqlite3_column_decltype(impl_.get(), id);
- }
-
- private:
-
- template<typename ... Args>
- void bind_impl(std::tuple<Args...> && vec,
- system::error_code & ec,
- error_info & ei)
- {
- const auto sz = sqlite3_bind_parameter_count(impl_.get());
- if (sizeof...(Args) < static_cast<std::size_t>(sz))
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_ERROR);
- ei.format("To few parameters provided. Needed %d got %ld",
- sz, sizeof...(Args));
- return;
- }
-
- int i = 1, ar = SQLITE_OK;
- mp11::tuple_for_each(std::move(vec),
- [&](param_ref pr)
- {
- if (ar == SQLITE_OK)
- ar = pr.apply(impl_.get(), i++);
- });
- if (ar != SQLITE_OK)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, ar);
- ei.set_message(sqlite3_errmsg(sqlite3_db_handle(impl_.get())));
- return;
- }
- }
-
-
- template<typename ... Args>
- void bind_impl(const std::tuple<Args...> & vec,
- system::error_code & ec,
- error_info & ei)
- {
- const auto sz = sqlite3_bind_parameter_count(impl_.get());
- if (static_cast<int>(sizeof...(Args)) < sz)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_ERROR);
- ei.format("To few parameters provided. Needed %d got %ld",
- sz, sizeof...(Args));
- return;
- }
-
- int i = 1, ar = SQLITE_OK;
- mp11::tuple_for_each(std::move(vec),
- [&](param_ref pr)
- {
- if (ar == SQLITE_OK)
- ar = pr.apply(impl_.get(), i++);
- });
- if (ar != SQLITE_OK)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, ar);
- ei.set_message(sqlite3_errmsg(sqlite3_db_handle(impl_.get())));
- return;
- }
- }
-
- template<typename ParamVector>
- void bind_impl(ParamVector && vec, system::error_code & ec, error_info & ei,
- typename std::enable_if<std::is_convertible<
- typename std::decay<ParamVector>::type::value_type, param_ref>::value>::type * = nullptr)
- {
- const auto sz = sqlite3_bind_parameter_count(impl_.get());
- if (vec.size() < static_cast<std::size_t>(sz))
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_ERROR);
- ei.format("To few parameters provided. Needed %d got %ld",
- sz, vec.size());
- }
- int i = 1;
- for (const param_ref & pr : std::forward<ParamVector>(vec))
- {
- int ar = pr.apply(impl_.get(), i++);
- if (ar != SQLITE_OK)
- {
-
- BOOST_SQLITE_ASSIGN_EC(ec, ar);
- ei.set_message(sqlite3_errmsg(sqlite3_db_handle(impl_.get())));
- return;
- }
- }
- }
-
- template<typename ParamMap>
- void bind_impl(ParamMap && vec, system::error_code & ec, error_info & ei,
- typename std::enable_if<
- std::is_convertible<typename std::decay<ParamMap>::type::key_type, string_view>::value &&
- std::is_convertible<typename std::decay<ParamMap>::type::mapped_type, param_ref>::value
- >::type * = nullptr)
- {
- for (auto i = 1; i <= sqlite3_bind_parameter_count(impl_.get()); i ++)
- {
- auto c = sqlite3_bind_parameter_name(impl_.get(), i);
- if (c == nullptr)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_MISUSE);
- ei.set_message("Parameter maps require all parameters to be named.");
- return ;
- }
- auto itr = vec.find(c+1);
- if (itr == vec.end())
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_MISUSE);
- ei.format("Can't find value for key '%s'", c+1);
- return ;
- }
- int ar = SQLITE_OK;
- if (std::is_rvalue_reference<ParamMap&&>::value)
- ar = param_ref(std::move(itr->second)).apply(impl_.get(), i);
- else
- ar = param_ref(itr->second).apply(impl_.get(), i);
-
- if (ar != SQLITE_OK)
- {
-
- BOOST_SQLITE_ASSIGN_EC(ec, ar);
- ei.set_message(sqlite3_errmsg(sqlite3_db_handle(impl_.get())));
- return;
- }
- }
- }
-
- void bind_impl(std::initializer_list<std::pair<string_view, param_ref>> params,
- system::error_code & ec, error_info & ei)
- {
- for (auto i = 1; i <= sqlite3_bind_parameter_count(impl_.get()); i ++)
- {
- auto c = sqlite3_bind_parameter_name(impl_.get(), i);
- if (c == nullptr)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_MISUSE);
- ei.set_message("Parameter maps require all parameters to be named.");
- return ;
- }
-
- auto itr = std::find_if(params.begin(), params.end(),
- [&](const std::pair<string_view, param_ref> & p)
- {
- return p.first == (c+1);
- });
- if (itr == params.end())
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_MISUSE);
- ei.format("Can't find value for key '%s'", c+1);
- return ;
- }
- auto ar = itr->second.apply(impl_.get(), i);
- if (ar != SQLITE_OK)
- {
-
- BOOST_SQLITE_ASSIGN_EC(ec, ar);
- ei.set_message(sqlite3_errmsg(sqlite3_db_handle(impl_.get())));
- return;
- }
- }
- }
-
-
- friend
- struct connection;
- struct deleter_
- {
- void operator()(sqlite3_stmt * sm)
- {
- sqlite3_finalize(sm);
- }
- };
- std::unique_ptr<sqlite3_stmt, deleter_> impl_;
-};
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_STATEMENT_HPP
diff --git a/include/boost/sqlite/static_resultset.hpp b/include/boost/sqlite/static_resultset.hpp
deleted file mode 100644
index fd6c359..0000000
--- a/include/boost/sqlite/static_resultset.hpp
+++ /dev/null
@@ -1,497 +0,0 @@
-//
-// Copyright (c) 2024 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_STATIC_RESULTSET_HPP
-#define BOOST_SQLITE_STATIC_RESULTSET_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/resultset.hpp>
-#include <boost/sqlite/connection.hpp>
-
-#include <boost/describe/members.hpp>
-
-#include <array>
-#include <cstdint>
-
-#if __cplusplus >= 202002L
-#include <boost/pfr/core.hpp>
-#include <boost/pfr/core_name.hpp>
-#include <boost/pfr/traits.hpp>
-#endif
-
-
-namespace boost { template<typename> class optional;}
-
-#if __cplusplus >= 201702L
-#include <optional>
-#endif
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-namespace detail
-{
-
-inline void convert_field(sqlite_int64 & target, const field & f) {target = f.get_int();}
-
-template<typename = std::enable_if_t<!std::is_same<std::int64_t, sqlite_int64>::value>>
-inline void convert_field(std::int64_t & target, const field & f)
-{
- target = static_cast<std::int64_t>(f.get_int());
-}
-
-inline void convert_field(double & target, const field & f) {target = f.get_double();}
-
-
-template<typename Traits = std::char_traits<char>, typename Allocator = std::allocator<char>>
-inline void convert_field(std::basic_string<char, Traits, Allocator> & target, const field & f)
-{
- auto t = f.get_text();
- target.assign(t.begin(), t.end());
-}
-
-inline void convert_field(string_view & target, const field & f) {target = f.get_text();}
-inline void convert_field(blob & target, const field & f) {target = blob(f.get_blob());}
-inline void convert_field(blob_view & target, const field & f) {target = f.get_blob();}
-
-#if __cplusplus >= 201702L
-template<typename T>
-inline void convert_field(std::optional<T> & target, const field & f)
-{
- if (f.is_null())
- target.reset();
- else
- convert_field(target.emplace(), f);
-}
-#endif
-
-template<typename T>
-inline void convert_field(boost::optional<T> & target, const field & f)
-{
- if (f.is_null())
- target.reset();
- else
- return convert_field(target.emplace_back(), f);
-}
-
-template<typename T>
-inline constexpr bool field_type_is_nullable(const T& ) {return false;}
-#if __cplusplus >= 201702L
-template<typename T>
-inline bool field_type_is_nullable(const std::optional<T> &) { return true; }
-#endif
-template<typename T>
-inline bool field_type_is_nullable(const boost::optional<T> &) { return true; }
-
-inline value_type required_field_type(const sqlite3_int64 &) {return value_type::integer;}
-
-template<typename = std::enable_if_t<!std::is_same<std::int64_t, sqlite_int64>::value>>
-inline value_type required_field_type(const std::int64_t &) {return value_type::integer;}
-
-template<typename Allocator, typename Traits>
-inline value_type required_field_type(const std::basic_string<char, Allocator, Traits> & )
-{
- return value_type::text;
-}
-
-inline value_type required_field_type(const string_view &) {return value_type::text;}
-inline value_type required_field_type(const blob &) {return value_type::blob;}
-inline value_type required_field_type(const blob_view &) {return value_type::blob;}
-
-
-template<typename ... Args>
-void check_columns(const std::tuple<Args...> *, const resultset & r,
- system::error_code &ec, error_info & ei)
-{
- if (r.column_count() != sizeof...(Args))
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_MISMATCH);
- ei.format("Tuple size doesn't match column count [%ld != %ld]", sizeof...(Args), r.column_count());
- }
-}
-
-template<bool Strict, typename ... Args>
-void convert_row(std::tuple<Args...> & res, const row & r, system::error_code ec, error_info & ei)
-{
- std::size_t idx = 0u;
-
- mp11::tuple_for_each(
- res,
- [&](auto & v)
- {
- const auto i = idx++;
- const auto & f = r[i];
- BOOST_IF_CONSTEXPR (Strict)
- {
- if (!ec) // only check if we don't have an error yet.
- {
- if (f.is_null() && !field_type_is_nullable(v))
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_CONSTRAINT_NOTNULL);
- ei.format("unexpected null in column %d", i);
- }
- else if (f.type() != required_field_type(v))
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_CONSTRAINT_DATATYPE);
- ei.format("unexpected type [%s] in column %d, expected [%s]",
- value_type_name(f.type()), i, value_type_name(required_field_type(v)));
- }
- }
- }
- else
- boost::ignore_unused(ec, ei);
-
- detail::convert_field(v, f);
- });
-}
-
-#if defined(BOOST_DESCRIBE_CXX14)
-
-template<typename T, typename = typename std::enable_if<describe::has_describe_members<T>::value>::type>
-void check_columns(const T *, const resultset & r,
- system::error_code &ec, error_info & ei)
-{
- using mems = boost::describe::describe_members<T, describe::mod_public>;
- constexpr std::size_t sz = mp11::mp_size<mems>();
- if (r.column_count() != sz)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_MISMATCH);
- ei.format("Describe size doesn't match column count [%ld != %ld]", sz, r.column_count());
- }
-
- // columns can be duplicated!
- std::array<bool, sz> found;
- std::fill(found.begin(), found.end(), false);
-
- for (std::size_t i = 0ul; i < r.column_count(); i++)
- {
- bool cfound = false;
- boost::mp11::mp_for_each<mp11::mp_iota_c<sz>>(
- [&](auto sz)
- {
- auto d = mp11::mp_at_c<mems, sz>();
- if (d.name == r.column_name(i))
- {
- found[sz] = true;
- cfound = true;
- }
- });
-
- if (!cfound)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_MISMATCH);
- ei.format("Column '%s' not found in described struct.", r.column_name(i).c_str());
- break;
- }
- }
-
- if (ec)
- return;
-
-
- auto itr = std::find(found.begin(), found.end(), false);
- if (itr != found.end())
- {
- mp11::mp_with_index<sz>(
- std::distance(found.begin(), itr),
- [&](auto sz)
- {
- auto d = mp11::mp_at_c<mems, sz>();
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_MISMATCH);
- ei.format("Described field '%s' not found in resultset struct.", d.name);
- });
- }
-}
-
-template<bool Strict, typename T,
- typename = typename std::enable_if<describe::has_describe_members<T>::value>::type>
-void convert_row(T & res, const row & r, system::error_code ec, error_info & ei)
-{
- for (auto && f: r)
- {
- boost::mp11::mp_for_each<boost::describe::describe_members<T, describe::mod_public> >(
- [&](auto D)
- {
- if (D.name == f.column_name())
- {
- auto & r = res.*D.pointer;
- BOOST_IF_CONSTEXPR(Strict)
- {
- if (!ec)
- {
- if (f.is_null() && !field_type_is_nullable(r))
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_CONSTRAINT_NOTNULL);
- ei.format("unexpected null in column %s", D.name);
- }
- else if (f.type() != required_field_type(r))
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_CONSTRAINT_DATATYPE);
- ei.format("unexpected type [%s] in column %s, expected [%s]",
- value_type_name(f.type()), D.name, value_type_name(required_field_type(r)));
- }
- }
- }
-
- detail::convert_field(r, f);
- }
- });
- }
-}
-
-#endif
-
-#if __cplusplus >= 202002L
-
-template<typename T>
- requires (std::is_aggregate_v<T> && !describe::has_describe_members<T>::value)
-void check_columns(const T *, const resultset & r,
- system::error_code &ec, error_info & ei)
-{
- constexpr std::size_t sz = pfr::tuple_size_v<T>;
- if (r.column_count() != sz)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_MISMATCH);
- ei.format("Describe size doesn't match column count [%ld != %ld]", sz, r.column_count());
- }
-
- // columns can be duplicated!
- std::array<bool, sz> found;
- std::fill(found.begin(), found.end(), false);
-
- for (std::size_t i = 0ul; i < r.column_count(); i++)
- {
- bool cfound = false;
- boost::mp11::mp_for_each<mp11::mp_iota_c<sz>>(
- [&](auto sz)
- {
- if (pfr::get_name<sz, T>() == r.column_name(i))
- {
- found[sz] = true;
- cfound = true;
- }
- });
-
- if (!cfound)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_MISMATCH);
- ei.format("Column %s not found in struct.", r.column_name(i).c_str());
- break;
- }
- }
-
- if (ec)
- return;
-
-
- auto itr = std::find(found.begin(), found.end(), false);
- if (itr != found.end())
- {
- mp11::mp_with_index<sz>(
- std::distance(found.begin(), itr),
- [&](auto sz)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_MISMATCH);
- auto nm = pfr::get_name<sz, T>();
- ei.format("PFR field %.*s not found in resultset struct.", static_cast<int>(nm.size()), nm.data());
- });
- }
-}
-
-template<bool Strict, typename T>
- requires (std::is_aggregate_v<T> && !describe::has_describe_members<T>::value)
-void convert_row(T & res, const row & r, system::error_code ec, error_info & ei)
-{
- for (auto && f: r)
- {
- boost::mp11::mp_for_each<mp11::mp_iota_c<pfr::tuple_size_v<T>>>(
- [&](auto D)
- {
- if (pfr::get_name<D, T>() == f.column_name().c_str())
- {
- auto & r = pfr::get<D()>(res);
- BOOST_IF_CONSTEXPR(Strict)
- {
- if (!ec)
- {
- if (f.is_null() && !field_type_is_nullable(r))
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_CONSTRAINT_NOTNULL);
- ei.format("unexpected null in column %s", D.name);
- }
- else if (f.type() != required_field_type(r))
- {
- BOOST_SQLITE_ASSIGN_EC(ec, SQLITE_CONSTRAINT_DATATYPE);
- ei.format("unexpected type [%s] in column %s, expected [%s]",
- value_type_name(f.type()), D.name, value_type_name(required_field_type(r)));
- }
- }
- }
- detail::convert_field(r, f);
- }
- });
- }
-}
-
-#endif
-
-}
-
-/**
- @brief A typed resultset using a tuple or a described struct.
- @ingroup reference
- @tparam T The static type of the query.
- @tparam Strict Disables implicit conversions.
-
- If is a forward-range with output iterators.
-
- @par Example
-
- @code{.cpp}
-
- extern sqlite::connection conn;
- struct user { std::string first_name; std::string last_name; };
- BOOST_DESCRIBE_STRUCT(user, (), (first_name, last_name));
-
- sqlite::resultset rs = conn.query("select first_name, last_name from users;");
-
- do
- {
- user usr = r.current();
- handle_row(u);
- }
- while (rs.read_next()) // read it line by line
-
- @endcode
-
-*/
-template<typename T, bool Strict >
-struct static_resultset
-{
- /// Returns the current row.
- T current() const &
- {
- system::error_code ec;
- error_info ei;
- auto tmp = current(ec, ei);
- if (ec)
- throw_exception(system::system_error(ec, ei.message()));
- return tmp;
- }
-
- /// Returns the current row.
- T current(system::error_code & ec, error_info & ei) const &
- {
- T res;
- detail::convert_row<Strict>(res, result_.current(), ec, ei);
- return res;
- }
-
- /// Checks if the last row has been reached.
- bool done() const {return result_.done();}
-
- ///@{
- /// Read the next row. Returns false if there's nothing more to read.
- BOOST_SQLITE_DECL bool read_next(system::error_code & ec, error_info & ei) { return result_.read_next(ec, ei); }
- BOOST_SQLITE_DECL bool read_next() { return result_.read_next(); }
- ///@}
-
- ///
- std::size_t column_count() const { return result_.column_count(); }
- /// Returns the name of the column idx.
- core::string_view column_name(std::size_t idx) const { return result_.column_name(idx); }
-
- /// Returns the name of the source table for column idx.
- core::string_view table_name(std::size_t idx) const { return result_.table_name(idx);}
- /// Returns the origin name of the column for column idx.
- core::string_view column_origin_name(std::size_t idx) const { return result_.column_origin_name(idx);}
-
- static_resultset() = default;
- static_resultset(resultset && result) : result_(std::move(result)) { }
-
-
- static_resultset(static_resultset<T, false> && rhs) : result_(std::move(rhs.result_)) {}
-
- /// The input iterator can be used to read every row in a for-loop
- struct iterator
- {
- using value_type = T;
- using difference_type = int;
- using reference = T&;
- using iterator_category = std::forward_iterator_tag;
-
- iterator()
- {
-
- }
- explicit iterator(resultset::iterator itr) : itr_(itr)
- {
- system::error_code ec;
- error_info ei;
- if (itr->size() > 0ul)
- detail::convert_row<Strict>(value_, *itr, ec, ei);
- if (ec)
- throw_exception(system::system_error(ec, ei.message()));
- }
-
- bool operator!=(iterator rhs) const
- {
- return itr_ != rhs.itr_;
- }
-
- value_type &operator*() { return value_; }
- value_type *operator->() { return &value_; }
-
- iterator& operator++()
- {
- ++itr_;
-
- system::error_code ec;
- error_info ei;
- if (itr_->size() > 0ul)
- detail::convert_row<Strict>(value_, *itr_, ec, ei);
- if (ec)
- throw_exception(system::system_error(ec, ei.message()));
-
- return *this;
- }
- iterator operator++(int)
- {
- auto l = *this;
- ++(*this);
- return l;
- }
- private:
- resultset::iterator itr_;
- value_type value_;
- };
-
- /// Return an input iterator to the currently unread row
- iterator begin() { return iterator(result_.begin());}
- /// Sentinel iterator.
- iterator end() { return iterator(result_.end()); }
-
-
-
- static_resultset<T, true> strict() &&
- {
- return {std::move(result_)};
- }
- private:
-
- friend struct static_resultset<T, true>;
- friend struct connection;
- friend struct statement;
- resultset result_;
- void check_columns_( system::error_code & ec, error_info & ei)
- {
- detail::check_columns(static_cast<T*>(nullptr), result_, ec, ei);
- }
-};
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_STATIC_RESULTSET_HPP
diff --git a/include/boost/sqlite/string.hpp b/include/boost/sqlite/string.hpp
deleted file mode 100644
index 5a81978..0000000
--- a/include/boost/sqlite/string.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2023 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_STRING_HPP
-#define BOOST_SQLITE_STRING_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/cstring_ref.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-inline
-bool like(
- cstring_ref lhs,
- cstring_ref rhs,
- char escape = '\0')
-{
- return sqlite3_strlike(lhs.c_str(), rhs.c_str(), escape) != 0;
-}
-
-inline
-bool glob(
- cstring_ref lhs,
- cstring_ref rhs)
-{
- return sqlite3_strglob(lhs.c_str(), rhs.c_str()) != 0;
-}
-
-inline
-int icmp(
- cstring_ref lhs,
- cstring_ref rhs)
-{
- return sqlite3_stricmp(lhs.c_str(), rhs.c_str());
-}
-
-inline
-int icmp(
- core::string_view lhs,
- core::string_view rhs,
- std::size_t n)
-{
- return sqlite3_strnicmp(lhs.data(), rhs.data(), static_cast<int>(n));
-}
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_STRING_HPP
diff --git a/include/boost/sqlite/transaction.hpp b/include/boost/sqlite/transaction.hpp
deleted file mode 100644
index b90bdbf..0000000
--- a/include/boost/sqlite/transaction.hpp
+++ /dev/null
@@ -1,198 +0,0 @@
-//
-// Copyright (c) 2024 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_TRANSACTION_HPP
-#define BOOST_SQLITE_TRANSACTION_HPP
-
-#include <boost/sqlite/connection.hpp>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-/**
- * @brief A simple transaction guard implementing RAAI for transactions
- * @ingroup reference
- *
- * @par Example
- * @code{.cpp}
- * sqlite::connection conn;
- * conn.connect("./my-database.db");
- *
- * sqlite::transaction t{conn};
- * conn.prepare("insert into log (text) values ($1)").execute(std::make_tuple("booting up"));
- * t.commit();
- * @endcode
- */
-struct transaction
-{
- /// The mode of the transaction
- enum behaviour {deferred, immediate, exclusive};
- /// A tag to use, to adopt an already initiated transaction.
- constexpr static struct adopt_transaction_t {} adopt_transaction{};
-
-
- /// Create transaction guard on an existing transaction
- transaction(connection & conn, adopt_transaction_t) : conn_(conn), completed_(false)
- {
- }
-
-
- /// Create transaction guard and initiate a transaction
- transaction(connection & conn) : conn_(conn)
- {
- conn.execute("BEGIN");
- completed_ = false;
- }
-
- /// Create transaction guard and initiate a transaction with the defined behaviour
- transaction(connection & conn, behaviour b) : conn_(conn)
- {
- switch (b)
- {
- case deferred: conn.execute("BEGIN DEFERRED"); break;
- case immediate: conn.execute("BEGIN IMMEDIATE"); break;
- case exclusive: conn.execute("BEGIN EXCLUSIVE"); break;
- }
- completed_ = false;
- }
-
- // see https://www.sqlite.org/lang_transaction.html re noexcept
- /// rollback the transaction if not committed.
- ~transaction() noexcept(SQLITE_VERSION_NUMBER >= 3007011)
- {
- if (!completed_)
- conn_.execute("ROLLBACK");
- }
-
- ///@{
- /// Commit the transaction.
- void commit()
- {
- conn_.execute("COMMIT");
- completed_ = true;
- }
-
- void commit(system::error_code & ec, error_info & ei)
- {
- conn_.execute("COMMIT", ec, ei);
- completed_ = true;
- }
- ///@}
-
- ///@{
- /// Rollback the transaction explicitly.
- void rollback()
- {
- conn_.execute("ROLLBACK");
- completed_ = true;
- }
-
- void rollback(system::error_code & ec, error_info & ei)
- {
- conn_.execute("ROLLBACK", ec, ei);
- completed_ = true;
- }
- ///@}
-
- private:
- connection & conn_;
- bool completed_ = true;
-};
-
-/**
- * @brief A simple transaction guard implementing RAAI for savepoints. Savepoints can be used recursively.
- * @ingroup reference
- *
- * @par Example
- * @code{.cpp}
- * sqlite::connection conn;
- * conn.connect("./my-database.db");
- *
- * sqlite::savepoint t{conn, "my-savepoint};
- * conn.prepare("insert into log (text) values ($1)").execute(std::make_tuple("booting up"));
- * t.commit();
- * @endcode
-*/
-struct savepoint
-{
- /// A tag to use, to adopt an already initiated transaction.
- constexpr static transaction::adopt_transaction_t adopt_transaction{};
-
- /// Create savepoint guard on an existing savepoint
- savepoint(connection & conn, std::string name, transaction::adopt_transaction_t)
- : conn_(conn), name_(std::move(name))
- {
- }
-
- /// Create transaction guard and initiate it
- savepoint(connection & conn, std::string name) : conn_(conn), name_(std::move(name))
- {
- conn.execute("SAVEPOINT " + name_);
- completed_ = false;
- }
-
-
- /// rollback to the savepoint if not committed.
- ~savepoint() noexcept(SQLITE_VERSION_NUMBER >= 3007011)
- {
- if (!completed_)
- conn_.execute("ROLLBACK TO " + name_);
- }
-
- ///@{
- /// Commit/Release the transaction.
- void commit()
- {
- conn_.execute("RELEASE " + name_);
- completed_ = true;
- }
-
- void commit(system::error_code & ec, error_info & ei)
- {
- conn_.execute("RELEASE " + name_, ec, ei);
- completed_ = true;
- }
-
- void release()
- {
- conn_.execute("RELEASE " + name_);
- completed_ = true;
- }
-
- void release(system::error_code & ec, error_info & ei)
- {
- conn_.execute("RELEASE " + name_, ec, ei);
- completed_ = true;
- }
- ///@}
-
- ///@{
- /// Rollback the transaction explicitly.
- void rollback()
- {
- conn_.execute("ROLLBACK TO" + name_);
- completed_ = true;
- }
-
- void rollback(system::error_code & ec, error_info & ei)
- {
- conn_.execute("ROLLBACK TO " + name_, ec, ei);
- completed_ = true;
- }
- ///@}
-
- /// The name of the savepoint.
- const std::string & name() const {return name_;}
- private:
- connection & conn_;
- std::string name_;
- bool completed_ = true;
-};
-
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_TRANSACTION_HPP
diff --git a/include/boost/sqlite/value.hpp b/include/boost/sqlite/value.hpp
deleted file mode 100644
index 16dc1c1..0000000
--- a/include/boost/sqlite/value.hpp
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright (c) 2022 Klemens D. Morgenstern
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-#ifndef BOOST_SQLITE_VALUE_HPP
-#define BOOST_SQLITE_VALUE_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/blob.hpp>
-#include <boost/sqlite/cstring_ref.hpp>
-
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-
-/** @brief The type of a value
- @ingroup reference
-
- [related sqlite documentation](https://www.sqlite.org/datatype3.html)
-*/
-enum class value_type
-{
- /// An integral value
- integer = SQLITE_INTEGER,
- /// A floating piont value
- floating = SQLITE_FLOAT,
- /// A textual value
- text = SQLITE_TEXT,
- /// A binary value
- blob = SQLITE_BLOB,
- /// No value
- null = SQLITE_NULL,
-};
-
-inline
-const char * value_type_name(value_type vt)
-{
- switch (vt)
- {
- case value_type::text: return "text";
- case value_type::blob: return "blob";
- case value_type::floating: return "floating";
- case value_type::integer: return "integer";
- case value_type::null: return "null";
- default: return "unknown";
- }
-}
-
-
-/** @brief A holder for a sqlite values used for internal APIs
- @ingroup reference
-
- */
-struct value
-{
- // The value for integers in the database
- typedef sqlite3_int64 int64 ;
-
- /// The type of the value
- value_type type() const
- {
- return static_cast<value_type>(sqlite3_value_type(value_));
- }
- /// The subtype of the value, see
- int subtype() const
- {
- return sqlite3_value_subtype(value_);
- }
- /// Is the held value null
- bool is_null() const
- {
- return type() == value_type::null;
- }
- /// Is the held value is not null
- explicit operator bool () const
- {
- return type() != value_type::null;
- }
- /// Returns the value as an `integer`.
- int64 get_int() const
- {
- return sqlite3_value_int64(value_);
- }
- /// Returns the value as an `double`.
- double get_double() const
- {
- return sqlite3_value_double(value_);
- }
- /// Returns the value as text, i.e. a string_view. Note that this value may be invalidated`.
- BOOST_SQLITE_DECL
- cstring_ref get_text() const;
- /// Returns the value as blob, i.e. raw memory. Note that this value may be invalidated`.
- BOOST_SQLITE_DECL
- blob_view get_blob() const;
-
- /// Best numeric datatype of the value
- value_type numeric_type() const{return static_cast<value_type>(sqlite3_value_numeric_type(value_));}
-
-#if SQLITE_VERSION_NUMBER >= 3032000
- /// True if the column is unchanged in an UPDATE against a virtual table.
- bool nochange() const {return 0 != sqlite3_value_nochange(value_);}
-#endif
-
-#if SQLITE_VERSION_NUMBER >= 3031000
- /// True if value originated from a bound parameter
- bool from_bind() const {return 0 != sqlite3_value_frombind(value_);}
-#endif
- /// Construct value from a handle.
- explicit value(sqlite3_value * value_) noexcept : value_(value_) {}
-
- /// The handle of the value.
- using handle_type = sqlite3_value *;
- /// Returns the handle.
- handle_type handle() const {return value_;}
- handle_type & handle() {return value_;}
-
-#if SQLITE_VERSION_NUMBER >= 3020000
- /// Get a value that was passed through the pointer interface.
- /// A value can be set as a pointer by binding/returning a unique_ptr.
- template<typename T>
- T * get_pointer() {return static_cast<T*>(sqlite3_value_pointer(value_, typeid(T).name()));}
-#endif
- private:
- sqlite3_value * value_ = nullptr;
-};
-
-static_assert(sizeof(value) == sizeof(sqlite3_value*), "value must be same as sqlite3_value* pointer");
-
-BOOST_SQLITE_END_NAMESPACE
-
-#endif //BOOST_SQLITE_VALUE_HPP
diff --git a/include/boost/sqlite/vtable.hpp b/include/boost/sqlite/vtable.hpp
deleted file mode 100644
index a984f4d..0000000
--- a/include/boost/sqlite/vtable.hpp
+++ /dev/null
@@ -1,615 +0,0 @@
-//
-// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_SQLITE_VTABLE_HPP
-#define BOOST_SQLITE_VTABLE_HPP
-
-#include <boost/sqlite/detail/config.hpp>
-#include <boost/sqlite/detail/catch.hpp>
-#include <boost/sqlite/function.hpp>
-
-#include <boost/core/span.hpp>
-#include <boost/core/demangle.hpp>
-
-#include <bitset>
-
-BOOST_SQLITE_BEGIN_NAMESPACE
-namespace detail
-{
-struct vtab_impl;
-}
-
-
-namespace vtab
-{
-
-/// Helper type to set a function through the xFindFunction callback
-struct function_setter
-{
- /** Set the function
- *
- * @tparam Func The function type (either a lambda by ref or a pointer by copy)
- * @param func The function to be used
- *
- * The function can either take a single argument, a `span<sqlite::value, N>`
- * for scalar functions,
- * or a `context<Args...>` as first, and the span as second for aggegrate functions.
- *
- */
- template<typename Func>
- void set(Func & func)
- {
- set_impl(func, static_cast<callable_traits::args_t<Func>*>(nullptr));
- }
-
- template<typename ... Args, std::size_t Extent>
- void set(void(* ptr)(context<Args...>, span<value, Extent>)) noexcept
- {
- *ppArg_ = reinterpret_cast<void*>(ptr);
- *pxFunc_ =
- +[](sqlite3_context* ctx, int len, sqlite3_value** args)
- {
- auto cc = context<Args...>(ctx);
- auto aa = reinterpret_cast<value*>(args);
- auto &f = *reinterpret_cast<void(*)(context<Args...>, span<value, Extent>)>(sqlite3_user_data(ctx));
- detail::execute_context_function(ctx, f, cc, boost::span<value, Extent>{aa, static_cast<std::size_t>(len)});
- };
- }
-
- template<typename T, typename ... Args, std::size_t Extent>
- void set(T(* ptr)(context<Args...>, span<value, Extent>))
- {
- *ppArg_ = reinterpret_cast<void*>(ptr);
- *pxFunc_ =
- +[](sqlite3_context* ctx, int len, sqlite3_value** args) noexcept
- {
- auto cc = context<Args...>(ctx);
- auto aa = reinterpret_cast<value*>(args);
- auto &f = *reinterpret_cast<T(*)(context<Args...>, span<value, Extent>)>(sqlite3_user_data(ctx));
- detail::execute_context_function(ctx, f, cc, boost::span<value, Extent>{aa, static_cast<std::size_t>(len)});
- };
- }
-
- template<std::size_t Extent>
- void set(void(* ptr)(span<value, Extent>))
- {
- *ppArg_ = reinterpret_cast<void*>(ptr);
- *pxFunc_ =
- +[](sqlite3_context* ctx, int len, sqlite3_value** args) noexcept
- {
- auto aa = reinterpret_cast<value*>(args);
- auto &f = *reinterpret_cast<void(*)(span<value, Extent>)>(sqlite3_user_data(ctx));
- detail::execute_context_function(ctx, f, boost::span<value, Extent>{aa, static_cast<std::size_t>(len)});
- };
- }
-
- template<typename T, std::size_t Extent>
- void set(T(* ptr)(span<value, Extent>))
- {
- *ppArg_ = reinterpret_cast<void*>(ptr);
- *pxFunc_ =
- +[](sqlite3_context* ctx, int len, sqlite3_value** args) noexcept
- {
- auto aa = reinterpret_cast<value*>(args);
- auto &f = *reinterpret_cast<T(*)(span<value, Extent>)>(sqlite3_user_data(ctx));
- detail::execute_context_function(ctx, f, boost::span<value, Extent>{aa, static_cast<std::size_t>(len)});
- };
- }
-
- explicit function_setter(void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
- void **ppArg) : pxFunc_(pxFunc), ppArg_(ppArg) {}
- private:
-
- template<typename Func, typename ... Args, std::size_t Extent>
- void set_impl(Func & func, std::tuple<context<Args...>, span<value, Extent>>)
- {
- *ppArg_ = &func;
- *pxFunc_ =
- +[](sqlite3_context* ctx, int len, sqlite3_value** args) noexcept
- {
- auto cc = context<Args...>(ctx);
- auto aa = reinterpret_cast<value*>(args);
- auto &f = *reinterpret_cast<Func*>(sqlite3_user_data(ctx));
- detail::execute_context_function(ctx, f, cc, boost::span<value, Extent>{aa, static_cast<std::size_t>(len)});
- };
- }
- template<typename Func, std::size_t Extent>
- void set_impl(Func & func, std::tuple<span<value, Extent>> * )
- {
- *ppArg_ = &func;
- *pxFunc_ =
- +[](sqlite3_context* ctx, int len, sqlite3_value** args) noexcept
- {
- auto aa = reinterpret_cast<value*>(args);
- auto &f = *reinterpret_cast<Func *>(sqlite3_user_data(ctx));
- detail::execute_context_function(ctx, f, boost::span<value, Extent>{aa, static_cast<std::size_t>(len)});
- };
- }
-
- void (**pxFunc_)(sqlite3_context*,int,sqlite3_value**);
- void **ppArg_;
-};
-
-#if SQLITE_VERSION_NUMBER >= 3038000
-/** @brief Utility function that can be used in `xFilter` for the `in` operator.
- @see https://www.sqlite.org/capi3ref.html#sqlite3_vtab_in_first
- @ingroup reference
- @Note requires sqlite version >= 3.38
-*/
-struct in
-{
- struct iterator
- {
- iterator() = default;
- explicit iterator(sqlite3_value * value ) : value_(value)
- {
- if (value == nullptr)
- return ;
- auto res = sqlite3_vtab_in_first(value, &out_.handle());
- if (res != SQLITE_OK)
- {
- system::error_code ec;
- BOOST_SQLITE_ASSIGN_EC(ec, res);
- detail::throw_error_code(ec, ec.location());
- }
- }
-
- iterator & operator++()
- {
- auto res = sqlite3_vtab_in_next(value_, &out_.handle());
- if (res != SQLITE_OK)
- {
- system::error_code ec;
- BOOST_SQLITE_ASSIGN_EC(ec, res);
- detail::throw_error_code(ec, ec.location());
- }
- return *this;
- }
-
- iterator operator++(int)
- {
- auto last = *this;
- ++(*this);
- return last;
- }
-
-
- const value & operator*() const
- {
- return out_;
- }
-
- const value * operator->() const
- {
- return &out_;
- }
-
- bool operator==(const iterator& other) const
- {
- return value_ == other.value_
- && out_.handle() == other.out_.handle();
- }
-
- bool operator!=(const iterator& other) const
- {
- return value_ != other.value_
- || out_.handle() != other.out_.handle();
- }
-
-
- private:
- sqlite3_value * value_{nullptr};
- value out_{nullptr};
- };
-
- /// Returns a forward iterator to the `in` sequence for an `in` constraint pointing to the begin.
- iterator begin() {return iterator(out_);}
- /// Returns a forward iterator to the `in` sequence for an `in` constraint pointing to the end.
- iterator end() {return iterator();}
-
- explicit in(sqlite3_value * out) : out_(out) {}
- explicit in(sqlite::value out) : out_(out.handle()) {}
- private:
- sqlite3_value * out_{nullptr};
-};
-
-#endif
-
-/// index info used by the find_index function
-/// @ingroup reference
-/// @see [sqlite reference](https://www.sqlite.org/vtab.html#xbestindex)
-struct index_info
-{
- /// Returns constraints of the index.
- BOOST_ATTRIBUTE_NODISCARD
- span<const sqlite3_index_info::sqlite3_index_constraint> constraints() const
- {
- return {info_->aConstraint, static_cast<std::size_t>(info_->nConstraint)};
- }
-
- /// Returns ordering of the index.
- BOOST_ATTRIBUTE_NODISCARD
- span<const sqlite3_index_info::sqlite3_index_orderby> order_by() const
- {
- return {info_->aOrderBy, static_cast<std::size_t>(info_->nOrderBy)};
- }
-
- BOOST_ATTRIBUTE_NODISCARD
- span<sqlite3_index_info::sqlite3_index_constraint_usage> usage()
- {
- return {info_->aConstraintUsage, static_cast<std::size_t>(info_->nConstraint)};
- }
-
- BOOST_ATTRIBUTE_NODISCARD
- sqlite3_index_info::sqlite3_index_constraint_usage & usage_of(
- const sqlite3_index_info::sqlite3_index_constraint & info)
- {
- auto dist = std::distance(constraints().begin(), &info);
- auto itr = usage().begin() + dist;
- BOOST_ASSERT(itr < usage().end());
- return *itr;
- }
-
-#if SQLITE_VERSION_NUMBER >= 3022000
-
- /// Receive the collation for the contrainst of the position.
- const char * collation(std::size_t idx) const
- {
- return sqlite3_vtab_collation(info_, static_cast<int>(idx));
- }
-#endif
-
- int on_conflict() const {return sqlite3_vtab_on_conflict(db_);}
-
-#if SQLITE_VERSION_NUMBER >= 3038000
- /// Returns true if the constraint is
- bool distinct() const {return sqlite3_vtab_distinct(info_);}
-
- value * rhs_value(std::size_t idx) const
- {
- value * v = nullptr;
- if (sqlite3_vtab_rhs_value(
- info_, static_cast<int>(idx),
- reinterpret_cast<sqlite3_value**>(v)) == SQLITE_OK)
- return v;
- else
- return nullptr;
- }
-#endif
-
- void set_already_ordered() { info_->orderByConsumed = 1; }
- void set_estimated_cost(double cost) { info_->estimatedCost = cost; }
-#if SQLITE_VERSION_NUMBER >= 3008200
- void set_estimated_rows(sqlite3_int64 rows) { info_->estimatedRows = rows; }
-#endif
-#if SQLITE_VERSION_NUMBER >= 3009000
- void set_index_scan_flags(int flags) { info_->idxFlags = flags; }
-#endif
-#if SQLITE_VERSION_NUMBER >= 3010000
- std::bitset<64u> columns_used()
- {
- return std::bitset<64u>(info_->colUsed);
- }
-#endif
-
- void set_index(int value) { info_->idxNum = value; }
- void set_index_string(char * str,
- bool take_ownership = true)
- {
- info_->idxStr = str;
- info_->needToFreeIdxStr = take_ownership ? 1 : 0;
- }
-
- sqlite3_index_info * info() const { return info_; }
- sqlite3 * db() const { return db_; }
-
- private:
- explicit index_info(sqlite3 * db, sqlite3_index_info * info) : db_(db), info_(info) {}
- sqlite3 * db_;
- sqlite3_index_info * info_{nullptr};
- friend struct detail::vtab_impl;
-};
-
-
-struct module_config
-{
-#if SQLITE_VERSION_NUMBER >= 3031000
- /// @brief Can be used to set SQLITE_VTAB_INNOCUOUS
- void set_innocuous()
- {
- sqlite3_vtab_config(db_, SQLITE_VTAB_INNOCUOUS);
- }
- /// @brief Can be used to set SQLITE_VTAB_DIRECTONLY
- void set_directonly() {sqlite3_vtab_config(db_, SQLITE_VTAB_DIRECTONLY);}
-
-#endif
-
- /// @brief Can be used to set SQLITE_VTAB_CONSTRAINT_SUPPORT
- void set_constraint_support(bool enabled = false)
- {
- sqlite3_vtab_config(db_, SQLITE_VTAB_CONSTRAINT_SUPPORT, enabled ? 1 : 0);
- }
-
- private:
- explicit module_config(sqlite3 *db) : db_(db) {}
- friend struct detail::vtab_impl;
- sqlite3 *db_;
-};
-
-template<typename Table>
-struct module
-{
- using table_type = Table;
-
- /// @brief Creates the instance
- /// The instance_type gets used & managed by value, OR a pointer to a class that inherits sqlite3_vtab.
- /// instance_type must have a member `declaration` that returns a `const char *` for the declaration.
- BOOST_SQLITE_VIRTUAL result<table_type> create(sqlite::connection db, int argc, const char * const argv[]) BOOST_SQLITE_PURE;
-
- /// @brief Create a table
- /// The table_type gets used & managed by value, OR a pointer to a class that inherits sqlite3_vtab.
- /// table_type must have a member `declaration` that returns a `const char *` for the declaration.
- BOOST_SQLITE_VIRTUAL result<table_type> connect(sqlite::connection db, int argc, const char * const argv[]) BOOST_SQLITE_PURE;
-};
-
-template<typename Table>
-struct eponymous_module
-{
- using table_type = Table;
-
- /// @brief Creates the instance
- /// The instance_type gets used & managed by value, OR a pointer to a class that inherits sqlite3_vtab.
- /// instance_type must have a member `declaration` that returns a `const char *` for the declaration.
- BOOST_SQLITE_VIRTUAL result<table_type> connect(sqlite::connection db, int argc, const char * const argv[]) BOOST_SQLITE_PURE;
-
- eponymous_module(bool eponymous_only = false) : eponymous_only_(eponymous_only) {}
-
- bool eponymous_only() const {return eponymous_only_;}
- protected:
- bool eponymous_only_{false};
-
-};
-
-template<typename ColumnType>
-struct cursor;
-
-/// The basis for vtable
-template<typename Cursor>
-struct table : protected sqlite3_vtab
-{
- using cursor_type = Cursor;
-
- BOOST_SQLITE_VIRTUAL result<void> config(module_config &) {return {};}
-
- /// The Table declaration to be used with sqlite3_declare_vtab
- BOOST_SQLITE_VIRTUAL const char *declaration() BOOST_SQLITE_PURE;
-
- /// Destroy the storage = this function needs to be present for non eponymous tables
- BOOST_SQLITE_VIRTUAL result<void> destroy() { return {}; }
-
- /// Tell sqlite how to communicate with the table.
- /// Optional, this library will fill in a default function that leaves comparisons to sqlite.
- BOOST_SQLITE_VIRTUAL result<void> best_index(index_info & /*info*/) {return {system::in_place_error, SQLITE_OK};}
-
- /// @brief Start a search on the table.
- /// The cursor_type gets used & managed by value, OR a pointer to a class that inherits sqlite3_vtab_cursor.
- BOOST_SQLITE_VIRTUAL result<cursor_type> open() BOOST_SQLITE_PURE;
-
- /// Get the connection of the vtable
- sqlite::connection connection() const {return sqlite::connection{db_, false};}
-
- table(const sqlite::connection & conn) : db_(conn.handle()) {}
- table(sqlite3 * db = nullptr) : db_(db) {}
- private:
- template<typename ColumnType>
- friend struct cursor;
- friend struct detail::vtab_impl;
-
- sqlite3 * db_{nullptr};
-};
-
-/// Cursor needs the following member. @ingroup reference
-template<typename ColumnType = void>
-struct cursor : protected sqlite3_vtab_cursor
-{
- using column_type = ColumnType;
-
- /// @brief Apply a filter to the cursor. Required when best_index is implemented.
- BOOST_SQLITE_VIRTUAL result<void> filter(
- int /*index*/, const char * /*index_data*/,
- boost::span<sqlite::value> /*values*/)
- {
- return {system::in_place_error, SQLITE_OK};
- }
-
- /// @brief Returns the next row.
- BOOST_SQLITE_VIRTUAL result<void> next() BOOST_SQLITE_PURE;
-
- /// @brief Check if the cursor is and the end
- BOOST_SQLITE_VIRTUAL bool eof() BOOST_SQLITE_PURE;
-
- /// @brief Returns the result of a value. It will use the set_result functionality to create a an sqlite function.
- /// see [vtab_no_change](https://www.sqlite.org/c3ref/vtab_nochange.html)
- BOOST_SQLITE_VIRTUAL result<column_type> column(int idx, bool no_change) BOOST_SQLITE_PURE;
- /// @brief Returns the id of the current row
- BOOST_SQLITE_VIRTUAL result<sqlite3_int64> row_id() BOOST_SQLITE_PURE;
-
- /// Get the table the cursor is pointing to.
- vtab::table<cursor> & table() { return *static_cast< vtab::table<cursor>*>(this->pVtab);}
- const vtab::table<cursor> & table() const { return *static_cast<const vtab::table<cursor>*>(this->pVtab);}
-
- friend struct detail::vtab_impl;
-};
-
-/// Cursor needs the following member. @ingroup reference
-template<>
-struct cursor<void> : protected sqlite3_vtab_cursor
-{
- using column_type = void;
-
- /// @brief Apply a filter to the cursor. Required when best_index is implemented.
- BOOST_SQLITE_VIRTUAL result<void> filter(
- int /*index*/, const char * /*index_data*/,
- boost::span<sqlite::value> /*values*/)
- {
- return {system::in_place_error, SQLITE_OK};
- }
-
- /// @brief Returns the next row.
- BOOST_SQLITE_VIRTUAL result<void> next() BOOST_SQLITE_PURE;
-
- /// @brief Check if the cursor is and the end
- BOOST_SQLITE_VIRTUAL bool eof() BOOST_SQLITE_PURE;
-
- /// @brief Returns the result of a value. It will use the set_result functionality to create a an sqlite function.
- /// see [vtab_no_change](https://www.sqlite.org/c3ref/vtab_nochange.html)
- BOOST_SQLITE_VIRTUAL void column(context<> ctx, int idx, bool no_change) BOOST_SQLITE_PURE;
- /// @brief Returns the id of the current row
- BOOST_SQLITE_VIRTUAL result<sqlite3_int64> row_id() BOOST_SQLITE_PURE;
-
- /// Get the table the cursor is pointing to.
- vtab::table<cursor> & table() { return *static_cast< vtab::table<cursor>*>(this->pVtab);}
- const vtab::table<cursor> & table() const { return *static_cast<const vtab::table<cursor>*>(this->pVtab);}
-
- friend struct detail::vtab_impl;
-};
-
-
-/// Group of functions for modifications. @ingroup reference
-struct modifiable
-{
- BOOST_SQLITE_VIRTUAL result<void> delete_(sqlite::value key) BOOST_SQLITE_PURE;
- /// Insert a new row
- BOOST_SQLITE_VIRTUAL result<sqlite_int64> insert(sqlite::value key, span<sqlite::value> values, int on_conflict) BOOST_SQLITE_PURE;
- /// Update the row
- BOOST_SQLITE_VIRTUAL result<sqlite_int64> update(sqlite::value old_key, sqlite::value new_key, span<sqlite::value> values, int on_conflict) BOOST_SQLITE_PURE;
-};
-
-/// Group of functions to support transactions. @ingroup reference
-struct transaction
-{
- /// Begin a tranasction
- BOOST_SQLITE_VIRTUAL result<void> begin() BOOST_SQLITE_PURE;
- /// synchronize the state
- BOOST_SQLITE_VIRTUAL result<void> sync() BOOST_SQLITE_PURE;
- /// commit the transaction
- BOOST_SQLITE_VIRTUAL result<void> commit() BOOST_SQLITE_PURE;
- /// rollback the transaction
- BOOST_SQLITE_VIRTUAL result<void> rollback() BOOST_SQLITE_PURE;
-};
-
-/// Fucntion to enable function overriding See `xFindFunction`.
-struct overload_functions
-{
- /// @see https://www.sqlite.org/vtab.html#xfindfunction
- BOOST_SQLITE_VIRTUAL result<void> find_function(
- function_setter fs,
- int arg, const char * name) BOOST_SQLITE_PURE;
-};
-
-/// Make the vtable renamable @ingroup reference
-struct renamable
-{
- /// Function to rename the table. Optional
- BOOST_SQLITE_VIRTUAL result<void> rename(const char * new_name) BOOST_SQLITE_PURE;
-
-};
-
-#if SQLITE_VERSION_NUMBER >= 3007007
-/// Support for recursive transactions @ingroup reference
-struct recursive_transaction
-{
- /// Save the current state with to `i`
- BOOST_SQLITE_VIRTUAL result<void> savepoint(int i) BOOST_SQLITE_PURE;
- /// Release all saves states down to `i`
- BOOST_SQLITE_VIRTUAL result<void> release(int i) BOOST_SQLITE_PURE;
- /// Roll the transaction back to `i`.
- BOOST_SQLITE_VIRTUAL result<void> rollback_to(int i) BOOST_SQLITE_PURE;
-};
-#endif
-
-}
-
-
-namespace detail
-{
-
-template<typename Module>
-const sqlite3_module make_module(const Module & mod);
-
-}
-
-////@{
-/** @brief Register a vtable
- @ingroup reference
- @see Sqlite vtab reference [vtab](https://www.sqlite.org/vtab.html)
-
- @param conn The connection to install the vtable into
- @param name The name for the vtable
- @param module The module to install as a vtable. See @ref vtab_module_prototype for the structure required
- @param ec The system::error_code used to deliver errors for the exception less overload.
- @param info The error_info used to deliver errors for the exception less overload.
-
- @param The requirements for `module`.
-
- @tparam T The implementation type of the module. It must inherit
-
- @returns A reference to the module as stored in the database. It's lifetime is managed by the database.
-
-
-*/
-template<typename T>
-auto create_module(connection & conn,
- cstring_ref name,
- T && module,
- system::error_code & ec,
- error_info & ei) -> typename std::decay<T>::type &
-{
- using module_type = typename std::decay<T>::type;
- static const sqlite3_module mod = detail::make_module(module);
-
- std::unique_ptr<module_type> p{new (memory_tag{}) module_type(std::forward<T>(module))};
- auto pp = p.get();
-
- int res = sqlite3_create_module_v2(
- conn.handle(), name.c_str(),
- &mod, p.release(),
- +[](void * ptr)
- {
- static_cast<module_type*>(ptr)->~module_type();
- sqlite3_free(ptr);
- });
-
- if (res != SQLITE_OK)
- {
- BOOST_SQLITE_ASSIGN_EC(ec, res);
- ei.set_message(sqlite3_errmsg(conn.handle()));
- }
- return *pp;
-}
-
-template<typename T>
-auto create_module(connection & conn,
- const char * name,
- T && module) -> typename std::decay<T>::type &
-{
- system::error_code ec;
- error_info ei;
- T & ref = create_module(conn, name, std::forward<T>(module), ec, ei);
- if (ec)
- detail::throw_error_code(ec, ei);
- return ref;
-}
-///@}
-
-
-BOOST_SQLITE_END_NAMESPACE
-
-#include <boost/sqlite/detail/vtable.hpp>
-
-#endif //BOOST_SQLITE_VTABLE_HPP
-