1use crate::entities::*;
16use crate::snapshot::{StoreSnapshot, StoreSnapshotTrait};
17use crate::types::EntityId;
18use std::collections::HashMap;
19use std::sync::RwLock;
20
21#[derive(Debug, Default)]
29pub struct HashMapStore {
30 pub roots: RwLock<HashMap<EntityId, Root>>,
32 pub documents: RwLock<HashMap<EntityId, Document>>,
33 pub frames: RwLock<HashMap<EntityId, Frame>>,
34 pub blocks: RwLock<HashMap<EntityId, Block>>,
35 pub inline_elements: RwLock<HashMap<EntityId, InlineElement>>,
36 pub lists: RwLock<HashMap<EntityId, List>>,
37 pub resources: RwLock<HashMap<EntityId, Resource>>,
38 pub tables: RwLock<HashMap<EntityId, Table>>,
39 pub table_cells: RwLock<HashMap<EntityId, TableCell>>,
40
41 pub jn_document_from_root_document: RwLock<HashMap<EntityId, Vec<EntityId>>>,
43 pub jn_frame_from_document_frames: RwLock<HashMap<EntityId, Vec<EntityId>>>,
44 pub jn_list_from_document_lists: RwLock<HashMap<EntityId, Vec<EntityId>>>,
45 pub jn_resource_from_document_resources: RwLock<HashMap<EntityId, Vec<EntityId>>>,
46 pub jn_table_from_document_tables: RwLock<HashMap<EntityId, Vec<EntityId>>>,
47 pub jn_block_from_frame_blocks: RwLock<HashMap<EntityId, Vec<EntityId>>>,
48 pub jn_frame_from_frame_parent_frame: RwLock<HashMap<EntityId, Vec<EntityId>>>,
49 pub jn_table_from_frame_table: RwLock<HashMap<EntityId, Vec<EntityId>>>,
50 pub jn_inline_element_from_block_elements: RwLock<HashMap<EntityId, Vec<EntityId>>>,
51 pub jn_list_from_block_list: RwLock<HashMap<EntityId, Vec<EntityId>>>,
52 pub jn_table_cell_from_table_cells: RwLock<HashMap<EntityId, Vec<EntityId>>>,
53 pub jn_frame_from_table_cell_cell_frame: RwLock<HashMap<EntityId, Vec<EntityId>>>,
54
55 pub jn_back_root_document: RwLock<HashMap<EntityId, Vec<EntityId>>>,
57 pub jn_back_document_frames: RwLock<HashMap<EntityId, Vec<EntityId>>>,
58 pub jn_back_frame_blocks: RwLock<HashMap<EntityId, Vec<EntityId>>>,
59 pub jn_back_frame_parent_frame: RwLock<HashMap<EntityId, Vec<EntityId>>>,
60
61 pub counters: RwLock<HashMap<String, EntityId>>,
63
64 savepoints: RwLock<HashMap<u64, HashMapStoreSnapshot>>,
66 next_savepoint_id: RwLock<u64>,
67}
68
69impl HashMapStore {
70 pub fn new() -> Self {
71 Self::default()
72 }
73
74 pub fn snapshot(&self) -> HashMapStoreSnapshot {
76 HashMapStoreSnapshot {
77 roots: self.roots.read().unwrap().clone(),
78 documents: self.documents.read().unwrap().clone(),
79 frames: self.frames.read().unwrap().clone(),
80 blocks: self.blocks.read().unwrap().clone(),
81 inline_elements: self.inline_elements.read().unwrap().clone(),
82 lists: self.lists.read().unwrap().clone(),
83 resources: self.resources.read().unwrap().clone(),
84 tables: self.tables.read().unwrap().clone(),
85 table_cells: self.table_cells.read().unwrap().clone(),
86 jn_document_from_root_document: self
87 .jn_document_from_root_document
88 .read()
89 .unwrap()
90 .clone(),
91 jn_frame_from_document_frames: self
92 .jn_frame_from_document_frames
93 .read()
94 .unwrap()
95 .clone(),
96 jn_list_from_document_lists: self.jn_list_from_document_lists.read().unwrap().clone(),
97 jn_resource_from_document_resources: self
98 .jn_resource_from_document_resources
99 .read()
100 .unwrap()
101 .clone(),
102 jn_table_from_document_tables: self
103 .jn_table_from_document_tables
104 .read()
105 .unwrap()
106 .clone(),
107 jn_block_from_frame_blocks: self.jn_block_from_frame_blocks.read().unwrap().clone(),
108 jn_frame_from_frame_parent_frame: self
109 .jn_frame_from_frame_parent_frame
110 .read()
111 .unwrap()
112 .clone(),
113 jn_table_from_frame_table: self.jn_table_from_frame_table.read().unwrap().clone(),
114 jn_inline_element_from_block_elements: self
115 .jn_inline_element_from_block_elements
116 .read()
117 .unwrap()
118 .clone(),
119 jn_list_from_block_list: self.jn_list_from_block_list.read().unwrap().clone(),
120 jn_table_cell_from_table_cells: self
121 .jn_table_cell_from_table_cells
122 .read()
123 .unwrap()
124 .clone(),
125 jn_frame_from_table_cell_cell_frame: self
126 .jn_frame_from_table_cell_cell_frame
127 .read()
128 .unwrap()
129 .clone(),
130 jn_back_root_document: self.jn_back_root_document.read().unwrap().clone(),
131 jn_back_document_frames: self.jn_back_document_frames.read().unwrap().clone(),
132 jn_back_frame_blocks: self.jn_back_frame_blocks.read().unwrap().clone(),
133 jn_back_frame_parent_frame: self.jn_back_frame_parent_frame.read().unwrap().clone(),
134 counters: self.counters.read().unwrap().clone(),
135 }
136 }
137
138 pub fn restore(&self, snap: &HashMapStoreSnapshot) {
140 *self.roots.write().unwrap() = snap.roots.clone();
141 *self.documents.write().unwrap() = snap.documents.clone();
142 *self.frames.write().unwrap() = snap.frames.clone();
143 *self.blocks.write().unwrap() = snap.blocks.clone();
144 *self.inline_elements.write().unwrap() = snap.inline_elements.clone();
145 *self.lists.write().unwrap() = snap.lists.clone();
146 *self.resources.write().unwrap() = snap.resources.clone();
147 *self.tables.write().unwrap() = snap.tables.clone();
148 *self.table_cells.write().unwrap() = snap.table_cells.clone();
149 *self.jn_document_from_root_document.write().unwrap() =
150 snap.jn_document_from_root_document.clone();
151 *self.jn_frame_from_document_frames.write().unwrap() =
152 snap.jn_frame_from_document_frames.clone();
153 *self.jn_list_from_document_lists.write().unwrap() =
154 snap.jn_list_from_document_lists.clone();
155 *self.jn_resource_from_document_resources.write().unwrap() =
156 snap.jn_resource_from_document_resources.clone();
157 *self.jn_table_from_document_tables.write().unwrap() =
158 snap.jn_table_from_document_tables.clone();
159 *self.jn_block_from_frame_blocks.write().unwrap() = snap.jn_block_from_frame_blocks.clone();
160 *self.jn_frame_from_frame_parent_frame.write().unwrap() =
161 snap.jn_frame_from_frame_parent_frame.clone();
162 *self.jn_table_from_frame_table.write().unwrap() = snap.jn_table_from_frame_table.clone();
163 *self.jn_inline_element_from_block_elements.write().unwrap() =
164 snap.jn_inline_element_from_block_elements.clone();
165 *self.jn_list_from_block_list.write().unwrap() = snap.jn_list_from_block_list.clone();
166 *self.jn_table_cell_from_table_cells.write().unwrap() =
167 snap.jn_table_cell_from_table_cells.clone();
168 *self.jn_frame_from_table_cell_cell_frame.write().unwrap() =
169 snap.jn_frame_from_table_cell_cell_frame.clone();
170 *self.jn_back_root_document.write().unwrap() = snap.jn_back_root_document.clone();
171 *self.jn_back_document_frames.write().unwrap() = snap.jn_back_document_frames.clone();
172 *self.jn_back_frame_blocks.write().unwrap() = snap.jn_back_frame_blocks.clone();
173 *self.jn_back_frame_parent_frame.write().unwrap() = snap.jn_back_frame_parent_frame.clone();
174 *self.counters.write().unwrap() = snap.counters.clone();
175 }
176
177 pub fn create_savepoint(&self) -> u64 {
179 let snap = self.snapshot();
180 let mut id_counter = self.next_savepoint_id.write().unwrap();
181 let id = *id_counter;
182 *id_counter += 1;
183 self.savepoints.write().unwrap().insert(id, snap);
184 id
185 }
186
187 pub fn restore_savepoint(&self, savepoint_id: u64) {
189 let snap = self
190 .savepoints
191 .read()
192 .unwrap()
193 .get(&savepoint_id)
194 .expect("savepoint not found")
195 .clone();
196 self.restore(&snap);
197 }
198
199 pub(crate) fn next_id(&self, entity_name: &str) -> EntityId {
201 let mut counters = self.counters.write().unwrap();
202 let counter = counters.entry(entity_name.to_string()).or_insert(1);
203 let id = *counter;
204 *counter += 1;
205 id
206 }
207
208 pub fn restore_without_counters(&self, snap: &HashMapStoreSnapshot) {
211 *self.roots.write().unwrap() = snap.roots.clone();
212 *self.documents.write().unwrap() = snap.documents.clone();
213 *self.frames.write().unwrap() = snap.frames.clone();
214 *self.blocks.write().unwrap() = snap.blocks.clone();
215 *self.inline_elements.write().unwrap() = snap.inline_elements.clone();
216 *self.lists.write().unwrap() = snap.lists.clone();
217 *self.resources.write().unwrap() = snap.resources.clone();
218 *self.tables.write().unwrap() = snap.tables.clone();
219 *self.table_cells.write().unwrap() = snap.table_cells.clone();
220 *self.jn_document_from_root_document.write().unwrap() =
221 snap.jn_document_from_root_document.clone();
222 *self.jn_frame_from_document_frames.write().unwrap() =
223 snap.jn_frame_from_document_frames.clone();
224 *self.jn_list_from_document_lists.write().unwrap() =
225 snap.jn_list_from_document_lists.clone();
226 *self.jn_resource_from_document_resources.write().unwrap() =
227 snap.jn_resource_from_document_resources.clone();
228 *self.jn_table_from_document_tables.write().unwrap() =
229 snap.jn_table_from_document_tables.clone();
230 *self.jn_block_from_frame_blocks.write().unwrap() = snap.jn_block_from_frame_blocks.clone();
231 *self.jn_frame_from_frame_parent_frame.write().unwrap() =
232 snap.jn_frame_from_frame_parent_frame.clone();
233 *self.jn_table_from_frame_table.write().unwrap() = snap.jn_table_from_frame_table.clone();
234 *self.jn_inline_element_from_block_elements.write().unwrap() =
235 snap.jn_inline_element_from_block_elements.clone();
236 *self.jn_list_from_block_list.write().unwrap() = snap.jn_list_from_block_list.clone();
237 *self.jn_table_cell_from_table_cells.write().unwrap() =
238 snap.jn_table_cell_from_table_cells.clone();
239 *self.jn_frame_from_table_cell_cell_frame.write().unwrap() =
240 snap.jn_frame_from_table_cell_cell_frame.clone();
241 *self.jn_back_root_document.write().unwrap() = snap.jn_back_root_document.clone();
242 *self.jn_back_document_frames.write().unwrap() = snap.jn_back_document_frames.clone();
243 *self.jn_back_frame_blocks.write().unwrap() = snap.jn_back_frame_blocks.clone();
244 *self.jn_back_frame_parent_frame.write().unwrap() = snap.jn_back_frame_parent_frame.clone();
245 }
247
248 pub fn store_snapshot(&self) -> StoreSnapshot {
250 StoreSnapshot::new(self.snapshot())
251 }
252
253 pub fn restore_store_snapshot(&self, snap: &StoreSnapshot) {
255 let s = snap
256 .downcast_ref::<HashMapStoreSnapshot>()
257 .expect("StoreSnapshot must contain HashMapStoreSnapshot");
258 self.restore_without_counters(s);
259 }
260}
261
262#[derive(Debug, Clone)]
264pub struct HashMapStoreSnapshot {
265 roots: HashMap<EntityId, Root>,
266 documents: HashMap<EntityId, Document>,
267 frames: HashMap<EntityId, Frame>,
268 blocks: HashMap<EntityId, Block>,
269 inline_elements: HashMap<EntityId, InlineElement>,
270 lists: HashMap<EntityId, List>,
271 resources: HashMap<EntityId, Resource>,
272 tables: HashMap<EntityId, Table>,
273 table_cells: HashMap<EntityId, TableCell>,
274 jn_document_from_root_document: HashMap<EntityId, Vec<EntityId>>,
275 jn_frame_from_document_frames: HashMap<EntityId, Vec<EntityId>>,
276 jn_list_from_document_lists: HashMap<EntityId, Vec<EntityId>>,
277 jn_resource_from_document_resources: HashMap<EntityId, Vec<EntityId>>,
278 jn_table_from_document_tables: HashMap<EntityId, Vec<EntityId>>,
279 jn_block_from_frame_blocks: HashMap<EntityId, Vec<EntityId>>,
280 jn_frame_from_frame_parent_frame: HashMap<EntityId, Vec<EntityId>>,
281 jn_table_from_frame_table: HashMap<EntityId, Vec<EntityId>>,
282 jn_inline_element_from_block_elements: HashMap<EntityId, Vec<EntityId>>,
283 jn_list_from_block_list: HashMap<EntityId, Vec<EntityId>>,
284 jn_table_cell_from_table_cells: HashMap<EntityId, Vec<EntityId>>,
285 jn_frame_from_table_cell_cell_frame: HashMap<EntityId, Vec<EntityId>>,
286 jn_back_root_document: HashMap<EntityId, Vec<EntityId>>,
287 jn_back_document_frames: HashMap<EntityId, Vec<EntityId>>,
288 jn_back_frame_blocks: HashMap<EntityId, Vec<EntityId>>,
289 jn_back_frame_parent_frame: HashMap<EntityId, Vec<EntityId>>,
290 counters: HashMap<String, EntityId>,
291}
292
293impl StoreSnapshotTrait for HashMapStoreSnapshot {
294 fn clone_box(&self) -> Box<dyn StoreSnapshotTrait> {
295 Box::new(self.clone())
296 }
297
298 fn as_any(&self) -> &dyn std::any::Any {
299 self
300 }
301}
302
303pub(crate) fn delete_from_backward_junction(
308 junction: &RwLock<HashMap<EntityId, Vec<EntityId>>>,
309 id: &EntityId,
310) {
311 let mut jn = junction.write().unwrap();
312 for right_ids in jn.values_mut() {
313 right_ids.retain(|eid| eid != id);
314 }
315}
316
317pub(crate) fn junction_get(
318 junction: &RwLock<HashMap<EntityId, Vec<EntityId>>>,
319 id: &EntityId,
320) -> Vec<EntityId> {
321 junction
322 .read()
323 .unwrap()
324 .get(id)
325 .cloned()
326 .unwrap_or_default()
327}
328
329pub(crate) fn junction_set(
330 junction: &RwLock<HashMap<EntityId, Vec<EntityId>>>,
331 id: EntityId,
332 ids: Vec<EntityId>,
333) {
334 junction.write().unwrap().insert(id, ids);
335}
336
337pub(crate) fn junction_remove(junction: &RwLock<HashMap<EntityId, Vec<EntityId>>>, id: &EntityId) {
338 junction.write().unwrap().remove(id);
339}
340
341pub(crate) fn junction_get_relationships_from_right_ids(
342 junction: &RwLock<HashMap<EntityId, Vec<EntityId>>>,
343 right_ids: &[EntityId],
344) -> Vec<(EntityId, Vec<EntityId>)> {
345 let jn = junction.read().unwrap();
346 jn.iter()
347 .filter(|(_, rids)| right_ids.iter().any(|eid| rids.contains(eid)))
348 .map(|(left_id, rids)| (*left_id, rids.clone()))
349 .collect()
350}
351
352pub(crate) fn junction_move_ids(
353 junction: &RwLock<HashMap<EntityId, Vec<EntityId>>>,
354 id: &EntityId,
355 ids_to_move: &[EntityId],
356 new_index: i32,
357) -> Vec<EntityId> {
358 let current = junction_get(junction, id);
359 if ids_to_move.is_empty() {
360 return current;
361 }
362 let move_set: std::collections::HashSet<EntityId> = ids_to_move.iter().copied().collect();
363 let mut remaining: Vec<EntityId> = current
364 .into_iter()
365 .filter(|eid| !move_set.contains(eid))
366 .collect();
367 let insert_pos = if new_index < 0 || (new_index as usize) > remaining.len() {
368 remaining.len()
369 } else {
370 new_index as usize
371 };
372 for (i, &eid) in ids_to_move.iter().enumerate() {
373 remaining.insert(insert_pos + i, eid);
374 }
375 junction_set(junction, *id, remaining.clone());
376 remaining
377}
378
379#[macro_export]
386macro_rules! impl_relationship_methods {
387 ($table_type:ty, $field_enum:ty) => {
388 fn get_relationship(
389 &self,
390 id: &$crate::types::EntityId,
391 field: &$field_enum,
392 ) -> Result<Vec<$crate::types::EntityId>, $crate::error::RepositoryError> {
393 Ok($crate::database::hashmap_store::junction_get(
394 self.resolve_junction(field),
395 id,
396 ))
397 }
398
399 fn get_relationship_many(
400 &self,
401 ids: &[$crate::types::EntityId],
402 field: &$field_enum,
403 ) -> Result<
404 std::collections::HashMap<$crate::types::EntityId, Vec<$crate::types::EntityId>>,
405 $crate::error::RepositoryError,
406 > {
407 let jn = self.resolve_junction(field);
408 let mut map = std::collections::HashMap::new();
409 for id in ids {
410 map.insert(*id, $crate::database::hashmap_store::junction_get(jn, id));
411 }
412 Ok(map)
413 }
414
415 fn get_relationship_count(
416 &self,
417 id: &$crate::types::EntityId,
418 field: &$field_enum,
419 ) -> Result<usize, $crate::error::RepositoryError> {
420 Ok(
421 $crate::database::hashmap_store::junction_get(self.resolve_junction(field), id)
422 .len(),
423 )
424 }
425
426 fn get_relationship_in_range(
427 &self,
428 id: &$crate::types::EntityId,
429 field: &$field_enum,
430 offset: usize,
431 limit: usize,
432 ) -> Result<Vec<$crate::types::EntityId>, $crate::error::RepositoryError> {
433 let all =
434 $crate::database::hashmap_store::junction_get(self.resolve_junction(field), id);
435 Ok(all.into_iter().skip(offset).take(limit).collect())
436 }
437
438 fn get_relationships_from_right_ids(
439 &self,
440 field: &$field_enum,
441 right_ids: &[$crate::types::EntityId],
442 ) -> Result<
443 Vec<($crate::types::EntityId, Vec<$crate::types::EntityId>)>,
444 $crate::error::RepositoryError,
445 > {
446 Ok(
447 $crate::database::hashmap_store::junction_get_relationships_from_right_ids(
448 self.resolve_junction(field),
449 right_ids,
450 ),
451 )
452 }
453 };
454}
455
456#[macro_export]
457macro_rules! impl_write_relationship_methods {
458 ($table_type:ty, $field_enum:ty) => {
459 $crate::impl_relationship_methods!($table_type, $field_enum);
460
461 fn set_relationship_multi(
462 &mut self,
463 field: &$field_enum,
464 relationships: Vec<($crate::types::EntityId, Vec<$crate::types::EntityId>)>,
465 ) -> Result<(), $crate::error::RepositoryError> {
466 let jn = self.resolve_junction(field);
467 for (left_id, entities) in relationships {
468 $crate::database::hashmap_store::junction_set(jn, left_id, entities);
469 }
470 Ok(())
471 }
472
473 fn set_relationship(
474 &mut self,
475 id: &$crate::types::EntityId,
476 field: &$field_enum,
477 right_ids: &[$crate::types::EntityId],
478 ) -> Result<(), $crate::error::RepositoryError> {
479 $crate::database::hashmap_store::junction_set(
480 self.resolve_junction(field),
481 *id,
482 right_ids.to_vec(),
483 );
484 Ok(())
485 }
486
487 fn move_relationship_ids(
488 &mut self,
489 id: &$crate::types::EntityId,
490 field: &$field_enum,
491 ids_to_move: &[$crate::types::EntityId],
492 new_index: i32,
493 ) -> Result<Vec<$crate::types::EntityId>, $crate::error::RepositoryError> {
494 Ok($crate::database::hashmap_store::junction_move_ids(
495 self.resolve_junction(field),
496 id,
497 ids_to_move,
498 new_index,
499 ))
500 }
501 };
502}
503
504#[macro_export]
509macro_rules! impl_leaf_entity_table {
510 (
511 entity: $Entity:ident,
512 entity_name: $entity_name:expr,
513 store_field: $store_field:ident,
514 table_trait: $TableTrait:ident,
515 table_ro_trait: $TableROTrait:ident,
516 table_struct: $TableStruct:ident,
517 table_ro_struct: $TableROStruct:ident,
518 backward_junctions: [ $( ($bj_field:ident, $bj_name:expr) ),* ],
519 ) => {
520 pub struct $TableStruct<'a> {
521 store: &'a $crate::database::hashmap_store::HashMapStore,
522 }
523
524 impl<'a> $TableStruct<'a> {
525 pub fn new(store: &'a $crate::database::hashmap_store::HashMapStore) -> Self {
526 Self { store }
527 }
528 }
529
530 impl<'a> $TableTrait for $TableStruct<'a> {
531 fn create(&mut self, entity: &$Entity) -> Result<$Entity, $crate::error::RepositoryError> {
532 self.create_multi(std::slice::from_ref(entity))
533 .map(|v| v.into_iter().next().unwrap())
534 }
535
536 fn create_multi(&mut self, entities: &[$Entity]) -> Result<Vec<$Entity>, $crate::error::RepositoryError> {
537 let mut created = Vec::with_capacity(entities.len());
538 let mut map = self.store.$store_field.write().unwrap();
539
540 for entity in entities {
541 let new_entity = if entity.id == $crate::types::EntityId::default() {
542 let id = self.store.next_id($entity_name);
543 $Entity {
544 id,
545 ..entity.clone()
546 }
547 } else {
548 if map.contains_key(&entity.id) {
549 return Err($crate::error::RepositoryError::DuplicateId {
550 entity: stringify!($Entity),
551 id: entity.id,
552 });
553 }
554 entity.clone()
555 };
556
557 map.insert(new_entity.id, new_entity.clone());
558 created.push(new_entity);
559 }
560 Ok(created)
561 }
562
563 fn get(&self, id: &$crate::types::EntityId) -> Result<Option<$Entity>, $crate::error::RepositoryError> {
564 Ok(self.store.$store_field.read().unwrap().get(id).cloned())
565 }
566
567 fn get_multi(&self, ids: &[$crate::types::EntityId]) -> Result<Vec<Option<$Entity>>, $crate::error::RepositoryError> {
568 let map = self.store.$store_field.read().unwrap();
569 Ok(ids.iter().map(|id| map.get(id).cloned()).collect())
570 }
571
572 fn get_all(&self) -> Result<Vec<$Entity>, $crate::error::RepositoryError> {
573 Ok(self.store.$store_field.read().unwrap().values().cloned().collect())
574 }
575
576 fn update(&mut self, entity: &$Entity) -> Result<$Entity, $crate::error::RepositoryError> {
577 self.update_multi(std::slice::from_ref(entity))
578 .map(|v| v.into_iter().next().unwrap())
579 }
580
581 fn update_multi(&mut self, entities: &[$Entity]) -> Result<Vec<$Entity>, $crate::error::RepositoryError> {
582 let mut map = self.store.$store_field.write().unwrap();
583 let mut result = Vec::with_capacity(entities.len());
584 for entity in entities {
585 map.insert(entity.id, entity.clone());
586 result.push(entity.clone());
587 }
588 Ok(result)
589 }
590
591 fn update_with_relationships(&mut self, entity: &$Entity) -> Result<$Entity, $crate::error::RepositoryError> {
592 self.update(entity)
593 }
594
595 fn update_with_relationships_multi(&mut self, entities: &[$Entity]) -> Result<Vec<$Entity>, $crate::error::RepositoryError> {
596 self.update_multi(entities)
597 }
598
599 fn remove(&mut self, id: &$crate::types::EntityId) -> Result<(), $crate::error::RepositoryError> {
600 self.remove_multi(std::slice::from_ref(id))
601 }
602
603 fn remove_multi(&mut self, ids: &[$crate::types::EntityId]) -> Result<(), $crate::error::RepositoryError> {
604 let mut map = self.store.$store_field.write().unwrap();
605 for id in ids {
606 map.remove(id);
607 $(
608 $crate::database::hashmap_store::delete_from_backward_junction(&self.store.$bj_field, id);
609 )*
610 }
611 Ok(())
612 }
613 }
614
615 pub struct $TableROStruct<'a> {
616 store: &'a $crate::database::hashmap_store::HashMapStore,
617 }
618
619 impl<'a> $TableROStruct<'a> {
620 pub fn new(store: &'a $crate::database::hashmap_store::HashMapStore) -> Self {
621 Self { store }
622 }
623 }
624
625 impl<'a> $TableROTrait for $TableROStruct<'a> {
626 fn get(&self, id: &$crate::types::EntityId) -> Result<Option<$Entity>, $crate::error::RepositoryError> {
627 Ok(self.store.$store_field.read().unwrap().get(id).cloned())
628 }
629
630 fn get_multi(&self, ids: &[$crate::types::EntityId]) -> Result<Vec<Option<$Entity>>, $crate::error::RepositoryError> {
631 let map = self.store.$store_field.read().unwrap();
632 Ok(ids.iter().map(|id| map.get(id).cloned()).collect())
633 }
634
635 fn get_all(&self) -> Result<Vec<$Entity>, $crate::error::RepositoryError> {
636 Ok(self.store.$store_field.read().unwrap().values().cloned().collect())
637 }
638 }
639 };
640}