From bb7f011f7974ccb5c402624d549aa56641bbb33b Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Tue, 10 Dec 2024 12:35:05 +0200 Subject: [PATCH] libsql: Wire up xCheckpointSeqCount --- .../injector/sqlite_injector/injector_wal.rs | 4 ++++ .../test/rust_suite/src/virtual_wal.rs | 4 ++++ libsql-storage/src/lib.rs | 4 ++++ libsql-sys/src/wal/either.rs | 6 ++++++ libsql-sys/src/wal/ffi.rs | 19 +++++++++++++++++++ libsql-sys/src/wal/mod.rs | 2 ++ libsql-sys/src/wal/sqlite3_wal.rs | 12 ++++++++++++ libsql-sys/src/wal/wrapper.rs | 12 ++++++++++++ libsql-wal/src/wal.rs | 5 +++++ 9 files changed, 68 insertions(+) diff --git a/libsql-replication/src/injector/sqlite_injector/injector_wal.rs b/libsql-replication/src/injector/sqlite_injector/injector_wal.rs index 545899d57a..9262c8dea2 100644 --- a/libsql-replication/src/injector/sqlite_injector/injector_wal.rs +++ b/libsql-replication/src/injector/sqlite_injector/injector_wal.rs @@ -138,6 +138,10 @@ impl Wal for InjectorWal { self.inner.savepoint_undo(rollback_data) } + fn checkpoint_seq_count(&self) -> Result { + self.inner.checkpoint_seq_count() + } + fn frame_count(&self, locked: i32) -> Result { self.inner.frame_count(locked) } diff --git a/libsql-sqlite3/test/rust_suite/src/virtual_wal.rs b/libsql-sqlite3/test/rust_suite/src/virtual_wal.rs index 2395a34b76..6e936d4176 100644 --- a/libsql-sqlite3/test/rust_suite/src/virtual_wal.rs +++ b/libsql-sqlite3/test/rust_suite/src/virtual_wal.rs @@ -106,6 +106,10 @@ mod tests { self.0.read_frame_raw(page_no, buffer) } + fn checkpoint_seq_count(&self) -> libsql_sys::wal::Result { + self.0.checkpoint_seq_count() + } + fn frame_count(&self, locked: i32) -> libsql_sys::wal::Result { self.0.frame_count(locked) } diff --git a/libsql-storage/src/lib.rs b/libsql-storage/src/lib.rs index ce65fe1307..20672cdc90 100644 --- a/libsql-storage/src/lib.rs +++ b/libsql-storage/src/lib.rs @@ -270,6 +270,10 @@ impl Wal for DurableWal { todo!() } + fn checkpoint_seq_count(&self) -> Result { + todo!() + } + fn frame_count(&self, _locked: i32) -> Result { todo!() } diff --git a/libsql-sys/src/wal/either.rs b/libsql-sys/src/wal/either.rs index dbad73f861..654b80c137 100644 --- a/libsql-sys/src/wal/either.rs +++ b/libsql-sys/src/wal/either.rs @@ -81,6 +81,12 @@ macro_rules! create_either { } } + fn checkpoint_seq_count(&self) -> super::Result { + match self { + $( $name::$t(inner) => inner.checkpoint_seq_count() ),* + } + } + fn frame_count(&self, locked: i32) -> super::Result { match self { $( $name::$t(inner) => inner.frame_count(locked) ),* diff --git a/libsql-sys/src/wal/ffi.rs b/libsql-sys/src/wal/ffi.rs index 6b1d303d8f..7526874ef2 100644 --- a/libsql-sys/src/wal/ffi.rs +++ b/libsql-sys/src/wal/ffi.rs @@ -30,6 +30,7 @@ pub(crate) fn construct_libsql_wal(wal: *mut W) -> libsql_wal { xUndo: Some(undo::), xSavepoint: Some(savepoint::), xSavepointUndo: Some(savepoint_undo::), + xCheckpointSeqCount: Some(checkpoint_seq_count::), xFrameCount: Some(frame_count::), xFrames: Some(frames::), xCheckpoint: Some(checkpoint::), @@ -295,6 +296,24 @@ pub unsafe extern "C" fn savepoint_undo(wal: *mut wal_impl, wal_data: *m } } +pub unsafe extern "C" fn checkpoint_seq_count( + wal: *mut wal_impl, + out: *mut c_uint, +) -> c_int { + let this = &mut (*(wal as *mut T)); + match this.checkpoint_seq_count() { + Ok(n) => { + if !out.is_null() { + unsafe { + *out = n as _; + } + } + SQLITE_OK + } + Err(code) => code.extended_code, + } +} + pub unsafe extern "C" fn frame_count( wal: *mut wal_impl, locked: i32, diff --git a/libsql-sys/src/wal/mod.rs b/libsql-sys/src/wal/mod.rs index 71e0c21ee3..4a7cbce447 100644 --- a/libsql-sys/src/wal/mod.rs +++ b/libsql-sys/src/wal/mod.rs @@ -199,6 +199,8 @@ pub trait Wal { fn savepoint(&mut self, rollback_data: &mut [u32]); fn savepoint_undo(&mut self, rollback_data: &mut [u32]) -> Result<()>; + fn checkpoint_seq_count(&self) -> Result; + fn frame_count(&self, locked: i32) -> Result; /// Insert frames in the wal. On commit, returns the number of inserted frames for that diff --git a/libsql-sys/src/wal/sqlite3_wal.rs b/libsql-sys/src/wal/sqlite3_wal.rs index 0764a79cd9..d89da362b8 100644 --- a/libsql-sys/src/wal/sqlite3_wal.rs +++ b/libsql-sys/src/wal/sqlite3_wal.rs @@ -288,6 +288,18 @@ impl Wal for Sqlite3Wal { } } + fn checkpoint_seq_count(&self) -> Result { + let mut out: u32 = 0; + let rc = unsafe { + (self.inner.methods.xCheckpointSeqCount.unwrap())(self.inner.pData, &mut out) + }; + if rc != 0 { + Err(Error::new(rc)) + } else { + Ok(out) + } + } + fn frame_count(&self, locked: i32) -> Result { let mut out: u32 = 0; let rc = unsafe { diff --git a/libsql-sys/src/wal/wrapper.rs b/libsql-sys/src/wal/wrapper.rs index 4f3fdb7159..af12d6463d 100644 --- a/libsql-sys/src/wal/wrapper.rs +++ b/libsql-sys/src/wal/wrapper.rs @@ -89,6 +89,10 @@ impl, W: Wal> Wal for WalRef { unsafe { (*self.wrapper).savepoint_undo(&mut *self.wrapped, rollback_data) } } + fn checkpoint_seq_count(&self) -> super::Result { + unsafe { (*self.wrapper).checkpoint_seq_count(&*self.wrapped) } + } + fn frame_count(&self, locked: i32) -> super::Result { unsafe { (*self.wrapper).frame_count(&*self.wrapped, locked) } } @@ -272,6 +276,10 @@ where .savepoint_undo(&mut self.wrapped, rollback_data) } + fn checkpoint_seq_count(&self) -> super::Result { + self.wrapper.checkpoint_seq_count(&self.wrapped) + } + fn frame_count(&self, locked: i32) -> super::Result { self.wrapper.frame_count(&self.wrapped, locked) } @@ -409,6 +417,10 @@ pub trait WrapWal { wrapped.savepoint_undo(rollback_data) } + fn checkpoint_seq_count(&self, wrapped: &W) -> super::Result { + wrapped.checkpoint_seq_count() + } + fn frame_count(&self, wrapped: &W, locked: i32) -> super::Result { wrapped.frame_count(locked) } diff --git a/libsql-wal/src/wal.rs b/libsql-wal/src/wal.rs index 6c89ce848f..8398adcbd6 100644 --- a/libsql-wal/src/wal.rs +++ b/libsql-wal/src/wal.rs @@ -275,6 +275,11 @@ where } } + #[tracing::instrument(skip_all, fields(id = self.conn_id))] + fn checkpoint_seq_count(&self) -> libsql_sys::wal::Result { + Err(libsql_sys::wal::Error::new(10)) // SQLITE_IOERR + } + #[tracing::instrument(skip_all, fields(id = self.conn_id))] fn frame_count(&self, _locked: i32) -> libsql_sys::wal::Result { Err(libsql_sys::wal::Error::new(10)) // SQLITE_IOERR