uqa_graph/persistent_store/
storage.rs1use uqa_core::{Edge, Vertex};
10use uqa_storage::{GraphEntityFilter, GraphEntityKind};
11
12use crate::{GraphLabelRegistry, GraphStoreResult};
13
14pub fn begin_graph_write(
16 backend: std::sync::Arc<dyn uqa_storage::PersistentStorageBackend>,
17) -> GraphStoreResult<Box<dyn GraphWriteTransaction>> {
18 let savepoint = if backend.in_transaction() {
19 let id = uqa_storage::StorageSavepointId::allocate();
20 backend.savepoint(id)?;
21 Some(id)
22 } else {
23 backend.begin_transaction()?;
24 None
25 };
26 Ok(Box::new(StorageGraphWriteTransaction {
27 backend,
28 savepoint,
29 active: true,
30 }))
31}
32
33struct StorageGraphWriteTransaction {
34 backend: std::sync::Arc<dyn uqa_storage::PersistentStorageBackend>,
35 savepoint: Option<uqa_storage::StorageSavepointId>,
36 active: bool,
37}
38
39impl GraphWriteTransaction for StorageGraphWriteTransaction {
40 fn commit(&mut self) -> GraphStoreResult<()> {
41 if let Some(id) = self.savepoint {
42 self.backend.release_savepoint(id)?;
43 } else {
44 self.backend.commit_transaction()?;
45 }
46 self.active = false;
47 Ok(())
48 }
49
50 fn rollback(&mut self) -> GraphStoreResult<()> {
51 if !self.active {
52 return Ok(());
53 }
54 if let Some(id) = self.savepoint {
55 self.backend.rollback_to_savepoint(id)?;
56 self.backend.release_savepoint(id)?;
57 } else {
58 self.backend.rollback_transaction()?;
59 }
60 self.active = false;
61 Ok(())
62 }
63}
64
65impl Drop for StorageGraphWriteTransaction {
66 fn drop(&mut self) {
67 if self.active {
68 let _ = self.rollback();
69 }
70 }
71}
72
73pub trait GraphWriteTransaction {
76 fn commit(&mut self) -> GraphStoreResult<()>;
77 fn rollback(&mut self) -> GraphStoreResult<()>;
78}
79
80pub trait GraphStorage: Send + Sync {
83 fn fork_overlay(&self) -> Option<std::sync::Arc<dyn GraphStorage>> {
86 None
87 }
88 fn unmodified_read_snapshot(&self) -> Option<super::PersistentGraphStore> {
89 None
90 }
91 fn begin_write(&self) -> GraphStoreResult<Box<dyn GraphWriteTransaction>>;
92 fn graph_names(&self) -> GraphStoreResult<Vec<String>>;
93 fn has_graph(&self, graph: &str) -> GraphStoreResult<bool>;
94 fn create_graph(&self, graph: &str) -> GraphStoreResult<()>;
95 fn delete_graph(&self, graph: &str) -> GraphStoreResult<()>;
96 fn registry(&self, graph: &str) -> GraphStoreResult<GraphLabelRegistry>;
97 fn save_registry(&self, graph: &str, registry: &GraphLabelRegistry) -> GraphStoreResult<()>;
98 fn counter(&self, kind: GraphEntityKind) -> GraphStoreResult<Option<u64>>;
99 fn save_counter(&self, kind: GraphEntityKind, next: u64) -> GraphStoreResult<()>;
100 fn vertex(&self, id: u64) -> GraphStoreResult<Option<Vertex>>;
101 fn edge(&self, id: u64) -> GraphStoreResult<Option<Edge>>;
102 fn save_vertex(&self, vertex: &Vertex) -> GraphStoreResult<()>;
103 fn save_edge(&self, edge: &Edge) -> GraphStoreResult<()>;
104 fn delete_vertex(&self, id: u64) -> GraphStoreResult<()>;
105 fn delete_edge(&self, id: u64) -> GraphStoreResult<()>;
106 fn ids(
107 &self,
108 filter: GraphEntityFilter<'_>,
109 after: Option<u64>,
110 limit: usize,
111 ) -> GraphStoreResult<Vec<u64>>;
112 fn count(&self, filter: GraphEntityFilter<'_>) -> GraphStoreResult<u64>;
113 fn max_id(&self, kind: GraphEntityKind) -> GraphStoreResult<Option<u64>>;
114 fn memberships(&self, kind: GraphEntityKind, id: u64) -> GraphStoreResult<Vec<String>>;
115 fn has_membership(&self, kind: GraphEntityKind, id: u64, graph: &str)
116 -> GraphStoreResult<bool>;
117 fn attach(&self, kind: GraphEntityKind, id: u64, graph: &str) -> GraphStoreResult<()>;
118 fn detach(&self, kind: GraphEntityKind, id: u64, graph: &str) -> GraphStoreResult<()>;
119}