1use std::fmt::Display;
4
5use crate::{
6 database::hashmap_store::HashMapStoreSnapshot,
7 database::hashmap_store::{read_or_recover, write_or_recover},
13 database::transactions::Transaction,
14 direct_access::repository_factory,
15 entities::System,
16 event::{DirectAccessEntity, EntityEvent, Event, EventBuffer, Origin},
17 snapshot::EntityTreeSnapshot,
18 types::EntityId,
19};
20
21use crate::direct_access::root::RootRelationshipField;
22use crate::error::RepositoryError;
23use serde::{Deserialize, Serialize};
24
25#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
26pub enum SystemRelationshipField {
27 Files,
28}
29
30impl Display for SystemRelationshipField {
31 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
32 write!(f, "{:?}", self)
33 }
34}
35
36pub trait SystemTable {
37 fn create(&mut self, entity: &System) -> Result<System, RepositoryError>;
38 fn create_multi(&mut self, entities: &[System]) -> Result<Vec<System>, RepositoryError>;
39 fn get(&self, id: &EntityId) -> Result<Option<System>, RepositoryError>;
40 fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<System>>, RepositoryError>;
41 fn get_all(&self) -> Result<Vec<System>, RepositoryError>;
42 fn update(&mut self, entity: &System) -> Result<System, RepositoryError>;
43 fn update_multi(&mut self, entities: &[System]) -> Result<Vec<System>, RepositoryError>;
44 fn update_with_relationships(&mut self, entity: &System) -> Result<System, RepositoryError>;
45 fn update_with_relationships_multi(
46 &mut self,
47 entities: &[System],
48 ) -> Result<Vec<System>, RepositoryError>;
49 fn remove(&mut self, id: &EntityId) -> Result<(), RepositoryError>;
50 fn remove_multi(&mut self, ids: &[EntityId]) -> Result<(), RepositoryError>;
51 fn get_relationship(
52 &self,
53 id: &EntityId,
54 field: &SystemRelationshipField,
55 ) -> Result<Vec<EntityId>, RepositoryError>;
56 fn get_relationship_many(
57 &self,
58 ids: &[EntityId],
59 field: &SystemRelationshipField,
60 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError>;
61 fn get_relationship_count(
62 &self,
63 id: &EntityId,
64 field: &SystemRelationshipField,
65 ) -> Result<usize, RepositoryError>;
66 fn get_relationship_in_range(
67 &self,
68 id: &EntityId,
69 field: &SystemRelationshipField,
70 offset: usize,
71 limit: usize,
72 ) -> Result<Vec<EntityId>, RepositoryError>;
73 fn get_relationships_from_right_ids(
74 &self,
75 field: &SystemRelationshipField,
76 right_ids: &[EntityId],
77 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError>;
78 fn set_relationship_multi(
79 &mut self,
80 field: &SystemRelationshipField,
81 relationships: Vec<(EntityId, Vec<EntityId>)>,
82 ) -> Result<(), RepositoryError>;
83 fn set_relationship(
84 &mut self,
85 id: &EntityId,
86 field: &SystemRelationshipField,
87 right_ids: &[EntityId],
88 ) -> Result<(), RepositoryError>;
89 fn move_relationship_ids(
90 &mut self,
91 id: &EntityId,
92 field: &SystemRelationshipField,
93 ids_to_move: &[EntityId],
94 new_index: i32,
95 ) -> Result<Vec<EntityId>, RepositoryError>;
96}
97
98pub trait SystemTableRO {
99 fn get(&self, id: &EntityId) -> Result<Option<System>, RepositoryError>;
100 fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<System>>, RepositoryError>;
101 fn get_all(&self) -> Result<Vec<System>, RepositoryError>;
102 fn get_relationship(
103 &self,
104 id: &EntityId,
105 field: &SystemRelationshipField,
106 ) -> Result<Vec<EntityId>, RepositoryError>;
107 fn get_relationship_many(
108 &self,
109 ids: &[EntityId],
110 field: &SystemRelationshipField,
111 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError>;
112 fn get_relationship_count(
113 &self,
114 id: &EntityId,
115 field: &SystemRelationshipField,
116 ) -> Result<usize, RepositoryError>;
117 fn get_relationship_in_range(
118 &self,
119 id: &EntityId,
120 field: &SystemRelationshipField,
121 offset: usize,
122 limit: usize,
123 ) -> Result<Vec<EntityId>, RepositoryError>;
124 fn get_relationships_from_right_ids(
125 &self,
126 field: &SystemRelationshipField,
127 right_ids: &[EntityId],
128 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError>;
129}
130
131pub struct SystemRepository<'a> {
132 table: Box<dyn SystemTable + 'a>,
133 transaction: &'a Transaction,
134}
135
136impl<'a> SystemRepository<'a> {
137 pub fn new(table: Box<dyn SystemTable + 'a>, transaction: &'a Transaction) -> Self {
138 SystemRepository { table, transaction }
139 }
140
141 pub fn create_orphan(
142 &mut self,
143 event_buffer: &mut EventBuffer,
144 entity: &System,
145 ) -> Result<System, RepositoryError> {
146 let new = self.table.create(entity)?;
147 event_buffer.push(Event {
148 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Created)),
149 ids: vec![new.id],
150 data: None,
151 });
152 Ok(new)
153 }
154
155 pub fn create_orphan_multi(
156 &mut self,
157 event_buffer: &mut EventBuffer,
158 entities: &[System],
159 ) -> Result<Vec<System>, RepositoryError> {
160 let new_entities = self.table.create_multi(entities)?;
161 event_buffer.push(Event {
162 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Created)),
163 ids: new_entities.iter().map(|e| e.id).collect(),
164 data: None,
165 });
166 Ok(new_entities)
167 }
168 pub fn create(
169 &mut self,
170 event_buffer: &mut EventBuffer,
171 entity: &System,
172 owner_id: EntityId,
173 _index: i32,
174 ) -> Result<System, RepositoryError> {
175 let new = self.table.create(entity)?;
176 let created_id = new.id;
177
178 let mut relationship_ids = self.get_relationships_from_owner(&owner_id)?;
179 if relationship_ids.is_empty() {
180 relationship_ids = vec![created_id];
181 } else {
182 self.remove_multi(event_buffer, &relationship_ids)?;
184 relationship_ids = vec![created_id];
185 }
186
187 self.set_relationships_in_owner(event_buffer, &owner_id, &relationship_ids)?;
188 event_buffer.push(Event {
189 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Created)),
190 ids: vec![created_id],
191 data: None,
192 });
193 Ok(new)
194 }
195
196 pub fn create_multi(
197 &mut self,
198 event_buffer: &mut EventBuffer,
199 entities: &[System],
200 owner_id: EntityId,
201 _index: i32,
202 ) -> Result<Vec<System>, RepositoryError> {
203 let new_entities = self.table.create_multi(entities)?;
204 let created_ids: Vec<EntityId> = new_entities.iter().map(|e| e.id).collect();
205
206 let mut relationship_ids = self.get_relationships_from_owner(&owner_id)?;
207 if relationship_ids.is_empty() {
208 relationship_ids = created_ids.clone();
209 } else {
210 self.remove_multi(event_buffer, &relationship_ids)?;
211 relationship_ids = created_ids.clone();
212 }
213
214 self.set_relationships_in_owner(event_buffer, &owner_id, &relationship_ids)?;
215 event_buffer.push(Event {
216 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Created)),
217 ids: created_ids,
218 data: None,
219 });
220 Ok(new_entities)
221 }
222
223 pub fn get(&self, id: &EntityId) -> Result<Option<System>, RepositoryError> {
224 self.table.get(id)
225 }
226 pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<System>>, RepositoryError> {
227 self.table.get_multi(ids)
228 }
229 pub fn get_all(&self) -> Result<Vec<System>, RepositoryError> {
230 self.table.get_all()
231 }
232
233 pub fn update(
234 &mut self,
235 event_buffer: &mut EventBuffer,
236 entity: &System,
237 ) -> Result<System, RepositoryError> {
238 let updated = self.table.update(entity)?;
239 event_buffer.push(Event {
240 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Updated)),
241 ids: vec![updated.id],
242 data: None,
243 });
244 Ok(updated)
245 }
246
247 pub fn update_multi(
248 &mut self,
249 event_buffer: &mut EventBuffer,
250 entities: &[System],
251 ) -> Result<Vec<System>, RepositoryError> {
252 let updated = self.table.update_multi(entities)?;
253 event_buffer.push(Event {
254 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Updated)),
255 ids: updated.iter().map(|e| e.id).collect(),
256 data: None,
257 });
258 Ok(updated)
259 }
260
261 pub fn update_with_relationships(
262 &mut self,
263 event_buffer: &mut EventBuffer,
264 entity: &System,
265 ) -> Result<System, RepositoryError> {
266 let updated = self.table.update_with_relationships(entity)?;
267 event_buffer.push(Event {
268 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Updated)),
269 ids: vec![updated.id],
270 data: None,
271 });
272 Ok(updated)
273 }
274
275 pub fn update_with_relationships_multi(
276 &mut self,
277 event_buffer: &mut EventBuffer,
278 entities: &[System],
279 ) -> Result<Vec<System>, RepositoryError> {
280 let updated = self.table.update_with_relationships_multi(entities)?;
281 event_buffer.push(Event {
282 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Updated)),
283 ids: updated.iter().map(|e| e.id).collect(),
284 data: None,
285 });
286 Ok(updated)
287 }
288
289 pub fn remove(
290 &mut self,
291 event_buffer: &mut EventBuffer,
292 id: &EntityId,
293 ) -> Result<(), RepositoryError> {
294 let entity = match self.table.get(id)? {
295 Some(e) => e,
296 None => return Ok(()),
297 };
298 let files = entity.files.clone();
301
302 repository_factory::write::create_file_repository(self.transaction)?
305 .remove_multi(event_buffer, &files)?;
306 let affected_owner_ids: Vec<EntityId> = {
308 let owner_repo = repository_factory::write::create_root_repository(self.transaction)?;
309 owner_repo
310 .get_relationships_from_right_ids(&RootRelationshipField::System, &[*id])?
311 .into_iter()
312 .map(|(owner_id, _)| owner_id)
313 .collect()
314 };
315 let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
317 std::collections::HashMap::new();
318 for owner_id in &affected_owner_ids {
319 owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
320 }
321
322 self.table.remove(id)?;
324 event_buffer.push(Event {
325 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Removed)),
326 ids: vec![*id],
327 data: None,
328 });
329 for owner_id in &affected_owner_ids {
331 if let Some(rel_ids) = owner_rel_before.get(owner_id) {
332 let updated: Vec<EntityId> =
333 rel_ids.iter().copied().filter(|rid| *rid != *id).collect();
334 self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
335 }
336 }
337
338 Ok(())
339 }
340
341 pub fn remove_multi(
342 &mut self,
343 event_buffer: &mut EventBuffer,
344 ids: &[EntityId],
345 ) -> Result<(), RepositoryError> {
346 let entities = self.table.get_multi(ids)?;
347 if entities.is_empty() || entities.iter().all(|e| e.is_none()) {
348 return Ok(());
349 }
350
351 let mut files_ids: Vec<EntityId> = entities
354 .iter()
355 .flat_map(|entity| entity.as_ref().map(|entity| entity.files.clone()))
356 .flatten()
357 .collect();
358 files_ids.sort();
360 files_ids.dedup();
361
362 repository_factory::write::create_file_repository(self.transaction)?
365 .remove_multi(event_buffer, &files_ids)?;
366 let affected_owner_ids: Vec<EntityId> = {
368 let owner_repo = repository_factory::write::create_root_repository(self.transaction)?;
369 owner_repo
370 .get_relationships_from_right_ids(&RootRelationshipField::System, ids)?
371 .into_iter()
372 .map(|(owner_id, _)| owner_id)
373 .collect()
374 };
375 let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
377 std::collections::HashMap::new();
378 for owner_id in &affected_owner_ids {
379 owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
380 }
381
382 self.table.remove_multi(ids)?;
383 event_buffer.push(Event {
384 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Removed)),
385 ids: ids.into(),
386 data: None,
387 });
388 {
390 let removed_set: std::collections::HashSet<EntityId> = ids.iter().copied().collect();
391 for owner_id in &affected_owner_ids {
392 if let Some(rel_ids) = owner_rel_before.get(owner_id) {
393 let updated: Vec<EntityId> = rel_ids
394 .iter()
395 .copied()
396 .filter(|rid| !removed_set.contains(rid))
397 .collect();
398 self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
399 }
400 }
401 }
402
403 Ok(())
404 }
405 pub fn get_relationship(
406 &self,
407 id: &EntityId,
408 field: &SystemRelationshipField,
409 ) -> Result<Vec<EntityId>, RepositoryError> {
410 self.table.get_relationship(id, field)
411 }
412 pub fn get_relationship_many(
413 &self,
414 ids: &[EntityId],
415 field: &SystemRelationshipField,
416 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
417 self.table.get_relationship_many(ids, field)
418 }
419 pub fn get_relationship_count(
420 &self,
421 id: &EntityId,
422 field: &SystemRelationshipField,
423 ) -> Result<usize, RepositoryError> {
424 self.table.get_relationship_count(id, field)
425 }
426 pub fn get_relationship_in_range(
427 &self,
428 id: &EntityId,
429 field: &SystemRelationshipField,
430 offset: usize,
431 limit: usize,
432 ) -> Result<Vec<EntityId>, RepositoryError> {
433 self.table
434 .get_relationship_in_range(id, field, offset, limit)
435 }
436 pub fn get_relationships_from_right_ids(
437 &self,
438 field: &SystemRelationshipField,
439 right_ids: &[EntityId],
440 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
441 self.table
442 .get_relationships_from_right_ids(field, right_ids)
443 }
444
445 pub fn set_relationship_multi(
446 &mut self,
447 event_buffer: &mut EventBuffer,
448 field: &SystemRelationshipField,
449 relationships: Vec<(EntityId, Vec<EntityId>)>,
450 ) -> Result<(), RepositoryError> {
451 let all_right_ids: Vec<EntityId> = relationships
453 .iter()
454 .flat_map(|(_, ids)| ids.iter().copied())
455 .collect();
456 if !all_right_ids.is_empty() {
457 match field {
458 SystemRelationshipField::Files => {
459 let child_repo =
460 repository_factory::write::create_file_repository(self.transaction)?;
461 let found = child_repo.get_multi(&all_right_ids)?;
462 let missing: Vec<_> = all_right_ids
463 .iter()
464 .zip(found.iter())
465 .filter(|(_, entity)| entity.is_none())
466 .map(|(id, _)| *id)
467 .collect();
468 if !missing.is_empty() {
469 return Err(RepositoryError::MissingRelationshipTarget {
470 operation: "set_relationship_multi",
471 ids: missing,
472 });
473 }
474 }
475 }
476 }
477 self.table
478 .set_relationship_multi(field, relationships.clone())?;
479 for (left_id, right_ids) in relationships {
480 event_buffer.push(Event {
481 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Updated)),
482 ids: vec![left_id],
483 data: Some(format!(
484 "{}:{}",
485 field,
486 right_ids
487 .iter()
488 .map(|id| id.to_string())
489 .collect::<Vec<_>>()
490 .join(",")
491 )),
492 });
493 }
494 Ok(())
495 }
496
497 pub fn set_relationship(
498 &mut self,
499 event_buffer: &mut EventBuffer,
500 id: &EntityId,
501 field: &SystemRelationshipField,
502 right_ids: &[EntityId],
503 ) -> Result<(), RepositoryError> {
504 if !right_ids.is_empty() {
506 match field {
507 SystemRelationshipField::Files => {
508 let child_repo =
509 repository_factory::write::create_file_repository(self.transaction)?;
510 let found = child_repo.get_multi(right_ids)?;
511 let missing: Vec<_> = right_ids
512 .iter()
513 .zip(found.iter())
514 .filter(|(_, entity)| entity.is_none())
515 .map(|(id, _)| *id)
516 .collect();
517 if !missing.is_empty() {
518 return Err(RepositoryError::MissingRelationshipTarget {
519 operation: "set_relationship",
520 ids: missing,
521 });
522 }
523 }
524 }
525 }
526 self.table.set_relationship(id, field, right_ids)?;
527 event_buffer.push(Event {
528 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Updated)),
529 ids: vec![*id],
530 data: Some(format!(
531 "{}:{}",
532 field,
533 right_ids
534 .iter()
535 .map(|id| id.to_string())
536 .collect::<Vec<_>>()
537 .join(",")
538 )),
539 });
540 Ok(())
541 }
542
543 pub fn move_relationship_ids(
544 &mut self,
545 event_buffer: &mut EventBuffer,
546 id: &EntityId,
547 field: &SystemRelationshipField,
548 ids_to_move: &[EntityId],
549 new_index: i32,
550 ) -> Result<Vec<EntityId>, RepositoryError> {
551 let reordered = self
552 .table
553 .move_relationship_ids(id, field, ids_to_move, new_index)?;
554 event_buffer.push(Event {
555 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Updated)),
556 ids: vec![*id],
557 data: Some(format!(
558 "{}:{}",
559 field,
560 reordered
561 .iter()
562 .map(|id| id.to_string())
563 .collect::<Vec<_>>()
564 .join(",")
565 )),
566 });
567 Ok(reordered)
568 }
569 pub fn get_relationships_from_owner(
570 &self,
571 owner_id: &EntityId,
572 ) -> Result<Vec<EntityId>, RepositoryError> {
573 let repo = repository_factory::write::create_root_repository(self.transaction)?;
574 repo.get_relationship(owner_id, &RootRelationshipField::System)
575 }
576
577 pub fn set_relationships_in_owner(
578 &mut self,
579 event_buffer: &mut EventBuffer,
580 owner_id: &EntityId,
581 ids: &[EntityId],
582 ) -> Result<(), RepositoryError> {
583 let mut repo = repository_factory::write::create_root_repository(self.transaction)?;
584 repo.set_relationship(event_buffer, owner_id, &RootRelationshipField::System, ids)
585 }
586
587 pub fn snapshot(&self, ids: &[EntityId]) -> Result<EntityTreeSnapshot, RepositoryError> {
588 let store_snap = self.transaction.snapshot_store();
590 Ok(EntityTreeSnapshot {
591 store_snapshot: Some(store_snap),
592 root_ids: ids.to_vec(),
593 })
594 }
595
596 pub fn restore(
597 &mut self,
598 event_buffer: &mut EventBuffer,
599 snap: &EntityTreeSnapshot,
600 ) -> Result<(), RepositoryError> {
601 let store_snap = snap
602 .store_snapshot
603 .as_ref()
604 .ok_or_else(|| RepositoryError::Serialization("missing store snapshot".into()))?;
605 let snap_store = store_snap
606 .downcast_ref::<HashMapStoreSnapshot>()
607 .ok_or_else(|| RepositoryError::Serialization("snapshot type mismatch".into()))?;
608
609 let mut visited = std::collections::HashSet::new();
612 self.restore_subtree(event_buffer, snap_store, &snap.root_ids, &mut visited)?;
613
614 self.reconcile_backref_root_system(event_buffer, snap_store, &snap.root_ids)?;
617
618 Ok(())
619 }
620
621 pub(crate) fn restore_subtree(
626 &self,
627 event_buffer: &mut EventBuffer,
628 snap: &HashMapStoreSnapshot,
629 ids: &[EntityId],
630 visited: &mut std::collections::HashSet<(&'static str, EntityId)>,
633 ) -> Result<(), RepositoryError> {
634 let ids: Vec<EntityId> = ids
635 .iter()
636 .copied()
637 .filter(|id| visited.insert(("system", *id)))
638 .collect();
639 if ids.is_empty() {
640 return Ok(());
641 }
642
643 let store = self.transaction.get_store();
644
645 let mut to_create: Vec<EntityId> = Vec::new(); let mut to_update: Vec<EntityId> = Vec::new(); let mut to_delete: Vec<EntityId> = Vec::new(); {
650 let live = read_or_recover(&store.systems);
651 for id in &ids {
652 match (snap.systems.contains_key(id), live.contains_key(id)) {
653 (true, false) => to_create.push(*id),
654 (true, true) => to_update.push(*id),
655 (false, true) => to_delete.push(*id),
656 (false, false) => {}
657 }
658 }
659 }
660
661 {
664 let mut child_ids: Vec<EntityId> = Vec::new();
665 for id in to_create.iter().chain(to_update.iter()) {
666 if let Some(list) = snap.jn_file_from_system_files.get(id) {
667 child_ids.extend(list.iter().copied());
668 }
669 }
670 {
671 let live_jn = read_or_recover(&store.jn_file_from_system_files);
672 for id in &ids {
673 if let Some(list) = live_jn.get(id) {
674 child_ids.extend(list.iter().copied());
675 }
676 }
677 }
678 child_ids.sort();
679 child_ids.dedup();
680 if !child_ids.is_empty() {
681 repository_factory::write::create_file_repository(self.transaction)?
682 .restore_subtree(event_buffer, snap, &child_ids, visited)?;
683 }
684 }
685
686 {
688 let mut live = write_or_recover(&store.systems);
689 for id in to_create.iter().chain(to_update.iter()) {
690 if let Some(row) = snap.systems.get(id) {
691 live.insert(*id, row.clone());
692 }
693 }
694 for id in &to_delete {
695 live.remove(id);
696 }
697 }
698
699 {
702 let mut live_jn = write_or_recover(&store.jn_file_from_system_files);
703 for id in to_create.iter().chain(to_update.iter()) {
704 match snap.jn_file_from_system_files.get(id) {
705 Some(v) => {
706 live_jn.insert(*id, v.clone());
707 }
708 None => {
709 live_jn.remove(id);
710 }
711 }
712 }
713 for id in &to_delete {
714 live_jn.remove(id);
715 }
716 }
717
718 if !to_create.is_empty() {
722 event_buffer.push(Event {
723 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Created)),
724 ids: to_create.clone(),
725 data: None,
726 });
727 event_buffer.push(Event {
728 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Updated)),
729 ids: to_create.clone(),
730 data: None,
731 });
732 }
733 if !to_update.is_empty() {
734 event_buffer.push(Event {
735 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Updated)),
736 ids: to_update.clone(),
737 data: None,
738 });
739 }
740 if !to_delete.is_empty() {
741 event_buffer.push(Event {
742 origin: Origin::DirectAccess(DirectAccessEntity::System(EntityEvent::Removed)),
743 ids: to_delete.clone(),
744 data: None,
745 });
746 }
747
748 Ok(())
749 }
750
751 fn reconcile_backref_root_system(
754 &self,
755 event_buffer: &mut EventBuffer,
756 snap: &HashMapStoreSnapshot,
757 scope_ids: &[EntityId],
758 ) -> Result<(), RepositoryError> {
759 let scope: std::collections::HashSet<EntityId> = scope_ids.iter().copied().collect();
760 if scope.is_empty() {
761 return Ok(());
762 }
763 let store = self.transaction.get_store();
764
765 let mut left_keys: std::collections::HashSet<EntityId> = std::collections::HashSet::new();
767 for (left, rights) in snap.jn_system_from_root_system.iter() {
768 if rights.iter().any(|rid| scope.contains(rid)) {
769 left_keys.insert(*left);
770 }
771 }
772 {
773 let live_jn = read_or_recover(&store.jn_system_from_root_system);
774 for (left, rights) in live_jn.iter() {
775 if rights.iter().any(|rid| scope.contains(rid)) {
776 left_keys.insert(*left);
777 }
778 }
779 }
780
781 for left in left_keys {
782 let snap_list: Vec<EntityId> = snap
783 .jn_system_from_root_system
784 .get(&left)
785 .cloned()
786 .unwrap_or_default();
787 let new_list = {
788 let live_jn = read_or_recover(&store.jn_system_from_root_system);
789 let live_list: Vec<EntityId> = live_jn.get(&left).cloned().unwrap_or_default();
790 let reconciled = crate::database::hashmap_store::reconcile_backref_list(
791 &live_list, &snap_list, &scope,
792 );
793 if reconciled == live_list {
794 None
795 } else {
796 Some(reconciled)
797 }
798 };
799 if let Some(reconciled) = new_list {
800 write_or_recover(&store.jn_system_from_root_system).insert(left, reconciled);
801 event_buffer.push(Event {
802 origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
803 ids: vec![left],
804 data: None,
805 });
806 }
807 }
808 Ok(())
809 }
810}
811
812pub struct SystemRepositoryRO<'a> {
813 table: Box<dyn SystemTableRO + 'a>,
814}
815impl<'a> SystemRepositoryRO<'a> {
816 pub fn new(table: Box<dyn SystemTableRO + 'a>) -> Self {
817 SystemRepositoryRO { table }
818 }
819 pub fn get(&self, id: &EntityId) -> Result<Option<System>, RepositoryError> {
820 self.table.get(id)
821 }
822 pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<System>>, RepositoryError> {
823 self.table.get_multi(ids)
824 }
825 pub fn get_all(&self) -> Result<Vec<System>, RepositoryError> {
826 self.table.get_all()
827 }
828 pub fn get_relationship(
829 &self,
830 id: &EntityId,
831 field: &SystemRelationshipField,
832 ) -> Result<Vec<EntityId>, RepositoryError> {
833 self.table.get_relationship(id, field)
834 }
835 pub fn get_relationship_many(
836 &self,
837 ids: &[EntityId],
838 field: &SystemRelationshipField,
839 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
840 self.table.get_relationship_many(ids, field)
841 }
842 pub fn get_relationship_count(
843 &self,
844 id: &EntityId,
845 field: &SystemRelationshipField,
846 ) -> Result<usize, RepositoryError> {
847 self.table.get_relationship_count(id, field)
848 }
849 pub fn get_relationship_in_range(
850 &self,
851 id: &EntityId,
852 field: &SystemRelationshipField,
853 offset: usize,
854 limit: usize,
855 ) -> Result<Vec<EntityId>, RepositoryError> {
856 self.table
857 .get_relationship_in_range(id, field, offset, limit)
858 }
859 pub fn get_relationships_from_right_ids(
860 &self,
861 field: &SystemRelationshipField,
862 right_ids: &[EntityId],
863 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
864 self.table
865 .get_relationships_from_right_ids(field, right_ids)
866 }
867}