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