ThinSQLite++
A thin, safe and convenient modern C++ wrapper for SQLite API.
Loading...
Searching...
No Matches
database_iface.hpp
1/*
2 Copyright 2019 Eugene Gershnik
3
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file or at
6 https://github.com/gershnik/thinsqlitepp/blob/main/LICENSE
7*/
8
9#ifndef HEADER_SQLITEPP_DATABASE_IFACE_INCLUDED
10#define HEADER_SQLITEPP_DATABASE_IFACE_INCLUDED
11
12#include "handle.hpp"
13#include "exception_iface.hpp"
14#include "mutex_iface.hpp"
15#include "blob_iface.hpp"
16#include "snapshot_iface.hpp"
17#include "memory_iface.hpp"
18#include "string_param.hpp"
19#include "span.hpp"
20#include "meta.hpp"
21
22#include <memory>
23#include <functional>
24#include <optional>
25
26#ifdef __GNUC__
27 #pragma GCC diagnostic push
28 #pragma GCC diagnostic ignored "-Wcast-function-type"
29
30 #if defined(__APPLE__) && defined(__clang__) && defined(SQLITE_AVAILABLE)
31 #pragma GCC diagnostic ignored "-Wunguarded-availability-new"
32 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
33 #endif
34#endif
35
36
37
38namespace thinsqlitepp
39{
40 class context;
41 class row;
42 class value;
43
46 struct database_detector
47 {
48 SQLITEPP_CALL_DETECTOR(enable_load_extension, int, sqlite3_enable_load_extension, (T *)nullptr, int{});
49 SQLITEPP_CALL_DETECTOR(load_extension, int, sqlite3_load_extension, (T *)nullptr,
50 (const char *)nullptr,
51 (const char *)nullptr,
52 (char **)nullptr);
53
54 SQLITEPP_METHOD_DETECTOR(void, step, (context *)nullptr, int{}, (value **)nullptr);
55 SQLITEPP_METHOD_DETECTOR(void, last, (context *)nullptr);
56 SQLITEPP_METHOD_DETECTOR(void, inverse, (context *)nullptr, int{}, (value **)nullptr);
57 SQLITEPP_METHOD_DETECTOR(void, current, (context *)nullptr);
58
59 public:
60 template<class T>
62
63 template<class T>
64 static constexpr bool is_aggregate_function = has_noexcept_step<T> && has_noexcept_last<T>;
65
66 template<class T>
67 static constexpr bool is_aggregate_window_function = is_aggregate_function<T> && has_noexcept_inverse<T> && has_noexcept_current<T>;
68
69 template<class R, class T, class... ArgTypes>
70 static constexpr bool is_pointer_to_callback = std::is_null_pointer_v<T> ||
72
73 template<class R, class T, class... ArgTypes>
74 static constexpr bool is_pointer_to_throwing_callback = std::is_null_pointer_v<T> ||
76
77 template<class T>
78 static constexpr bool is_pointer_to_function = std::is_null_pointer_v<T> ||
80 (
81 is_function<std::remove_pointer_t<T>> ||
82 is_aggregate_function<std::remove_pointer_t<T>>
83 )
84 );
85
86 template<class T>
87 static constexpr bool is_pointer_to_window_function = std::is_null_pointer_v<T> ||
88 (std::is_pointer_v<T> && is_aggregate_window_function<std::remove_pointer_t<T>>);
89 };
90
107 class database final : public handle<sqlite3, database>
108 {
109 private:
110 template<int Code, class ...Args>
111 struct config_option
112 {
113 static void apply(database & db, Args && ...args)
114 {
115 int res = sqlite3_db_config(db.c_ptr(), Code, std::forward<Args>(args)...);
116 if (res != SQLITE_OK)
117 throw exception(res, db);
118 }
119 };
120 template<int Code> struct config_mapping;
121
122 template<int Code, class ...Args>
123 struct vtab_config_option
124 {
125 static void apply(database & db, Args && ...args)
126 {
127 int res = sqlite3_vtab_config(db.c_ptr(), Code, std::forward<Args>(args)...);
128 if (res != SQLITE_OK)
129 throw exception(res, db);
130 }
131 };
132 template<int Code> struct vtab_config_mapping;
133
134 public:
140 static std::unique_ptr<database> open(const string_param & db_filename, int flags, const char * vfs = nullptr);
141
143 ~database() noexcept
144 { sqlite3_close_v2(c_ptr()); }
145
146
147 //MARK: -
148
154 void busy_timeout(int ms)
155 { check_error(sqlite3_busy_timeout(c_ptr(), ms)); }
156
157 //MARK: -
158
164 int64_t changes() const noexcept
165 {
166 #if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 36, 1)
167 return sqlite3_changes64(c_ptr());
168 #else
169 return sqlite3_changes(c_ptr());
170 #endif
171 }
172
173 //MARK: - exec
174
195
196 #if __cpp_char8_t >= 201811
198 template<class T>
200 { return exec(std::string_view((const char *)sql.data(), sql.size())); }
201 #endif
202
242 template<class T>
243 SQLITEPP_ENABLE_IF((
248 T) exec(std::string_view sql, T callback);
249
250 #if __cpp_char8_t >= 201811
252 template<class T>
253 T exec(std::u8string_view sql, T callback)
254 { return exec(std::string_view((const char *)sql.data(), sql.size()), callback); }
255 #endif
256
258
264 //MARK: - busy_handler
265
275 template<class T>
277 void) busy_handler(int (* handler)(type_identity_t<T> data_ptr, int count_invoked) noexcept, T data_ptr)
278 { check_error(sqlite3_busy_handler(this->c_ptr(), (int (*)(void*,int))handler, data_ptr)); }
279
294 template<class T>
295 SQLITEPP_ENABLE_IF((database_detector::is_pointer_to_callback<bool, T, int>),
296 void) busy_handler(T handler_ptr);
297
298
299 //MARK: - collation_needed
300
310 template<class T>
312 void) collation_needed(T data_ptr, void (* handler)(type_identity_t<T> data_ptr, database *, int encoding, const char * name) noexcept)
313 { check_error(sqlite3_collation_needed(this->c_ptr(), data_ptr, (void(*)(void*,sqlite3*,int,const char*))handler)); }
314
331 template<class T>
332 SQLITEPP_ENABLE_IF((database_detector::is_pointer_to_callback<void, T, database *, int, const char *>),
333 void) collation_needed(T handler_ptr);
334
335 //MARK: - commit_hook
336
346 template<class T>
348 void) commit_hook(int (* handler)(type_identity_t<T> data_ptr) noexcept, T data_ptr) noexcept
349 { sqlite3_commit_hook(this->c_ptr(), (int(*)(void*))handler, data_ptr); }
350
364 template<class T>
365 SQLITEPP_ENABLE_IF((database_detector::is_pointer_to_callback<bool, T>),
366 void) commit_hook(T handler_ptr) noexcept;
367
368
369 //MARK: - rollback_hook
370
380 template<class T>
382 void) rollback_hook(void (* handler)(type_identity_t<T> data_ptr) noexcept, T data_ptr) noexcept
383 { sqlite3_rollback_hook(this->c_ptr(), (void(*)(void*))(handler), data_ptr); }
384
398 template<class T>
399 SQLITEPP_ENABLE_IF((database_detector::is_pointer_to_callback<void, T>),
400 void) rollback_hook(T handler_ptr) noexcept;
401
402
403 //MARK: - update_hook
404
414 template<class T>
416 void) update_hook(void (* handler)(type_identity_t<T> data_ptr, int op, const char * db_name, const char * table, sqlite3_int64 rowid) noexcept,
417 T data_ptr) noexcept
418 { sqlite3_update_hook(this->c_ptr(), (void(*)(void*,int,char const *,char const *,sqlite3_int64))(handler), data_ptr); }
419
420
434 template<class T>
435 SQLITEPP_ENABLE_IF((database_detector::is_pointer_to_callback<void, T, int, const char *, const char *, int64_t>),
436 void) update_hook(T handler_ptr) noexcept;
437
438 //MARK: - preupdate_hook
439
440 #if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 16, 0) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
454 template<class T>
456 void) preupdate_hook(void (* handler)(type_identity_t<T> data_ptr,
457 database * db,
458 int op,
459 const char * db_name,
460 const char * table,
461 sqlite3_int64 rowid_old,
462 sqlite3_int64 rowid_new) noexcept,
463 T data_ptr) noexcept
464 {
465 sqlite3_preupdate_hook(this->c_ptr(), (void(*)(void*,sqlite3 *,int,char const *,char const *,sqlite3_int64,sqlite3_int64))(handler),
466 data_ptr);
467 }
468
486 template<class T>
487 SQLITEPP_ENABLE_IF((database_detector::is_pointer_to_callback<void, T, database *, int, const char *, const char *, int64_t, int64_t>),
488 void) preupdate_hook(T handler_ptr) noexcept;
489
490 #endif
491
501 template<class T>
503 void) wal_hook(int (* handler)(type_identity_t<T> data_ptr, database * db, const char * db_name, int num_pages) noexcept,
504 T data_ptr) noexcept
505 { sqlite3_wal_hook(this->c_ptr(), (int(*)(void *,sqlite3*,const char*,int))(handler), data_ptr); }
506
507
521 template<class T>
522 SQLITEPP_ENABLE_IF((database_detector::is_pointer_to_throwing_callback<void, T, database *, const char *, int>),
523 void) wal_hook(T handler_ptr) noexcept;
524
526
527 //MARK: -
528
529 #if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
530 #if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 16, 0)
531
546 value * preupdate_old(int column_idx);
547
558 value * preupdate_new(int column_idx);
559
570 int preupdate_count() const noexcept
571 { return sqlite3_preupdate_count(c_ptr()); }
572
588 int preupdate_depth() const noexcept
589 { return sqlite3_preupdate_depth(c_ptr()); }
590
591
592 #endif
593 #if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 36, 0)
604 int preupdate_blobwrite() const noexcept
606
607
608 #endif
609 #endif
610
611
614 //MARK: -
615
630 std::pair<int, int> checkpoint(const string_param & db_name, int mode = SQLITE_CHECKPOINT_PASSIVE);
631
637 void autocheckpoint(int num_frames)
638 { check_error(sqlite3_wal_autocheckpoint(c_ptr(), num_frames)); }
639
640 /* @} */
641
642
643
644 //MARK: - create_collation
645
665 template<class T>
667 void) create_collation(const string_param & name, int encoding,
668 T collator_ptr,
669 int (*compare)(type_identity_t<T> collator, int lhs_len, const void * lhs_bytes, int rhs_len, const void * rhs_bytes) noexcept,
670 void (*destructor)(type_identity_t<T> collator) noexcept);
671
691 template<class T>
692 SQLITEPP_ENABLE_IF((database_detector::is_pointer_to_callback<int, T, span<const std::byte>, span<const std::byte>>),
693 void) create_collation(const string_param & name, int encoding, T collator_ptr,
694 void (*destructor)(type_identity_t<T> obj) noexcept = nullptr);
695
697
698 //MARK: - create_function
699
724 template<class T>
726 void) create_function(const char * name, int arg_count, int flags, T data_ptr,
727 void (*func)(context *, int, value **) noexcept,
728 void (*step)(context *, int, value **) noexcept,
729 void (*last)(context*) noexcept,
730 void (*destructor)(type_identity_t<T> data_ptr) noexcept);
731
732
733
760 template<class T>
761 SQLITEPP_ENABLE_IF(database_detector::is_pointer_to_function<T>,
762 void) create_function(const char * name, int arg_count, int flags,
763 T impl_ptr, void (*destructor)(type_identity_t<T> obj) noexcept = nullptr);
764
765 //MARK: - create_window_function
766
767#if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 25, 0)
768
791 template<class T>
793 void) create_window_function(const char * name, int arg_count, int flags, T data_ptr,
794 void (*step)(context *, int, value **) noexcept,
795 void (*last)(context*) noexcept,
796 void (*current)(context*) noexcept,
797 void (*inverse)(context *, int, value **) noexcept,
798 void (*destructor)(type_identity_t<T> data_ptr) noexcept);
799
800
826 template<class T>
827 SQLITEPP_ENABLE_IF(database_detector::is_pointer_to_window_function<T>,
828 void) create_window_function(const char * name, int arg_count, int flags,
829 T impl_ptr, void (*destructor)(type_identity_t<T> obj) noexcept = nullptr);
830#endif
831
833
834 //MARK: -
835#if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 10, 0)
844 {
845 if (int res = sqlite3_db_cacheflush(c_ptr()); res != SQLITE_OK)
846 throw exception(res); //sic! sqlite3_db_cacheflush doesn't set DB error
847 }
848#endif
863 template<int Code, class ...Args>
864 auto config(Args && ...args) ->
865 #ifndef DOXYGEN
866 //void but prevents instantiation with wrong types
867 decltype(
868 config_mapping<Code>::type::apply(*this, std::forward<decltype(args)>(args)...)
869 )
870 #else
871 void
872 #endif
873 { config_mapping<Code>::type::apply(*this, std::forward<Args>(args)...); }
874
875
876 //MARK: - create_module
877
891 void create_module(const string_param & name, const sqlite3_module * mod)
892 { check_error(sqlite3_create_module_v2(c_ptr(), name.c_str(), mod, nullptr, nullptr)); }
893
904 template<typename T>
905 void create_module(const string_param & name, const sqlite3_module * mod,
906 T * data, void(*destructor)(T *) = nullptr)
907 { check_error(sqlite3_create_module_v2(c_ptr(), name.c_str(), mod, (void*)data, (void (*)(void *))destructor)); }
908
909
910 //MARK: -
911
917 void declare_vtab(const string_param & sdl)
918 { check_error(sqlite3_declare_vtab(c_ptr(), sdl.c_str())); }
919
920
935 template<int Code, class ...Args>
936 auto vtab_config(Args && ...args) ->
937 #ifndef DOXYGEN
938 //void but prevents instantiation with wrong types
939 decltype(
940 vtab_config_mapping<Code>::type::apply(*this, std::forward<decltype(args)>(args)...)
941 )
942 #else
943 void
944 #endif
945 { vtab_config_mapping<Code>::type::apply(*this, std::forward<Args>(args)...); }
946
956 int vtab_on_conflict() const noexcept
957 { return sqlite3_vtab_on_conflict(c_ptr()); }
958
959 //MARK: - drop_modules
960#if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 30, 0)
969 { check_error(sqlite3_drop_modules(c_ptr(), nullptr)); }
970
978 void drop_modules_except(const char * const * keep)
979 { check_error(sqlite3_drop_modules(c_ptr(), (const char **)keep)); }
980
981
989 template<size_t N>
990 SQLITEPP_ENABLE_IF(N > 0,
991 void) drop_modules_except(const char * const (&keep)[N])
992 {
993 if (keep[N-1] != nullptr) throw exception(SQLITE_MISUSE);
994 check_error(sqlite3_drop_modules(this->c_ptr(), (const char **)keep));
995 }
996
1007 template<class ...Args>
1009 void) drop_modules_except(Args && ...args)
1010 {
1011 const char * buf[] = {string_param(std::forward<Args>(args)).c_str() ..., nullptr};
1012 check_error(sqlite3_drop_modules(this->c_ptr(), buf));
1013 }
1014#endif
1015
1017
1018 //MARK: -
1019
1025 void extended_result_codes(bool onoff)
1026 { check_error(sqlite3_extended_result_codes(c_ptr(), onoff)); }
1027
1028
1034 void file_control(const string_param & db_name, int op, void * data)
1035 { check_error(sqlite3_file_control(c_ptr(), db_name.c_str(), op, data)); }
1036
1042 const char * filename(const string_param & db_name) const noexcept
1043 {
1044 auto ret = sqlite3_db_filename(c_ptr(), db_name.c_str());
1045 return ret ? ret : "";
1046 }
1047
1053 bool get_autocommit() const noexcept
1054 { return sqlite3_get_autocommit(c_ptr()); }
1055
1061 void interrupt() noexcept
1062 { sqlite3_interrupt(c_ptr()); }
1063
1064 #if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 41, 0)
1072 bool is_interrupted() noexcept
1073 { return sqlite3_is_interrupted(c_ptr()) != 0; }
1074 #endif
1075
1081 int64_t last_insert_rowid() const noexcept
1082 { return sqlite3_last_insert_rowid(c_ptr()); }
1083
1084#if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 18, 0)
1094#endif
1095
1096 //returns -1 on bad limit or other issues
1106 int limit(int id, int new_val) noexcept
1107 { return sqlite3_limit(c_ptr(), id, new_val); }
1108
1109
1110
1121 { check_error(call_sqlite3_enable_load_extension(this->c_ptr(), val)); }
1122
1123
1129 void load_extension(const string_param & file, const string_param & proc = nullptr);
1130
1131 #if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 8, 7)
1132
1140 void auto_extension(void(*entry_point)(database *, const char **, const struct sqlite3_api_routines *))
1141 { check_error(sqlite3_auto_extension((void(*)(void))entry_point)); }
1142
1143
1151 void cancel_auto_extension(void(*entry_point)(database *, const char **, const struct sqlite3_api_routines *))
1152 { check_error(sqlite3_cancel_auto_extension((void(*)(void))entry_point)); }
1153
1154
1164
1165 #endif
1166
1174 class mutex * mutex() const noexcept
1175 { return (class mutex *)sqlite3_db_mutex(c_ptr()); }
1176
1177 //MARK: - next_statement
1178
1184 const class statement * next_statement(const class statement * prev) const noexcept
1185 { return (class statement *)sqlite3_next_stmt(c_ptr(), (sqlite3_stmt *)prev); }
1186
1188 class statement * next_statement(const class statement * prev) noexcept
1189 { return (class statement *)sqlite3_next_stmt(c_ptr(), (sqlite3_stmt *)prev); }
1190
1191 //MARK: -
1192
1198 void overload_function(const string_param & name, int arg_count) noexcept
1199 { check_error(sqlite3_overload_function(c_ptr(), name.c_str(), arg_count)); }
1200
1201 //MARK: - progress_handler
1202
1217 template<class T>
1218 SQLITEPP_ENABLE_IF(std::is_pointer_v<T> || std::is_null_pointer_v<T>,
1219 void) progress_handler(int step_count, int(*handler)(type_identity_t<T> data_ptr) noexcept, T data_ptr) const noexcept
1220 { sqlite3_progress_handler(this->c_ptr(), step_count, (int(*)(void*))handler, data_ptr); }
1221
1239 template<class T>
1240 SQLITEPP_ENABLE_IF((std::is_null_pointer_v<T> ||
1242 void) progress_handler(int step_count, T handler_ptr) const noexcept;
1243
1244 //MARK: -
1256
1262 void release_memory() const
1263 { check_error(sqlite3_db_release_memory(c_ptr())); }
1264
1265 //MARK: - status
1266
1268 struct status
1269 {
1270 int current;
1271 int high;
1272 };
1273
1279 struct status status(int op, bool reset = false) const;
1280
1281 //MARK: - table_column_metadata
1282
1285 {
1286 const char * data_type;
1287 const char * collation_sequence;
1291 };
1292
1299 const string_param & table_name,
1300 const string_param & column_name) const;
1301
1302 //MARK: -
1303
1309 int64_t total_changes() const noexcept
1310 {
1311 #if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 36, 1)
1312 return sqlite3_total_changes64(c_ptr());
1313 #else
1314 return sqlite3_total_changes(c_ptr());
1315 #endif
1316 }
1317
1318#if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 34, 0)
1319
1327 int txn_state(const string_param & schema) const noexcept
1328 { return sqlite3_txn_state(c_ptr(), schema.c_str()); }
1329#endif
1330
1337 const string_param & table,
1338 const string_param & column,
1339 int64_t rowid,
1340 bool writable);
1341
1342#if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 39, 0)
1343
1356
1364 span<std::byte> serialize_reference(const string_param & schema_name) noexcept;
1365
1366
1374 void deserialize(const string_param & schema_name,
1375 std::byte * buf,
1376 size_t size,
1377 size_t buf_size,
1378 unsigned flags = 0)
1379 { check_error(sqlite3_deserialize(c_ptr(), schema_name.c_str(), (unsigned char *)buf, int64_size(size), int64_size(buf_size), flags)); }
1380
1381
1391 void deserialize(const string_param & schema_name,
1392 const std::byte * buf,
1393 size_t size,
1394 size_t buf_size,
1395 unsigned flags = 0)
1396 { deserialize(schema_name, (std::byte *)buf, size, buf_size, flags | SQLITE_DESERIALIZE_READONLY); }
1397
1398
1408 void deserialize(const string_param & schema_name,
1409 allocated_bytes buf,
1410 size_t size,
1411 size_t buf_size,
1412 unsigned flags = 0);
1413
1414
1415
1417#endif
1418
1423#if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 10, 0) && THINSQLITEPP_ENABLE_EXPIREMENTAL
1435
1446 void open_snapshot(const string_param & schema, const snapshot & snap)
1447 { check_error(sqlite3_snapshot_open(c_ptr(), schema.c_str(), snap.c_ptr())); }
1448
1460 { check_error(sqlite3_snapshot_recover(c_ptr(), db.c_str())); }
1461
1462#endif
1463
1467 #if SQLITE_VERSION_NUMBER >= SQLITEPP_SQLITE_VERSION(3, 39, 0)
1478 const char * db_name(int idx) noexcept
1479 { return sqlite3_db_name(c_ptr(), idx); }
1480
1481 #endif
1482
1483 //MARK: - Private methods
1484
1485 private:
1486 void check_error(int res) const
1487 {
1488 if (res != SQLITE_OK)
1489 throw exception(res, this);
1490 }
1491
1492 template<class T>
1493 static int call_sqlite3_enable_load_extension(T * db, int onoff)
1494 {
1495 if constexpr (database_detector::has_enable_load_extension<T>)
1496 return sqlite3_enable_load_extension(db, onoff);
1497 else
1498 return SQLITE_ERROR;
1499 }
1500
1501 template<class T>
1502 static int call_sqlite3_load_extension(T * db, const char * file, const char * proc, char ** err)
1503 {
1504 if constexpr (database_detector::has_load_extension<T>)
1505 return sqlite3_load_extension(db, file, proc, err);
1506 else
1507 return SQLITE_ERROR;
1508 }
1509 };
1510
1516 SQLITEPP_SUPPRESS_SILLY_VARARG_WARNING_BEGIN
1517
1518 #if SQLITEPP_USE_VARARG_POUND_POUND_TRICK
1519
1520 #define SQLITEPP_DEFINE_DB_OPTION(code, ...) \
1521 template<> struct database::config_mapping<code> { using type = database::config_option<code, ##__VA_ARGS__>; };
1522
1523 //Idiotic GCC in pedantic mode warns on MACRO(arg) for MARCO(x,...) in < C++20 mode
1524 //with no way to disable the warning(!!!).
1525 #define SQLITEPP_DEFINE_VTAB_OPTION_0(code) \
1526 template<> struct database::vtab_config_mapping<code> { using type = database::vtab_config_option<code>; };
1527 #define SQLITEPP_DEFINE_VTAB_OPTION_N(code, ...) \
1528 template<> struct database::vtab_config_mapping<code> { using type = database::vtab_config_option<code, ##__VA_ARGS__>; };
1529
1530 #else
1531
1532 #define SQLITEPP_DEFINE_DB_OPTION(code, ...) \
1533 template<> struct database::config_mapping<code> { using type = database::config_option<code __VA_OPT__(,) __VA_ARGS__>; };
1534
1535 #define SQLITEPP_DEFINE_VTAB_OPTION_N(code, ...) \
1536 template<> struct database::vtab_config_mapping<code> { using type = database::vtab_config_option<code __VA_OPT__(,) __VA_ARGS__>; };
1537
1538 #define SQLITEPP_DEFINE_VTAB_OPTION_0(code) SQLITEPP_DEFINE_VTAB_OPTION_N(code)
1539
1540 #endif
1541
1542
1543 //@ [DB Options]
1544#ifdef SQLITE_DBCONFIG_MAINDBNAME
1545 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_MAINDBNAME, const char *);
1546#endif
1547 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_LOOKASIDE, void *, int, int);
1548 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_ENABLE_FKEY, int, int *);
1549 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_ENABLE_TRIGGER, int, int *);
1550#ifdef SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
1551 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, int, int *);
1552#endif
1553#ifdef SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
1554 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, int, int *);
1555#endif
1556#ifdef SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
1557 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, int, int *);
1558#endif
1559#ifdef SQLITE_DBCONFIG_ENABLE_QPSG
1560 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_ENABLE_QPSG, int, int *);
1561#endif
1562#ifdef SQLITE_DBCONFIG_TRIGGER_EQP
1563 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_TRIGGER_EQP, int, int *);
1564#endif
1565#ifdef SQLITE_DBCONFIG_RESET_DATABASE
1566 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_RESET_DATABASE, int, int *);
1567#endif
1568#ifdef SQLITE_DBCONFIG_DEFENSIVE
1569 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_DEFENSIVE, int, int *);
1570#endif
1571#ifdef SQLITE_DBCONFIG_WRITABLE_SCHEMA
1572 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_WRITABLE_SCHEMA, int, int *);
1573#endif
1574#ifdef SQLITE_DBCONFIG_LEGACY_ALTER_TABLE
1575 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, int, int *);
1576#endif
1577#ifdef SQLITE_DBCONFIG_ENABLE_VIEW
1578 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_ENABLE_VIEW, int, int *);
1579#endif
1580#ifdef SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
1581 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, int, int *);
1582#endif
1583#ifdef SQLITE_DBCONFIG_TRUSTED_SCHEMA
1584 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_TRUSTED_SCHEMA, int, int *);
1585#endif
1586#ifdef SQLITE_DBCONFIG_STMT_SCANSTATUS
1587 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_STMT_SCANSTATUS, int, int *);
1588#endif
1589#ifdef SQLITE_DBCONFIG_REVERSE_SCANORDER
1590 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_REVERSE_SCANORDER, int, int *);
1591#endif
1592#ifdef SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE
1593 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE, int, int *);
1594#endif
1595#ifdef SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE
1596 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE, int, int *);
1597#endif
1598#ifdef SQLITE_DBCONFIG_ENABLE_COMMENTS
1599 SQLITEPP_DEFINE_DB_OPTION( SQLITE_DBCONFIG_ENABLE_COMMENTS, int, int *);
1600#endif
1601 //@ [DB Options]
1602
1603 //@ [VTab Options]
1604
1605 SQLITEPP_DEFINE_VTAB_OPTION_N(SQLITE_VTAB_CONSTRAINT_SUPPORT, int);
1606#ifdef SQLITE_VTAB_INNOCUOUS
1607 SQLITEPP_DEFINE_VTAB_OPTION_0(SQLITE_VTAB_INNOCUOUS );
1608#endif
1609#ifdef SQLITE_VTAB_DIRECTONLY
1610 SQLITEPP_DEFINE_VTAB_OPTION_0(SQLITE_VTAB_DIRECTONLY );
1611#endif
1612#ifdef SQLITE_VTAB_USES_ALL_SCHEMAS
1613 SQLITEPP_DEFINE_VTAB_OPTION_0(SQLITE_VTAB_USES_ALL_SCHEMAS );
1614#endif
1615
1616 //@ [VTab Options]
1617
1618 #undef SQLITEPP_DEFINE_DB_OPTION
1619 #undef SQLITEPP_DEFINE_VTAB_OPTION_0
1620 #undef SQLITEPP_DEFINE_VTAB_OPTION_N
1621
1622 SQLITEPP_SUPPRESS_SILLY_VARARG_WARNING_END
1623
1625}
1626
1627#ifdef __GNUC__
1628 #pragma GCC diagnostic pop
1629#endif
1630
1631#endif
1632
sqlite3_auto_extension
sqlite3_busy_handler
sqlite3_busy_timeout
sqlite3_cancel_auto_extension
sqlite3_changes64
A reference to a null terminated string.
Definition string_param.hpp:37
const T * c_str() const noexcept
Returns the stored pointer.
Definition string_param.hpp:50
SQL Function Context Object.
Definition context_iface.hpp:37
Database Connection.
Definition database_iface.hpp:108
void release_memory() const
Free memory used by the database connection.
Definition database_iface.hpp:1262
bool auto_increment
Whether column is auto-increment.
Definition database_iface.hpp:1290
void interrupt() noexcept
Interrupt a long-running query.
Definition database_iface.hpp:1061
void drop_modules_except(const char *const *keep)
Remove virtual table modules from database connection.
Definition database_iface.hpp:978
const char * collation_sequence
Collation sequence name.
Definition database_iface.hpp:1287
int vtab_on_conflict() const noexcept
Determine the virtual table conflict policy.
Definition database_iface.hpp:956
void create_module(const string_param &name, const sqlite3_module *mod, T *data, void(*destructor)(T *)=nullptr)
Register a virtual table implementation.
Definition database_iface.hpp:905
value * preupdate_new(int column_idx)
Returns value of a column of the table row after it is updated.
void busy_timeout(int ms)
Set a busy timeout.
Definition database_iface.hpp:154
void enable_load_extension(bool val)
Enable or disable extension loading.
Definition database_iface.hpp:1120
std::unique_ptr< blob > open_blob(const string_param &dbname, const string_param &table, const string_param &column, int64_t rowid, bool writable)
Open a blob.
void commit_hook(int(*handler)(type_identity_t< T > data_ptr) noexcept, T data_ptr) noexcept
Register a callback to be called on commit.
Definition database_iface.hpp:348
void drop_modules_except(const char *const (&keep)[N])
Remove virtual table modules from database connection.
Definition database_iface.hpp:991
class mutex * mutex() const noexcept
Retrieve the mutex for the database connection.
Definition database_iface.hpp:1174
void cacheflush()
Flush caches to disk mid-transaction.
Definition database_iface.hpp:843
void create_function(const char *name, int arg_count, int flags, T data_ptr, void(*func)(context *, int, value **) noexcept, void(*step)(context *, int, value **) noexcept, void(*last)(context *) noexcept, void(*destructor)(type_identity_t< T > data_ptr) noexcept)
Create or redefine SQL function.
T exec(std::u8string_view sql, T callback)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition database_iface.hpp:253
void update_hook(T handler_ptr) noexcept
Register a callback to be called whenever a row is updated, inserted or deleted in a rowid table.
int txn_state(const string_param &schema) const noexcept
Returns the transaction state of a database.
Definition database_iface.hpp:1327
T exec(std::string_view sql, T callback)
Run multiple statements of SQL with a callback.
void drop_modules()
Remove all virtual table modules from database connection.
Definition database_iface.hpp:968
void deserialize(const string_param &schema_name, std::byte *buf, size_t size, size_t buf_size, unsigned flags=0)
Deserialize a database.
Definition database_iface.hpp:1374
void overload_function(const string_param &name, int arg_count) noexcept
Overload a function for a virtual table.
Definition database_iface.hpp:1198
void create_function(const char *name, int arg_count, int flags, T impl_ptr, void(*destructor)(type_identity_t< T > obj) noexcept=nullptr)
Create or redefine SQL function.
void create_collation(const string_param &name, int encoding, T collator_ptr, void(*destructor)(type_identity_t< T > obj) noexcept=nullptr)
Define a new collating sequence.
void drop_modules_except(Args &&...args)
Remove virtual table modules from database connection.
Definition database_iface.hpp:1009
void autocheckpoint(int num_frames)
Configure an auto-checkpoint.
Definition database_iface.hpp:637
void file_control(const string_param &db_name, int op, void *data)
Low-level control of database file.
Definition database_iface.hpp:1034
void open_snapshot(const string_param &schema, const snapshot &snap)
Start a read transaction on an historical snapshot.
Definition database_iface.hpp:1446
void wal_hook(int(*handler)(type_identity_t< T > data_ptr, database *db, const char *db_name, int num_pages) noexcept, T data_ptr) noexcept
Register a callback to be called each time data is committed to a database in wal mode.
Definition database_iface.hpp:503
void declare_vtab(const string_param &sdl)
Declare the schema of a virtual table.
Definition database_iface.hpp:917
column_metadata table_column_metadata(const string_param &db_name, const string_param &table_name, const string_param &column_name) const
Extract metadata about a column of a table.
void create_collation(const string_param &name, int encoding, T collator_ptr, int(*compare)(type_identity_t< T > collator, int lhs_len, const void *lhs_bytes, int rhs_len, const void *rhs_bytes) noexcept, void(*destructor)(type_identity_t< T > collator) noexcept)
Define a new collating sequence.
void busy_handler(T handler_ptr)
Register a callback to handle SQLITE_BUSY errors.
void commit_hook(T handler_ptr) noexcept
Register a callback to be called on commit.
auto config(Args &&...args) -> void
Configure database connection.
Definition database_iface.hpp:864
bool is_interrupted() noexcept
Returns whether or not an interrupt is currently in effect.
Definition database_iface.hpp:1072
std::unique_ptr< snapshot > get_snapshot(const string_param &schema)
Record a database snapshot.
void auto_extension(void(*entry_point)(database *, const char **, const struct sqlite3_api_routines *))
Automatically load statically linked extension.
Definition database_iface.hpp:1140
~database() noexcept
Equivalent to sqlite3_close_v2.
Definition database_iface.hpp:143
std::pair< int, int > checkpoint(const string_param &db_name, int mode=SQLITE_CHECKPOINT_PASSIVE)
Checkpoint a database.
void create_window_function(const char *name, int arg_count, int flags, T impl_ptr, void(*destructor)(type_identity_t< T > obj) noexcept=nullptr)
Create or redefine SQL aggregate window function
int preupdate_blobwrite() const noexcept
Returns the index of the column being written via sqlite3_blob_write.
Definition database_iface.hpp:604
void cancel_auto_extension(void(*entry_point)(database *, const char **, const struct sqlite3_api_routines *))
Cancel automatic extension Loading.
Definition database_iface.hpp:1151
static std::unique_ptr< database > open(const string_param &db_filename, int flags, const char *vfs=nullptr)
Open a new database connection.
void preupdate_hook(T handler_ptr) noexcept
Register a callback to be called prior to each INSERT, UPDATE, and DELETE operation on a database tab...
void extended_result_codes(bool onoff)
Enable or disable extended result codes.
Definition database_iface.hpp:1025
const char * filename(const string_param &db_name) const noexcept
Return the filename for the database connection.
Definition database_iface.hpp:1042
int preupdate_count() const noexcept
Returns the number of columns in the row that is being inserted, updated, or deleted.
Definition database_iface.hpp:570
int limit(int id, int new_val) noexcept
Set or retrieve run-time limits.
Definition database_iface.hpp:1106
class statement * next_statement(const class statement *prev) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition database_iface.hpp:1188
void update_hook(void(*handler)(type_identity_t< T > data_ptr, int op, const char *db_name, const char *table, sqlite3_int64 rowid) noexcept, T data_ptr) noexcept
Register a callback to be called whenever a row is updated, inserted or deleted in a rowid table.
Definition database_iface.hpp:416
void create_window_function(const char *name, int arg_count, int flags, T data_ptr, void(*step)(context *, int, value **) noexcept, void(*last)(context *) noexcept, void(*current)(context *) noexcept, void(*inverse)(context *, int, value **) noexcept, void(*destructor)(type_identity_t< T > data_ptr) noexcept)
Create or redefine SQL aggregate window function
void collation_needed(T data_ptr, void(*handler)(type_identity_t< T > data_ptr, database *, int encoding, const char *name) noexcept)
Register a callback to be called when undefined collation sequence is required.
Definition database_iface.hpp:312
void deserialize(const string_param &schema_name, const std::byte *buf, size_t size, size_t buf_size, unsigned flags=0)
Deserialize a database.
Definition database_iface.hpp:1391
void load_extension(const string_param &file, const string_param &proc=nullptr)
Load an extension.
int64_t last_insert_rowid() const noexcept
Returns last insert rowid.
Definition database_iface.hpp:1081
void progress_handler(int step_count, T handler_ptr) const noexcept
Register a callback to be called on query progress.
int preupdate_depth() const noexcept
Returns the "depth" of an update from the top level SQL.
Definition database_iface.hpp:588
void deserialize(const string_param &schema_name, allocated_bytes buf, size_t size, size_t buf_size, unsigned flags=0)
Deserialize a database.
void preupdate_hook(void(*handler)(type_identity_t< T > data_ptr, database *db, int op, const char *db_name, const char *table, sqlite3_int64 rowid_old, sqlite3_int64 rowid_new) noexcept, T data_ptr) noexcept
Register a callback to be called prior to each INSERT, UPDATE, and DELETE operation on a database tab...
Definition database_iface.hpp:456
std::optional< bool > readonly(const string_param &db_name) const noexcept
Determine if a database is read-only.
const class statement * next_statement(const class statement *prev) const noexcept
Find the next prepared statement.
Definition database_iface.hpp:1184
bool not_null
Whether NOT NULL constraint exists.
Definition database_iface.hpp:1288
void create_module(const string_param &name, const sqlite3_module *mod)
Register a virtual table implementation.
Definition database_iface.hpp:891
value * preupdate_old(int column_idx)
Returns value of a column of the table row before it is updated.
void rollback_hook(T handler_ptr) noexcept
Register a callback to be called on rollback.
void collation_needed(T handler_ptr)
Register a callback to be called when undefined collation sequence is required.
T exec(std::u8string_view sql)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition database_iface.hpp:199
bool get_autocommit() const noexcept
Return the auto-commit mode.
Definition database_iface.hpp:1053
int64_t total_changes() const noexcept
Returns total number of rows modified.
Definition database_iface.hpp:1309
const char * data_type
Declared data type.
Definition database_iface.hpp:1286
void progress_handler(int step_count, int(*handler)(type_identity_t< T > data_ptr) noexcept, T data_ptr) const noexcept
Register a callback to be called on query progress.
Definition database_iface.hpp:1219
void busy_handler(int(*handler)(type_identity_t< T > data_ptr, int count_invoked) noexcept, T data_ptr)
Register a callback to handle SQLITE_BUSY errors.
Definition database_iface.hpp:277
auto vtab_config(Args &&...args) -> void
Configure virtual table.
Definition database_iface.hpp:936
int64_t changes() const noexcept
Count of the number of rows modified.
Definition database_iface.hpp:164
std::pair< allocated_bytes, size_t > serialize(const string_param &schema_name)
Serialize a database.
void recover_snapshot(const string_param &db)
Recover snapshots from a wal file.
Definition database_iface.hpp:1459
void exec(std::string_view sql)
Run multiple statements of SQL.
void rollback_hook(void(*handler)(type_identity_t< T > data_ptr) noexcept, T data_ptr) noexcept
Register a callback to be called on rollback.
Definition database_iface.hpp:382
span< std::byte > serialize_reference(const string_param &schema_name) noexcept
Serialize a database.
void reset_auto_extension() noexcept
Reset automatic extension loading.
Definition database_iface.hpp:1162
void set_last_insert_rowid(int64_t value) noexcept
Set the last insert rowid value.
Definition database_iface.hpp:1092
bool primary_key
Whether column part of PK.
Definition database_iface.hpp:1289
const char * db_name(int idx) noexcept
Return schema names.
Definition database_iface.hpp:1478
void wal_hook(T handler_ptr) noexcept
Register a callback to be called each time data is committed to a database in wal mode.
Return type for table_column_metadata()
Definition database_iface.hpp:1285
Return type for status()
Definition database_iface.hpp:1269
Exception used to report any SQLite errors.
Definition exception_iface.hpp:166
Base functionality for all fake wrapper classes
Definition handle.hpp:27
T * c_ptr() const noexcept
Access the real underlying SQLite type.
Definition handle.hpp:45
SQLite Mutex.
Definition mutex_iface.hpp:45
A database snapshot.
Definition snapshot_iface.hpp:42
Prepared Statement Object.
Definition statement_iface.hpp:41
Dynamically Typed Value Object.
Definition value_iface.hpp:35
sqlite3_close_v2
sqlite3_collation_needed
sqlite3_commit_hook
T conjunction_v
sqlite3_create_module_v2
T data(T... args)
sqlite3_db_cacheflush
sqlite3_db_config
sqlite3_db_filename
sqlite3_db_mutex
sqlite3_db_name
sqlite3_db_release_memory
sqlite3_declare_vtab
sqlite3_deserialize
sqlite3_drop_modules
sqlite3_enable_load_extension
sqlite3_extended_result_codes
sqlite3_file_control
T forward(T... args)
sqlite3_get_autocommit
basic_string_param< char > string_param
Convenience typedef.
Definition string_param.hpp:57
@ reset
Reset the statement (does not affect the bindings)
sqlite3_interrupt
T is_nothrow_invocable_r_v
T is_null_pointer_v
T is_pointer_v
sqlite3_last_insert_rowid
sqlite3_limit
sqlite3_load_extension
ThinSQLite++ namespace.
Definition backup_iface.hpp:17
sqlite3_next_stmt
sqlite3_overload_function
sqlite3_preupdate_hook
sqlite3_progress_handler
#define SQLITE_ERROR
#define SQLITE_OK
sqlite3_reset_auto_extension
sqlite3_set_last_insert_rowid
T size(T... args)
sqlite3_snapshot_open
sqlite3_snapshot_recover
sqlite3_total_changes64
sqlite3_txn_state
sqlite3_update_hook
sqlite3_vtab_config
sqlite3_vtab_on_conflict
sqlite3_wal_autocheckpoint
sqlite3_wal_hook