diff --git a/examples/prev-snapshot.rs b/examples/prev-snapshot.rs new file mode 100644 index 00000000..79b03bdd --- /dev/null +++ b/examples/prev-snapshot.rs @@ -0,0 +1,85 @@ +use std::error::Error; + +use heed::types::*; +use heed::{Database, EnvFlags, EnvOpenOptions}; + +// In this test we are checking that we can move to a previous environement snapshot. +fn main() -> Result<(), Box> { + let env_path = tempfile::tempdir()?; + + let env = unsafe { + EnvOpenOptions::new() + .map_size(10 * 1024 * 1024) // 10MB + .max_dbs(3) + .open(&env_path)? + }; + + let mut wtxn = env.write_txn()?; + let db: Database = env.create_database(&mut wtxn, None)?; + + // We fill the db database with entries. + db.put(&mut wtxn, "I am here", "to test things")?; + db.put(&mut wtxn, "I am here too", "for the same purpose")?; + + wtxn.commit()?; + + env.prepare_for_closing().wait(); + + // We can get the env state from before the last commit + // and therefore see an empty env. + let env = unsafe { + EnvOpenOptions::new() + .map_size(10 * 1024 * 1024) // 10MB + .max_dbs(3) + .flags(EnvFlags::PREV_SNAPSHOT) + .open(&env_path)? + }; + + let mut wtxn = env.write_txn()?; + let db: Database = env.create_database(&mut wtxn, None)?; + + assert!(db.is_empty(&wtxn)?); + + wtxn.abort(); + env.prepare_for_closing().wait(); + + // However, if we don't commit we can still get + // back the latest version of the env. + let env = unsafe { + EnvOpenOptions::new() + .map_size(10 * 1024 * 1024) // 10MB + .max_dbs(3) + .open(&env_path)? + }; + + let mut wtxn = env.write_txn()?; + let db: Database = env.create_database(&mut wtxn, None)?; + + assert_eq!(db.get(&wtxn, "I am here")?, Some("to test things")); + assert_eq!(db.get(&wtxn, "I am here too")?, Some("for the same purpose")); + + // And write new stuff in the env. + db.put(&mut wtxn, "I will fade away", "I am so sad")?; + + wtxn.commit()?; + env.prepare_for_closing().wait(); + + // Once again we can get back the previous version + // of the env and see some entries disappear. + let env = unsafe { + EnvOpenOptions::new() + .map_size(10 * 1024 * 1024) // 10MB + .max_dbs(3) + .flags(EnvFlags::PREV_SNAPSHOT) + .open(&env_path)? + }; + + let rtxn = env.read_txn()?; + let db: Database = env.open_database(&rtxn, None)?.unwrap(); + + assert_eq!(db.get(&rtxn, "I am here")?, Some("to test things")); + assert_eq!(db.get(&rtxn, "I am here too")?, Some("for the same purpose")); + assert_eq!(db.get(&rtxn, "I will fade away")?, None); + + Ok(()) +} diff --git a/heed/Cargo.toml b/heed/Cargo.toml index 5dd0f87c..d1f7e7f9 100644 --- a/heed/Cargo.toml +++ b/heed/Cargo.toml @@ -131,6 +131,10 @@ path = "../examples/multi-env.rs" name = "nested" path = "../examples/nested.rs" +[[example]] +name = "prev-snapshot" +path = "../examples/prev-snapshot.rs" + [[example]] name = "rmp-serde" path = "../examples/rmp-serde.rs" diff --git a/heed3/Cargo.toml b/heed3/Cargo.toml index e0b1b3e2..01f768fb 100644 --- a/heed3/Cargo.toml +++ b/heed3/Cargo.toml @@ -106,6 +106,10 @@ longer-keys = ["lmdb-master3-sys/longer-keys"] # Examples are located outside the standard heed/examples directory to prevent # conflicts between heed3 and heed examples when working on both crates. +[[example]] +name = "prev-snapshot" +path = "../examples/prev-snapshot.rs" + [[example]] name = "heed3-encrypted" path = "../examples/heed3-encrypted.rs"