Skip to content

SQLite3 bindings for Arc. Zero configuration — just import and use.

Notifications You must be signed in to change notification settings

arc-language/sqlite3

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sqlite3

SQLite3 bindings for Arc. Zero configuration — just import and use.


Installation

import "github.com/arc-language/sqlite3"

Quick Start

git clone https://github.com/arc-language/sqlite3
cd sqlite3
arc build main.ax -o main
./main

Example

namespace main

import c "libc"
import "github.com/arc-language/sqlite3"

extern c {
    func printf(*byte, ...) int32
}

func main() {
    let (db, rc) = sqlite3.open("myapp.db")
    if rc != sqlite3.SQLITE_OK {
        printf("failed: %s\n", db.errmsg())
        return
    }
    defer db.close()

    db.exec("CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, name TEXT)")

    let (ins, _) = db.prepare("INSERT INTO items (name) VALUES (?)")
    defer ins.finalize()

    ins.bind_text(1, "widget", 6)
    ins.step()

    let (sel, _) = db.prepare("SELECT id, name FROM items")
    defer sel.finalize()

    for sel.step() == sqlite3.SQLITE_ROW {
        printf("id=%d  name=%s\n", sel.column_int(0), sel.column_text(1))
    }
}

Project Structure

db.ax              — constants and raw C extern declarations
db_handle.ax       — DB struct: open / close / exec / prepare
stmt.ax            — Stmt struct: step / reset / finalize / column metadata
stmt_bind.ax       — bind_int / bind_float / bind_text / bind_blob / bind_null
stmt_column.ax     — column_int / column_float / column_text / column_blob
main.ax            — usage example

API Reference

Database Operations

Function Signature Description
open (path: *byte) -> (DB, int32) Open or create a database file
open_v2 (path: *byte, flags: int32) -> (DB, int32) Open with explicit flags
close (self db: *DB) -> int32 Close the database connection
exec (self db: *DB, sql: *byte) -> int32 Execute SQL with no result rows
prepare (self db: *DB, sql: *byte) -> (Stmt, int32) Compile SQL into a prepared statement
errmsg (self db: *DB) -> *byte Get last error message
errcode (self db: *DB) -> int32 Get last error code
changes (self db: *DB) -> int32 Number of rows affected by last write
last_insert_rowid (self db: *DB) -> int64 Rowid of last INSERT operation

Statement Lifecycle

Function Signature Description
step (self s: *Stmt) -> int32 Advance to next row (SQLITE_ROW or SQLITE_DONE)
reset (self s: *Stmt) -> int32 Rewind statement for re-execution
finalize (self s: *Stmt) -> int32 Destroy the prepared statement
clear_bindings (self s: *Stmt) -> int32 Unbind all parameters
bind_parameter_count (self s: *Stmt) -> int32 Number of ? placeholders

Parameter Binding (1-indexed)

Function Signature Description
bind_int (self s: *Stmt, idx: int32, val: int64) -> int32 Bind an integer value
bind_float (self s: *Stmt, idx: int32, val: float64) -> int32 Bind a floating-point value
bind_text (self s: *Stmt, idx: int32, val: *byte, len: int32) -> int32 Bind a text string (copied internally)
bind_blob (self s: *Stmt, idx: int32, data: *void, len: int32) -> int32 Bind raw bytes (copied internally)
bind_null (self s: *Stmt, idx: int32) -> int32 Bind NULL value

Column Access (0-indexed)

Function Signature Description
column_int (self s: *Stmt, idx: int32) -> int64 Read integer column
column_float (self s: *Stmt, idx: int32) -> float64 Read floating-point column
column_text (self s: *Stmt, idx: int32) -> *byte Read text column
column_blob (self s: *Stmt, idx: int32) -> *void Read blob column
column_bytes (self s: *Stmt, idx: int32) -> int32 Byte length of column value
column_type (self s: *Stmt, idx: int32) -> int32 SQLite type of column value
column_name (self s: *Stmt, idx: int32) -> *byte Column name from schema
column_is_null (self s: *Stmt, idx: int32) -> bool Check if column is NULL

Constants

Result Codes

SQLITE_OK              0    // Successful result
SQLITE_ERROR           1    // Generic error
SQLITE_BUSY            5    // Database is locked
SQLITE_ROW             100  // Step has another row ready
SQLITE_DONE            101  // Step has finished executing

Open Flags

SQLITE_OPEN_READWRITE  0x00000002  // Open for reading and writing
SQLITE_OPEN_CREATE     0x00000004  // Create file if it doesn't exist

Data Types

SQLITE_INTEGER         1
SQLITE_FLOAT           2
SQLITE_TEXT            3
SQLITE_BLOB            4
SQLITE_NULL            5

Best Practices

Use Defer for Resource Cleanup

Always pair close and finalize with defer for automatic cleanup:

let (db, _) = sqlite3.open("app.db")
defer db.close()

let (stmt, _) = db.prepare("SELECT * FROM users")
defer stmt.finalize()

Reset Statements for Reuse

Call reset before re-executing a prepared statement with new bindings:

ins.bind_text(1, "Alice", 5)
ins.step()
ins.reset()

ins.bind_text(1, "Bob", 3)
ins.step()
ins.reset()

Check Column Types

Use column_type or column_is_null before reading columns:

if sel.column_is_null(2) {
    printf("  score is NULL\n")
} else {
    printf("  score=%.1f\n", sel.column_float(2))
}

Read-Only Access

Use open_v2 with explicit flags for read-only operations:

let (db, _) = sqlite3.open_v2("data.db", sqlite3.SQLITE_OPEN_READWRITE)
defer db.close()

License

MIT

About

SQLite3 bindings for Arc. Zero configuration — just import and use.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages