libsl3 1.2.47002
A C++ interface for SQLite
|
libsl3 enables efficient communication with SQLite3 databases using the natural approach, SQL.
The library does not attempt to function as an ORM (Object-Relational Mapping) and does not introduce C++ syntax resembling SQL for interacting with a SQLite database.
Reading from and writing to a database is accomplished through SQL and prepared commands, also known as stored procedures.
The library fully supports the SQLite duck typing concept, but it also offers a means to incorporate type checking when communicating with a database.
libsl3 stared as a C++98 project long time ago. Later, when C++11 was new, it became a modern C++11 interface to sqlite. Today, libsl3 it's still around. A C++ interface for SQLite. Active development happens rarely but the library is still maintained and updated if required.
libsl3 can be build and consumed without any external dependencies. But you might want to use sqlite3 installations from your system.
An easy way is consuming sl3 via CMake's 'FetchContent'
If you want to use the system sqlite3 installation, you can omit the line SET(sl3_USE_INTERNAL_SQLITE3 ON)
Get you copy of the source code from the libsl3 GitHub repository.
The project has the following dependencies:
There are 3 options to deal with dependencies.
If doxygen is not found it will not be possible to build the documentation.
See below for how to use either vcpkg or FetchContent.
The library can be build with CMake. No surprises here.
If you use vcpkg, the most easy way to build the library is:
There is also a xcode preset for MacOS, and a msv22 preset for Windows.
MacOS:
Windows:
In case you do not have vcpkg installed, the most simple way to get started is
If you have sqlite3 installed on your system, you can use it by omitting -Dsl3_USE_INTERNAL_SQLITE3=ON
CMake options to control the build process:
sl3_USE_INTERNAL_SQLITE3:
sl3_BUILD_TESTING:
For the internal sqlite distribution there are several options to configure sqlite3 available.
Advantages using the internal sqlite3
Programs consuming libsl3 do not need to link against sqlite3.
Disadvantages using the internal sqlite3
All the tests can be found in the tests subdirectory.
Existing tests try to cover as much as possible, see the coverage report for details.
A database is represented via sl3::Database.
A database can execute SQL strings to read or write data.
A sl3::Command is a compiled SQL statement which can contain parameters.
Parameters are sl3::DbValues, a sl3::Container of sl3::DbValue instances.
sl3::DbValues can also be used to receive data from a database.
Requesting data from a database will return a sl3::Dataset with rows of sl3::DbValues where each field is a sl3::DbValue.
Another and fully customizable way to receive data from a database is covered in the RowCallback and Callback functions section.
since the ostream operator for sl3::DbValue is overloaded, this will print
sl3::Database encapsulates a sqlite database.
It can be directly used, but it has also a virtual destructor and can be used as a base class.
The types in libsl3 are those which are available in datatypes as sqlite does.
since a database value can also be NULL there is a type for it.
There is one additional sl3::Type.
In sqlite a column can hold different types and libsl3 supports this concept.
See sl3::DbValue for more information.
This class can be used to read from and write to a sl3::Database.
A sl3::DbValues can hold different types. It can be defined if any type is allowed for an instance or only a certain one.
There are two sl3::Type properties. One defines the type rule, the other the type value.
Both properties are used to validate reads and writes at runtime.
If a value is set or read that is omitted by the type property an sl3::ErrTypeMisMatch exception is thrown.
Setting a value can be done via
sl3::DbValue::setNull can be used to set a value to Null.
There are getters for each type
There are 2 version for each of this function. With and without a default value as argument.
The version without a default value will throw a sl3::ErrNullValueAccess exception is case that sl3::DbValue::isNull is true for the instance.
The version with a default value as argument will return the passed argument in case that the current sl3::DbValue::isNull.
If a type getter is used for a wrong storage type a sl3::ErrTypeMisMatch exception is thrown.
Additional, there is a sl3::DbValue::get version which will never throw.
This function always requires a default value which has to be one of the 4 value types.
If the type is incorrect or the value is Null the given default value will be returned.
This example will print
A sl3::Command is a compiled SQL statement which can contain parameters.
sl3::Database::prepare does create a command.
If a command has parameters the types are specified at creation.
A command can return data or not, depending on the SQL that is used.
A insert or update statement does not return data, while a select statement does.
A command has therefor 2 ways to run it.
In the A first example overview example all sl3::Command parameters have been of type sl3::Typ::Variant since nothing was specified.
But it can be ensured that certain types are used.
The output of this program will be:
It is not a problem to insert different types into a column, sqlite supports this and so does libsl3
But is might be unwanted and can therefore be turned off.
A sl3::Dataset is a generic way to receive data from a sl3::Database.
It is return by a sl3::Command::select or sl3::Database::select
If there are different types in a column, a sl3::Dataset will automatically provide correct sl3::DbValue object.
running this program will print
It might be unwanted to get different types for one column into a sl3::Dataset.
This can be ensured by passing the allowed sl3::Types to the sl3::Database::select call.
If the wanted types are not those in the table, an sl3::TypeMisMatch exception is thrown.
this code will throw an exception, as expected and print
A custom way to handle query results is to use a sl3::RowCallback or the sl3::Command::Callback function.
They can be passed to the sl3::Database::execute and sl3::Command::execute function.
The callback will be called with a sl3::Columns representing the current row for each row in the query result.
The callback returns if it wants proceed to be called or not.
In a callback the sl3::Columns class give access to the current row.
There are several methods to query the type, size and get the values.
Running this program, the output will be