diff options
author | John Turner <jturner.usa@gmail.com> | 2025-09-14 00:16:10 -0400 |
---|---|---|
committer | John Turner <jturner.usa@gmail.com> | 2025-09-14 00:16:10 -0400 |
commit | 13e0821fd783a1d5083d825af53cf20e8dcbfd76 (patch) | |
tree | 1ea363b0f13b3e87d177100e6ae6b9f30a2de1b8 /subprojects/boost-sqlite/doc/reference/vtable.adoc | |
parent | aa55cb93036a89c64c08e08f4e1de4fa1fd5a775 (diff) | |
parent | efcea3a80da7c4479d5fe168435ecc9fd06bdc72 (diff) | |
download | sqlite-kv-bench-13e0821fd783a1d5083d825af53cf20e8dcbfd76.tar.gz |
Merge commit 'efcea3a80da7c4479d5fe168435ecc9fd06bdc72' as 'subprojects/boost-sqlite'
Diffstat (limited to 'subprojects/boost-sqlite/doc/reference/vtable.adoc')
-rw-r--r-- | subprojects/boost-sqlite/doc/reference/vtable.adoc | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/subprojects/boost-sqlite/doc/reference/vtable.adoc b/subprojects/boost-sqlite/doc/reference/vtable.adoc new file mode 100644 index 0000000..5063ffc --- /dev/null +++ b/subprojects/boost-sqlite/doc/reference/vtable.adoc @@ -0,0 +1,275 @@ +== `sqlite/vtable.hpp` + +Please read the <<vtables, virtual tables section>> for a more detailed explanation. + +[source,cpp] +---- +namespace vtab +{ + + +// Helper type to set a function through the xFindFunction callback +struct function_setter +{ + /** Set the function + * + * The function can either take a single argument, a `span<sqlite::value, N>` + * for scalar functions, + * or a `context<Args...>` as first, and the span as second for aggegrate functions. + * + */ + template<typename Func> + void set(Func & func); + template<typename ... Args, std::size_t Extent> + void set(void(* ptr)(context<Args...>, span<value, Extent>)) noexcept; + template<typename T, typename ... Args, std::size_t Extent> + void set(T(* ptr)(context<Args...>, span<value, Extent>)); + + template<std::size_t Extent> + void set(void(* ptr)(span<value, Extent>)); + template<typename T, std::size_t Extent> + void set(T(* ptr)(span<value, Extent>)); +}; + + +// requires Sqlite 3.38 +// Utility function that can be used in `xFilter` for the `in` operator. <1> + +struct in +{ + struct iterator + { + iterator() = default; + + iterator & operator++(); + iterator operator++(int); + + const value & operator*() const; + + const value * operator->() const; + + bool operator==(const iterator& other) const; + bool operator!=(const iterator& other) const; + }; + + // Returns a forward iterator to the `in` sequence for an `in` constraint pointing to the begin. + iterator begin(); + // Returns a forward iterator to the `in` sequence for an `in` constraint pointing to the end. + iterator end(); +explicit in(sqlite::value out); +}; + + + +// index info used by the find_index function <2> +struct index_info +{ + // Returns constraints of the index. + span<const sqlite3_index_info::sqlite3_index_constraint> constraints() const; + + // Returns ordering of the index. + span<const sqlite3_index_info::sqlite3_index_orderby> order_by() const; + + span<sqlite3_index_info::sqlite3_index_constraint_usage> usage(); + + + sqlite3_index_info::sqlite3_index_constraint_usage & usage_of( + const sqlite3_index_info::sqlite3_index_constraint & info); + + // Receive the collation for the contrainst of the position. requires 3.22 + const char * collation(std::size_t idx) const; + + int on_conflict() const; + + // Returns true if the constraint is distinct. requires sqlite 3.38 + bool distinct() const; + + // Requires sqlite 3.38 + value * rhs_value(std::size_t idx) const; + + void set_already_ordered(); + void set_estimated_cost(double cost); + // requires sqlite 3.8.2 + void set_estimated_rows(sqlite3_int64 rows); + // requires sqlite 3.9 + void set_index_scan_flags(int flags); + // requires sqlite 3.10 + std::bitset<64u> columns_used(); + + void set_index(int value); + void set_index_string(char * str, bool take_ownership = true); + + sqlite3_index_info * info() const; + sqlite3 * db() const; +}; + + +struct module_config +{ + // Can be used to set SQLITE_VTAB_INNOCUOUS. Requires sqlite 3.31 + void set_innocuous(); + // Can be used to set SQLITE_VTAB_DIRECTONLY. Requires sqlite 3.31 + void set_directonly() {sqlite3_vtab_config(db_, SQLITE_VTAB_DIRECTONLY);} + + + // Can be used to set SQLITE_VTAB_CONSTRAINT_SUPPORT + void set_constraint_support(bool enabled = false); +}; + +template<typename Table> +struct module +{ + using table_type = Table; + + // Creates the instance + // The instance_type gets used & managed by value, OR a pointer to a class that inherits sqlite3_vtab. + // instance_type must have a member `declaration` that returns a `const char *` for the declaration. + virtual result<table_type> create(sqlite::connection db, int argc, const char * const argv[]) = 0; + + // Create a table + // The table_type gets used & managed by value, OR a pointer to a class that inherits sqlite3_vtab. + // table_type must have a member `declaration` that returns a `const char *` for the declaration. + virtual result<table_type> connect(sqlite::connection db, int argc, const char * const argv[]) = 0; +}; + +template<typename Table> +struct eponymous_module +{ + using table_type = Table; + + // Creates the instance + // The instance_type gets used & managed by value, OR a pointer to a class that inherits sqlite3_vtab. + // instance_type must have a member `declaration` that returns a `const char *` for the declaration. + virtual result<table_type> connect(sqlite::connection db, int argc, const char * const argv[]) = 0; + + eponymous_module(bool eponymous_only = false); + + bool eponymous_only() const;' + protected: + bool eponymous_only_{false}; + +}; + + +// The basis for vtable +template<typename Cursor> +struct table : protected sqlite3_vtab +{ + using cursor_type = Cursor; + + virtual result<void> config(module_config &); + + // The Table declaration to be used with sqlite3_declare_vtab + virtual const char *declaration() = 0; + + // Destroy the storage = this function needs to be present for non eponymous tables + virtual result<void> destroy(); + + // Tell sqlite how to communicate with the table. + // Optional, this library will fill in a default function that leaves comparisons to sqlite. + virtual result<void> best_index(index_info & /*info*/); + + // Start a search on the table. + // The cursor_type gets used & managed by value, OR a pointer to a class that inherits sqlite3_vtab_cursor. + virtual result<cursor_type> open() = 0; + + // Get the connection of the vtable + sqlite::connection connection() const; + + table(const sqlite::connection & conn); +}; + + +// Cursor needs the following member. +template<typename ColumnType = void> +struct cursor : protected sqlite3_vtab_cursor +{ + using column_type = ColumnType; + + // Apply a filter to the cursor. Required when best_index is implemented. + virtual result<void> filter( + int /*index*/, const char * /*index_data*/, + boost::span<sqlite::value> /*values*/) + { + return {system::in_place_error, SQLITE_OK}; + } + + // Returns the next row. + virtual result<void> next() = 0; + + // Check if the cursor is and the end + virtual bool eof() = 0; + + // Returns the result of a value. It will use the set_result functionality to create a an sqlite function. <3> + virtual result<column_type> column(int idx, bool no_change) = 0; + // Returns the id of the current row + virtual result<sqlite3_int64> row_id() = 0; + + // Get the table the cursor is pointing to. + vtab::table<cursor> & table(); + const vtab::table<cursor> & table() const; +}; + + +// Group of functions for modifications. The table must inherit this to be modifiable. +struct modifiable +{ + virtual result<void> delete_(sqlite::value key) = 0; + // Insert a new row + virtual result<sqlite_int64> insert(sqlite::value key, span<sqlite::value> values, int on_conflict) = 0; + // Update the row + virtual result<sqlite_int64> update(sqlite::value old_key, sqlite::value new_key, span<sqlite::value> values, int on_conflict) = 0; +}; + +// Group of functions to support transactions. The table must inherit this to support transactions. +struct transaction +{ + // Begin a tranasction + virtual result<void> begin() = 0; + // synchronize the state + virtual result<void> sync() = 0; + // commit the transaction + virtual result<void> commit() = 0; + // rollback the transaction + virtual result<void> rollback() = 0; +}; + +// Base class to enable function overriding See `xFindFunction`. +struct overload_functions +{ + virtual result<void> find_function( + function_setter fs, + int arg, const char * name) = 0; // <4> +}; + +// Support for recursive transactions. Requires sqlite 3.7.7 +struct recursive_transaction +{ + // Save the current state with to `i` + virtual result<void> savepoint(int i) = 0; + // Release all saves states down to `i` + virtual result<void> release(int i) = 0; + // Roll the transaction back to `i`. + virtual result<void> rollback_to(int i) = 0; +}; + +/** Register a vtable <5> + Returns a reference to the module as stored in the database. It's lifetime is managed by the database. +*/ +template<typename T> +auto create_module(connection & conn, + cstring_ref name, + T && module, + system::error_code & ec, + error_info & ei) -> typename std::decay<T>::type &; +template<typename T> +auto create_module(connection & conn, + const char * name, + T && module) -> typename std::decay<T>::type &; +---- +<1> See https://www.sqlite.org/capi3ref.html#sqlite3_vtab_in_first[vtab_in_first] +<2> See https://www.sqlite.org/vtab.html#xbestindex[best_index] +<3> See https://www.sqlite.org/c3ref/vtab_nochange.html[vtab_no_change] +<4> See https://www.sqlite.org/vtab.html#xfindfunction[find_function] +<5> See https://www.sqlite.org/vtab.html[vtab] + |