boost_sqlite 1
A sqlite C++ library
|
This library provides a simple C++ sqlite library.
It includes:
sqlite provides an excellent C-API, so this library does not attempt to hide, but to augment it.
You can either build the library and link against boost_sqlite
for embedding it, or boost_sqlite_ext
for extensions.
If you want to use it for extensions you'll need to define BOOST_SQLITE_COMPILE_EXTENSION
or include boost/sqlite/extensions.hpp
first.
First we open a database. Note that this can be ":memory:"
for an in-memory database.
Next we're creating tables using boost::sqlite::connection::execute, because it can execute multiple statements in one command:
Next, we'll use a prepared statement to insert multiple values by index:
Prepared statements can also be used multiple time and used with named parameters instead of indexed.
Now that we have the values in the table, let's add a custom aggregate function to create a comma separated list:
Print out the query with aggregates libraries:
Alternatively a query result can also be read manually instead of using a loop:
sqlite3 has a weak typesystem, where everything is one of following value_types:
integer
floating
text
blob
null
The result of a query is a field type, while a value is used in functions.
Fields & values can have subtypes, while parameter to prepared statements do not have thos associated.
Because of this the values that can be bound to an execute need to be convertible to a fixed set of types (see param_ref for details).
When a value is returned from a custom function, such as done through create_scalar_function, additional types can be added with the following tag_invoke function:
An implementation can look like this:
Queries can be typed through tuples, describe or, if you're on C++20, by plain structs. The type to hold them is static_resultset<T>
which will check if the columns match the result types before usage. Tuples are matched by position, structs by name.
The following types are allowed in a static query result:
sqlite::value
int
sqlite_int64
double
std::string
sqlite::string_view
sqlite::blob
sqlite::blob_view
You'll need to include boost/sqlite/static_resultset.hpp
for this to work.
Since sqlite is running in the same process you can add custom functions that can be used from within sqlite.
This library also simplifies adding virtual tables significantly; virtual tables are table that are backed by code instead of data.
See create_module and prototype for more details.
This library can also be used to build a sql plugin:
The plugin can then be loaded & used like this:
To build a plugin you need to define BOOST_SQLITE_COMPILE_EXTENSION
(e.g. by including boost/sqlite/extension.hpp
or linking against boost_sqlite_ext
).
This will include the matching sqlite header (sqlite3ext.h
) and will move all the symbols into an inline namespace ext
inside boost::sqlite
.
While there are many sqlite wrappers out there, most haven't been updated in the last five years - while sqlite has.
Here are some actively maintained ones:
SQLiteCpp is the closest to this library, a C++11 wrapper only depending on sqlite & the STL. It's great and served as an inspiration for this library. boost.sqlite does provide more functionality when it comes to hooks, custom functions & virtual tables. Furthermore, boost.sqlite has a non-throwing interface and supports variants & json, as those are available through boost.
This library takes a different approach, by making everything an iostream
interface. iostream
interfaces have somewhat fallen out of favor.
As the name says, it's an ORM. While there is nothing wrong with ORMs, they are one layer of abstraction above a client library like this.
SOCI is an abstraction layer for multiple databases in C++, including sqlite. It's interfaces encourages dynamic building of query string, which should not be considered safe.