boost_sqlite 1
A sqlite C++ library
Loading...
Searching...
No Matches
hooks.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_HOOKS_HPP
9#define BOOST_SQLITE_HOOKS_HPP
10
11#include <boost/sqlite/detail/config.hpp>
12#include <boost/sqlite/function.hpp>
13#include <boost/system/result.hpp>
14
15BOOST_SQLITE_BEGIN_NAMESPACE
16
17
18#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
25{
27 system::result<value> old(int column) const
28 {
29 sqlite3_value * val;
30 int res = sqlite3_preupdate_old(db_, column, &val);
31 if (res != 0)
32 BOOST_SQLITE_RETURN_EC(res);
33 return value(val);
34 }
36 int count() const { return sqlite3_preupdate_count(db_); }
38 int depth() const { return sqlite3_preupdate_depth(db_); }
40 system::result<value> new_(int column) const
41 {
42 sqlite3_value * val;
43 int res = sqlite3_preupdate_new(db_, column, &val);
44 if (res != 0)
45 BOOST_SQLITE_RETURN_EC(res);
46 return value(val);
47 }
48
51 int blob_write() const { return sqlite3_preupdate_blobwrite(db_); }
52
53 explicit preupdate_context(sqlite3 * db) noexcept : db_(db) {}
54 private:
55 sqlite3 * db_;
56};
57
58#endif
59
60namespace detail
61{
62
63
64template<typename Func>
65bool commit_hook_impl(sqlite3 * db,
66 Func * func,
67 std::true_type)
68{
69 static_assert(noexcept(func()), "hook must be noexcept");
70 return sqlite3_commit_hook( db, func, [](void * data) { return (*static_cast<Func *>(data))() ? 1 : 0; }, nullptr) != nullptr;
71}
72
73
74template<typename Func>
75bool commit_hook_impl(sqlite3 * db,
76 Func && func,
77 std::false_type)
78{
79 static_assert(noexcept(func()), "hook must be noexcept");
80 return sqlite3_commit_hook(
81 db,
82 [](void * data) { return (*static_cast<Func *>(data))() ? 1 : 0; },
83 &func) != nullptr;
84}
85
86inline bool commit_hook(sqlite3 * db, std::nullptr_t, std::false_type)
87{
88 return sqlite3_commit_hook(db, nullptr, nullptr);
89}
90
91
92
93template<typename Func>
94bool commit_hook(sqlite3 * db,
95 Func && func)
96{
97 using func_type = typename std::decay<Func>::type;
98 return commit_hook_impl(db, std::forward<Func>(func), std::is_pointer<func_type>{});
99}
100
101
102
103template<typename Func>
104bool rollback_hook_impl(sqlite3 * db,
105 Func * func,
106 std::true_type)
107{
108 static_assert(noexcept(func()), "hook must be noexcept");
109 return sqlite3_rollback_hook( db, func, [](void * data) { (*static_cast<Func *>(data))(); }, nullptr) != nullptr;
110}
111
112
113template<typename Func>
114bool rollback_hook_impl(sqlite3 * db,
115 Func && func,
116 std::false_type)
117{
118 static_assert(noexcept(func()), "hook must be noexcept");
119 return sqlite3_rollback_hook(
120 db,
121 [](void * data) { (*static_cast<Func *>(data))(); },
122 &func) != nullptr;
123}
124
125inline bool rollback_hook_impl(sqlite3 * db, std::nullptr_t, std::false_type)
126{
127 return sqlite3_rollback_hook(db, nullptr, nullptr);
128}
129
130template<typename Func>
131bool rollback_hook(sqlite3 * db,
132 Func && func)
133{
134 using func_type = typename std::decay<Func>::type;
135 return rollback_hook_impl(db, std::forward<Func>(func), std::is_pointer<func_type>{});
136}
137
138#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
139
140template<typename Func>
141bool preupdate_hook_impl(sqlite3 * db,
142 Func * func,
143 std::true_type)
144{
145 static_assert(noexcept(func(preupdate_context(nullptr), SQLITE_SELECT, "", "", 0, 0)), "hook must be noexcept");
146 return sqlite3_preupdate_hook(
147 db, func,
148 [](void * data,
149 sqlite3* db,
150 int op,
151 const char * db_name,
152 const char * table_name,
153 sqlite_int64 key1,
154 sqlite_int64 key2)
155 {
156 (*static_cast<Func *>(data))(preupdate_context(db), op, db_name, table_name, key1, key2);
157 }, nullptr) != nullptr;
158}
159
160
161template<typename Func>
162bool preupdate_hook_impl(sqlite3 * db,
163 Func & func,
164 std::false_type)
165{
166 static_assert(noexcept(func(preupdate_context(nullptr), SQLITE_SELECT, "", "", 0, 0)),
167 "hooks but be noexcept");
168 using func_type = typename std::decay<Func>::type;
169
170 return sqlite3_preupdate_hook(
171 db,
172 [](void * data,
173 sqlite3* db,
174 int op,
175 const char * db_name,
176 const char * table_name,
177 sqlite_int64 key1,
178 sqlite_int64 key2)
179 {
180 (*static_cast<Func *>(data))(preupdate_context(db), op, db_name, table_name, key1, key2);
181 }, &func) != nullptr;
182}
183
184inline bool preupdate_hook_impl(sqlite3 * db, std::nullptr_t, std::false_type)
185{
186 return sqlite3_preupdate_hook(db, nullptr, nullptr);
187}
188
189template<typename Func>
190bool preupdate_hook(sqlite3 * db,
191 Func && func)
192{
193 using func_type = typename std::decay<Func>::type;
194 return preupdate_hook_impl(db, std::forward<Func>(func), std::is_pointer<func_type>{});
195}
196
197#endif
198
199template<typename Func>
200bool update_hook_impl(sqlite3 * db,
201 Func * func,
202 std::true_type)
203{
204 static_assert(noexcept(func(SQLITE_SELECT, "", "", 0)), "hook must be noexcept");
205 return sqlite3_update_hook(
206 db, func,
207 [](void * data,
208 sqlite3*,
209 int op,
210 const char * db,
211 const char * name,
212 sqlite_int64 key)
213 {
214 (*static_cast<Func *>(data))(op, db, name, key);
215 }, nullptr) != nullptr;
216}
217
218
219template<typename Func>
220bool update_hook_impl(sqlite3 * db,
221 Func & func,
222 std::false_type)
223{
224 static_assert(noexcept(func(SQLITE_SELECT, "", "", 0)), "hook must be noexcept");
225 using func_type = typename std::decay<Func>::type;
226
227 return sqlite3_update_hook(
228 db,
229 [](void * data,
230 int op,
231 const char * db,
232 const char * name,
233 sqlite_int64 key)
234 {
235 (*static_cast<func_type*>(data))(op, db, name, key);
236 }, &func) != nullptr;
237}
238
239inline
240bool update_hook_impl(sqlite3 * db,
241 std::nullptr_t,
242 std::false_type)
243{
244 return sqlite3_update_hook(db, nullptr, nullptr);
245}
246
247template<typename Func>
248bool update_hook(sqlite3 * db,
249 Func && func)
250{
251 using func_type = typename std::decay<Func>::type;
252 return update_hook_impl(db, std::forward<Func>(func), std::is_pointer<func_type>{});
253}
254
255
256}
257
275template<typename Func>
276bool commit_hook(connection & conn, Func && func)
277{
278 return detail::commit_hook(conn.handle(), std::forward<Func>(func));
279}
280
297template<typename Func>
298bool rollback_hook(connection & conn, Func && func)
299{
300 return detail::rollback_hook(conn.handle(), std::forward<Func>(func));
301}
302
303#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
335template<typename Func>
336bool preupdate_hook(connection & conn, Func && func)
337{
338 return detail::preupdate_hook(conn.handle(), std::forward<Func>(func));
339}
340
341#endif
342
362template<typename Func>
363bool update_hook(connection & conn, Func && func)
364{
365 return detail::update_hook(conn.handle(), std::forward<Func>(func));
366}
367
368BOOST_SQLITE_END_NAMESPACE
369
370#endif //BOOST_SQLITE_HOOKS_HPP
main object for a connection to a database.
int depth() const
The nesting depth of the update.
Definition hooks.hpp:38
int blob_write() const
Query the status of blob access, e.g. when using blob_handle.
Definition hooks.hpp:51
system::result< value > old(int column) const
Returns the old value, i.e. the value before the update.
Definition hooks.hpp:27
system::result< value > new_(int column) const
The new value to be written to column.
Definition hooks.hpp:40
int count() const
The count of colums to be updated.
Definition hooks.hpp:36
A holder for a sqlite values used for internal APIs.
Definition value.hpp:39