#![expect(non_camel_case_types)]
use std::{
error::Error,
ffi::{c_char, c_int, c_uint, c_void},
fmt::{Display, Formatter},
};
pub struct sqlite3(#[expect(dead_code)] u8);
pub struct sqlite3_stmt(#[expect(dead_code)] u8);
dynload! {
SQLITE: Sqlite from "libsqlite3.so.0" {
sqlite3_bind_blob: unsafe extern "C" fn(
arg1: *mut sqlite3_stmt,
arg2: c_int,
arg3: *const c_void,
n: c_int,
arg4: sqlite3_destructor_type,
) -> SqliteResult,
sqlite3_bind_int64: unsafe extern "C" fn(
arg1: *mut sqlite3_stmt,
arg2: c_int,
arg3: i64,
) -> SqliteResult,
sqlite3_clear_bindings: unsafe extern "C" fn(arg1: *mut sqlite3_stmt) -> SqliteResult,
sqlite3_close: unsafe extern "C" fn(arg1: *mut sqlite3) -> SqliteResult,
sqlite3_column_blob: unsafe extern "C" fn(
arg1: *mut sqlite3_stmt,
iCol: c_int,
) -> *const c_void,
sqlite3_column_bytes: unsafe extern "C" fn(
arg1: *mut sqlite3_stmt,
iCol: c_int,
) -> c_int,
sqlite3_column_int64: unsafe extern "C" fn(
arg1: *mut sqlite3_stmt,
iCol: c_int,
) -> i64,
sqlite3_column_type: unsafe extern "C" fn(
arg1: *mut sqlite3_stmt,
iCol: c_int,
) -> c_int,
sqlite3_config: unsafe extern "C" fn(arg1: c_int, ...) -> SqliteResult,
sqlite3_exec: unsafe extern "C" fn(
arg1: *mut sqlite3,
sql: *const c_char,
callback: Option<
unsafe extern "C" fn(
arg1: *mut c_void,
arg2: c_int,
arg3: *mut *mut c_char,
arg4: *mut *mut c_char,
) -> c_int,
>,
arg2: *mut c_void,
errmsg: *mut *mut c_char,
) -> SqliteResult,
sqlite3_finalize: unsafe extern "C" fn(pStmt: *mut sqlite3_stmt) -> SqliteResult,
sqlite3_open_v2: unsafe extern "C" fn(
filename: *const c_char,
ppDb: *mut *mut sqlite3,
flags: c_int,
zVfs: *const c_char,
) -> SqliteResult,
sqlite3_prepare_v3: unsafe extern "C" fn(
db: *mut sqlite3,
zSql: *const c_char,
nByte: c_int,
prepFlags: c_uint,
ppStmt: *mut *mut sqlite3_stmt,
pzTail: *mut *const c_char,
) -> SqliteResult,
sqlite3_reset: unsafe extern "C" fn(pStmt: *mut sqlite3_stmt) -> SqliteResult,
sqlite3_step: unsafe extern "C" fn(arg1: *mut sqlite3_stmt) -> SqliteResult,
}
}
macro_rules! sqlite_result {
(
@basic:
$($bcode:ident = $bvalue:expr,)*
@extended:
$($ecode:ident = $evalue:expr,)*
) => {
$(pub const $bcode: c_int = $bvalue;)*
$(pub const $ecode: c_int = $evalue;)*
impl Display for SqliteResult {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
'extended: {
let s = match self.0 {
$($ecode => stringify!($ecode),)*
_ => break 'extended,
};
return f.write_str(s);
}
let s = match self.0 & 0xff {
$($bcode => stringify!($bcode),)*
_ => return write!(f, "0x{:x}", self.0),
};
f.write_str(s)?;
if self.0 & !0xff != 0 {
write!(f, " (0x{:x})", self.0)?;
}
Ok(())
}
}
};
}
sqlite_result! {
@basic:
SQLITE_OK = 0,
SQLITE_ERROR = 1,
SQLITE_INTERNAL = 2,
SQLITE_PERM = 3,
SQLITE_ABORT = 4,
SQLITE_BUSY = 5,
SQLITE_LOCKED = 6,
SQLITE_NOMEM = 7,
SQLITE_READONLY = 8,
SQLITE_INTERRUPT = 9,
SQLITE_IOERR = 10,
SQLITE_CORRUPT = 11,
SQLITE_NOTFOUND = 12,
SQLITE_FULL = 13,
SQLITE_CANTOPEN = 14,
SQLITE_PROTOCOL = 15,
SQLITE_EMPTY = 16,
SQLITE_SCHEMA = 17,
SQLITE_TOOBIG = 18,
SQLITE_CONSTRAINT = 19,
SQLITE_MISMATCH = 20,
SQLITE_MISUSE = 21,
SQLITE_NOLFS = 22,
SQLITE_AUTH = 23,
SQLITE_FORMAT = 24,
SQLITE_RANGE = 25,
SQLITE_NOTADB = 26,
SQLITE_NOTICE = 27,
SQLITE_WARNING = 28,
SQLITE_ROW = 100,
SQLITE_DONE = 101,
@extended:
SQLITE_ERROR_MISSING_COLLSEQ = SQLITE_ERROR | (1 << 8),
SQLITE_ERROR_RETRY = SQLITE_ERROR | (2 << 8),
SQLITE_ERROR_SNAPSHOT = SQLITE_ERROR | (3 << 8),
SQLITE_ERROR_RESERVESIZE = SQLITE_ERROR | (4 << 8),
SQLITE_ERROR_KEY = SQLITE_ERROR | (5 << 8),
SQLITE_ERROR_UNABLE = SQLITE_ERROR | (6 << 8),
SQLITE_IOERR_READ = SQLITE_IOERR | (1 << 8),
SQLITE_IOERR_SHORT_READ = SQLITE_IOERR | (2 << 8),
SQLITE_IOERR_WRITE = SQLITE_IOERR | (3 << 8),
SQLITE_IOERR_FSYNC = SQLITE_IOERR | (4 << 8),
SQLITE_IOERR_DIR_FSYNC = SQLITE_IOERR | (5 << 8),
SQLITE_IOERR_TRUNCATE = SQLITE_IOERR | (6 << 8),
SQLITE_IOERR_FSTAT = SQLITE_IOERR | (7 << 8),
SQLITE_IOERR_UNLOCK = SQLITE_IOERR | (8 << 8),
SQLITE_IOERR_RDLOCK = SQLITE_IOERR | (9 << 8),
SQLITE_IOERR_DELETE = SQLITE_IOERR | (10 << 8),
SQLITE_IOERR_BLOCKED = SQLITE_IOERR | (11 << 8),
SQLITE_IOERR_NOMEM = SQLITE_IOERR | (12 << 8),
SQLITE_IOERR_ACCESS = SQLITE_IOERR | (13 << 8),
SQLITE_IOERR_CHECKRESERVEDLOCK = SQLITE_IOERR | (14 << 8),
SQLITE_IOERR_LOCK = SQLITE_IOERR | (15 << 8),
SQLITE_IOERR_CLOSE = SQLITE_IOERR | (16 << 8),
SQLITE_IOERR_DIR_CLOSE = SQLITE_IOERR | (17 << 8),
SQLITE_IOERR_SHMOPEN = SQLITE_IOERR | (18 << 8),
SQLITE_IOERR_SHMSIZE = SQLITE_IOERR | (19 << 8),
SQLITE_IOERR_SHMLOCK = SQLITE_IOERR | (20 << 8),
SQLITE_IOERR_SHMMAP = SQLITE_IOERR | (21 << 8),
SQLITE_IOERR_SEEK = SQLITE_IOERR | (22 << 8),
SQLITE_IOERR_DELETE_NOENT = SQLITE_IOERR | (23 << 8),
SQLITE_IOERR_MMAP = SQLITE_IOERR | (24 << 8),
SQLITE_IOERR_GETTEMPPATH = SQLITE_IOERR | (25 << 8),
SQLITE_IOERR_CONVPATH = SQLITE_IOERR | (26 << 8),
SQLITE_IOERR_VNODE = SQLITE_IOERR | (27 << 8),
SQLITE_IOERR_AUTH = SQLITE_IOERR | (28 << 8),
SQLITE_IOERR_BEGIN_ATOMIC = SQLITE_IOERR | (29 << 8),
SQLITE_IOERR_COMMIT_ATOMIC = SQLITE_IOERR | (30 << 8),
SQLITE_IOERR_ROLLBACK_ATOMIC = SQLITE_IOERR | (31 << 8),
SQLITE_IOERR_DATA = SQLITE_IOERR | (32 << 8),
SQLITE_IOERR_CORRUPTFS = SQLITE_IOERR | (33 << 8),
SQLITE_IOERR_IN_PAGE = SQLITE_IOERR | (34 << 8),
SQLITE_IOERR_BADKEY = SQLITE_IOERR | (35 << 8),
SQLITE_IOERR_CODEC = SQLITE_IOERR | (36 << 8),
SQLITE_LOCKED_SHAREDCACHE = SQLITE_LOCKED | (1 << 8),
SQLITE_LOCKED_VTAB = SQLITE_LOCKED | (2 << 8),
SQLITE_BUSY_RECOVERY = SQLITE_BUSY | (1 << 8),
SQLITE_BUSY_SNAPSHOT = SQLITE_BUSY | (2 << 8),
SQLITE_BUSY_TIMEOUT = SQLITE_BUSY | (3 << 8),
SQLITE_CANTOPEN_NOTEMPDIR = SQLITE_CANTOPEN | (1 << 8),
SQLITE_CANTOPEN_ISDIR = SQLITE_CANTOPEN | (2 << 8),
SQLITE_CANTOPEN_FULLPATH = SQLITE_CANTOPEN | (3 << 8),
SQLITE_CANTOPEN_CONVPATH = SQLITE_CANTOPEN | (4 << 8),
SQLITE_CANTOPEN_DIRTYWAL = SQLITE_CANTOPEN | (5 << 8),
SQLITE_CANTOPEN_SYMLINK = SQLITE_CANTOPEN | (6 << 8),
SQLITE_CORRUPT_VTAB = SQLITE_CORRUPT | (1 << 8),
SQLITE_CORRUPT_SEQUENCE = SQLITE_CORRUPT | (2 << 8),
SQLITE_CORRUPT_INDEX = SQLITE_CORRUPT | (3 << 8),
SQLITE_READONLY_RECOVERY = SQLITE_READONLY | (1 << 8),
SQLITE_READONLY_CANTLOCK = SQLITE_READONLY | (2 << 8),
SQLITE_READONLY_ROLLBACK = SQLITE_READONLY | (3 << 8),
SQLITE_READONLY_DBMOVED = SQLITE_READONLY | (4 << 8),
SQLITE_READONLY_CANTINIT = SQLITE_READONLY | (5 << 8),
SQLITE_READONLY_DIRECTORY = SQLITE_READONLY | (6 << 8),
SQLITE_ABORT_ROLLBACK = SQLITE_ABORT | (2 << 8),
SQLITE_CONSTRAINT_CHECK = SQLITE_CONSTRAINT | (1 << 8),
SQLITE_CONSTRAINT_COMMITHOOK = SQLITE_CONSTRAINT | (2 << 8),
SQLITE_CONSTRAINT_FOREIGNKEY = SQLITE_CONSTRAINT | (3 << 8),
SQLITE_CONSTRAINT_FUNCTION = SQLITE_CONSTRAINT | (4 << 8),
SQLITE_CONSTRAINT_NOTNULL = SQLITE_CONSTRAINT | (5 << 8),
SQLITE_CONSTRAINT_PRIMARYKEY = SQLITE_CONSTRAINT | (6 << 8),
SQLITE_CONSTRAINT_TRIGGER = SQLITE_CONSTRAINT | (7 << 8),
SQLITE_CONSTRAINT_UNIQUE = SQLITE_CONSTRAINT | (8 << 8),
SQLITE_CONSTRAINT_VTAB = SQLITE_CONSTRAINT | (9 << 8),
SQLITE_CONSTRAINT_ROWID = SQLITE_CONSTRAINT | (10 << 8),
SQLITE_CONSTRAINT_PINNED = SQLITE_CONSTRAINT | (11 << 8),
SQLITE_CONSTRAINT_DATATYPE = SQLITE_CONSTRAINT | (12 << 8),
SQLITE_NOTICE_RECOVER_WAL = SQLITE_NOTICE | (1 << 8),
SQLITE_NOTICE_RECOVER_ROLLBACK = SQLITE_NOTICE | (2 << 8),
SQLITE_NOTICE_RBU = SQLITE_NOTICE | (3 << 8),
SQLITE_WARNING_AUTOINDEX = SQLITE_WARNING | (1 << 8),
SQLITE_AUTH_USER = SQLITE_AUTH | (1 << 8),
SQLITE_OK_LOAD_PERMANENTLY = SQLITE_OK | (1 << 8),
SQLITE_OK_SYMLINK = SQLITE_OK | (2 << 8),
}
#[derive(Copy, Clone, Debug)]
#[repr(transparent)]
#[must_use]
pub struct SqliteResult(pub c_int);
impl SqliteResult {
pub fn is_ok(&self) -> bool {
self.0 & 0xff == SQLITE_OK
}
pub fn result(self) -> Result<(), Self> {
if self.is_ok() { Ok(()) } else { Err(self) }
}
}
impl Error for SqliteResult {}
pub const SQLITE_CONFIG_LOG: c_int = 16;
pub const SQLITE_OPEN_READWRITE: c_int = 0x00000002;
pub const SQLITE_OPEN_CREATE: c_int = 0x00000004;
pub const SQLITE_OPEN_NOMUTEX: c_int = 0x00008000;
pub const SQLITE_OPEN_EXRESCODE: c_int = 0x02000000;
pub type sqlite3_destructor_type = *const u8;
pub const SQLITE_STATIC: sqlite3_destructor_type = 0 as _;
pub const SQLITE_PREPARE_PERSISTENT: c_uint = 0x01;
pub const SQLITE_INTEGER: c_int = 1;
pub const SQLITE_BLOB: c_int = 4;