SQLite3 ORM Engine
Relevant source files
The following files were used as context for generating this wiki page:
The SQLite3 ORM Engine provides a C++20 type-safe interface for interacting with SQLite3 databases. It automates the mapping between C++ structures and database tables, generates SQL statements at compile-time or through templates, and manages resource lifecycles for database connections and prepared statements.
This engine utilizes template metaprogramming and C++20 concepts to ensure that database operations are validated against C++ types. It supports schema generation, CRUD operations, and complex query building with automatic parameter binding.
Sources: include/HXLibs/db/sqlite3/SqliteDB.hpp, include/HXLibs/db/sql/DataBase.hpp, include/HXLibs/db/sql/Dml.hpp
Core Architecture
The architecture relies on a CRTP (Curiously Recurring Template Pattern) structure to provide a common interface for different database backends while maintaining high performance.
Component Hierarchy
The diagram shows the relationship between the base database templates and the SQLite-specific implementation.
Sources: include/HXLibs/db/sqlite3/SqliteDB.hpp:33-40, include/HXLibs/db/sql/DataBase.hpp:31-75
Database Management
SqliteDB manages the raw sqlite3* handle and statement cache. It provides methods to open and close database files and execute raw SQL strings. The class ensures that leaked statements are tracked in debug mode and finalized before the database is closed.
Sources: include/HXLibs/db/sqlite3/SqliteDB.hpp:54-94
Schema Generation
The CreateDbSql utility generates CREATE TABLE and CREATE INDEX SQL statements by reflecting on C++ structures.
Type Mapping
C++ types map to SQLite storage classes as follows:
| C++ Type | SQLite Type |
|---|---|
std::is_integral | INTEGER |
std::is_floating_point | REAL |
meta::StringType | TEXT |
db::Date | DATE |
db::Time | TIME |
db::Blob | BLOB |
CustomType | TEXT (default) |
Sources: include/HXLibs/db/sqlite3/MakeCreateDbSql.hpp:42-70, include/HXLibs/db/sql/SqlType.hpp:32-47
Constraint Handling
The engine supports various field and table-level constraints through the Constraint<T, ...> wrapper:
- Primary Keys: Defined via
attr::PrimaryKeyordb::AutoIncrementPrimaryKey. - Not Null: Ensures fields cannot contain NULL values.
- Foreign Keys: Enforces relationships between tables, ensuring type consistency between local and referenced fields.
- Indexes: Supports single-column and composite indexes with ordering (ASC/DESC).
Sources: include/HXLibs/db/sqlite3/MakeCreateDbSql.hpp:95-155, include/HXLibs/db/sqlite3/MakeCreateDbSql.hpp:240-300
Data Manipulation (DML)
The engine provides a fluent API for SQL operations, including SELECT, INSERT, UPDATE, and DELETE.
Query Execution Flow
The flow shows how a SQL operation progresses from high-level C++ calls to database execution.
Sources: include/HXLibs/db/sql/Dml.hpp:85-110, include/HXLibs/db/sql/Dml.hpp:320-350
Statement Caching
The sqlTemplate<UniqueId>() function caches generated SQL and prepared statements. The SQL string is constructed only once for a given unique identifier, significantly reducing overhead for repeated operations.
Sources: include/HXLibs/db/sql/DataBase.hpp:38-51
Selection and Result Mapping
SqliteStmt handles the low-level data extraction. It maps SQLite columns back to C++ types using sqlite3_column_* functions based on the expected type in the C++ struct.
// Example: Selecting data into a vector of results
auto res = db.sqlTemplate<"unique_query"_fs>()
.select<Col(&User::id), Col(&User::name)>()
.from<User>()
.where<Col(&User::age) > 18>()
.exec();
Sources: include/HXLibs/db/sqlite3/SqliteStmt.hpp:67-95, tests/db/MakeSql.cpp:108-120
Advanced Features
Composite and Foreign Keys
Table-level constraints like composite primary keys and union foreign keys are defined in a nested UnionAttr structure within the table class. The CreateDbSql engine iterates through this structure to generate correct table-level SQL constraints.
Sources: include/HXLibs/db/sqlite3/MakeCreateDbSql.hpp:169-217
Parameter Binding
The engine supports both positional and named parameters using db::param<T> and db::bind<"name">. This prevents SQL injection and allows reusing prepared statements with different values.
Sources: include/HXLibs/db/sql/Param.hpp, include/HXLibs/db/sqlite3/SqliteStmt.hpp:145-168
Transaction and Mutation Feedback
For INSERT, UPDATE, and DELETE, the engine can return modified data using the RETURNING clause (supported by modern SQLite versions). The execGetChanges() method provides the number of rows affected by the last operation.
Sources: include/HXLibs/db/sql/Dml.hpp:615-650, include/HXLibs/db/sqlite3/SqliteStmt.hpp:176-193
Summary
The SQLite3 ORM Engine in HXLibs bridges C++20 structures and SQLite3 databases through a high-performance, type-safe API. By leveraging compile-time reflection and a sophisticated DML builder, it eliminates manual SQL string concatenation and error-prone manual column binding. The inclusion of schema generation and comprehensive constraint support makes it a robust solution for embedded data persistence.