sqlite bindings: honest C integer widths on the wrappers

The wrapper surface previously widened every integer to i64. Wrappers
now carry SQLite's own widths: i32 where the C API says int (result
codes, counts, indexes, byte sizes), u32/u64 where it says unsigned
(prepare flags, strlike escape, zeroblob64), i64 only for the genuinely
64-bit APIs (rowids, changes64, memory accounting, serialize sizes).
sx converts implicitly in both directions, so call sites are unchanged.
This commit is contained in:
agra
2026-06-12 15:43:29 +03:00
parent b5b8ab092b
commit 3747c40e90

View File

@@ -41,6 +41,10 @@
// views pass without copying — and `column_text`/`column_blob`/ // views pass without copying — and `column_text`/`column_blob`/
// `serialize` return `?*u8` + explicit byte counts, never `cstring`: // `serialize` return `?*u8` + explicit byte counts, never `cstring`:
// their payloads may carry interior NULs that a strlen would truncate. // their payloads may carry interior NULs that a strlen would truncate.
// Integer widths are SQLite's own, on the wrappers too: `i32` where
// the C API says `int` (result codes, counts, indexes, byte sizes),
// `u32`/`u64` where it says unsigned, and `i64` only for the genuinely
// 64-bit APIs (rowids, changes64, memory accounting, serialize sizes).
// ===================================================================== // =====================================================================
#import "modules/std.sx"; #import "modules/std.sx";
@@ -322,8 +326,8 @@ sq_copy_bytes :: (p: ?*u8, n: i64) -> string {
sqlite_version :: () -> string { sqlite_version :: () -> string {
return sq_from_cstr(sqlite3_libversion()); return sq_from_cstr(sqlite3_libversion());
} }
sqlite_version_number :: () -> i64 { sqlite_version_number :: () -> i32 {
return xx sqlite3_libversion_number(); return sqlite3_libversion_number();
} }
sqlite_sourceid :: () -> string { sqlite_sourceid :: () -> string {
return sq_from_cstr(sqlite3_sourceid()); return sq_from_cstr(sqlite3_sourceid());
@@ -335,26 +339,27 @@ sqlite_compileoption_used :: (name: string) -> bool {
return sqlite3_compileoption_used(to_cstring(name)) != 0; return sqlite3_compileoption_used(to_cstring(name)) != 0;
} }
// The n'th compile option ("" past the end). // The n'th compile option ("" past the end).
sqlite_compileoption_get :: (n: i64) -> string { sqlite_compileoption_get :: (n: i32) -> string {
return sq_from_cstr(sqlite3_compileoption_get(xx n)); return sq_from_cstr(sqlite3_compileoption_get(n));
} }
// Human text for a result code (static storage; copied anyway). // Human text for a result code (static storage; copied anyway).
sqlite_errstr :: (code: i64) -> string { sqlite_errstr :: (code: i32) -> string {
return sq_from_cstr(sqlite3_errstr(xx code)); return sq_from_cstr(sqlite3_errstr(code));
} }
// True iff `sql` ends in a complete SQL statement. // True iff `sql` ends in a complete SQL statement.
sqlite_complete :: (sql: string) -> bool { sqlite_complete :: (sql: string) -> bool {
return sqlite3_complete(to_cstring(sql)) != 0; return sqlite3_complete(to_cstring(sql)) != 0;
} }
// `n` bytes from SQLite's CSPRNG. // `n` bytes from SQLite's CSPRNG.
sqlite_randomness :: (n: i64) -> string { sqlite_randomness :: (n: i32) -> string {
raw : [*]u8 = xx context.allocator.alloc_bytes(n + 1); len : i64 = n;
sqlite3_randomness(xx n, raw); raw : [*]u8 = xx context.allocator.alloc_bytes(len + 1);
raw[n] = 0; sqlite3_randomness(n, raw);
return string.{ ptr = raw, len = n }; raw[len] = 0;
return string.{ ptr = raw, len = len };
} }
sqlite_sleep :: (ms: i64) -> i64 { sqlite_sleep :: (ms: i32) -> i32 {
return xx sqlite3_sleep(xx ms); return sqlite3_sleep(ms);
} }
// memory_used/highwater read 0 in this build: SQLITE_DEFAULT_MEMSTATUS=0. // memory_used/highwater read 0 in this build: SQLITE_DEFAULT_MEMSTATUS=0.
sqlite_memory_used :: () -> i64 { sqlite_memory_used :: () -> i64 {
@@ -363,8 +368,8 @@ sqlite_memory_used :: () -> i64 {
sqlite_memory_highwater :: (reset: bool) -> i64 { sqlite_memory_highwater :: (reset: bool) -> i64 {
return sqlite3_memory_highwater(if reset then 1 else 0); return sqlite3_memory_highwater(if reset then 1 else 0);
} }
sqlite_release_memory :: (n: i64) -> i64 { sqlite_release_memory :: (n: i32) -> i32 {
return xx sqlite3_release_memory(xx n); return sqlite3_release_memory(n);
} }
sqlite_soft_heap_limit :: (n: i64) -> i64 { sqlite_soft_heap_limit :: (n: i64) -> i64 {
return sqlite3_soft_heap_limit64(n); return sqlite3_soft_heap_limit64(n);
@@ -377,11 +382,11 @@ sqlite_hard_heap_limit :: (n: i64) -> i64 {
sqlite_strglob :: (glob: string, s: string) -> bool { sqlite_strglob :: (glob: string, s: string) -> bool {
return sqlite3_strglob(to_cstring(glob), to_cstring(s)) == 0; return sqlite3_strglob(to_cstring(glob), to_cstring(s)) == 0;
} }
sqlite_strlike :: (like: string, s: string, esc: i64) -> bool { sqlite_strlike :: (like: string, s: string, esc: u32) -> bool {
return sqlite3_strlike(to_cstring(like), to_cstring(s), xx esc) == 0; return sqlite3_strlike(to_cstring(like), to_cstring(s), esc) == 0;
} }
sqlite_stricmp :: (a: string, b: string) -> i64 { sqlite_stricmp :: (a: string, b: string) -> i32 {
return xx sqlite3_stricmp(to_cstring(a), to_cstring(b)); return sqlite3_stricmp(to_cstring(a), to_cstring(b));
} }
// ── prepared statements ─────────────────────────────────────────────── // ── prepared statements ───────────────────────────────────────────────
@@ -393,34 +398,34 @@ SqliteStmt :: struct {
db: usize; db: usize;
// ── binding ── // ── binding ──
bind_text :: (self: *SqliteStmt, idx: i64, s: string) -> !SqliteErr { bind_text :: (self: *SqliteStmt, idx: i32, s: string) -> !SqliteErr {
rc := sqlite3_bind_text(self.handle, xx idx, s.ptr, xx s.len, SQLITE_TRANSIENT); rc := sqlite3_bind_text(self.handle, idx, s.ptr, xx s.len, SQLITE_TRANSIENT);
if rc != SQLITE_OK { raise error.Bind; } if rc != SQLITE_OK { raise error.Bind; }
return; return;
} }
bind_blob :: (self: *SqliteStmt, idx: i64, bytes: string) -> !SqliteErr { bind_blob :: (self: *SqliteStmt, idx: i32, bytes: string) -> !SqliteErr {
rc := sqlite3_bind_blob(self.handle, xx idx, bytes.ptr, xx bytes.len, SQLITE_TRANSIENT); rc := sqlite3_bind_blob(self.handle, idx, bytes.ptr, xx bytes.len, SQLITE_TRANSIENT);
if rc != SQLITE_OK { raise error.Bind; } if rc != SQLITE_OK { raise error.Bind; }
return; return;
} }
bind_double :: (self: *SqliteStmt, idx: i64, v: f64) -> !SqliteErr { bind_double :: (self: *SqliteStmt, idx: i32, v: f64) -> !SqliteErr {
rc := sqlite3_bind_double(self.handle, xx idx, v); rc := sqlite3_bind_double(self.handle, idx, v);
if rc != SQLITE_OK { raise error.Bind; } if rc != SQLITE_OK { raise error.Bind; }
return; return;
} }
bind_int64 :: (self: *SqliteStmt, idx: i64, v: i64) -> !SqliteErr { bind_int64 :: (self: *SqliteStmt, idx: i32, v: i64) -> !SqliteErr {
rc := sqlite3_bind_int64(self.handle, xx idx, v); rc := sqlite3_bind_int64(self.handle, idx, v);
if rc != SQLITE_OK { raise error.Bind; } if rc != SQLITE_OK { raise error.Bind; }
return; return;
} }
bind_null :: (self: *SqliteStmt, idx: i64) -> !SqliteErr { bind_null :: (self: *SqliteStmt, idx: i32) -> !SqliteErr {
rc := sqlite3_bind_null(self.handle, xx idx); rc := sqlite3_bind_null(self.handle, idx);
if rc != SQLITE_OK { raise error.Bind; } if rc != SQLITE_OK { raise error.Bind; }
return; return;
} }
// Reserve an `n`-byte zero-filled blob (fill it via SqliteBlob I/O). // Reserve an `n`-byte zero-filled blob (fill it via SqliteBlob I/O).
bind_zeroblob :: (self: *SqliteStmt, idx: i64, n: i64) -> !SqliteErr { bind_zeroblob :: (self: *SqliteStmt, idx: i32, n: u64) -> !SqliteErr {
rc := sqlite3_bind_zeroblob64(self.handle, xx idx, xx n); rc := sqlite3_bind_zeroblob64(self.handle, idx, n);
if rc != SQLITE_OK { raise error.Bind; } if rc != SQLITE_OK { raise error.Bind; }
return; return;
} }
@@ -429,25 +434,25 @@ SqliteStmt :: struct {
} }
// ── parameters ── // ── parameters ──
parameter_count :: (self: *SqliteStmt) -> i64 { parameter_count :: (self: *SqliteStmt) -> i32 {
return xx sqlite3_bind_parameter_count(self.handle); return sqlite3_bind_parameter_count(self.handle);
} }
// 1-based index of a named parameter (":name" / "@name" / "?N"), 0 if absent. // 1-based index of a named parameter (":name" / "@name" / "?N"), 0 if absent.
parameter_index :: (self: *SqliteStmt, name: string) -> i64 { parameter_index :: (self: *SqliteStmt, name: string) -> i32 {
return xx sqlite3_bind_parameter_index(self.handle, to_cstring(name)); return sqlite3_bind_parameter_index(self.handle, to_cstring(name));
} }
// The name of parameter `idx` ("" for nameless `?` parameters). // The name of parameter `idx` ("" for nameless `?` parameters).
parameter_name :: (self: *SqliteStmt, idx: i64) -> string { parameter_name :: (self: *SqliteStmt, idx: i32) -> string {
return sq_from_cstr(sqlite3_bind_parameter_name(self.handle, xx idx)); return sq_from_cstr(sqlite3_bind_parameter_name(self.handle, idx));
} }
// ── execution ── // ── execution ──
// SQLITE_ROW / SQLITE_DONE on success; anything else raises with the // SQLITE_ROW / SQLITE_DONE on success; anything else raises with the
// detail left in the connection's errmsg. // detail left in the connection's errmsg.
step :: (self: *SqliteStmt) -> (i64, !SqliteErr) { step :: (self: *SqliteStmt) -> (i32, !SqliteErr) {
rc := sqlite3_step(self.handle); rc := sqlite3_step(self.handle);
if rc != SQLITE_ROW and rc != SQLITE_DONE { raise error.Step; } if rc != SQLITE_ROW and rc != SQLITE_DONE { raise error.Step; }
return xx rc; return rc;
} }
reset :: (self: *SqliteStmt) { reset :: (self: *SqliteStmt) {
sqlite3_reset(self.handle); sqlite3_reset(self.handle);
@@ -458,49 +463,49 @@ SqliteStmt :: struct {
} }
// ── columns (copies into context.allocator; NULL reads as ""/0) ── // ── columns (copies into context.allocator; NULL reads as ""/0) ──
column_int64 :: (self: *SqliteStmt, icol: i64) -> i64 { column_int64 :: (self: *SqliteStmt, icol: i32) -> i64 {
return sqlite3_column_int64(self.handle, xx icol); return sqlite3_column_int64(self.handle, icol);
} }
column_double :: (self: *SqliteStmt, icol: i64) -> f64 { column_double :: (self: *SqliteStmt, icol: i32) -> f64 {
return sqlite3_column_double(self.handle, xx icol); return sqlite3_column_double(self.handle, icol);
} }
column_text :: (self: *SqliteStmt, icol: i64) -> string { column_text :: (self: *SqliteStmt, icol: i32) -> string {
p := sqlite3_column_text(self.handle, xx icol); p := sqlite3_column_text(self.handle, icol);
n := sqlite3_column_bytes(self.handle, xx icol); n := sqlite3_column_bytes(self.handle, icol);
return sq_copy_bytes(p, xx n); return sq_copy_bytes(p, xx n);
} }
column_blob :: (self: *SqliteStmt, icol: i64) -> string { column_blob :: (self: *SqliteStmt, icol: i32) -> string {
p := sqlite3_column_blob(self.handle, xx icol); p := sqlite3_column_blob(self.handle, icol);
n := sqlite3_column_bytes(self.handle, xx icol); n := sqlite3_column_bytes(self.handle, icol);
return sq_copy_bytes(p, xx n); return sq_copy_bytes(p, xx n);
} }
column_bytes :: (self: *SqliteStmt, icol: i64) -> i64 { column_bytes :: (self: *SqliteStmt, icol: i32) -> i32 {
return xx sqlite3_column_bytes(self.handle, xx icol); return sqlite3_column_bytes(self.handle, icol);
} }
column_type :: (self: *SqliteStmt, icol: i64) -> i64 { column_type :: (self: *SqliteStmt, icol: i32) -> i32 {
return xx sqlite3_column_type(self.handle, xx icol); return sqlite3_column_type(self.handle, icol);
} }
column_count :: (self: *SqliteStmt) -> i64 { column_count :: (self: *SqliteStmt) -> i32 {
return xx sqlite3_column_count(self.handle); return sqlite3_column_count(self.handle);
} }
column_name :: (self: *SqliteStmt, icol: i64) -> string { column_name :: (self: *SqliteStmt, icol: i32) -> string {
return sq_from_cstr(sqlite3_column_name(self.handle, xx icol)); return sq_from_cstr(sqlite3_column_name(self.handle, icol));
} }
// The declared type from the schema ("" for expressions). // The declared type from the schema ("" for expressions).
column_decltype :: (self: *SqliteStmt, icol: i64) -> string { column_decltype :: (self: *SqliteStmt, icol: i32) -> string {
return sq_from_cstr(sqlite3_column_decltype(self.handle, xx icol)); return sq_from_cstr(sqlite3_column_decltype(self.handle, icol));
} }
column_database_name :: (self: *SqliteStmt, icol: i64) -> string { column_database_name :: (self: *SqliteStmt, icol: i32) -> string {
return sq_from_cstr(sqlite3_column_database_name(self.handle, xx icol)); return sq_from_cstr(sqlite3_column_database_name(self.handle, icol));
} }
column_table_name :: (self: *SqliteStmt, icol: i64) -> string { column_table_name :: (self: *SqliteStmt, icol: i32) -> string {
return sq_from_cstr(sqlite3_column_table_name(self.handle, xx icol)); return sq_from_cstr(sqlite3_column_table_name(self.handle, icol));
} }
column_origin_name :: (self: *SqliteStmt, icol: i64) -> string { column_origin_name :: (self: *SqliteStmt, icol: i32) -> string {
return sq_from_cstr(sqlite3_column_origin_name(self.handle, xx icol)); return sq_from_cstr(sqlite3_column_origin_name(self.handle, icol));
} }
data_count :: (self: *SqliteStmt) -> i64 { data_count :: (self: *SqliteStmt) -> i32 {
return xx sqlite3_data_count(self.handle); return sqlite3_data_count(self.handle);
} }
// ── introspection ── // ── introspection ──
@@ -522,11 +527,11 @@ SqliteStmt :: struct {
return sqlite3_stmt_readonly(self.handle) != 0; return sqlite3_stmt_readonly(self.handle) != 0;
} }
// 0 = normal, 1 = EXPLAIN, 2 = EXPLAIN QUERY PLAN. // 0 = normal, 1 = EXPLAIN, 2 = EXPLAIN QUERY PLAN.
isexplain :: (self: *SqliteStmt) -> i64 { isexplain :: (self: *SqliteStmt) -> i32 {
return xx sqlite3_stmt_isexplain(self.handle); return sqlite3_stmt_isexplain(self.handle);
} }
status :: (self: *SqliteStmt, op: i64, reset: bool) -> i64 { status :: (self: *SqliteStmt, op: i32, reset: bool) -> i32 {
return xx sqlite3_stmt_status(self.handle, xx op, if reset then 1 else 0); return sqlite3_stmt_status(self.handle, op, if reset then 1 else 0);
} }
} }
@@ -557,9 +562,9 @@ Sqlite :: struct {
return Sqlite.{ handle = h }; return Sqlite.{ handle = h };
} }
open_v2 :: (path: string, flags: i64) -> (Sqlite, !SqliteErr) { open_v2 :: (path: string, flags: i32) -> (Sqlite, !SqliteErr) {
h : usize = 0; h : usize = 0;
rc := sqlite3_open_v2(to_cstring(path), @h, xx flags, 0); rc := sqlite3_open_v2(to_cstring(path), @h, flags, 0);
if rc != SQLITE_OK { if rc != SQLITE_OK {
if h != 0 { sqlite3_close(h); } if h != 0 { sqlite3_close(h); }
raise error.Open; raise error.Open;
@@ -594,9 +599,9 @@ Sqlite :: struct {
} }
// prepare with SQLITE_PREPARE_* flags (e.g. PERSISTENT for the // prepare with SQLITE_PREPARE_* flags (e.g. PERSISTENT for the
// statement cache a storage layer keeps hot). // statement cache a storage layer keeps hot).
prepare_v3 :: (self: *Sqlite, sql: string, flags: i64) -> (SqliteStmt, !SqliteErr) { prepare_v3 :: (self: *Sqlite, sql: string, flags: u32) -> (SqliteStmt, !SqliteErr) {
sh : usize = 0; sh : usize = 0;
rc := sqlite3_prepare_v3(self.handle, sql.ptr, xx sql.len, xx flags, @sh, 0); rc := sqlite3_prepare_v3(self.handle, sql.ptr, xx sql.len, flags, @sh, 0);
if rc != SQLITE_OK { raise error.Prepare; } if rc != SQLITE_OK { raise error.Prepare; }
return SqliteStmt.{ handle = sh, db = self.handle }; return SqliteStmt.{ handle = sh, db = self.handle };
} }
@@ -605,23 +610,23 @@ Sqlite :: struct {
errmsg :: (self: *Sqlite) -> string { errmsg :: (self: *Sqlite) -> string {
return sq_from_cstr(sqlite3_errmsg(self.handle)); return sq_from_cstr(sqlite3_errmsg(self.handle));
} }
errcode :: (self: *Sqlite) -> i64 { errcode :: (self: *Sqlite) -> i32 {
return xx sqlite3_errcode(self.handle); return sqlite3_errcode(self.handle);
} }
extended_errcode :: (self: *Sqlite) -> i64 { extended_errcode :: (self: *Sqlite) -> i32 {
return xx sqlite3_extended_errcode(self.handle); return sqlite3_extended_errcode(self.handle);
} }
// Byte offset of the most recent error's token in its SQL, -1 if n/a. // Byte offset of the most recent error's token in its SQL, -1 if n/a.
error_offset :: (self: *Sqlite) -> i64 { error_offset :: (self: *Sqlite) -> i32 {
return xx sqlite3_error_offset(self.handle); return sqlite3_error_offset(self.handle);
} }
extended_result_codes :: (self: *Sqlite, on: bool) { extended_result_codes :: (self: *Sqlite, on: bool) {
sqlite3_extended_result_codes(self.handle, if on then 1 else 0); sqlite3_extended_result_codes(self.handle, if on then 1 else 0);
} }
// ── state & control ── // ── state & control ──
busy_timeout :: (self: *Sqlite, ms: i64) { busy_timeout :: (self: *Sqlite, ms: i32) {
sqlite3_busy_timeout(self.handle, xx ms); sqlite3_busy_timeout(self.handle, ms);
} }
interrupt :: (self: *Sqlite) { interrupt :: (self: *Sqlite) {
sqlite3_interrupt(self.handle); sqlite3_interrupt(self.handle);
@@ -633,15 +638,15 @@ Sqlite :: struct {
return sqlite3_get_autocommit(self.handle) != 0; return sqlite3_get_autocommit(self.handle) != 0;
} }
// SQLITE_TXN_NONE / _READ / _WRITE for the "main" schema. // SQLITE_TXN_NONE / _READ / _WRITE for the "main" schema.
txn_state :: (self: *Sqlite) -> i64 { txn_state :: (self: *Sqlite) -> i32 {
return xx sqlite3_txn_state(self.handle, to_cstring("main")); return sqlite3_txn_state(self.handle, to_cstring("main"));
} }
db_filename :: (self: *Sqlite) -> string { db_filename :: (self: *Sqlite) -> string {
return sq_from_cstr(sqlite3_db_filename(self.handle, to_cstring("main"))); return sq_from_cstr(sqlite3_db_filename(self.handle, to_cstring("main")));
} }
// 1 readonly, 0 read-write, -1 no such database name. // 1 readonly, 0 read-write, -1 no such database name.
db_readonly :: (self: *Sqlite) -> i64 { db_readonly :: (self: *Sqlite) -> i32 {
return xx sqlite3_db_readonly(self.handle, to_cstring("main")); return sqlite3_db_readonly(self.handle, to_cstring("main"));
} }
cacheflush :: (self: *Sqlite) { cacheflush :: (self: *Sqlite) {
sqlite3_db_cacheflush(self.handle); sqlite3_db_cacheflush(self.handle);
@@ -663,8 +668,8 @@ Sqlite :: struct {
} }
// Set a SQLITE_LIMIT_* runtime limit; answers the PRIOR value. // Set a SQLITE_LIMIT_* runtime limit; answers the PRIOR value.
// new_val < 0 reads without changing. // new_val < 0 reads without changing.
limit :: (self: *Sqlite, id: i64, new_val: i64) -> i64 { limit :: (self: *Sqlite, id: i32, new_val: i32) -> i32 {
return xx sqlite3_limit(self.handle, xx id, xx new_val); return sqlite3_limit(self.handle, id, new_val);
} }
// Schema introspection for one column of "main".`table`. // Schema introspection for one column of "main".`table`.
@@ -731,18 +736,19 @@ SqliteBlob :: struct {
if rc != SQLITE_OK { raise error.Blob; } if rc != SQLITE_OK { raise error.Blob; }
return; return;
} }
bytes :: (self: *SqliteBlob) -> i64 { bytes :: (self: *SqliteBlob) -> i32 {
return xx sqlite3_blob_bytes(self.handle); return sqlite3_blob_bytes(self.handle);
} }
read :: (self: *SqliteBlob, offset: i64, n: i64) -> (string, !SqliteErr) { read :: (self: *SqliteBlob, offset: i32, n: i32) -> (string, !SqliteErr) {
raw : [*]u8 = xx context.allocator.alloc_bytes(n + 1); len : i64 = n;
rc := sqlite3_blob_read(self.handle, raw, xx n, xx offset); raw : [*]u8 = xx context.allocator.alloc_bytes(len + 1);
rc := sqlite3_blob_read(self.handle, raw, n, offset);
if rc != SQLITE_OK { raise error.Blob; } if rc != SQLITE_OK { raise error.Blob; }
raw[n] = 0; raw[len] = 0;
return string.{ ptr = raw, len = n }; return string.{ ptr = raw, len = len };
} }
write :: (self: *SqliteBlob, offset: i64, data: string) -> !SqliteErr { write :: (self: *SqliteBlob, offset: i32, data: string) -> !SqliteErr {
rc := sqlite3_blob_write(self.handle, data.ptr, xx data.len, xx offset); rc := sqlite3_blob_write(self.handle, data.ptr, xx data.len, offset);
if rc != SQLITE_OK { raise error.Blob; } if rc != SQLITE_OK { raise error.Blob; }
return; return;
} }
@@ -767,19 +773,19 @@ SqliteBackup :: struct {
} }
// Copy up to `n` pages (-1 = all remaining). SQLITE_OK = more to do, // Copy up to `n` pages (-1 = all remaining). SQLITE_OK = more to do,
// SQLITE_DONE = complete; BUSY/LOCKED are retryable per the C API. // SQLITE_DONE = complete; BUSY/LOCKED are retryable per the C API.
step :: (self: *SqliteBackup, n: i64) -> i64 { step :: (self: *SqliteBackup, n: i32) -> i32 {
return xx sqlite3_backup_step(self.handle, xx n); return sqlite3_backup_step(self.handle, n);
} }
remaining :: (self: *SqliteBackup) -> i64 { remaining :: (self: *SqliteBackup) -> i32 {
return xx sqlite3_backup_remaining(self.handle); return sqlite3_backup_remaining(self.handle);
} }
pagecount :: (self: *SqliteBackup) -> i64 { pagecount :: (self: *SqliteBackup) -> i32 {
return xx sqlite3_backup_pagecount(self.handle); return sqlite3_backup_pagecount(self.handle);
} }
finish :: (self: *SqliteBackup) -> i64 { finish :: (self: *SqliteBackup) -> i32 {
rc := sqlite3_backup_finish(self.handle); rc := sqlite3_backup_finish(self.handle);
self.handle = 0; self.handle = 0;
return xx rc; return rc;
} }
} }