These libraries are experimental. APIs may change without notice. Generated from source on 6/15/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 *Connection<opened!>
| err { code: i32, msg: []const u8 }~pub event close {
conn: *Connection<!opened>
}// ============================================================================
// Query Execution
// ============================================================================
~pub event exec {
conn: *Connection<!opened>, sql: []const u8
}
| ok *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 *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 *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 *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 *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 }