/
nv-lang
/
nova
Обзор
Документация
Войти
/
nv-lang
/
nova
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
examples/ffi/sqlite_mini.nv
94 строки
3 KB
Evgeniy Golovin
docs: правка ссылок на перемещённые docs/guide|dev файлы
02 авг 2026, 03:04
02 авг 2026, 03:04
07df7d2
Код
Авторство
О чём код?
// SPDX-License-Identifier: MIT OR Apache-2.0 // // Minimal libsqlite3 binding sketch. Example only (без реального // libsqlite3 link). Демонстрирует структуру extern "nova" fn declarations // + typed handle wrap + error mapping. // // Pattern: // 1. extern "nova" fn declarations match C shim (см. docs/guide/ffi-cookbook.md). // 2. Wrap raw *() returns в typed record handles. // 3. Multi-value return через tuple-by-value ABI. // 4. consume close() для resource ownership. module ffi.sqlite_mini // Typed handles (V1 record form). type Db { ro value *() } type Stmt { ro value *() } // SQLite constants (subset). const SQLITE_OK = 0 const SQLITE_ROW = 100 const SQLITE_DONE = 101 // Error sum type (Nova-native, distinct от raw C codes). type DbError | OpenFailed(int) | ExecFailed(int) | PrepareFailed(int) | StepFailed(int) // External declarations — sqlite3_ffi.h (см. cookbook). // Shim header нужен в compiler-codegen/nova_rt/ для actual link. extern "nova" fn mini_sqlite_open(path str) -> (*(), int) extern "nova" fn mini_sqlite_close(db *()) -> int extern "nova" fn mini_sqlite_exec(db *(), sql str) -> int extern "nova" fn mini_sqlite_prepare(db *(), sql str) -> (*(), int) extern "nova" fn mini_sqlite_step(stmt *()) -> int extern "nova" fn mini_sqlite_column_int(stmt *(), col int) -> int extern "nova" fn mini_sqlite_finalize(stmt *()) -> int // Layer 2: typed wrappers. // Every `mini_sqlite_*` extern above carries a raw pointer — each is // `unsafe fn` by inference, calls wrapped below. fn Db.open(path str) Fail[DbError] -> Db { ro (raw, rc) = unsafe { mini_sqlite_open(path) } if rc != SQLITE_OK { throw DbError.OpenFailed(rc) } Db { value: raw } } fn Db @exec(sql str) Fail[DbError] -> () { ro rc = unsafe { mini_sqlite_exec(self.value, sql) } if rc != SQLITE_OK { throw DbError.ExecFailed(rc) } } fn Db @prepare(sql str) Fail[DbError] -> Stmt { ro (raw, rc) = unsafe { mini_sqlite_prepare(self.value, sql) } if rc != SQLITE_OK { throw DbError.PrepareFailed(rc) } Stmt { value: raw } } fn Db consume @close() -> () { unsafe { mini_sqlite_close(self.value) } } // Stmt methods. fn Stmt @step_to_int(col int) Fail[DbError] -> int { ro rc = unsafe { mini_sqlite_step(self.value) } if rc != SQLITE_ROW && rc != SQLITE_DONE { throw DbError.StepFailed(rc) } unsafe { mini_sqlite_column_int(self.value, col) } } fn Stmt consume @close() -> () { unsafe { mini_sqlite_finalize(self.value) } } // Example usage. Would actually exercise libsqlite3 if shim is wired up // at build time. Illustrative only. fn open_and_close_demo(path str) Fail[DbError] -> int { ro db = Db.open(path) db.exec("CREATE TABLE IF NOT EXISTS users (id INT, name TEXT)") db.close() 0 }