These libraries are experimental. APIs may change without notice. Generated from source on 3/14/2026.
SQLite3
First official Koru library package.
@koru/sqlite3
@koru/sqlite - SQLite bindings for Koru
First official Koru library package.
Demonstrates: phantom obligations, auto-dispose, ~std.build:requires
// ============================================================================
// Connection Management
// ============================================================================
~pub event open {
path: []const u8
}
| db { conn: *Connection[opened!] }
| err { code: i32, msg: []const u8 }~pub event close {
conn: *Connection[!opened]
}
| closed {}// ============================================================================
// Query Execution
// ============================================================================
~pub event exec {
conn: *Connection[!opened], sql: []const u8
}
| ok { conn: *Connection[opened!] }
| err { conn: *Connection[opened!], code: i32, msg: []const u8 }// Literal SQL query - takes a runtime SQL string
// For compile-time parameterized queries, use ~query { ... } with Source block
~pub event query.literal {
conn: *Connection[!opened], sql: []const u8
}
| row { conn: *Connection[opened!], stmt: *Statement[prepared!] }
| empty { conn: *Connection[opened!] }
| err { conn: *Connection[opened!], code: i32, msg: []const u8 }// ============================================================================
// Parameterized Query - Compile-time SQL with type-safe bindings
// ============================================================================
// Usage:
// ~libs.sqlite3:query(conn: db) {
// SELECT * FROM users WHERE id = {{user_id:d}} AND name = {{name:s}}
// }
// | row r |> ...
// | empty |> ...
// | err e |> ...
//
// Type hints: :d = int64, :s = text, :f = float64
// Variables are captured from scope - no need to pass them as parameters
~[comptime|transform]pub event query {
source: Source,
invocation: *const Invocation, // The specific invocation being transformed
item: *const Item,
program: *const Program,
allocator: std.mem.Allocator
}
| transformed { program: *const Program }// Runtime impl event for shape-checking (never actually runs - inline code does)
// conn comes from invocation args, captured in generated code
~[norun]pub event query.impl {
conn: *Connection[!opened]
}
| row { conn: *Connection[opened!], stmt: *Statement[prepared!] }
| empty { conn: *Connection[opened!] }
| err { conn: *Connection[opened!], code: i32, msg: []const u8 }// Get next row from statement
~pub event next {
conn: *Connection[!opened], stmt: *Statement[!prepared]
}
| row { conn: *Connection[opened!], stmt: *Statement[prepared!] }
| done { conn: *Connection[opened!] }
| err { conn: *Connection[opened!], code: i32, msg: []const u8 }// Finalize text - acknowledges we're done with borrowed text pointer
// Must be called BEFORE finalize.stmt (text becomes invalid after stmt finalize)
~pub event finalize.text {
text: []const u8[!text]
}// Finalize statement - releases the prepared statement
~pub event finalize.stmt {
stmt: *Statement[!prepared]
}// ============================================================================
// Column Access (within row context)
// ============================================================================
~pub event col.int {
stmt: *Statement[!prepared], index: i32
}
| value { stmt: *Statement[prepared!], val: i64 }~pub event col.text {
stmt: *Statement[!prepared], index: i32
}
| value { stmt: *Statement[prepared!], text: []const u8[text!] }~pub event col.real {
stmt: *Statement[!prepared], index: i32
}
| value { stmt: *Statement[prepared!], val: f64 }