/Code /Blog /About /Resume

zig-sqlite - small wrapper around SQLite's C API

zig-sqlite is a Zig wrapper around SQLite's C API.


SQLite is a C library, directly usable in Zig using @cImport.

While this works, the goal of zig-sqlite is to:

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:

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 !