# SQLite binding (core slice) This is a small, hand-written V3 binding for the core SQLite API: scalar values, BLOBs, prepared statements, connection control and callbacks. It is not a replacement for the full `m2SQLITE` definition. ## Current surface ```modula2 (* connection *) sqlite3_open sqlite3_open_v2 sqlite3_exec sqlite3_close sqlite3_close_v2 (* prepared statements *) sqlite3_prepare_v2 sqlite3_bind_int sqlite3_bind_int64 sqlite3_bind_double sqlite3_bind_null sqlite3_bind_blob sqlite3_bind_zeroblob sqlite3_bind_text sqlite3_bind_parameter_count sqlite3_bind_parameter_name sqlite3_bind_parameter_index sqlite3_step sqlite3_sql sqlite3_expanded_sql sqlite3_stmt_readonly sqlite3_stmt_busy sqlite3_next_stmt sqlite3_stmt_status sqlite3_reset sqlite3_clear_bindings sqlite3_finalize (* row change metadata *) sqlite3_changes sqlite3_total_changes sqlite3_last_insert_rowid (* column metadata and scalar results *) sqlite3_column_count sqlite3_data_count sqlite3_column_type sqlite3_column_bytes sqlite3_column_int sqlite3_column_int64 sqlite3_column_double sqlite3_column_blob sqlite3_column_text sqlite3_column_name sqlite3_column_decltype (* errors and ownership *) sqlite3_errmsg sqlite3_errstr sqlite3_errcode sqlite3_extended_errcode sqlite3_extended_result_codes sqlite3_free sqlite3_libversion sqlite3_libversion_number sqlite3_sourceid sqlite3_threadsafe sqlite3_error_offset sqlite3_get_autocommit sqlite3_complete sqlite3_limit (* incremental BLOB I/O *) sqlite3_blob_open sqlite3_blob_close sqlite3_blob_read sqlite3_blob_write sqlite3_blob_bytes sqlite3_blob_reopen (* callbacks and user-defined scalar functions *) sqlite3_create_function_v2 sqlite3_value_type sqlite3_value_int sqlite3_value_int64 sqlite3_value_double sqlite3_value_text sqlite3_value_blob sqlite3_value_bytes sqlite3_result_null sqlite3_result_int sqlite3_result_int64 sqlite3_result_double sqlite3_result_text sqlite3_result_blob sqlite3_result_error sqlite3_result_error_code sqlite3_user_data sqlite3_context_db_handle (* connection hooks *) sqlite3_busy_timeout sqlite3_busy_handler sqlite3_interrupt sqlite3_progress_handler sqlite3_trace_v2 sqlite3_update_hook sqlite3_commit_hook sqlite3_rollback_hook sqlite3_set_authorizer sqlite3_db_handle (* binding helpers *) SQLiteArrayAt SQLiteTransient ``` The matching constants include the primary result codes (`SQLiteOk`, `SQLiteConstraint`, ...), `SQLiteRow`, `SQLiteDone`, storage classes (`SQLiteInteger`, `SQLiteFloat`, `SQLiteText`, `SQLiteBlob`, `SQLiteNull`), a few extended constraints, the `SQLiteOpen*` flags used by `sqlite3_open_v2` and `sqlite3_blob_open`, and `SQLiteUtf*` / `SQLiteDeterministic` for function registration. Hook-related constants include `SQLiteOp*`, `SQLiteAuth*` and `SQLiteTrace*`. ## Tests and showcase `run.sh` builds and runs: - `SQLiteSmoke.mod` - open / exec / close - `SQLitePrepared.mod` - prepared insert and select - `SQLiteParams.mod` - parameter names/count/index, named parameters, unbound NULL - `SQLiteIntrospection.mod` - sql/expanded_sql, statement state, version, limits - `SQLiteScalar.mod` - int, int64, double, text, NULL and column metadata - `SQLiteErrors.mod` - error codes, errmsg/errstr and `sqlite3_free` - `SQLiteBlob.mod` - bind_blob, bind_zeroblob, column_blob and incremental BLOB I/O - `SQLiteConnection.mod` - open_v2, close_v2, changes/rowid and deferred close - `SQLiteCallback.mod` - exec row callbacks and user-defined scalar functions - `SQLiteHooks.mod` - busy/progress/trace/update/commit/rollback/authorizer hooks - `showcase/SQLiteShowcase.mod` - prepared-statement walkthrough The showcase prints: ```text 1: Ada 2: Grace ``` ## Build/run ```sh ./run.sh ``` The script uses `pkg-config --libs sqlite3` when available; otherwise it links the versioned runtime library directly: ```text /usr/lib/x86_64-linux-gnu/libsqlite3.so.0 ``` That fallback matters on systems with the SQLite runtime installed but without `libsqlite3-dev`. ## Ownership notes - `sqlite3_exec` now takes `VAR errmsg : ADDRESS`. A non-NIL message is allocated by SQLite and must be released with `sqlite3_free`. - `sqlite3_errmsg` and `sqlite3_errstr` return borrowed C strings. Copy them with `CStr.Copy` if they need to outlive the next SQLite call. - `sqlite3_column_text` and `sqlite3_column_blob` return pointers valid only until the next `step`, `reset` or `finalize`; copy or consume them immediately. - For a raw C data pointer to a V3 array, use `ADR(a[0])`, not `ADR(a)`: `ADR(a)` points at the V3 array descriptor. - `SQLiteTransient()` supplies the `SQLITE_TRANSIENT` sentinel so SQLite copies bound text or BLOB data. Passing `NIL` means `SQLITE_STATIC`; the caller's buffer must then stay alive until the statement is reset or finalized. - `sqlite3_blob_open` needs an explicit `SQLiteOpenReadOnly` or `SQLiteOpenReadWrite` flag. A BLOB handle holds a read/write lock on its row until `sqlite3_blob_close`. - SQLite callbacks must be top-level V3 procedures: they are C-callable, while nested procedures still carry a hidden frame link. - `sqlite3_exec` callbacks receive `char **argv` and `char **colNames` as `ADDRESS`; use `SQLiteArrayAt(argv, i)` and `SQLiteArrayAt(colNames, i)` to reach each entry. - User-defined functions receive `sqlite3_value **argv` as `ADDRESS`; pass each `SQLiteArrayAt(argv, i)` result to `sqlite3_value_*` or `sqlite3_result_*`. - `sqlite3_update_hook` and `sqlite3_commit_hook` return the previous hook pointer. Assign the result to an `ADDRESS`; pass `NIL` as the callback to unregister. - `sqlite3_set_authorizer` must return `SQLiteAuthOk`, `SQLiteAuthDeny` or `SQLiteAuthIgnore`. - `sqlite3_sql` returns borrowed SQL text; `sqlite3_expanded_sql` returns allocated text and must be released with `sqlite3_free`. - When extended result codes are enabled, `sqlite3_exec` and `sqlite3_errcode` can report an extended code such as `SQLiteConstraintPrimaryKey` (1555) rather than only `SQLiteConstraint` (19). ## Still to add Backup, extension loading, WAL/checkpoint helpers and connection configuration.