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