Skip to content

Commit c2d6faa

Browse files
authored
Merge pull request #62 from orbitinghail/fix-log-issues
remove register logger, return SqliteLogger from register* methods
2 parents 317776a + 168e6db commit c2d6faa

6 files changed

Lines changed: 142 additions & 143 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
All notable changes will be documented in this file.
44

5+
## 0.5.0 - 2025-11-26
6+
7+
- BREAKING: remove register_logger method from Vfs
8+
- return SqliteLogger instance from register_dynamic/register_static
9+
510
## 0.4.1 - 2025-06-19
611

712
- expose SqliteApi in public API

examples/memvfs.rs

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
// cargo build --example memvfs --features dynamic
22

3-
use std::{
4-
ffi::{CStr, c_void},
5-
os::raw::c_char,
6-
sync::Arc,
7-
};
3+
use std::{ffi::c_void, os::raw::c_char, sync::Arc};
84

95
use parking_lot::Mutex;
106
use sqlite_plugin::{
@@ -45,33 +41,6 @@ struct MemVfs {
4541
impl Vfs for MemVfs {
4642
type Handle = File;
4743

48-
fn register_logger(&self, logger: SqliteLogger) {
49-
struct LogCompat {
50-
logger: Mutex<SqliteLogger>,
51-
}
52-
53-
impl log::Log for LogCompat {
54-
fn enabled(&self, _metadata: &log::Metadata) -> bool {
55-
true
56-
}
57-
58-
fn log(&self, record: &log::Record) {
59-
let level = match record.level() {
60-
log::Level::Error => SqliteLogLevel::Error,
61-
log::Level::Warn => SqliteLogLevel::Warn,
62-
_ => SqliteLogLevel::Notice,
63-
};
64-
let msg = format!("{}", record.args());
65-
self.logger.lock().log(level, msg.as_bytes());
66-
}
67-
68-
fn flush(&self) {}
69-
}
70-
71-
let log = LogCompat { logger: Mutex::new(logger) };
72-
log::set_boxed_logger(Box::new(log)).expect("failed to setup global logger");
73-
}
74-
7544
fn open(&self, path: Option<&str>, opts: OpenOpts) -> VfsResult<Self::Handle> {
7645
log::debug!("open: path={:?}, opts={:?}", path, opts);
7746
let mode = opts.mode();
@@ -216,6 +185,33 @@ impl Vfs for MemVfs {
216185
}
217186
}
218187

188+
fn setup_logger(logger: SqliteLogger) {
189+
struct LogCompat {
190+
logger: Mutex<SqliteLogger>,
191+
}
192+
193+
impl log::Log for LogCompat {
194+
fn enabled(&self, _metadata: &log::Metadata) -> bool {
195+
true
196+
}
197+
198+
fn log(&self, record: &log::Record) {
199+
let level = match record.level() {
200+
log::Level::Error => SqliteLogLevel::Error,
201+
log::Level::Warn => SqliteLogLevel::Warn,
202+
_ => SqliteLogLevel::Notice,
203+
};
204+
let msg = format!("{}", record.args());
205+
self.logger.lock().log(level, &msg);
206+
}
207+
208+
fn flush(&self) {}
209+
}
210+
211+
let log = LogCompat { logger: Mutex::new(logger) };
212+
log::set_boxed_logger(Box::new(log)).expect("failed to setup global logger");
213+
}
214+
219215
/// This function is called by `SQLite` when the extension is loaded. It registers
220216
/// the memvfs VFS with `SQLite`.
221217
/// # Safety
@@ -226,18 +222,17 @@ pub unsafe extern "C" fn sqlite3_memvfs_init(
226222
_pz_err_msg: *mut *mut c_char,
227223
p_api: *mut sqlite3_api_routines,
228224
) -> std::os::raw::c_int {
229-
let vfs = MemVfs { files: Default::default() };
230-
const MEMVFS_NAME: &CStr = c"mem";
231-
if let Err(err) = unsafe {
225+
match unsafe {
232226
register_dynamic(
233227
p_api,
234-
MEMVFS_NAME.to_owned(),
235-
vfs,
228+
c"mem".to_owned(),
229+
MemVfs { files: Default::default() },
236230
RegisterOpts { make_default: true },
237231
)
238232
} {
239-
return err;
240-
}
233+
Ok(logger) => setup_logger(logger),
234+
Err(err) => return err,
235+
};
241236

242237
// set the log level to trace
243238
log::set_max_level(log::LevelFilter::Trace);

examples/test_memvfs.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
.load target/debug/examples/libmemvfs.so
99
.open main.db
10+
.mode table
11+
.log stdout
1012

1113
.databases
1214
.vfsinfo

src/logger.rs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use core::ffi::{c_char, c_int};
33

44
use crate::vars;
55

6+
#[allow(non_snake_case)]
67
type Sqlite3Log = unsafe extern "C" fn(iErrCode: c_int, arg2: *const c_char, ...);
78

89
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -32,20 +33,13 @@ impl SqliteLogger {
3233
Self { log }
3334
}
3435

35-
/// Log bytes to the `SQLite3` log handle.
36-
/// This function will write each line separately to `SQLite3`.
37-
/// Note that `SQLite3` silently truncates log lines larger than roughly
38-
/// 230 bytes by default.
39-
pub fn log(&self, level: SqliteLogLevel, buf: &[u8]) {
36+
/// Log bytes directly to the `SQLite3` log handle.
37+
/// Note that `SQLite` silently truncates writes larger than
38+
/// roughly 230 bytes by default. It's recommended that you
39+
/// split your log messages by lines before calling this method.
40+
pub fn log(&self, level: SqliteLogLevel, msg: &str) {
4041
let code = level.into_err_code();
41-
for line in buf.split(|b| *b == b'\n') {
42-
// skip if line only contains whitespace
43-
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-
}
42+
let z_format = CString::new(msg).unwrap();
43+
unsafe { (self.log)(code, z_format.as_ptr()) }
5044
}
5145
}

0 commit comments

Comments
 (0)