Skip to main content

cratestack_client_store_sqlite/
lib.rs

1//! SQLite-backed `ClientStateStore` for `cratestack-client-rust`.
2
3mod bootstrap;
4mod ops;
5mod store;
6
7pub use store::SqliteStateStore;
8
9#[cfg(test)]
10mod tests {
11    use std::path::{Path, PathBuf};
12    use std::time::{SystemTime, UNIX_EPOCH};
13
14    use chrono::Utc;
15    use cratestack_client_rust::{ClientStateStore, RequestJournalEntry};
16
17    use super::SqliteStateStore;
18
19    #[test]
20    fn bootstrap_loads_default_state() {
21        let path = project_tmp_path("bootstrap");
22        cleanup(&path);
23
24        let store = SqliteStateStore::open(&path).expect("store should open");
25        let state = store.load().expect("state should load");
26
27        assert_eq!(state.schema_version, 1);
28        assert_eq!(state.state_version, 0);
29        assert!(state.request_journal.is_empty());
30
31        cleanup(&path);
32    }
33
34    #[test]
35    fn append_round_trips_and_increments_state_version() {
36        let path = project_tmp_path("append");
37        cleanup(&path);
38
39        let store = SqliteStateStore::open(&path).expect("store should open");
40        store
41            .append_request_journal(&RequestJournalEntry {
42                method: "POST".to_owned(),
43                path: "/$procs/getFeed".to_owned(),
44                status_code: 200,
45                content_type: Some("application/cbor".to_owned()),
46                recorded_at: Utc::now(),
47            })
48            .expect("journal entry should append");
49
50        let state = store.load().expect("state should load");
51        assert_eq!(state.state_version, 1);
52        assert_eq!(state.request_journal.len(), 1);
53
54        cleanup(&path);
55    }
56
57    fn project_tmp_path(label: &str) -> PathBuf {
58        let suffix = SystemTime::now()
59            .duration_since(UNIX_EPOCH)
60            .expect("time should move forward")
61            .as_nanos();
62        PathBuf::from(env!("CARGO_MANIFEST_DIR"))
63            .join("../../tmp/client-store-sqlite-tests")
64            .join(format!("{label}-{suffix}.sqlite"))
65    }
66
67    fn cleanup(path: &Path) {
68        if path.exists() {
69            std::fs::remove_file(path).expect("tmp file should be removable");
70        }
71    }
72}