SQLite API Reference

SQLite3 database bindings for Vais

Dependencies: -lsqlite3

Import

U std/sqlite

Constants

Result Codes

NameValueDescription
SQLITE_OK0Success
SQLITE_ERROR1Generic error
SQLITE_INTERNAL2Internal logic error
SQLITE_PERM3Access permission denied
SQLITE_ABORT4Callback requested abort
SQLITE_BUSY5Database file is locked
SQLITE_LOCKED6A table in the database is locked
SQLITE_NOMEM7Memory allocation failed
SQLITE_READONLY8Attempt to write to readonly database
SQLITE_INTERRUPT9Operation terminated
SQLITE_IOERR10Disk I/O error
SQLITE_CORRUPT11Database disk image is malformed
SQLITE_NOTFOUND12Unknown operation
SQLITE_FULL13Database is full
SQLITE_CANTOPEN14Unable to open database file
SQLITE_PROTOCOL15Database lock protocol error
SQLITE_CONSTRAINT19Constraint violation
SQLITE_MISMATCH20Data type mismatch
SQLITE_MISUSE21Library used incorrectly
SQLITE_ROW100Row available from step()
SQLITE_DONE101Statement execution complete

Column Type Codes

NameValueDescription
SQLITE_INTEGER1Integer column type
SQLITE_FLOAT2Float column type
SQLITE_TEXT3Text column type
SQLITE_BLOB4Blob column type
SQLITE_NULL5NULL column type

Structs

Database

Database connection handle.

FieldTypeDescription
handlei64Internal SQLite handle
pathstrDatabase file path
is_openi641 if open, 0 if closed

Methods

MethodSignatureDescription
openF open(path: str) -> DatabaseOpen database file (creates if not exists)
memoryF memory() -> DatabaseOpen in-memory database
is_validF is_valid(&self) -> i64Check if database is open (returns 1/0)
closeF close(&self) -> i64Close connection, returns result code
execF exec(&self, sql: str) -> i64Execute SQL statement, returns result code
prepareF prepare(&self, sql: str) -> StatementPrepare SQL statement for execution
error_messageF error_message(&self) -> strGet last error message
last_insert_idF last_insert_id(&self) -> i64Get rowid of last inserted row
changesF changes(&self) -> i64Get number of rows changed by last statement
beginF begin(&self) -> i64Begin transaction
commitF commit(&self) -> i64Commit transaction
rollbackF rollback(&self) -> i64Rollback transaction
begin_immediateF begin_immediate(&self) -> i64Begin immediate transaction (acquires write lock)
create_tableF create_table(&self, sql: str) -> i64Create table from SQL statement
drop_tableF drop_table(&self, table_name: str) -> i64Drop table if exists
enable_walF enable_wal(&self) -> i64Enable Write-Ahead Logging mode
enable_foreign_keysF enable_foreign_keys(&self) -> i64Enable foreign key enforcement
dropF drop(&self) -> i64RAII cleanup (calls close)

Statement

Prepared statement handle.

FieldTypeDescription
handlei64Internal statement handle
db_handlei64Parent database handle
column_counti64Number of columns in result set

Methods

MethodSignatureDescription
is_validF is_valid(&self) -> i64Check if statement is valid (returns 1/0)
bind_intF bind_int(&self, index: i64, value: i64) -> i64Bind integer parameter (1-indexed)
bind_textF bind_text(&self, index: i64, value: str) -> i64Bind text parameter (1-indexed)
bind_doubleF bind_double(&self, index: i64, value: i64) -> i64Bind double parameter (1-indexed, value as i64 bits)
bind_nullF bind_null(&self, index: i64) -> i64Bind NULL parameter (1-indexed)
stepF step(&self) -> i64Execute one step, returns SQLITE_ROW/SQLITE_DONE/error
column_intF column_int(&self, index: i64) -> i64Get integer column value (0-indexed)
column_textF column_text(&self, index: i64) -> strGet text column value (0-indexed)
column_doubleF column_double(&self, index: i64) -> i64Get double column as i64 bits (0-indexed)
column_typeF column_type(&self, index: i64) -> i64Get column type (0-indexed)
column_nameF column_name(&self, index: i64) -> strGet column name (0-indexed)
columnsF columns(&self) -> i64Get number of columns
resetF reset(&self) -> i64Reset for re-execution (bindings not cleared)
finalizeF finalize(&self) -> i64Finalize and destroy statement
executeF execute(&self) -> i64Execute to completion (no results expected)
dropF drop(&self) -> i64RAII cleanup (calls finalize)

Row

Convenience wrapper for result rows during iteration.

FieldTypeDescription
stmt_handlei64Internal statement handle
column_counti64Number of columns

Methods

MethodSignatureDescription
from_stmtF from_stmt(stmt: &Statement) -> RowCreate Row from Statement
get_intF get_int(&self, index: i64) -> i64Get integer column value (0-indexed)
get_textF get_text(&self, index: i64) -> strGet text column value (0-indexed)
get_doubleF get_double(&self, index: i64) -> i64Get double column as i64 bits (0-indexed)
get_typeF get_type(&self, index: i64) -> i64Get column type (0-indexed)
get_nameF get_name(&self, index: i64) -> strGet column name (0-indexed)
is_nullF is_null(&self, index: i64) -> i64Check if column is NULL (0-indexed)
columnsF columns(&self) -> i64Get column count

Convenience Functions

FunctionSignatureDescription
openF open(path: str) -> DatabaseOpen database file
memoryF memory() -> DatabaseOpen in-memory database
execF exec(db: &Database, sql: str) -> i64Execute SQL statement
result_code_strF result_code_str(code: i64) -> strConvert result code to string
is_okF is_ok(code: i64) -> i64Check if result code indicates success
has_rowF has_row(code: i64) -> i64Check if step result indicates row available
is_doneF is_done(code: i64) -> i64Check if step result indicates completion

Usage Examples

Basic Usage

U std/sqlite

F main() -> i64 {
    db := Database::open("test.db")
    I db.is_valid() == 0 {
        R 1
    }

    db.exec("CREATE TABLE users (id INTEGER, name TEXT)")
    db.exec("INSERT INTO users VALUES (1, 'Alice')")

    stmt := db.prepare("SELECT name FROM users WHERE id = ?")
    stmt.bind_int(1, 1)

    I stmt.step() == SQLITE_ROW {
        name := stmt.column_text(0)
        # Use name...
    }

    stmt.finalize()
    db.close()
    0
}

Query Iteration with Row

U std/sqlite

F main() -> i64 {
    db := Database::open("users.db")
    stmt := db.prepare("SELECT id, name FROM users")

    L stmt.step() == SQLITE_ROW {
        row := Row::from_stmt(&stmt)
        id := row.get_int(0)
        name := row.get_text(1)
        # Process row...
    }

    stmt.finalize()
    db.close()
    0
}

Transaction Management

U std/sqlite

F main() -> i64 {
    db := Database::open("data.db")

    db.begin()
    rc := db.exec("INSERT INTO accounts VALUES (1, 100)")
    I rc != SQLITE_OK {
        db.rollback()
        R 1
    }

    rc = db.exec("UPDATE accounts SET balance = balance - 100 WHERE id = 2")
    I rc != SQLITE_OK {
        db.rollback()
        R 1
    }

    db.commit()
    db.close()
    0
}

In-Memory Database

U std/sqlite

F main() -> i64 {
    db := Database::memory()
    db.exec("CREATE TABLE temp (id INTEGER)")
    db.exec("INSERT INTO temp VALUES (42)")

    stmt := db.prepare("SELECT id FROM temp")
    I stmt.step() == SQLITE_ROW {
        value := stmt.column_int(0)
        # value is 42
    }

    stmt.finalize()
    db.close()
    0
}

Error Handling

U std/sqlite

F main() -> i64 {
    db := Database::open("test.db")
    rc := db.exec("INVALID SQL")

    I rc != SQLITE_OK {
        error_msg := db.error_message()
        code_name := result_code_str(rc)
        # Handle error...
        R 1
    }

    db.close()
    0
}

Convenience Functions

U std/sqlite

F main() -> i64 {
    # Using convenience functions
    db := open("data.db")
    rc := exec(&db, "CREATE TABLE test (id INTEGER)")

    I is_ok(rc) {
        # Success
    }

    stmt := db.prepare("SELECT * FROM test")
    step_result := stmt.step()

    I has_row(step_result) {
        # Process row
    }

    I is_done(step_result) {
        # Query complete
    }

    stmt.finalize()
    db.close()
    0
}

Compilation

To compile programs using SQLite:

vaisc --emit-ir your_app.vais
clang -o your_app your_app.ll std/sqlite_runtime.c -lsqlite3

Requires SQLite3 development headers and library installed on your system.