sqlite_tiny/ffi/
mod.rs

1//! FFI bindings to the shipped sqlite variant
2
3#![allow(unused, reason = "Includes autogenerated bindings")]
4#![allow(non_snake_case, reason = "Includes autogenerated bindings")]
5#![allow(non_camel_case_types, reason = "Includes autogenerated bindings")]
6
7include!("bindgen.rs");
8
9// Glue bindings
10extern "C" {
11    /// Internal helper to get the pointer constant to define "transient" ownership (i.e. order SQLite to copy the value
12    /// immediately)
13    //sqlite3_destructor_type sqlite3_transient()
14    #[doc(hidden)]
15    pub fn sqlite3_transient() -> sqlite3_destructor_type;
16}
17
18/// Gets the last error from the database as [`crate::error::Error`]
19///
20/// # Safety
21/// This function operates on a raw SQLite handle. If `database` is not `NULL` but invalid or points to an invalid
22/// handle, the behaviour is undefined.
23#[doc(hidden)]
24pub unsafe fn sqlite3_last_error(retval: i32, database: *mut sqlite3) -> crate::error::Error {
25    use std::{borrow::Cow, ffi::CStr};
26
27    // Get the error string
28    let error = sqlite3_errstr(retval);
29    let mut message = match error.is_null() {
30        true => Cow::Borrowed("Unknown"),
31        false => CStr::from_ptr(error).to_string_lossy(),
32    };
33
34    // Append database specific error
35    if !database.is_null() {
36        // Get error from database
37        let error = sqlite3_errmsg(database);
38        let message_ = CStr::from_ptr(error).to_string_lossy();
39        message = Cow::Owned(format!("{message} ({message_})"));
40    }
41    crate::err!("SQLite error: {message}")
42}
43
44/// Helper to translate a result code into a `Result`
45///
46/// # Safety
47/// This function operates on a raw SQLite handle. If `database` is not `NULL` but invalid or points to an invalid
48/// handle, the behaviour is undefined.
49#[doc(hidden)]
50#[inline]
51pub unsafe fn sqlite3_check_result(retval: i32, database: *mut sqlite3) -> Result<(), crate::error::Error> {
52    match retval {
53        SQLITE_OK => Ok(()),
54        _ => Err(sqlite3_last_error(retval, database)),
55    }
56}
57
58/// Asserts that sqlite is compiled threadsafe
59#[test]
60fn assert_threadsafe() {
61    let threadsafe = unsafe { sqlite3_threadsafe() };
62    assert_ne!(threadsafe, 0, "sqlite is not compiled threadsafe?!")
63}