summaryrefslogtreecommitdiff
path: root/include/boost/sqlite/detail
diff options
context:
space:
mode:
Diffstat (limited to 'include/boost/sqlite/detail')
-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
7 files changed, 0 insertions, 1487 deletions
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