1use alloc::ffi::CString;
2use core::ffi::{c_char, c_int};
3
4use crate::vars;
5
6type Sqlite3Log = unsafe extern "C" fn(iErrCode: c_int, arg2: *const c_char, ...);
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub enum SqliteLogLevel {
10 Error = 1,
11 Warn,
12 Notice,
13}
14
15impl SqliteLogLevel {
16 fn into_err_code(self) -> c_int {
17 match self {
18 Self::Notice => vars::SQLITE_NOTICE,
19 Self::Warn => vars::SQLITE_WARNING,
20 Self::Error => vars::SQLITE_INTERNAL,
21 }
22 }
23}
24
25#[derive(Clone, Copy)]
26pub struct SqliteLogger {
27 log: Sqlite3Log,
28}
29
30impl SqliteLogger {
31 pub(crate) fn new(log: Sqlite3Log) -> Self {
32 Self { log }
33 }
34
35 pub fn log(&self, level: SqliteLogLevel, buf: &[u8]) {
40 let code = level.into_err_code();
41 for line in buf.split(|b| *b == b'\n') {
42 if line.iter().all(|b| b.is_ascii_whitespace()) {
44 continue;
45 }
46
47 let z_format = CString::new(line).unwrap();
48 unsafe { (self.log)(code, z_format.as_ptr()) }
49 }
50 }
51}