#![allow(non_camel_case_types)]
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::unreadable_literal)]
use std::ffi::{c_char, c_double, c_int, c_void};
#[repr(C)]
pub struct sqlite3 {
_private: [u8; 0],
}
#[repr(C)]
pub struct sqlite3_stmt {
_private: [u8; 0],
}
#[repr(C)]
pub struct sqlite3_backup {
_private: [u8; 0],
}
pub const SQLITE_OK: c_int = 0;
pub const SQLITE_ERROR: c_int = 1;
pub const SQLITE_INTERNAL: c_int = 2;
pub const SQLITE_PERM: c_int = 3;
pub const SQLITE_ABORT: c_int = 4;
pub const SQLITE_BUSY: c_int = 5;
pub const SQLITE_LOCKED: c_int = 6;
pub const SQLITE_NOMEM: c_int = 7;
pub const SQLITE_READONLY: c_int = 8;
pub const SQLITE_INTERRUPT: c_int = 9;
pub const SQLITE_IOERR: c_int = 10;
pub const SQLITE_CORRUPT: c_int = 11;
pub const SQLITE_NOTFOUND: c_int = 12;
pub const SQLITE_FULL: c_int = 13;
pub const SQLITE_CANTOPEN: c_int = 14;
pub const SQLITE_PROTOCOL: c_int = 15;
pub const SQLITE_EMPTY: c_int = 16;
pub const SQLITE_SCHEMA: c_int = 17;
pub const SQLITE_TOOBIG: c_int = 18;
pub const SQLITE_CONSTRAINT: c_int = 19;
pub const SQLITE_MISMATCH: c_int = 20;
pub const SQLITE_MISUSE: c_int = 21;
pub const SQLITE_NOLFS: c_int = 22;
pub const SQLITE_AUTH: c_int = 23;
pub const SQLITE_FORMAT: c_int = 24;
pub const SQLITE_RANGE: c_int = 25;
pub const SQLITE_NOTADB: c_int = 26;
pub const SQLITE_NOTICE: c_int = 27;
pub const SQLITE_WARNING: c_int = 28;
pub const SQLITE_ROW: c_int = 100;
pub const SQLITE_DONE: c_int = 101;
pub const SQLITE_OPEN_READONLY: c_int = 0x00000001;
pub const SQLITE_OPEN_READWRITE: c_int = 0x00000002;
pub const SQLITE_OPEN_CREATE: c_int = 0x00000004;
pub const SQLITE_OPEN_URI: c_int = 0x00000040;
pub const SQLITE_OPEN_MEMORY: c_int = 0x00000080;
pub const SQLITE_OPEN_NOMUTEX: c_int = 0x00008000;
pub const SQLITE_OPEN_FULLMUTEX: c_int = 0x00010000;
pub const SQLITE_OPEN_SHAREDCACHE: c_int = 0x00020000;
pub const SQLITE_OPEN_PRIVATECACHE: c_int = 0x00040000;
pub const SQLITE_INTEGER: c_int = 1;
pub const SQLITE_FLOAT: c_int = 2;
pub const SQLITE_TEXT: c_int = 3;
pub const SQLITE_BLOB: c_int = 4;
pub const SQLITE_NULL: c_int = 5;
pub type sqlite3_destructor_type = Option<unsafe extern "C" fn(*mut c_void)>;
#[inline]
pub fn sqlite_transient() -> sqlite3_destructor_type {
const SQLITE_TRANSIENT_SENTINEL: isize = -1;
unsafe { std::mem::transmute::<isize, sqlite3_destructor_type>(SQLITE_TRANSIENT_SENTINEL) }
}
#[link(name = "sqlite3", kind = "static")]
unsafe extern "C" {
pub fn sqlite3_open(filename: *const c_char, ppDb: *mut *mut sqlite3) -> c_int;
pub fn sqlite3_open_v2(
filename: *const c_char,
ppDb: *mut *mut sqlite3,
flags: c_int,
zVfs: *const c_char,
) -> c_int;
pub fn sqlite3_close(db: *mut sqlite3) -> c_int;
pub fn sqlite3_close_v2(db: *mut sqlite3) -> c_int;
pub fn sqlite3_backup_init(
pDest: *mut sqlite3,
zDestName: *const c_char,
pSource: *mut sqlite3,
zSourceName: *const c_char,
) -> *mut sqlite3_backup;
pub fn sqlite3_backup_step(p: *mut sqlite3_backup, nPage: c_int) -> c_int;
pub fn sqlite3_backup_finish(p: *mut sqlite3_backup) -> c_int;
pub fn sqlite3_backup_remaining(p: *mut sqlite3_backup) -> c_int;
pub fn sqlite3_backup_pagecount(p: *mut sqlite3_backup) -> c_int;
pub fn sqlite3_errmsg(db: *mut sqlite3) -> *const c_char;
pub fn sqlite3_errcode(db: *mut sqlite3) -> c_int;
pub fn sqlite3_extended_errcode(db: *mut sqlite3) -> c_int;
pub fn sqlite3_errstr(errcode: c_int) -> *const c_char;
pub fn sqlite3_prepare_v2(
db: *mut sqlite3,
zSql: *const c_char,
nByte: c_int,
ppStmt: *mut *mut sqlite3_stmt,
pzTail: *mut *const c_char,
) -> c_int;
pub fn sqlite3_finalize(pStmt: *mut sqlite3_stmt) -> c_int;
pub fn sqlite3_reset(pStmt: *mut sqlite3_stmt) -> c_int;
pub fn sqlite3_clear_bindings(pStmt: *mut sqlite3_stmt) -> c_int;
pub fn sqlite3_bind_null(pStmt: *mut sqlite3_stmt, index: c_int) -> c_int;
pub fn sqlite3_bind_int(pStmt: *mut sqlite3_stmt, index: c_int, value: c_int) -> c_int;
pub fn sqlite3_bind_int64(pStmt: *mut sqlite3_stmt, index: c_int, value: i64) -> c_int;
pub fn sqlite3_bind_double(pStmt: *mut sqlite3_stmt, index: c_int, value: c_double) -> c_int;
pub fn sqlite3_bind_text(
pStmt: *mut sqlite3_stmt,
index: c_int,
value: *const c_char,
nBytes: c_int,
destructor: sqlite3_destructor_type,
) -> c_int;
pub fn sqlite3_bind_blob(
pStmt: *mut sqlite3_stmt,
index: c_int,
value: *const c_void,
nBytes: c_int,
destructor: sqlite3_destructor_type,
) -> c_int;
pub fn sqlite3_bind_parameter_count(pStmt: *mut sqlite3_stmt) -> c_int;
pub fn sqlite3_bind_parameter_index(pStmt: *mut sqlite3_stmt, name: *const c_char) -> c_int;
pub fn sqlite3_bind_parameter_name(pStmt: *mut sqlite3_stmt, index: c_int) -> *const c_char;
pub fn sqlite3_step(pStmt: *mut sqlite3_stmt) -> c_int;
pub fn sqlite3_column_count(pStmt: *mut sqlite3_stmt) -> c_int;
pub fn sqlite3_column_name(pStmt: *mut sqlite3_stmt, index: c_int) -> *const c_char;
pub fn sqlite3_column_type(pStmt: *mut sqlite3_stmt, index: c_int) -> c_int;
pub fn sqlite3_column_decltype(pStmt: *mut sqlite3_stmt, index: c_int) -> *const c_char;
pub fn sqlite3_column_int(pStmt: *mut sqlite3_stmt, index: c_int) -> c_int;
pub fn sqlite3_column_int64(pStmt: *mut sqlite3_stmt, index: c_int) -> i64;
pub fn sqlite3_column_double(pStmt: *mut sqlite3_stmt, index: c_int) -> c_double;
pub fn sqlite3_column_text(pStmt: *mut sqlite3_stmt, index: c_int) -> *const c_char;
pub fn sqlite3_column_blob(pStmt: *mut sqlite3_stmt, index: c_int) -> *const c_void;
pub fn sqlite3_column_bytes(pStmt: *mut sqlite3_stmt, index: c_int) -> c_int;
pub fn sqlite3_exec(
db: *mut sqlite3,
sql: *const c_char,
callback: Option<
unsafe extern "C" fn(*mut c_void, c_int, *mut *mut c_char, *mut *mut c_char) -> c_int,
>,
arg: *mut c_void,
errmsg: *mut *mut c_char,
) -> c_int;
pub fn sqlite3_free(ptr: *mut c_void);
pub fn sqlite3_changes(db: *mut sqlite3) -> c_int;
pub fn sqlite3_total_changes(db: *mut sqlite3) -> c_int;
pub fn sqlite3_last_insert_rowid(db: *mut sqlite3) -> i64;
pub fn sqlite3_busy_timeout(db: *mut sqlite3, ms: c_int) -> c_int;
pub fn sqlite3_libversion() -> *const c_char;
pub fn sqlite3_libversion_number() -> c_int;
}
pub fn version() -> &'static str {
unsafe {
let ptr = sqlite3_libversion();
std::ffi::CStr::from_ptr(ptr).to_str().unwrap_or("unknown")
}
}
pub fn version_number() -> i32 {
unsafe { sqlite3_libversion_number() }
}
pub fn error_string(code: c_int) -> &'static str {
unsafe {
let ptr = sqlite3_errstr(code);
std::ffi::CStr::from_ptr(ptr)
.to_str()
.unwrap_or("unknown error")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_version() {
let v = version();
assert!(!v.is_empty());
assert!(v.starts_with('3'));
}
#[test]
fn test_version_number() {
let v = version_number();
assert!(v >= 3_000_000);
}
#[test]
fn test_error_string() {
assert_eq!(error_string(SQLITE_OK), "not an error");
assert_eq!(error_string(SQLITE_ERROR), "SQL logic error");
assert_eq!(error_string(SQLITE_BUSY), "database is locked");
assert_eq!(error_string(SQLITE_CONSTRAINT), "constraint failed");
}
#[test]
fn test_result_codes() {
assert_eq!(SQLITE_OK, 0);
assert_eq!(SQLITE_ROW, 100);
assert_eq!(SQLITE_DONE, 101);
}
}