Skip to main content

text_document_common/database/
transactions.rs

1use crate::database::db_context::DbContext;
2use crate::database::hashmap_store::HashMapStore;
3use crate::snapshot::StoreSnapshot;
4use anyhow::{Ok, Result, bail};
5use std::sync::Arc;
6
7use crate::types;
8
9pub struct Transaction {
10    store: Arc<HashMapStore>,
11    is_write: bool,
12}
13
14impl Transaction {
15    pub fn begin_write_transaction(db_context: &DbContext) -> Result<Transaction> {
16        Ok(Transaction {
17            store: Arc::clone(db_context.get_store()),
18            is_write: true,
19        })
20    }
21
22    pub fn begin_read_transaction(db_context: &DbContext) -> Result<Transaction> {
23        Ok(Transaction {
24            store: Arc::clone(db_context.get_store()),
25            is_write: false,
26        })
27    }
28
29    pub fn commit(&mut self) -> Result<()> {
30        if !self.is_write {
31            bail!("Cannot commit a read transaction");
32        }
33        // HashMap store commits are immediate — nothing to do
34        Ok(())
35    }
36
37    pub fn rollback(&mut self) -> Result<()> {
38        if !self.is_write {
39            bail!("Cannot rollback a read transaction");
40        }
41        // No-op: mutations are already applied in-place.
42        // Real rollback is done via restore_to_savepoint.
43        Ok(())
44    }
45
46    pub fn end_read_transaction(&mut self) -> Result<()> {
47        if self.is_write {
48            bail!("Cannot end a write transaction as read");
49        }
50        Ok(())
51    }
52
53    pub fn get_store(&self) -> &HashMapStore {
54        &self.store
55    }
56
57    pub fn create_savepoint(&self) -> Result<types::Savepoint> {
58        if !self.is_write {
59            bail!("Cannot create savepoint on a read transaction");
60        }
61        Ok(self.store.create_savepoint())
62    }
63
64    pub fn restore_to_savepoint(&mut self, savepoint: types::Savepoint) -> Result<()> {
65        if !self.is_write {
66            bail!("Cannot restore savepoint on a read transaction");
67        }
68        self.store.restore_savepoint(savepoint);
69        Ok(())
70    }
71
72    /// Snapshot the entire store for undo. O(n) clone, no serialization.
73    pub fn snapshot_store(&self) -> StoreSnapshot {
74        self.store.store_snapshot()
75    }
76
77    /// Restore the entire store from an undo snapshot (preserves counters).
78    pub fn restore_store(&self, snap: &StoreSnapshot) {
79        self.store.restore_store_snapshot(snap);
80    }
81}