sqlite is part of the program: #import c unit replaces the Makefile cc build

src/db/sqlite.sx declares the vendored amalgamation as a named
'#import c' unit (pinned defines + -O2 + #source); every #foreign
binding resolves against it with UNPREFIXED sqlite3_* names. sx
compiles the unit through its content-addressed object cache — once
per checkout — links the objects into 'sx build' binaries, and loads
them as a priority symbol target under 'sx run', so the OS libsqlite3
can never shadow the vendored copy (the version pin in sqlite_smoke
proves it).

Retired: the Makefile vendor targets (cc -> .a + jit/.dylib), the
GENERATED dist_sqlite3_* rename.h (the JIT no longer resolves
program-owned symbols through the process images, so the rename's
reason is gone), and the -L plumbing in make build + tests/run.sh.
make test 22/22; otool -L build/dist carries no libsqlite3.
This commit is contained in:
agra
2026-06-12 17:27:21 +03:00
parent a1f13c4356
commit 06f99b3606
6 changed files with 154 additions and 172 deletions

View File

@@ -2,15 +2,17 @@
// sqlite.sx — sx bindings over the VENDORED SQLite amalgamation
// (vendor/sqlite/, see its README for version + upgrade notes).
//
// `#library "sqlite3"` resolves to the vendored build products under
// build/vendor/ (never the OS copy): `sx build` links the static
// archive via `-L build/vendor`; `sx run` dlopens the dylib via
// `-L build/vendor/jit` (tests/run.sh). Every bound symbol is renamed
// `dist_sqlite3_*` in the vendored build — `build/vendor/rename.h` is
// GENERATED by the Makefile from THIS FILE's `#foreign` names, so the
// rename list and the bindings cannot drift. tests/sqlite_smoke.sx pins
// `sqlite3_libversion()` to the vendored version so a silent fallback
// to the system library fails the suite.
// The amalgamation is part of THIS program: the named `#import c`
// unit below compiles vendor/sqlite/sqlite3.c with the pinned options
// (through sx's content-addressed object cache, so it compiles once
// per checkout, not once per run) and every `#foreign sqlib` decl
// binds against it. Under `sx run` the unit's dylib is a PRIORITY
// symbol-search target consulted before the process images, so the OS
// libsqlite3 (loaded into the compiler via CoreServices) can never
// shadow the vendored copy; under `sx build` the unit's objects link
// directly into the binary. tests/sqlite_smoke.sx pins
// `sqlite3_libversion()` to the vendored version so any fallback
// fails the suite.
//
// COVERAGE — the full practical C API, ONE variant per function (the
// modern/64-bit form where duplicates exist; `bind_text`/`bind_blob`
@@ -24,7 +26,7 @@
// * the sqlite3_value_* family + bind/column_value — only
// meaningful with user-defined functions (callbacks, above);
// * varargs APIs (sqlite3_config, db_config, log, mprintf) —
// configuration happens via compile-time defines in the Makefile;
// configuration happens via the unit's compile-time defines;
// * UTF-16 variants (we are UTF-8 only), the mutex/VFS layer
// (built SQLITE_THREADSAFE=0), sessions/snapshots/vtabs/loadable
// extensions (not compiled in), deprecated API (compiled out via
@@ -49,124 +51,134 @@
#import "modules/std.sx";
sqlib :: #library "sqlite3";
sqlib :: #import c {
#define "SQLITE_DQS=0";
#define "SQLITE_THREADSAFE=0";
#define "SQLITE_DEFAULT_MEMSTATUS=0";
#define "SQLITE_OMIT_DEPRECATED";
#define "SQLITE_OMIT_SHARED_CACHE";
#define "SQLITE_LIKE_DOESNT_MATCH_BLOBS";
#define "SQLITE_ENABLE_COLUMN_METADATA";
#flags "-O2";
#source "../../vendor/sqlite/sqlite3.c";
};
// ── FFI: connection lifecycle ─────────────────────────────────────────
sqlite3_open :: (path: cstring, out_db: *usize) -> i32 #foreign sqlib "dist_sqlite3_open";
sqlite3_open_v2 :: (path: cstring, out_db: *usize, flags: i32, vfs: usize) -> i32 #foreign sqlib "dist_sqlite3_open_v2";
sqlite3_close :: (db: usize) -> i32 #foreign sqlib "dist_sqlite3_close";
sqlite3_close_v2 :: (db: usize) -> i32 #foreign sqlib "dist_sqlite3_close_v2";
sqlite3_open :: (path: cstring, out_db: *usize) -> i32 #foreign sqlib "sqlite3_open";
sqlite3_open_v2 :: (path: cstring, out_db: *usize, flags: i32, vfs: usize) -> i32 #foreign sqlib "sqlite3_open_v2";
sqlite3_close :: (db: usize) -> i32 #foreign sqlib "sqlite3_close";
sqlite3_close_v2 :: (db: usize) -> i32 #foreign sqlib "sqlite3_close_v2";
// ── FFI: errors ───────────────────────────────────────────────────────
sqlite3_errcode :: (db: usize) -> i32 #foreign sqlib "dist_sqlite3_errcode";
sqlite3_extended_errcode :: (db: usize) -> i32 #foreign sqlib "dist_sqlite3_extended_errcode";
sqlite3_errmsg :: (db: usize) -> ?cstring #foreign sqlib "dist_sqlite3_errmsg";
sqlite3_errstr :: (code: i32) -> ?cstring #foreign sqlib "dist_sqlite3_errstr";
sqlite3_error_offset :: (db: usize) -> i32 #foreign sqlib "dist_sqlite3_error_offset";
sqlite3_extended_result_codes :: (db: usize, onoff: i32) -> i32 #foreign sqlib "dist_sqlite3_extended_result_codes";
sqlite3_errcode :: (db: usize) -> i32 #foreign sqlib "sqlite3_errcode";
sqlite3_extended_errcode :: (db: usize) -> i32 #foreign sqlib "sqlite3_extended_errcode";
sqlite3_errmsg :: (db: usize) -> ?cstring #foreign sqlib "sqlite3_errmsg";
sqlite3_errstr :: (code: i32) -> ?cstring #foreign sqlib "sqlite3_errstr";
sqlite3_error_offset :: (db: usize) -> i32 #foreign sqlib "sqlite3_error_offset";
sqlite3_extended_result_codes :: (db: usize, onoff: i32) -> i32 #foreign sqlib "sqlite3_extended_result_codes";
// ── FFI: connection state & control ───────────────────────────────────
sqlite3_busy_timeout :: (db: usize, ms: i32) -> i32 #foreign sqlib "dist_sqlite3_busy_timeout";
sqlite3_interrupt :: (db: usize) #foreign sqlib "dist_sqlite3_interrupt";
sqlite3_is_interrupted :: (db: usize) -> i32 #foreign sqlib "dist_sqlite3_is_interrupted";
sqlite3_get_autocommit :: (db: usize) -> i32 #foreign sqlib "dist_sqlite3_get_autocommit";
sqlite3_txn_state :: (db: usize, schema: cstring) -> i32 #foreign sqlib "dist_sqlite3_txn_state";
sqlite3_db_filename :: (db: usize, db_name: cstring) -> ?cstring #foreign sqlib "dist_sqlite3_db_filename";
sqlite3_db_readonly :: (db: usize, db_name: cstring) -> i32 #foreign sqlib "dist_sqlite3_db_readonly";
sqlite3_db_cacheflush :: (db: usize) -> i32 #foreign sqlib "dist_sqlite3_db_cacheflush";
sqlite3_db_release_memory :: (db: usize) -> i32 #foreign sqlib "dist_sqlite3_db_release_memory";
sqlite3_last_insert_rowid :: (db: usize) -> i64 #foreign sqlib "dist_sqlite3_last_insert_rowid";
sqlite3_set_last_insert_rowid :: (db: usize, rowid: i64) #foreign sqlib "dist_sqlite3_set_last_insert_rowid";
sqlite3_changes64 :: (db: usize) -> i64 #foreign sqlib "dist_sqlite3_changes64";
sqlite3_total_changes64 :: (db: usize) -> i64 #foreign sqlib "dist_sqlite3_total_changes64";
sqlite3_limit :: (db: usize, id: i32, new_val: i32) -> i32 #foreign sqlib "dist_sqlite3_limit";
sqlite3_exec :: (db: usize, sql: cstring, cb: usize, arg: usize, errmsg: usize) -> i32 #foreign sqlib "dist_sqlite3_exec";
sqlite3_table_column_metadata :: (db: usize, db_name: cstring, table: cstring, column: cstring, out_data_type: *usize, out_coll_seq: *usize, out_not_null: *i32, out_primary_key: *i32, out_autoinc: *i32) -> i32 #foreign sqlib "dist_sqlite3_table_column_metadata";
sqlite3_busy_timeout :: (db: usize, ms: i32) -> i32 #foreign sqlib "sqlite3_busy_timeout";
sqlite3_interrupt :: (db: usize) #foreign sqlib "sqlite3_interrupt";
sqlite3_is_interrupted :: (db: usize) -> i32 #foreign sqlib "sqlite3_is_interrupted";
sqlite3_get_autocommit :: (db: usize) -> i32 #foreign sqlib "sqlite3_get_autocommit";
sqlite3_txn_state :: (db: usize, schema: cstring) -> i32 #foreign sqlib "sqlite3_txn_state";
sqlite3_db_filename :: (db: usize, db_name: cstring) -> ?cstring #foreign sqlib "sqlite3_db_filename";
sqlite3_db_readonly :: (db: usize, db_name: cstring) -> i32 #foreign sqlib "sqlite3_db_readonly";
sqlite3_db_cacheflush :: (db: usize) -> i32 #foreign sqlib "sqlite3_db_cacheflush";
sqlite3_db_release_memory :: (db: usize) -> i32 #foreign sqlib "sqlite3_db_release_memory";
sqlite3_last_insert_rowid :: (db: usize) -> i64 #foreign sqlib "sqlite3_last_insert_rowid";
sqlite3_set_last_insert_rowid :: (db: usize, rowid: i64) #foreign sqlib "sqlite3_set_last_insert_rowid";
sqlite3_changes64 :: (db: usize) -> i64 #foreign sqlib "sqlite3_changes64";
sqlite3_total_changes64 :: (db: usize) -> i64 #foreign sqlib "sqlite3_total_changes64";
sqlite3_limit :: (db: usize, id: i32, new_val: i32) -> i32 #foreign sqlib "sqlite3_limit";
sqlite3_exec :: (db: usize, sql: cstring, cb: usize, arg: usize, errmsg: usize) -> i32 #foreign sqlib "sqlite3_exec";
sqlite3_table_column_metadata :: (db: usize, db_name: cstring, table: cstring, column: cstring, out_data_type: *usize, out_coll_seq: *usize, out_not_null: *i32, out_primary_key: *i32, out_autoinc: *i32) -> i32 #foreign sqlib "sqlite3_table_column_metadata";
// ── FFI: statements ───────────────────────────────────────────────────
sqlite3_prepare_v2 :: (db: usize, sql: [*]u8, nbyte: i32, out_stmt: *usize, out_tail: usize) -> i32 #foreign sqlib "dist_sqlite3_prepare_v2";
sqlite3_prepare_v3 :: (db: usize, sql: [*]u8, nbyte: i32, prep_flags: u32, out_stmt: *usize, out_tail: usize) -> i32 #foreign sqlib "dist_sqlite3_prepare_v3";
sqlite3_step :: (stmt: usize) -> i32 #foreign sqlib "dist_sqlite3_step";
sqlite3_reset :: (stmt: usize) -> i32 #foreign sqlib "dist_sqlite3_reset";
sqlite3_finalize :: (stmt: usize) -> i32 #foreign sqlib "dist_sqlite3_finalize";
sqlite3_clear_bindings :: (stmt: usize) -> i32 #foreign sqlib "dist_sqlite3_clear_bindings";
sqlite3_sql :: (stmt: usize) -> ?cstring #foreign sqlib "dist_sqlite3_sql";
sqlite3_expanded_sql :: (stmt: usize) -> ?cstring #foreign sqlib "dist_sqlite3_expanded_sql";
sqlite3_stmt_busy :: (stmt: usize) -> i32 #foreign sqlib "dist_sqlite3_stmt_busy";
sqlite3_stmt_readonly :: (stmt: usize) -> i32 #foreign sqlib "dist_sqlite3_stmt_readonly";
sqlite3_stmt_isexplain :: (stmt: usize) -> i32 #foreign sqlib "dist_sqlite3_stmt_isexplain";
sqlite3_stmt_explain :: (stmt: usize, mode: i32) -> i32 #foreign sqlib "dist_sqlite3_stmt_explain";
sqlite3_stmt_status :: (stmt: usize, op: i32, reset: i32) -> i32 #foreign sqlib "dist_sqlite3_stmt_status";
sqlite3_db_handle :: (stmt: usize) -> usize #foreign sqlib "dist_sqlite3_db_handle";
sqlite3_next_stmt :: (db: usize, stmt: usize) -> usize #foreign sqlib "dist_sqlite3_next_stmt";
sqlite3_prepare_v2 :: (db: usize, sql: [*]u8, nbyte: i32, out_stmt: *usize, out_tail: usize) -> i32 #foreign sqlib "sqlite3_prepare_v2";
sqlite3_prepare_v3 :: (db: usize, sql: [*]u8, nbyte: i32, prep_flags: u32, out_stmt: *usize, out_tail: usize) -> i32 #foreign sqlib "sqlite3_prepare_v3";
sqlite3_step :: (stmt: usize) -> i32 #foreign sqlib "sqlite3_step";
sqlite3_reset :: (stmt: usize) -> i32 #foreign sqlib "sqlite3_reset";
sqlite3_finalize :: (stmt: usize) -> i32 #foreign sqlib "sqlite3_finalize";
sqlite3_clear_bindings :: (stmt: usize) -> i32 #foreign sqlib "sqlite3_clear_bindings";
sqlite3_sql :: (stmt: usize) -> ?cstring #foreign sqlib "sqlite3_sql";
sqlite3_expanded_sql :: (stmt: usize) -> ?cstring #foreign sqlib "sqlite3_expanded_sql";
sqlite3_stmt_busy :: (stmt: usize) -> i32 #foreign sqlib "sqlite3_stmt_busy";
sqlite3_stmt_readonly :: (stmt: usize) -> i32 #foreign sqlib "sqlite3_stmt_readonly";
sqlite3_stmt_isexplain :: (stmt: usize) -> i32 #foreign sqlib "sqlite3_stmt_isexplain";
sqlite3_stmt_explain :: (stmt: usize, mode: i32) -> i32 #foreign sqlib "sqlite3_stmt_explain";
sqlite3_stmt_status :: (stmt: usize, op: i32, reset: i32) -> i32 #foreign sqlib "sqlite3_stmt_status";
sqlite3_db_handle :: (stmt: usize) -> usize #foreign sqlib "sqlite3_db_handle";
sqlite3_next_stmt :: (db: usize, stmt: usize) -> usize #foreign sqlib "sqlite3_next_stmt";
// ── FFI: binding ──────────────────────────────────────────────────────
sqlite3_bind_parameter_count :: (stmt: usize) -> i32 #foreign sqlib "dist_sqlite3_bind_parameter_count";
sqlite3_bind_parameter_index :: (stmt: usize, name: cstring) -> i32 #foreign sqlib "dist_sqlite3_bind_parameter_index";
sqlite3_bind_parameter_name :: (stmt: usize, idx: i32) -> ?cstring #foreign sqlib "dist_sqlite3_bind_parameter_name";
sqlite3_bind_text :: (stmt: usize, idx: i32, text: [*]u8, n: i32, destructor: isize) -> i32 #foreign sqlib "dist_sqlite3_bind_text";
sqlite3_bind_blob :: (stmt: usize, idx: i32, data: [*]u8, n: i32, destructor: isize) -> i32 #foreign sqlib "dist_sqlite3_bind_blob";
sqlite3_bind_double :: (stmt: usize, idx: i32, v: f64) -> i32 #foreign sqlib "dist_sqlite3_bind_double";
sqlite3_bind_int64 :: (stmt: usize, idx: i32, v: i64) -> i32 #foreign sqlib "dist_sqlite3_bind_int64";
sqlite3_bind_null :: (stmt: usize, idx: i32) -> i32 #foreign sqlib "dist_sqlite3_bind_null";
sqlite3_bind_zeroblob64 :: (stmt: usize, idx: i32, n: u64) -> i32 #foreign sqlib "dist_sqlite3_bind_zeroblob64";
sqlite3_bind_parameter_count :: (stmt: usize) -> i32 #foreign sqlib "sqlite3_bind_parameter_count";
sqlite3_bind_parameter_index :: (stmt: usize, name: cstring) -> i32 #foreign sqlib "sqlite3_bind_parameter_index";
sqlite3_bind_parameter_name :: (stmt: usize, idx: i32) -> ?cstring #foreign sqlib "sqlite3_bind_parameter_name";
sqlite3_bind_text :: (stmt: usize, idx: i32, text: [*]u8, n: i32, destructor: isize) -> i32 #foreign sqlib "sqlite3_bind_text";
sqlite3_bind_blob :: (stmt: usize, idx: i32, data: [*]u8, n: i32, destructor: isize) -> i32 #foreign sqlib "sqlite3_bind_blob";
sqlite3_bind_double :: (stmt: usize, idx: i32, v: f64) -> i32 #foreign sqlib "sqlite3_bind_double";
sqlite3_bind_int64 :: (stmt: usize, idx: i32, v: i64) -> i32 #foreign sqlib "sqlite3_bind_int64";
sqlite3_bind_null :: (stmt: usize, idx: i32) -> i32 #foreign sqlib "sqlite3_bind_null";
sqlite3_bind_zeroblob64 :: (stmt: usize, idx: i32, n: u64) -> i32 #foreign sqlib "sqlite3_bind_zeroblob64";
// ── FFI: result columns ───────────────────────────────────────────────
sqlite3_column_blob :: (stmt: usize, icol: i32) -> ?*u8 #foreign sqlib "dist_sqlite3_column_blob";
sqlite3_column_double :: (stmt: usize, icol: i32) -> f64 #foreign sqlib "dist_sqlite3_column_double";
sqlite3_column_int64 :: (stmt: usize, icol: i32) -> i64 #foreign sqlib "dist_sqlite3_column_int64";
sqlite3_column_text :: (stmt: usize, icol: i32) -> ?*u8 #foreign sqlib "dist_sqlite3_column_text";
sqlite3_column_bytes :: (stmt: usize, icol: i32) -> i32 #foreign sqlib "dist_sqlite3_column_bytes";
sqlite3_column_type :: (stmt: usize, icol: i32) -> i32 #foreign sqlib "dist_sqlite3_column_type";
sqlite3_column_count :: (stmt: usize) -> i32 #foreign sqlib "dist_sqlite3_column_count";
sqlite3_column_name :: (stmt: usize, icol: i32) -> ?cstring #foreign sqlib "dist_sqlite3_column_name";
sqlite3_column_decltype :: (stmt: usize, icol: i32) -> ?cstring #foreign sqlib "dist_sqlite3_column_decltype";
sqlite3_column_database_name :: (stmt: usize, icol: i32) -> ?cstring #foreign sqlib "dist_sqlite3_column_database_name";
sqlite3_column_table_name :: (stmt: usize, icol: i32) -> ?cstring #foreign sqlib "dist_sqlite3_column_table_name";
sqlite3_column_origin_name :: (stmt: usize, icol: i32) -> ?cstring #foreign sqlib "dist_sqlite3_column_origin_name";
sqlite3_data_count :: (stmt: usize) -> i32 #foreign sqlib "dist_sqlite3_data_count";
sqlite3_column_blob :: (stmt: usize, icol: i32) -> ?*u8 #foreign sqlib "sqlite3_column_blob";
sqlite3_column_double :: (stmt: usize, icol: i32) -> f64 #foreign sqlib "sqlite3_column_double";
sqlite3_column_int64 :: (stmt: usize, icol: i32) -> i64 #foreign sqlib "sqlite3_column_int64";
sqlite3_column_text :: (stmt: usize, icol: i32) -> ?*u8 #foreign sqlib "sqlite3_column_text";
sqlite3_column_bytes :: (stmt: usize, icol: i32) -> i32 #foreign sqlib "sqlite3_column_bytes";
sqlite3_column_type :: (stmt: usize, icol: i32) -> i32 #foreign sqlib "sqlite3_column_type";
sqlite3_column_count :: (stmt: usize) -> i32 #foreign sqlib "sqlite3_column_count";
sqlite3_column_name :: (stmt: usize, icol: i32) -> ?cstring #foreign sqlib "sqlite3_column_name";
sqlite3_column_decltype :: (stmt: usize, icol: i32) -> ?cstring #foreign sqlib "sqlite3_column_decltype";
sqlite3_column_database_name :: (stmt: usize, icol: i32) -> ?cstring #foreign sqlib "sqlite3_column_database_name";
sqlite3_column_table_name :: (stmt: usize, icol: i32) -> ?cstring #foreign sqlib "sqlite3_column_table_name";
sqlite3_column_origin_name :: (stmt: usize, icol: i32) -> ?cstring #foreign sqlib "sqlite3_column_origin_name";
sqlite3_data_count :: (stmt: usize) -> i32 #foreign sqlib "sqlite3_data_count";
// ── FFI: incremental blob I/O ─────────────────────────────────────────
sqlite3_blob_open :: (db: usize, db_name: cstring, table: cstring, column: cstring, rowid: i64, flags: i32, out_blob: *usize) -> i32 #foreign sqlib "dist_sqlite3_blob_open";
sqlite3_blob_reopen :: (blob: usize, rowid: i64) -> i32 #foreign sqlib "dist_sqlite3_blob_reopen";
sqlite3_blob_close :: (blob: usize) -> i32 #foreign sqlib "dist_sqlite3_blob_close";
sqlite3_blob_bytes :: (blob: usize) -> i32 #foreign sqlib "dist_sqlite3_blob_bytes";
sqlite3_blob_read :: (blob: usize, buf: [*]u8, n: i32, offset: i32) -> i32 #foreign sqlib "dist_sqlite3_blob_read";
sqlite3_blob_write :: (blob: usize, buf: [*]u8, n: i32, offset: i32) -> i32 #foreign sqlib "dist_sqlite3_blob_write";
sqlite3_blob_open :: (db: usize, db_name: cstring, table: cstring, column: cstring, rowid: i64, flags: i32, out_blob: *usize) -> i32 #foreign sqlib "sqlite3_blob_open";
sqlite3_blob_reopen :: (blob: usize, rowid: i64) -> i32 #foreign sqlib "sqlite3_blob_reopen";
sqlite3_blob_close :: (blob: usize) -> i32 #foreign sqlib "sqlite3_blob_close";
sqlite3_blob_bytes :: (blob: usize) -> i32 #foreign sqlib "sqlite3_blob_bytes";
sqlite3_blob_read :: (blob: usize, buf: [*]u8, n: i32, offset: i32) -> i32 #foreign sqlib "sqlite3_blob_read";
sqlite3_blob_write :: (blob: usize, buf: [*]u8, n: i32, offset: i32) -> i32 #foreign sqlib "sqlite3_blob_write";
// ── FFI: online backup ────────────────────────────────────────────────
sqlite3_backup_init :: (dst: usize, dst_name: cstring, src: usize, src_name: cstring) -> usize #foreign sqlib "dist_sqlite3_backup_init";
sqlite3_backup_step :: (bk: usize, n_page: i32) -> i32 #foreign sqlib "dist_sqlite3_backup_step";
sqlite3_backup_finish :: (bk: usize) -> i32 #foreign sqlib "dist_sqlite3_backup_finish";
sqlite3_backup_remaining :: (bk: usize) -> i32 #foreign sqlib "dist_sqlite3_backup_remaining";
sqlite3_backup_pagecount :: (bk: usize) -> i32 #foreign sqlib "dist_sqlite3_backup_pagecount";
sqlite3_backup_init :: (dst: usize, dst_name: cstring, src: usize, src_name: cstring) -> usize #foreign sqlib "sqlite3_backup_init";
sqlite3_backup_step :: (bk: usize, n_page: i32) -> i32 #foreign sqlib "sqlite3_backup_step";
sqlite3_backup_finish :: (bk: usize) -> i32 #foreign sqlib "sqlite3_backup_finish";
sqlite3_backup_remaining :: (bk: usize) -> i32 #foreign sqlib "sqlite3_backup_remaining";
sqlite3_backup_pagecount :: (bk: usize) -> i32 #foreign sqlib "sqlite3_backup_pagecount";
// ── FFI: serialization ────────────────────────────────────────────────
sqlite3_serialize :: (db: usize, schema: cstring, out_size: *i64, flags: u32) -> ?*u8 #foreign sqlib "dist_sqlite3_serialize";
sqlite3_deserialize :: (db: usize, schema: cstring, data: usize, sz_db: i64, sz_buf: i64, flags: u32) -> i32 #foreign sqlib "dist_sqlite3_deserialize";
sqlite3_serialize :: (db: usize, schema: cstring, out_size: *i64, flags: u32) -> ?*u8 #foreign sqlib "sqlite3_serialize";
sqlite3_deserialize :: (db: usize, schema: cstring, data: usize, sz_db: i64, sz_buf: i64, flags: u32) -> i32 #foreign sqlib "sqlite3_deserialize";
// ── FFI: library utilities ────────────────────────────────────────────
sqlite3_libversion :: () -> ?cstring #foreign sqlib "dist_sqlite3_libversion";
sqlite3_libversion_number :: () -> i32 #foreign sqlib "dist_sqlite3_libversion_number";
sqlite3_sourceid :: () -> ?cstring #foreign sqlib "dist_sqlite3_sourceid";
sqlite3_threadsafe :: () -> i32 #foreign sqlib "dist_sqlite3_threadsafe";
sqlite3_compileoption_used :: (name: cstring) -> i32 #foreign sqlib "dist_sqlite3_compileoption_used";
sqlite3_compileoption_get :: (n: i32) -> ?cstring #foreign sqlib "dist_sqlite3_compileoption_get";
sqlite3_complete :: (sql: cstring) -> i32 #foreign sqlib "dist_sqlite3_complete";
sqlite3_free :: (p: usize) #foreign sqlib "dist_sqlite3_free";
sqlite3_malloc64 :: (n: u64) -> usize #foreign sqlib "dist_sqlite3_malloc64";
sqlite3_msize :: (p: usize) -> u64 #foreign sqlib "dist_sqlite3_msize";
sqlite3_memory_used :: () -> i64 #foreign sqlib "dist_sqlite3_memory_used";
sqlite3_memory_highwater :: (reset: i32) -> i64 #foreign sqlib "dist_sqlite3_memory_highwater";
sqlite3_release_memory :: (n: i32) -> i32 #foreign sqlib "dist_sqlite3_release_memory";
sqlite3_soft_heap_limit64 :: (n: i64) -> i64 #foreign sqlib "dist_sqlite3_soft_heap_limit64";
sqlite3_hard_heap_limit64 :: (n: i64) -> i64 #foreign sqlib "dist_sqlite3_hard_heap_limit64";
sqlite3_randomness :: (n: i32, buf: [*]u8) #foreign sqlib "dist_sqlite3_randomness";
sqlite3_sleep :: (ms: i32) -> i32 #foreign sqlib "dist_sqlite3_sleep";
sqlite3_stricmp :: (a: cstring, b: cstring) -> i32 #foreign sqlib "dist_sqlite3_stricmp";
sqlite3_strnicmp :: (a: cstring, b: cstring, n: i32) -> i32 #foreign sqlib "dist_sqlite3_strnicmp";
sqlite3_strglob :: (glob: cstring, s: cstring) -> i32 #foreign sqlib "dist_sqlite3_strglob";
sqlite3_strlike :: (like: cstring, s: cstring, esc: u32) -> i32 #foreign sqlib "dist_sqlite3_strlike";
sqlite3_libversion :: () -> ?cstring #foreign sqlib "sqlite3_libversion";
sqlite3_libversion_number :: () -> i32 #foreign sqlib "sqlite3_libversion_number";
sqlite3_sourceid :: () -> ?cstring #foreign sqlib "sqlite3_sourceid";
sqlite3_threadsafe :: () -> i32 #foreign sqlib "sqlite3_threadsafe";
sqlite3_compileoption_used :: (name: cstring) -> i32 #foreign sqlib "sqlite3_compileoption_used";
sqlite3_compileoption_get :: (n: i32) -> ?cstring #foreign sqlib "sqlite3_compileoption_get";
sqlite3_complete :: (sql: cstring) -> i32 #foreign sqlib "sqlite3_complete";
sqlite3_free :: (p: usize) #foreign sqlib "sqlite3_free";
sqlite3_malloc64 :: (n: u64) -> usize #foreign sqlib "sqlite3_malloc64";
sqlite3_msize :: (p: usize) -> u64 #foreign sqlib "sqlite3_msize";
sqlite3_memory_used :: () -> i64 #foreign sqlib "sqlite3_memory_used";
sqlite3_memory_highwater :: (reset: i32) -> i64 #foreign sqlib "sqlite3_memory_highwater";
sqlite3_release_memory :: (n: i32) -> i32 #foreign sqlib "sqlite3_release_memory";
sqlite3_soft_heap_limit64 :: (n: i64) -> i64 #foreign sqlib "sqlite3_soft_heap_limit64";
sqlite3_hard_heap_limit64 :: (n: i64) -> i64 #foreign sqlib "sqlite3_hard_heap_limit64";
sqlite3_randomness :: (n: i32, buf: [*]u8) #foreign sqlib "sqlite3_randomness";
sqlite3_sleep :: (ms: i32) -> i32 #foreign sqlib "sqlite3_sleep";
sqlite3_stricmp :: (a: cstring, b: cstring) -> i32 #foreign sqlib "sqlite3_stricmp";
sqlite3_strnicmp :: (a: cstring, b: cstring, n: i32) -> i32 #foreign sqlib "sqlite3_strnicmp";
sqlite3_strglob :: (glob: cstring, s: cstring) -> i32 #foreign sqlib "sqlite3_strglob";
sqlite3_strlike :: (like: cstring, s: cstring, esc: u32) -> i32 #foreign sqlib "sqlite3_strlike";
// ── Result codes (primary; full set) ──────────────────────────────────
SQLITE_OK :: 0;