Nyx by Example

SQLite

std/sqlite provides SQLite3 bindings loaded at runtime via dlopen. sqlite_open(":memory:") creates an in-memory database, sqlite_exec runs DDL/DML statements, and sqlite_query returns rows as arrays of strings. No external dependencies are needed — SQLite is bundled with most operating systems.

Code

// SQLite — in-memory database with SQL queries

import "std/sqlite"

fn main() -> int {
    let db: int = sqlite_open(":memory:")
    if db < 0 {
        print("failed to open database")
        return 1
    }

    sqlite_exec(db, "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)")

    sqlite_exec(db, "INSERT INTO users (name, age) VALUES ('Alice', 30)")
    sqlite_exec(db, "INSERT INTO users (name, age) VALUES ('Bob', 25)")
    sqlite_exec(db, "INSERT INTO users (name, age) VALUES ('Charlie', 35)")

    let rows: Array = sqlite_query(db, "SELECT name, age FROM users ORDER BY age")
    var i: int = 0
    while i < rows.length() {
        let row: Array = rows[i]
        let name: String = row[0]
        let age: String = row[1]
        print(name + " is " + age + " years old")
        i = i + 1
    }

    let seniors: Array = sqlite_query(db, "SELECT name FROM users WHERE age >= 30")
    print("users 30+: " + int_to_string(seniors.length()))

    sqlite_close(db)
    return 0
}

Output

Bob is 25 years old
Alice is 30 years old
Charlie is 35 years old
users 30+: 2

Explanation

sqlite_open returns a database handle (integer). The special path ":memory:" creates a temporary in-memory database that is discarded when the handle is closed. For persistent storage, pass a file path like "data.db".

sqlite_query returns an array of rows, where each row is an array of string values (SQLite stores all values as text internally). Column order matches the SELECT clause. sqlite_exec is used for statements that don't return data (CREATE, INSERT, UPDATE, DELETE).

← Previous Next →

Source: examples/by-example/55-sqlite.nx