diff --git a/core/lib.rs b/core/lib.rs index e4874e755..fcd894ac4 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -44,7 +44,7 @@ use crate::incremental::view::ViewTransactionState; use crate::translate::optimizer::optimize_plan; use crate::translate::pragma::TURSO_CDC_DEFAULT_TABLE_NAME; #[cfg(all(feature = "fs", feature = "conn_raw_api"))] -use crate::types::WalFrameInfo; +use crate::types::{WalFrameInfo, WalState}; #[cfg(feature = "fs")] use crate::util::{OpenMode, OpenOptions}; use crate::vdbe::metrics::ConnectionMetrics; @@ -1340,8 +1340,8 @@ impl Connection { } #[cfg(all(feature = "fs", feature = "conn_raw_api"))] - pub fn wal_frame_count(&self) -> Result { - self.pager.borrow().wal_frame_count() + pub fn wal_state(&self) -> Result { + self.pager.borrow().wal_state() } #[cfg(all(feature = "fs", feature = "conn_raw_api"))] diff --git a/core/storage/pager.rs b/core/storage/pager.rs index 87f211c89..4851c563d 100644 --- a/core/storage/pager.rs +++ b/core/storage/pager.rs @@ -8,7 +8,7 @@ use crate::storage::{ }, wal::{CheckpointResult, Wal}, }; -use crate::types::IOCompletions; +use crate::types::{IOCompletions, WalState}; use crate::util::IOExt as _; use crate::{io_yield_many, io_yield_one}; use crate::{ @@ -1202,13 +1202,16 @@ impl Pager { page.set_dirty(); } - pub fn wal_frame_count(&self) -> Result { + pub fn wal_state(&self) -> Result { let Some(wal) = self.wal.as_ref() else { return Err(LimboError::InternalError( - "wal_frame_count() called on database without WAL".to_string(), + "wal_state() called on database without WAL".to_string(), )); }; - Ok(wal.borrow().get_max_frame()) + Ok(WalState { + checkpoint_seq_no: wal.borrow().get_checkpoint_seq(), + max_frame: wal.borrow().get_max_frame(), + }) } /// Flush all dirty pages to disk. diff --git a/core/storage/wal.rs b/core/storage/wal.rs index c93b5476c..2b08715af 100644 --- a/core/storage/wal.rs +++ b/core/storage/wal.rs @@ -2211,7 +2211,7 @@ pub mod test { ); drop(wal); - assert_eq!(pager.wal_frame_count().unwrap(), 0); + assert_eq!(pager.wal_state().unwrap().max_frame, 0); tracing::info!("wal filepath: {walpath:?}, size: {}", stat.len()); let meta_after = std::fs::metadata(&walpath).unwrap(); diff --git a/core/types.rs b/core/types.rs index 00fdbe741..8affdd800 100644 --- a/core/types.rs +++ b/core/types.rs @@ -2646,10 +2646,21 @@ pub struct WalFrameInfo { pub db_size: u32, } +#[derive(Debug)] +pub struct WalState { + pub checkpoint_seq_no: u32, + pub max_frame: u64, +} + impl WalFrameInfo { pub fn is_commit_frame(&self) -> bool { self.db_size > 0 } + pub fn from_frame_header(frame: &[u8]) -> Self { + let page_no = u32::from_be_bytes(frame[0..4].try_into().unwrap()); + let db_size = u32::from_be_bytes(frame[4..8].try_into().unwrap()); + Self { page_no, db_size } + } pub fn put_to_frame_header(&self, frame: &mut [u8]) { frame[0..4].copy_from_slice(&self.page_no.to_be_bytes()); frame[4..8].copy_from_slice(&self.db_size.to_be_bytes()); diff --git a/sqlite3/src/lib.rs b/sqlite3/src/lib.rs index d912a56d5..32a2976e3 100644 --- a/sqlite3/src/lib.rs +++ b/sqlite3/src/lib.rs @@ -1404,8 +1404,8 @@ pub unsafe extern "C" fn libsql_wal_frame_count( } let db: &mut sqlite3 = &mut *db; let db = db.inner.lock().unwrap(); - let frame_count = match db.conn.wal_frame_count() { - Ok(count) => count as u32, + let frame_count = match db.conn.wal_state() { + Ok(state) => state.max_frame as u32, Err(_) => return SQLITE_ERROR, }; *p_frame_count = frame_count;