These libraries are experimental. APIs may change without notice. Generated from source with koruc 0.1.7 on 8/19/2026.
SQLite3
@korulang/sqlite3@0.0.1SQLite3 bindings for Koru with phantom type obligations
sqlite3/index.kz · 13 tors
@koru/sqlite - SQLite bindings for Koru
First official Koru library package.
Demonstrates: phantom obligations, auto-dispose, ~std/build:requires
Phantom lifecycles
Derived from the phantom labels in the declarations below — state! issues an
obligation the compiler will chase, !state discharges it, a bare state holds it without moving it. Nothing here is hand-drawn.
Connection 1 state opened!Statement 2 states row!prepared!string 1 state // Connection Management
~pub tor open { path: string }
| db *Connection<opened!>
| err { code: i32, msg: string }~pub tor close { conn: *Connection<!opened> }// Query Execution
//
// `exec` only READS the connection to run SQL — it never closes it — so it
// BORROWS `<opened>` rather than consuming and re-minting. The caller keeps its
// live `opened!` obligation across the call and still owes exactly one `close`.
~pub tor exec { conn: *Connection<opened>, sql: string }
| ok
| err { code: i32, msg: string }// Literal SQL query - takes a runtime SQL string
// For compile-time parameterized queries, use ~query { ... } with Source block
~pub tor query.literal { conn: *Connection<!opened>, sql: string }
! row *Statement<row!>
| done *Connection<opened!>
| err { conn: *Connection<opened!>, code: i32, msg: string }// No-op consumer of the per-row borrow. The compiler auto-inserts this to
// release `<row!>` at each row-body boundary; the user never calls it. Its
// existence is what lets the phantom checker prove the row borrow is scoped —
// escape it (capture past the row body) and the build fails with KORU030.
~pub tor release.row { stmt: *Statement<!row> }~[comptime|transform] pub tor query {
source: Source,
invocation: *const Invocation,
item: *const Item,
program: *const Program,
allocator: std.mem.Allocator
} -> SiteResult// Runtime impl event for shape-checking (never actually runs - inline code does)
// conn comes from invocation args, captured in generated code
~[norun] pub tor query.impl { conn: *Connection<!opened> }
| row { conn: *Connection<opened!>, stmt: *Statement<prepared!> }
| empty *Connection<opened!>
| err { conn: *Connection<opened!>, code: i32, msg: string }// Get next row from statement
~pub tor next { conn: *Connection<!opened>, stmt: *Statement<!prepared> }
| row { conn: *Connection<opened!>, stmt: *Statement<prepared!> }
| done *Connection<opened!>
| err { conn: *Connection<opened!>, code: i32, msg: string }// Finalize text - acknowledges we're done with borrowed text pointer
// Must be called BEFORE finalize.stmt (text becomes invalid after stmt finalize)
~pub tor finalize.text { text: string<!text> }// Finalize statement - releases the prepared statement
~pub tor finalize.stmt { stmt: *Statement<!prepared> }// Column Access (within row context)
~pub tor col.int { stmt: *Statement<row>, index: i32 } -> i64// NOTE: text is a ROW-SCOPED borrow (valid only within the `! row` body, like
// std/fs:read-lines' `! line`). Pristine-later: hand back an owned copy so it's
// safe to capture across rows. For now it matches the stdlib borrow idiom.
~pub tor col.text { stmt: *Statement<row>, index: i32 } -> string~pub tor col.real { stmt: *Statement<row>, index: i32 } -> f64