boost_sqlite 1
A sqlite C++ library
Loading...
Searching...
No Matches
function.hpp
1//
2// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8#ifndef BOOST_SQLITE_FUNCTION_HPP
9#define BOOST_SQLITE_FUNCTION_HPP
10
11#include <boost/sqlite/detail/config.hpp>
12#include <boost/sqlite/detail/aggregate_function.hpp>
13#include <boost/sqlite/detail/scalar_function.hpp>
14#include <boost/sqlite/detail/window_function.hpp>
15#include <boost/sqlite/connection.hpp>
16#include <boost/sqlite/result.hpp>
17#include <boost/sqlite/value.hpp>
18#include <boost/sqlite/detail/exception.hpp>
19#include <boost/sqlite/cstring_ref.hpp>
20
21#include <boost/core/span.hpp>
22#include <boost/callable_traits/args.hpp>
23#include <boost/callable_traits/has_void_return.hpp>
24#include <boost/callable_traits/return_type.hpp>
25
26BOOST_SQLITE_BEGIN_NAMESPACE
27
28
53template<typename ... Args>
54struct context
55{
56 template<std::size_t N>
57 using element = mp11::mp_take_c<mp11::mp_list<Args...>, N>;
58
60 template<std::size_t Idx>
61 void set(element<Idx> value)
62 {
63 sqlite3_set_auxdata(ctx_, Idx, *static_cast<void**>(&value),
64 new (memory_tag{}) element<Idx>(std::move(value)),
65 +[](void * ptr)
66 {
67 delete_(static_cast<element<Idx> *>(ptr));
68 });
69 }
70
72 template<std::size_t Idx>
73 auto get() -> element<Idx> &
74 {
75 using type = element<Idx> ;
76 auto p = static_cast<type*>(sqlite3_get_auxdata(ctx_, Idx));
77 if (p == nullptr)
78 detail::throw_invalid_argument("argument not set",
79 BOOST_CURRENT_LOCATION);
80 return *p;
81 }
82
84 template<std::size_t Idx>
85 auto get_if() -> element<Idx> *
86 {
87 using type = element<Idx> ;
88 return static_cast<type*>(sqlite3_get_auxdata(ctx_, Idx));
89 }
90
91
92 explicit context(sqlite3_context * ctx) noexcept : ctx_(ctx) {}
93
95 template<typename T>
96 auto set_result(T && val)
97#if !defined(BOOST_SQLITE_GENERATING_DOCS)
98 -> decltype(detail::set_result(static_cast<sqlite3_context*>(nullptr), std::forward<T>(val)))
99#endif
100 {
101 detail::set_result(ctx_, std::forward<T>(val));
102 }
104 void set_error(cstring_ref message, int code = SQLITE_ERROR)
105 {
106 sqlite3_result_error(ctx_, message.c_str(), code);
107 }
109 connection get_connection() const
110 {
111 return connection{sqlite3_context_db_handle(ctx_), false};
112 }
113
114 private:
115 sqlite3_context * ctx_;
116};
117
118
120
154template<typename Func>
155auto create_scalar_function(
156 connection & conn,
157 cstring_ref name,
158 Func && func,
159 system::error_code & ec)
160#if !defined(BOOST_SQLITE_GENERATING_DOCS)
161 -> typename std::enable_if<
162 std::is_same<
163 decltype(
164 detail::create_scalar_function(
165 static_cast<sqlite3*>(nullptr), name,
166 std::declval<Func>())
167 ), int>::value>::type
168#endif
169{
170 auto res = detail::create_scalar_function(conn.handle(), name, std::forward<Func>(func));
171 if (res != 0)
172 BOOST_SQLITE_ASSIGN_EC(ec, res);
173}
174
176
209template<typename Func>
210auto create_scalar_function(
211 connection & conn,
212 cstring_ref name,
213 Func && func)
214 -> typename std::enable_if<
215 std::is_same<
216 decltype(
217 detail::create_scalar_function(
218 static_cast<sqlite3*>(nullptr), name,
219 std::declval<Func>())
220 ), int>::value>::type
221{
222 system::error_code ec;
223 create_scalar_function(conn, name, std::forward<Func>(func), ec);
224 if (ec)
225 detail::throw_error_code(ec,
226 BOOST_CURRENT_LOCATION);
227}
229
230
232
279template<typename Func>
280void create_aggregate_function(
281 connection & conn,
282 cstring_ref name,
283 Func && func,
284 system::error_code & ec,
285 error_info & ei)
286{
287 using func_type = typename std::decay<Func>::type;
288 auto res = detail::create_aggregate_function(
289 conn.handle(), name, std::forward<Func>(func),
290 callable_traits::has_void_return<decltype(&func_type::step)>{}
291 );
292 if (res != 0)
293 {
294 BOOST_SQLITE_ASSIGN_EC(ec, res);
295 ei.set_message(sqlite3_errmsg(conn.handle()));
296 }
297}
298
299template<typename Func>
300void create_aggregate_function(
301 connection & conn,
302 cstring_ref name,
303 Func && func)
304{
305 system::error_code ec;
306 error_info ei;
307 create_aggregate_function(conn, name, std::forward<Func>(func), ec, ei);
308 if (ec)
309 detail::throw_error_code(ec, ei);
310}
312
313#if SQLITE_VERSION_NUMBER >= 3025000
314
316
367template<typename Func>
368void create_window_function(
369 connection & conn,
370 cstring_ref name,
371 Func && func,
372 system::error_code & ec)
373{
374 using func_type = typename std::decay<Func>::type;
375 auto res = detail::create_window_function(
376 conn.handle(), name, std::forward<Func>(func),
377 callable_traits::has_void_return<decltype(&func_type::step)>{});
378 if (res != 0)
379 BOOST_SQLITE_ASSIGN_EC(ec, res);
380}
381
382template<typename Func>
383void create_window_function(
384 connection & conn,
385 cstring_ref name,
386 Func && func)
387{
388 system::error_code ec;
389 create_window_function(conn, name, std::forward<Func>(func), ec);
390 if (ec)
391 detail::throw_error_code(ec);
392}
393
395
396#endif
397
398BOOST_SQLITE_END_NAMESPACE
399
400#endif //BOOST_SQLITE_FUNCTION_HPP
main object for a connection to a database.
A context that can be passed into scalar functions.
Definition function.hpp:54
Small wrapper for a null-terminated string that can be directly passed to C APIS.
Additional information about error conditions stored in an sqlite-allocate string.
Definition error.hpp:33
A holder for a sqlite values used for internal APIs.
Definition value.hpp:39