Most useful programs eventually keep something, and for twenty-five years the
answer to “keep it where?” has very often been sqlite — a library whose
reliability and testing culture we admire and do not pretend to match. What we
can do is meet it well. As of today the
starter repository carries
libraries/sqlite: a reusable Mica library over the system sqlite3, the first
rung of the libraries shelf.
What using it looks like
db := Open("notes.db") on fail e do WriteLn("open failed");
q := Query(db, "select title, stars from notes where stars >= ? order by stars desc") on fail e do WriteLn("query failed");
BindInt64(q, 1, 3) on fail e do WriteLn("bind failed");
for row in Rows(q) do
begin
WriteLn("%ls (%lld)", ColumnText(row, 0), ColumnInt64(row, 1));
end
on fail e do WriteLn("step failed");
Close(db);Prepared statements with binds, rows arriving through a for loop, text
columns as real strings, and failure on the language’s own channel — Open
and Query fail with a named error domain, and forgetting to handle that is
a compile error, never a silent nil. The database handle is a borrow: sqlite
owns its cells, Close returns them, and the ownership analysis holds the
program to exactly that story.
Not a binding — source you own
The rung is three files you copy into your project: the library unit, its contract, and a four-function C shim. No package manager, no version to chase, no wrapper layer to trust blindly. The unit is written as teaching material — every procedure carries the why, not just the what — so the code you depend on is code you can read in one sitting and change when your application needs something we did not think of.
The build is one Makefile with two steps, and it bakes C and Mica together: the shim compiles like any C file, the library compiles once into an archive and emits its own contract, and your program links against the two contracts — each side speaking its own language, the contracts telling the truth between them. We think mixed C-and-Mica projects should feel exactly this boring.
The boundary, honestly
Mica has no function pointers, and sqlite’s sqlite3_exec wants one. That
meeting produced the language’s third declared subprogram kind, the
callback — bound by name at a contract-declared slot, fired only by the
library while the call runs, its whole environment the context record the
call visibly hands over. And where C answers a handle through a
pointer-to-pointer parameter, a spelling Mica’s value model deliberately does
not have, a two-line shim answers the handle directly. The library names both
patterns in its README, because every later rung of the shelf — compression,
HTTP, postgres — will reuse them.
To the sqlite community
Thank you for a quarter century of software we could build on with a straight face. If you find something in our binding that sqlite would do differently or better, we want to hear it — the shelf exists to meet great C libraries on their own terms, and to help the communities around them wherever a Mica program can. The tutorial builds a small notes application on this rung, start to finish.