text_document_common/direct_access/document/
document_table.rs1use crate::database::hashmap_store::{
2 HashMapStore, delete_from_backward_junction, junction_get, junction_remove, junction_set,
3};
4use crate::entities::*;
5use crate::error::RepositoryError;
6use crate::types::EntityId;
7use crate::{impl_relationship_methods, impl_write_relationship_methods};
8use std::collections::HashMap;
9use std::sync::RwLock;
10
11use super::document_repository::{DocumentRelationshipField, DocumentTable, DocumentTableRO};
12
13pub struct DocumentHashMapTable<'a> {
14 store: &'a HashMapStore,
15}
16
17impl<'a> DocumentHashMapTable<'a> {
18 pub fn new(store: &'a HashMapStore) -> Self {
19 Self { store }
20 }
21
22 fn resolve_junction(
23 &self,
24 field: &DocumentRelationshipField,
25 ) -> &RwLock<HashMap<EntityId, Vec<EntityId>>> {
26 match field {
27 DocumentRelationshipField::Frames => &self.store.jn_frame_from_document_frames,
28 DocumentRelationshipField::Lists => &self.store.jn_list_from_document_lists,
29 DocumentRelationshipField::Resources => &self.store.jn_resource_from_document_resources,
30 DocumentRelationshipField::Tables => &self.store.jn_table_from_document_tables,
31 }
32 }
33
34 fn hydrate(&self, entity: &mut Document) {
35 entity.frames = junction_get(&self.store.jn_frame_from_document_frames, &entity.id);
36 entity.lists = junction_get(&self.store.jn_list_from_document_lists, &entity.id);
37 entity.resources =
38 junction_get(&self.store.jn_resource_from_document_resources, &entity.id);
39 entity.tables = junction_get(&self.store.jn_table_from_document_tables, &entity.id);
40 }
41}
42
43impl<'a> DocumentTable for DocumentHashMapTable<'a> {
44 fn create(&mut self, entity: &Document) -> Result<Document, RepositoryError> {
45 self.create_multi(std::slice::from_ref(entity))
46 .map(|v| v.into_iter().next().unwrap())
47 }
48
49 fn create_multi(&mut self, entities: &[Document]) -> Result<Vec<Document>, RepositoryError> {
50 let mut created = Vec::with_capacity(entities.len());
51 let mut docs = self.store.documents.write().unwrap();
52
53 for entity in entities {
54 let new_entity = if entity.id == EntityId::default() {
55 let id = self.store.next_id("document");
56 Document {
57 id,
58 ..entity.clone()
59 }
60 } else {
61 if docs.contains_key(&entity.id) {
62 return Err(RepositoryError::DuplicateId {
63 entity: "Document",
64 id: entity.id,
65 });
66 }
67 entity.clone()
68 };
69
70 docs.insert(new_entity.id, new_entity.clone());
71 junction_set(
72 &self.store.jn_frame_from_document_frames,
73 new_entity.id,
74 new_entity.frames.clone(),
75 );
76 junction_set(
77 &self.store.jn_list_from_document_lists,
78 new_entity.id,
79 new_entity.lists.clone(),
80 );
81 junction_set(
82 &self.store.jn_resource_from_document_resources,
83 new_entity.id,
84 new_entity.resources.clone(),
85 );
86 junction_set(
87 &self.store.jn_table_from_document_tables,
88 new_entity.id,
89 new_entity.tables.clone(),
90 );
91 created.push(new_entity);
92 }
93 Ok(created)
94 }
95
96 fn get(&self, id: &EntityId) -> Result<Option<Document>, RepositoryError> {
97 let docs = self.store.documents.read().unwrap();
98 match docs.get(id) {
99 Some(entity) => {
100 let mut e = entity.clone();
101 drop(docs);
102 self.hydrate(&mut e);
103 Ok(Some(e))
104 }
105 None => Ok(None),
106 }
107 }
108
109 fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Document>>, RepositoryError> {
110 let mut result = Vec::with_capacity(ids.len());
111 for id in ids {
112 result.push(self.get(id)?);
113 }
114 Ok(result)
115 }
116
117 fn get_all(&self) -> Result<Vec<Document>, RepositoryError> {
118 let docs = self.store.documents.read().unwrap();
119 let entries: Vec<Document> = docs.values().cloned().collect();
120 drop(docs);
121 let mut result = Vec::with_capacity(entries.len());
122 for mut entity in entries {
123 self.hydrate(&mut entity);
124 result.push(entity);
125 }
126 Ok(result)
127 }
128
129 fn update(&mut self, entity: &Document) -> Result<Document, RepositoryError> {
130 self.update_multi(std::slice::from_ref(entity))
131 .map(|v| v.into_iter().next().unwrap())
132 }
133
134 fn update_multi(&mut self, entities: &[Document]) -> Result<Vec<Document>, RepositoryError> {
135 let mut docs = self.store.documents.write().unwrap();
136 for entity in entities {
137 docs.insert(entity.id, entity.clone());
138 }
139 drop(docs);
140 let ids: Vec<EntityId> = entities.iter().map(|e| e.id).collect();
141 let result = self.get_multi(&ids)?;
142 Ok(result.into_iter().flatten().collect())
143 }
144
145 fn update_with_relationships(
146 &mut self,
147 entity: &Document,
148 ) -> Result<Document, RepositoryError> {
149 self.update_with_relationships_multi(std::slice::from_ref(entity))
150 .map(|v| v.into_iter().next().unwrap())
151 }
152
153 fn update_with_relationships_multi(
154 &mut self,
155 entities: &[Document],
156 ) -> Result<Vec<Document>, RepositoryError> {
157 let mut docs = self.store.documents.write().unwrap();
158 for entity in entities {
159 docs.insert(entity.id, entity.clone());
160 junction_set(
161 &self.store.jn_frame_from_document_frames,
162 entity.id,
163 entity.frames.clone(),
164 );
165 junction_set(
166 &self.store.jn_list_from_document_lists,
167 entity.id,
168 entity.lists.clone(),
169 );
170 junction_set(
171 &self.store.jn_resource_from_document_resources,
172 entity.id,
173 entity.resources.clone(),
174 );
175 junction_set(
176 &self.store.jn_table_from_document_tables,
177 entity.id,
178 entity.tables.clone(),
179 );
180 }
181 drop(docs);
182 let ids: Vec<EntityId> = entities.iter().map(|e| e.id).collect();
183 let result = self.get_multi(&ids)?;
184 Ok(result.into_iter().flatten().collect())
185 }
186
187 fn remove(&mut self, id: &EntityId) -> Result<(), RepositoryError> {
188 self.remove_multi(std::slice::from_ref(id))
189 }
190
191 fn remove_multi(&mut self, ids: &[EntityId]) -> Result<(), RepositoryError> {
192 let mut docs = self.store.documents.write().unwrap();
193 for id in ids {
194 docs.remove(id);
195 junction_remove(&self.store.jn_frame_from_document_frames, id);
196 junction_remove(&self.store.jn_list_from_document_lists, id);
197 junction_remove(&self.store.jn_resource_from_document_resources, id);
198 junction_remove(&self.store.jn_table_from_document_tables, id);
199 delete_from_backward_junction(&self.store.jn_document_from_root_document, id);
200 }
201 Ok(())
202 }
203
204 impl_write_relationship_methods!(DocumentHashMapTable<'a>, DocumentRelationshipField);
205}
206
207pub struct DocumentHashMapTableRO<'a> {
208 store: &'a HashMapStore,
209}
210
211impl<'a> DocumentHashMapTableRO<'a> {
212 pub fn new(store: &'a HashMapStore) -> Self {
213 Self { store }
214 }
215
216 fn resolve_junction(
217 &self,
218 field: &DocumentRelationshipField,
219 ) -> &RwLock<HashMap<EntityId, Vec<EntityId>>> {
220 match field {
221 DocumentRelationshipField::Frames => &self.store.jn_frame_from_document_frames,
222 DocumentRelationshipField::Lists => &self.store.jn_list_from_document_lists,
223 DocumentRelationshipField::Resources => &self.store.jn_resource_from_document_resources,
224 DocumentRelationshipField::Tables => &self.store.jn_table_from_document_tables,
225 }
226 }
227
228 fn hydrate(&self, entity: &mut Document) {
229 entity.frames = junction_get(&self.store.jn_frame_from_document_frames, &entity.id);
230 entity.lists = junction_get(&self.store.jn_list_from_document_lists, &entity.id);
231 entity.resources =
232 junction_get(&self.store.jn_resource_from_document_resources, &entity.id);
233 entity.tables = junction_get(&self.store.jn_table_from_document_tables, &entity.id);
234 }
235}
236
237impl<'a> DocumentTableRO for DocumentHashMapTableRO<'a> {
238 fn get(&self, id: &EntityId) -> Result<Option<Document>, RepositoryError> {
239 let docs = self.store.documents.read().unwrap();
240 match docs.get(id) {
241 Some(entity) => {
242 let mut e = entity.clone();
243 drop(docs);
244 self.hydrate(&mut e);
245 Ok(Some(e))
246 }
247 None => Ok(None),
248 }
249 }
250
251 fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Document>>, RepositoryError> {
252 let mut result = Vec::with_capacity(ids.len());
253 for id in ids {
254 result.push(self.get(id)?);
255 }
256 Ok(result)
257 }
258
259 fn get_all(&self) -> Result<Vec<Document>, RepositoryError> {
260 let docs = self.store.documents.read().unwrap();
261 let entries: Vec<Document> = docs.values().cloned().collect();
262 drop(docs);
263 let mut result = Vec::with_capacity(entries.len());
264 for mut entity in entries {
265 self.hydrate(&mut entity);
266 result.push(entity);
267 }
268 Ok(result)
269 }
270
271 impl_relationship_methods!(DocumentHashMapTableRO<'a>, DocumentRelationshipField);
272}