zig-sqlite - small wrapper around SQLite's C API
zig-sqlite is a Zig wrapper around SQLite's C API.
Introduction
SQLite is a C library, directly usable in Zig using @cImport
.
While this works, the goal of zig-sqlite
is to:
- abstract away the C semantics of directly using sqlite
- provide powerful, type safe abstractions for a statement and iterator
How it works
C interop
@cImport
parses the sqlite3.h
header and import symbols such as functions, types, etc. Zig code can then use these symbols directly.
One problem with this is that sqlite is designed for C:
- errors are returned as an int
- strings are represented by a pointer to UTF-8 or UTF-16 bytes and a length integer
This doesn't match well with Zig's builtin features:
Enabling my users to use these features is one of the primary goal of this wrapper.
Type safe statement
I designed a statement abstraction which make use of a comptime known query and the anytype
type.
The high level goal is to know at comptime the number and types of bind parameters, such as calls to bind values will not compile if their types do not match.
This is achieved by parsing the query at comptime and extracting its bind parameters types.
The statement type is then completely specific for this particular parsed query which allows us to type check the bind parameters.
The API looks something like this:
var stmt = try db.prepare("SELECT id FROM user WHERE name = ?{text} AND age < ?{usize}");
defer stmt.deinit();
const rows = try stmt.all(usize, .{
.name = "Vincent",
.age = @as(usize, 200),
});
defer rows.deinit();
for (rows) |row| {
std.debug.print("row: {any}\n", .{row});
}
The statement obtained by calling prepare
has a all
method that will fail to compile if the provided bind parameters aren't of the correct type.
Learn more
The README provides highly detailed information on how to use the library in your Zig code. Give it a try !