module sqlite
module lib/sqlite.mu
import "sqlite"
sqlite provides minimal SQLite bindings via the FFI.
Imports
Functions
close#
close closes a SQLite database handle.
Source lib/sqlite.mu:112
fn close(db) {
err := _require_handle(db, "sqlite.close")
if is_error(err) {
return err
}
rc := _sqlite3_close(db)
if is_error(rc) {
return rc
}
if rc != _SQLITE_OK {
return error("sqlite.close failed with code " + inspect(rc))
}
return nil
}exec#
exec executes a SQL statement without returning rows.
Source lib/sqlite.mu:128
fn exec(db, sql) {
err := _require_handle(db, "sqlite.exec")
if is_error(err) {
return err
}
if !typing.is_str(sql) {
return error("sqlite.exec expects string sql, got " + type(sql))
}
rc := _sqlite3_exec(db, sql, nil, nil, nil)
if is_error(rc) {
return rc
}
if rc != _SQLITE_OK {
return _error_with_db(db, rc, "sqlite.exec")
}
return nil
}open#
open opens a SQLite database and returns a handle.
Source lib/sqlite.mu:81
fn open(path) {
if !typing.is_str(path) {
return error("sqlite.open expects string path, got " + type(path))
}
out := _ptr_buffer()
rc := _sqlite3_open(path, out)
if is_error(rc) {
return rc
}
db := _ptr_from_buffer(out)
if is_error(db) {
return db
}
if rc != _SQLITE_OK {
if db != 0 {
msg := _errmsg(db)
_sqlite3_close(db)
if is_error(msg) {
return msg
}
return error("sqlite.open failed: " + msg)
}
return error("sqlite.open failed with code " + inspect(rc))
}
if db == 0 {
return error("sqlite.open returned null handle")
}
return db
}prepare#
prepare compiles a statement and returns the statement handle.
Source lib/sqlite.mu:197
fn prepare(db, sql) {
err := _require_handle(db, "sqlite.prepare")
if is_error(err) {
return err
}
if !typing.is_str(sql) {
return error("sqlite.prepare expects string sql, got " + type(sql))
}
out := _ptr_buffer()
rc := _sqlite3_prepare_v2(db, sql, -1, out, nil)
if is_error(rc) {
return rc
}
if rc != _SQLITE_OK {
return _error_with_db(db, rc, "sqlite.prepare")
}
stmt := _ptr_from_buffer(out)
if is_error(stmt) {
return stmt
}
if stmt == 0 {
return error("sqlite.prepare returned null statement")
}
return stmt
}query#
query executes a SQL statement and returns rows as lists of values.
Source lib/sqlite.mu:147
fn query(db, sql) {
err := _require_handle(db, "sqlite.query")
if is_error(err) {
return err
}
if !typing.is_str(sql) {
return error("sqlite.query expects string sql, got " + type(sql))
}
stmt := prepare(db, sql)
if is_error(stmt) {
return stmt
}
rows := []
while true {
rc := _sqlite3_step(stmt)
if is_error(rc) {
_sqlite3_finalize(stmt)
return rc
}
if rc == _SQLITE_ROW {
row := _read_row(stmt)
if is_error(row) {
_sqlite3_finalize(stmt)
return row
}
rows = append(rows, row)
if is_error(rows) {
_sqlite3_finalize(stmt)
return rows
}
continue
}
if rc == _SQLITE_DONE {
break
}
query_err := _error_with_db(db, rc, "sqlite.query")
_sqlite3_finalize(stmt)
return query_err
}
rc := _sqlite3_finalize(stmt)
if is_error(rc) {
return rc
}
if rc != _SQLITE_OK {
return _error_with_db(db, rc, "sqlite.query finalize")
}
return rows
}Macros
sqlite_path#
sqlite_path() expands to the path of the SQLite shared library to bind against, decided at COMPILE time: MU_SQLITE_PATH if it is set, otherwise the platform's usual location.
It is exported because the choice belongs to whoever builds the program, and because a cross-compile has to override it -- platform() inside a macro reports the BUILD host, not the target.
Source lib/sqlite.mu:47
macro.define("sqlite_path", fn() {
override := env("MU_SQLITE_PATH")
if override != nil && type(override) == "STRING" {
return quote { unquote override }
}
platformKey := platform()
return quote { unquote _sqlite_default_path(platformKey) }
})Internal helpers
Underscore-prefixed names are implementation detail. They are listed so the module's source reads without surprises, not as API — they may change at any time.
| _SQLITE_BLOB | — |
| _SQLITE_DONE | — |
| _SQLITE_FLOAT | — |
| _SQLITE_INTEGER | — |
| _SQLITE_NULL | — |
| _SQLITE_OK | — |
| _SQLITE_ROW | — |
| _SQLITE_TEXT | — |
| _column_blob(stmt, index) | — |
| _column_text(stmt, index) | — |
| _column_value(stmt, index) | — |
| _copy_bytes(ptr, length) | copy_bytes copies length bytes from ptr into a new buffer. |
| _copy_string_len(ptr, length) | copy_string_len copies length bytes from ptr and returns a string. |
| _cstring(ptr) | cstring copies a null-terminated string from ptr. |
| _decode_uint64_le(buffer) | decode_uint64_le reads an unsigned 64-bit little-endian value from buffer. |
| _errmsg(db) | — |
| _error_with_db(db, rc, action) | — |
| _memcpy | — |
| _ptr_buffer() | ptr_buffer allocates an 8-byte buffer suitable for pointer out-params. |
| _ptr_from_buffer(buffer) | ptr_from_buffer decodes a pointer-sized value from an 8-byte buffer. |
| _read_row(stmt) | — |
| _require_handle(value, name) | — |
| _sqlite3_close | — |
| _sqlite3_column_blob | — |
| _sqlite3_column_bytes | — |
| _sqlite3_column_count | — |
| _sqlite3_column_int64 | — |
| _sqlite3_column_text | — |
| _sqlite3_column_type | — |
| _sqlite3_errmsg | — |
| _sqlite3_exec | — |
| _sqlite3_finalize | — |
| _sqlite3_open | — |
| _sqlite3_prepare_v2 | — |
| _sqlite3_step | — |
| _sqlite_default_path(platformKey) | — |
| _sqlite_default_paths() | — |
| _strlen | — |