An Ecto-Style ORM
This project is longer than a recipe: one library, designed in public, with one decision in each chapter. The library is a database layer in the shape of Ecto. That design is a good stress test of comptime. The schema is a type, and the compiler checks the query builder against that type before the program runs. Migrations are data. The driver is behind one seam, so the same code runs on SQLite or PostgreSQL.
- The schema is a type. At compile time, the library derives every other part from the schema, and declares nothing twice.
- A query builder that checks field names during compilation changes a class of runtime SQL errors into build errors.
errdefermakes a transaction correct on the error paths that you did not think about.- If you put the driver behind one seam, the same query code runs on two databases. If the driver code is in many places, the code runs only on the database that you wrote first.
9 chapters.
- What Is an Ecto-Style ORM?The Elixir design that these chapters copy, explained for readers who never wrote Elixir.
- A Type Function as the Front DoorThe central pattern of a Zig library: take the type of the caller, and return a richer type.
- A Typed Query BuilderCompile-time field checks and output that stops injection, with no allocator.
- Validation from DeclarationsOptional capabilities found with @hasDecl, the convention-over-configuration of Zig.
- Write RowsINSERT and UPDATE statements derived from the schema, with the values in a typed array.
- The Adapter SeamOne query renderer, several SQL dialects, resolved at compile time.
- Migrations as DataThe schema history as an append-only list, and a pure plan that applies it.
- The RepoThe composition root, and the fake driver that lets you test the full ORM.
- Transactions and errdeferCOMMIT on success, ROLLBACK on each error path, enforced by four lines.