From 5dd571483f04f3d55eaa24f7395cade323d131cb Mon Sep 17 00:00:00 2001 From: Diego Reis Date: Mon, 14 Jul 2025 11:50:17 -0300 Subject: [PATCH] Add cacheflush to Rust binding --- bindings/rust/src/lib.rs | 11 +++++ bindings/rust/tests/integration_tests.rs | 60 ++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 85cfbdc09..13592ec6c 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -205,6 +205,17 @@ impl Connection { })?; Ok(()) } + + /// Flush dirty pages to disk. + /// This will write the dirty pages to the WAL. + pub fn cacheflush(&self) -> Result<()> { + let conn = self + .inner + .lock() + .map_err(|e| Error::MutexError(e.to_string()))?; + conn.cacheflush()?; + Ok(()) + } } impl Debug for Connection { diff --git a/bindings/rust/tests/integration_tests.rs b/bindings/rust/tests/integration_tests.rs index 14ac01273..9a6b9d837 100644 --- a/bindings/rust/tests/integration_tests.rs +++ b/bindings/rust/tests/integration_tests.rs @@ -1,3 +1,4 @@ +use tokio::fs; use turso::{Builder, Value}; #[tokio::test] @@ -55,3 +56,62 @@ async fn test_rows_next() { ); assert!(res.next().await.unwrap().is_none()); } + +#[tokio::test] +async fn test_cacheflush() { + let builder = Builder::new_local("test.db"); + let db = builder.build().await.unwrap(); + + let conn = db.connect().unwrap(); + + conn.execute("CREATE TABLE IF NOT EXISTS asdf (x INTEGER)", ()) + .await + .unwrap(); + + // Tests if cache flush breaks transaction isolation + conn.execute("BEGIN", ()).await.unwrap(); + conn.execute("INSERT INTO asdf (x) VALUES (1)", ()) + .await + .unwrap(); + conn.cacheflush().unwrap(); + conn.execute("ROLLBACK", ()).await.unwrap(); + + conn.execute("INSERT INTO asdf (x) VALUES (2)", ()) + .await + .unwrap(); + conn.execute("INSERT INTO asdf (x) VALUES (3)", ()) + .await + .unwrap(); + + let mut res = conn.query("SELECT * FROM asdf", ()).await.unwrap(); + + assert_eq!( + res.next().await.unwrap().unwrap().get_value(0).unwrap(), + 2.into() + ); + assert_eq!( + res.next().await.unwrap().unwrap().get_value(0).unwrap(), + 3.into() + ); + + // Tests if cache flush doesn't break a committed transaction + conn.execute("BEGIN", ()).await.unwrap(); + conn.execute("INSERT INTO asdf (x) VALUES (1)", ()) + .await + .unwrap(); + conn.cacheflush().unwrap(); + conn.execute("COMMIT", ()).await.unwrap(); + + let mut res = conn + .query("SELECT * FROM asdf WHERE x = 1", ()) + .await + .unwrap(); + + assert_eq!( + res.next().await.unwrap().unwrap().get_value(0).unwrap(), + 1.into() + ); + + fs::remove_file("test.db").await.unwrap(); + fs::remove_file("test.db-wal").await.unwrap(); +}