diff --git a/Cargo.lock b/Cargo.lock index 1973af3af..a61e2659a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1532,7 +1532,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "cfg-if", "libc", ] diff --git a/cli/tests/test_journal.rs b/cli/tests/test_journal.rs index cea1449c9..fa3b851df 100644 --- a/cli/tests/test_journal.rs +++ b/cli/tests/test_journal.rs @@ -19,7 +19,6 @@ mod tests { Ok(()) } - #[ignore = "wal checkpoint not yet implemented"] #[test] fn test_pragma_wal_checkpoint() -> Result<(), Error> { let mut child = spawn_command(run_cli(), Some(1000))?; diff --git a/core/storage/wal.rs b/core/storage/wal.rs index 679e0f0f0..5d40d5a1d 100644 --- a/core/storage/wal.rs +++ b/core/storage/wal.rs @@ -25,6 +25,7 @@ pub const NO_LOCK: u32 = 0; pub const SHARED_LOCK: u32 = 1; pub const WRITE_LOCK: u32 = 2; +#[derive(Debug)] pub enum CheckpointMode { Passive, Full, diff --git a/core/translate/mod.rs b/core/translate/mod.rs index 61c9ff195..c37e5dbbd 100644 --- a/core/translate/mod.rs +++ b/core/translate/mod.rs @@ -37,6 +37,7 @@ use std::cell::RefCell; use std::fmt::Display; use std::rc::{Rc, Weak}; use std::str::FromStr; +use crate::storage::wal::CheckpointMode; /// Translate SQL statement into bytecode program. pub fn translate( @@ -624,7 +625,8 @@ fn query_pragma( } PragmaName::WalCheckpoint => { program.emit_insn(Insn::Checkpoint { - reg: 12, // TODO fix hard-coded + database: 0, + checkpoint_mode: CheckpointMode::Passive, dest: register, }); } diff --git a/core/vdbe/explain.rs b/core/vdbe/explain.rs index 9a72fa96e..e959af17e 100644 --- a/core/vdbe/explain.rs +++ b/core/vdbe/explain.rs @@ -2,6 +2,7 @@ use crate::vdbe::builder::CursorType; use super::{Insn, InsnReference, OwnedValue, Program}; use std::rc::Rc; +use crate::storage::wal::CheckpointMode; pub fn insn_to_str( program: &Program, @@ -84,14 +85,14 @@ pub fn insn_to_str( 0, format!("r[{}]=~r[{}]", dest, reg), ), - Insn::Checkpoint { reg, dest } => ( + Insn::Checkpoint { database, checkpoint_mode: _, dest } => ( "Checkpoint", - *reg as i32, + *database as i32, *dest as i32, 0, OwnedValue::build_text(Rc::new("".to_string())), 0, - format!("r[{}]=~r[{}]", dest, reg), + format!("r[{}]=~r[{}]", dest, database), ), Insn::Remainder { lhs, rhs, dest } => ( "Remainder", diff --git a/core/vdbe/insn.rs b/core/vdbe/insn.rs index eeea049e5..093041456 100644 --- a/core/vdbe/insn.rs +++ b/core/vdbe/insn.rs @@ -3,6 +3,7 @@ use std::num::NonZero; use super::{AggFunc, BranchOffset, CursorID, FuncCtx, PageIdx}; use crate::types::{OwnedRecord, OwnedValue}; use limbo_macros::Description; +use crate::storage::wal::CheckpointMode; #[derive(Description, Debug)] pub enum Insn { @@ -68,9 +69,9 @@ pub enum Insn { }, // Checkpoint the database (applying wal file content to database file). Checkpoint { - // TODO support registers as in sqlite - reg: usize, - dest: usize, + database: usize, // checkpoint database P1 + checkpoint_mode: CheckpointMode, // P2 checkpoint mode + dest: usize, // P3 checkpoint result }, // Divide lhs by rhs and place the remainder in dest register. Remainder { diff --git a/core/vdbe/mod.rs b/core/vdbe/mod.rs index 6f7d282e4..5a720afd1 100644 --- a/core/vdbe/mod.rs +++ b/core/vdbe/mod.rs @@ -362,10 +362,18 @@ impl Program { state.registers[*dest] = exec_bit_not(&state.registers[*reg]); state.pc += 1; } - Insn::Checkpoint { reg: _, dest } => { + Insn::Checkpoint { database: _, checkpoint_mode: _, dest } => { // Write 1 (checkpoint SQLITE_BUSY) or 0 (not busy). // fixme currently hard coded not implemented - state.registers[*dest] = OwnedValue::Integer(0); + let result = self.connection + .upgrade() + .unwrap() + .checkpoint(); + match result { + Ok(()) => state.registers[*dest] = OwnedValue::Integer(0), + Err(err) => state.registers[*dest] = OwnedValue::Integer(1) + } + state.pc += 1; } Insn::Null { dest, dest_end } => {