Skip to main content

common/direct_access/document/
document_repository.rs

1// Generated by Qleany v1.7.3 from common_entity_repository.tera
2
3use 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,
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}
94
95pub trait DocumentTableRO {
96    fn get(&self, id: &EntityId) -> Result<Option<Document>, RepositoryError>;
97    fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Document>>, RepositoryError>;
98    fn get_all(&self) -> Result<Vec<Document>, RepositoryError>;
99    fn get_relationship(
100        &self,
101        id: &EntityId,
102        field: &DocumentRelationshipField,
103    ) -> Result<Vec<EntityId>, RepositoryError>;
104    fn get_relationship_many(
105        &self,
106        ids: &[EntityId],
107        field: &DocumentRelationshipField,
108    ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError>;
109    fn get_relationship_count(
110        &self,
111        id: &EntityId,
112        field: &DocumentRelationshipField,
113    ) -> Result<usize, RepositoryError>;
114    fn get_relationship_in_range(
115        &self,
116        id: &EntityId,
117        field: &DocumentRelationshipField,
118        offset: usize,
119        limit: usize,
120    ) -> Result<Vec<EntityId>, RepositoryError>;
121    fn get_relationships_from_right_ids(
122        &self,
123        field: &DocumentRelationshipField,
124        right_ids: &[EntityId],
125    ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError>;
126}
127
128pub struct DocumentRepository<'a> {
129    table: Box<dyn DocumentTable + 'a>,
130    transaction: &'a Transaction,
131}
132
133impl<'a> DocumentRepository<'a> {
134    pub fn new(table: Box<dyn DocumentTable + 'a>, transaction: &'a Transaction) -> Self {
135        DocumentRepository { table, transaction }
136    }
137
138    pub fn create_orphan(
139        &mut self,
140        event_buffer: &mut EventBuffer,
141        entity: &Document,
142    ) -> Result<Document, RepositoryError> {
143        let new = self.table.create(entity)?;
144        event_buffer.push(Event {
145            origin: Origin::DirectAccess(DirectAccessEntity::Document(EntityEvent::Created)),
146            ids: vec![new.id],
147            data: None,
148        });
149        Ok(new)
150    }
151
152    pub fn create_orphan_multi(
153        &mut self,
154        event_buffer: &mut EventBuffer,
155        entities: &[Document],
156    ) -> Result<Vec<Document>, RepositoryError> {
157        let new_entities = self.table.create_multi(entities)?;
158        event_buffer.push(Event {
159            origin: Origin::DirectAccess(DirectAccessEntity::Document(EntityEvent::Created)),
160            ids: new_entities.iter().map(|e| e.id).collect(),
161            data: None,
162        });
163        Ok(new_entities)
164    }
165    pub fn create(
166        &mut self,
167        event_buffer: &mut EventBuffer,
168        entity: &Document,
169        owner_id: EntityId,
170        _index: i32,
171    ) -> Result<Document, RepositoryError> {
172        let new = self.table.create(entity)?;
173        let created_id = new.id;
174
175        let mut relationship_ids = self.get_relationships_from_owner(&owner_id)?;
176        if relationship_ids.is_empty() {
177            relationship_ids = vec![created_id];
178        } else {
179            // Replace existing relationship: cascade-remove old entities first
180            self.remove_multi(event_buffer, &relationship_ids)?;
181            relationship_ids = vec![created_id];
182        }
183
184        self.set_relationships_in_owner(event_buffer, &owner_id, &relationship_ids)?;
185        event_buffer.push(Event {
186            origin: Origin::DirectAccess(DirectAccessEntity::Document(EntityEvent::Created)),
187            ids: vec![created_id],
188            data: None,
189        });
190        Ok(new)
191    }
192
193    pub fn create_multi(
194        &mut self,
195        event_buffer: &mut EventBuffer,
196        entities: &[Document],
197        owner_id: EntityId,
198        _index: i32,
199    ) -> Result<Vec<Document>, RepositoryError> {
200        let new_entities = self.table.create_multi(entities)?;
201        let created_ids: Vec<EntityId> = new_entities.iter().map(|e| e.id).collect();
202
203        let mut relationship_ids = self.get_relationships_from_owner(&owner_id)?;
204        if relationship_ids.is_empty() {
205            relationship_ids = created_ids.clone();
206        } else {
207            self.remove_multi(event_buffer, &relationship_ids)?;
208            relationship_ids = created_ids.clone();
209        }
210
211        self.set_relationships_in_owner(event_buffer, &owner_id, &relationship_ids)?;
212        event_buffer.push(Event {
213            origin: Origin::DirectAccess(DirectAccessEntity::Document(EntityEvent::Created)),
214            ids: created_ids,
215            data: None,
216        });
217        Ok(new_entities)
218    }
219
220    pub fn get(&self, id: &EntityId) -> Result<Option<Document>, RepositoryError> {
221        self.table.get(id)
222    }
223    pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Document>>, RepositoryError> {
224        self.table.get_multi(ids)
225    }
226    pub fn get_all(&self) -> Result<Vec<Document>, RepositoryError> {
227        self.table.get_all()
228    }
229
230    pub fn update(
231        &mut self,
232        event_buffer: &mut EventBuffer,
233        entity: &Document,
234    ) -> Result<Document, RepositoryError> {
235        let updated = self.table.update(entity)?;
236        event_buffer.push(Event {
237            origin: Origin::DirectAccess(DirectAccessEntity::Document(EntityEvent::Updated)),
238            ids: vec![updated.id],
239            data: None,
240        });
241        Ok(updated)
242    }
243
244    pub fn update_multi(
245        &mut self,
246        event_buffer: &mut EventBuffer,
247        entities: &[Document],
248    ) -> Result<Vec<Document>, RepositoryError> {
249        let updated = self.table.update_multi(entities)?;
250        event_buffer.push(Event {
251            origin: Origin::DirectAccess(DirectAccessEntity::Document(EntityEvent::Updated)),
252            ids: updated.iter().map(|e| e.id).collect(),
253            data: None,
254        });
255        Ok(updated)
256    }
257
258    pub fn update_with_relationships(
259        &mut self,
260        event_buffer: &mut EventBuffer,
261        entity: &Document,
262    ) -> Result<Document, RepositoryError> {
263        let updated = self.table.update_with_relationships(entity)?;
264        event_buffer.push(Event {
265            origin: Origin::DirectAccess(DirectAccessEntity::Document(EntityEvent::Updated)),
266            ids: vec![updated.id],
267            data: None,
268        });
269        Ok(updated)
270    }
271
272    pub fn update_with_relationships_multi(
273        &mut self,
274        event_buffer: &mut EventBuffer,
275        entities: &[Document],
276    ) -> Result<Vec<Document>, RepositoryError> {
277        let updated = self.table.update_with_relationships_multi(entities)?;
278        event_buffer.push(Event {
279            origin: Origin::DirectAccess(DirectAccessEntity::Document(EntityEvent::Updated)),
280            ids: updated.iter().map(|e| e.id).collect(),
281            data: None,
282        });
283        Ok(updated)
284    }
285
286    pub fn remove(
287        &mut self,
288        event_buffer: &mut EventBuffer,
289        id: &EntityId,
290    ) -> Result<(), RepositoryError> {
291        let entity = match self.table.get(id)? {
292            Some(e) => e,
293            None => return Ok(()),
294        };
295        // get all strong forward relationship fields
296
297        let frames = entity.frames.clone();
298        let resources = entity.resources.clone();
299        let lists = entity.lists.clone();
300        let tables = entity.tables.clone();
301
302        // remove all strong relationships, initiating a cascade remove
303
304        repository_factory::write::create_frame_repository(self.transaction)?
305            .remove_multi(event_buffer, &frames)?;
306        repository_factory::write::create_resource_repository(self.transaction)?
307            .remove_multi(event_buffer, &resources)?;
308        repository_factory::write::create_list_repository(self.transaction)?
309            .remove_multi(event_buffer, &lists)?;
310        repository_factory::write::create_table_repository(self.transaction)?
311            .remove_multi(event_buffer, &tables)?;
312        // Before removal, find which owner(s) reference this entity
313        let affected_owner_ids: Vec<EntityId> = {
314            let owner_repo = repository_factory::write::create_root_repository(self.transaction)?;
315            owner_repo
316                .get_relationships_from_right_ids(&RootRelationshipField::Document, &[*id])?
317                .into_iter()
318                .map(|(owner_id, _)| owner_id)
319                .collect()
320        };
321        // Save each owner's current relationship IDs (properly ordered via get_relationships_from_owner)
322        let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
323            std::collections::HashMap::new();
324        for owner_id in &affected_owner_ids {
325            owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
326        }
327
328        // remove entity
329        self.table.remove(id)?;
330        event_buffer.push(Event {
331            origin: Origin::DirectAccess(DirectAccessEntity::Document(EntityEvent::Removed)),
332            ids: vec![*id],
333            data: None,
334        });
335        // Update each affected owner's relationship to exclude removed ID (emits Updated event)
336        for owner_id in &affected_owner_ids {
337            if let Some(rel_ids) = owner_rel_before.get(owner_id) {
338                let updated: Vec<EntityId> =
339                    rel_ids.iter().copied().filter(|rid| *rid != *id).collect();
340                self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
341            }
342        }
343
344        Ok(())
345    }
346
347    pub fn remove_multi(
348        &mut self,
349        event_buffer: &mut EventBuffer,
350        ids: &[EntityId],
351    ) -> Result<(), RepositoryError> {
352        let entities = self.table.get_multi(ids)?;
353        if entities.is_empty() || entities.iter().all(|e| e.is_none()) {
354            return Ok(());
355        }
356
357        // get all strong forward relationship fields
358
359        let mut frames_ids: Vec<EntityId> = entities
360            .iter()
361            .flat_map(|entity| entity.as_ref().map(|entity| entity.frames.clone()))
362            .flatten()
363            .collect();
364        // remove duplicates
365        frames_ids.sort();
366        frames_ids.dedup();
367        let mut resources_ids: Vec<EntityId> = entities
368            .iter()
369            .flat_map(|entity| entity.as_ref().map(|entity| entity.resources.clone()))
370            .flatten()
371            .collect();
372        // remove duplicates
373        resources_ids.sort();
374        resources_ids.dedup();
375        let mut lists_ids: Vec<EntityId> = entities
376            .iter()
377            .flat_map(|entity| entity.as_ref().map(|entity| entity.lists.clone()))
378            .flatten()
379            .collect();
380        // remove duplicates
381        lists_ids.sort();
382        lists_ids.dedup();
383        let mut tables_ids: Vec<EntityId> = entities
384            .iter()
385            .flat_map(|entity| entity.as_ref().map(|entity| entity.tables.clone()))
386            .flatten()
387            .collect();
388        // remove duplicates
389        tables_ids.sort();
390        tables_ids.dedup();
391
392        // remove all strong relationships, initiating a cascade remove
393
394        repository_factory::write::create_frame_repository(self.transaction)?
395            .remove_multi(event_buffer, &frames_ids)?;
396        repository_factory::write::create_resource_repository(self.transaction)?
397            .remove_multi(event_buffer, &resources_ids)?;
398        repository_factory::write::create_list_repository(self.transaction)?
399            .remove_multi(event_buffer, &lists_ids)?;
400        repository_factory::write::create_table_repository(self.transaction)?
401            .remove_multi(event_buffer, &tables_ids)?;
402        // Before removal, find which owner(s) reference these entities
403        let affected_owner_ids: Vec<EntityId> = {
404            let owner_repo = repository_factory::write::create_root_repository(self.transaction)?;
405            owner_repo
406                .get_relationships_from_right_ids(&RootRelationshipField::Document, ids)?
407                .into_iter()
408                .map(|(owner_id, _)| owner_id)
409                .collect()
410        };
411        // Save each owner's current relationship IDs (properly ordered via get_relationships_from_owner)
412        let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
413            std::collections::HashMap::new();
414        for owner_id in &affected_owner_ids {
415            owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
416        }
417
418        self.table.remove_multi(ids)?;
419        event_buffer.push(Event {
420            origin: Origin::DirectAccess(DirectAccessEntity::Document(EntityEvent::Removed)),
421            ids: ids.into(),
422            data: None,
423        });
424        // Update each affected owner's relationship to exclude removed IDs (emits Updated event)
425        {
426            let removed_set: std::collections::HashSet<EntityId> = ids.iter().copied().collect();
427            for owner_id in &affected_owner_ids {
428                if let Some(rel_ids) = owner_rel_before.get(owner_id) {
429                    let updated: Vec<EntityId> = rel_ids
430                        .iter()
431                        .copied()
432                        .filter(|rid| !removed_set.contains(rid))
433                        .collect();
434                    self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
435                }
436            }
437        }
438
439        Ok(())
440    }
441    pub fn get_relationship(
442        &self,
443        id: &EntityId,
444        field: &DocumentRelationshipField,
445    ) -> Result<Vec<EntityId>, RepositoryError> {
446        self.table.get_relationship(id, field)
447    }
448    pub fn get_relationship_many(
449        &self,
450        ids: &[EntityId],
451        field: &DocumentRelationshipField,
452    ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
453        self.table.get_relationship_many(ids, field)
454    }
455    pub fn get_relationship_count(
456        &self,
457        id: &EntityId,
458        field: &DocumentRelationshipField,
459    ) -> Result<usize, RepositoryError> {
460        self.table.get_relationship_count(id, field)
461    }
462    pub fn get_relationship_in_range(
463        &self,
464        id: &EntityId,
465        field: &DocumentRelationshipField,
466        offset: usize,
467        limit: usize,
468    ) -> Result<Vec<EntityId>, RepositoryError> {
469        self.table
470            .get_relationship_in_range(id, field, offset, limit)
471    }
472    pub fn get_relationships_from_right_ids(
473        &self,
474        field: &DocumentRelationshipField,
475        right_ids: &[EntityId],
476    ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
477        self.table
478            .get_relationships_from_right_ids(field, right_ids)
479    }
480
481    pub fn set_relationship_multi(
482        &mut self,
483        event_buffer: &mut EventBuffer,
484        field: &DocumentRelationshipField,
485        relationships: Vec<(EntityId, Vec<EntityId>)>,
486    ) -> Result<(), RepositoryError> {
487        // Validate that all right_ids exist
488        let all_right_ids: Vec<EntityId> = relationships
489            .iter()
490            .flat_map(|(_, ids)| ids.iter().copied())
491            .collect();
492        if !all_right_ids.is_empty() {
493            match field {
494                DocumentRelationshipField::Frames => {
495                    let child_repo =
496                        repository_factory::write::create_frame_repository(self.transaction)?;
497                    let found = child_repo.get_multi(&all_right_ids)?;
498                    let missing: Vec<_> = all_right_ids
499                        .iter()
500                        .zip(found.iter())
501                        .filter(|(_, entity)| entity.is_none())
502                        .map(|(id, _)| *id)
503                        .collect();
504                    if !missing.is_empty() {
505                        return Err(RepositoryError::MissingRelationshipTarget {
506                            operation: "set_relationship_multi",
507                            ids: missing,
508                        });
509                    }
510                }
511                DocumentRelationshipField::Lists => {
512                    let child_repo =
513                        repository_factory::write::create_list_repository(self.transaction)?;
514                    let found = child_repo.get_multi(&all_right_ids)?;
515                    let missing: Vec<_> = all_right_ids
516                        .iter()
517                        .zip(found.iter())
518                        .filter(|(_, entity)| entity.is_none())
519                        .map(|(id, _)| *id)
520                        .collect();
521                    if !missing.is_empty() {
522                        return Err(RepositoryError::MissingRelationshipTarget {
523                            operation: "set_relationship_multi",
524                            ids: missing,
525                        });
526                    }
527                }
528                DocumentRelationshipField::Resources => {
529                    let child_repo =
530                        repository_factory::write::create_resource_repository(self.transaction)?;
531                    let found = child_repo.get_multi(&all_right_ids)?;
532                    let missing: Vec<_> = all_right_ids
533                        .iter()
534                        .zip(found.iter())
535                        .filter(|(_, entity)| entity.is_none())
536                        .map(|(id, _)| *id)
537                        .collect();
538                    if !missing.is_empty() {
539                        return Err(RepositoryError::MissingRelationshipTarget {
540                            operation: "set_relationship_multi",
541                            ids: missing,
542                        });
543                    }
544                }
545                DocumentRelationshipField::Tables => {
546                    let child_repo =
547                        repository_factory::write::create_table_repository(self.transaction)?;
548                    let found = child_repo.get_multi(&all_right_ids)?;
549                    let missing: Vec<_> = all_right_ids
550                        .iter()
551                        .zip(found.iter())
552                        .filter(|(_, entity)| entity.is_none())
553                        .map(|(id, _)| *id)
554                        .collect();
555                    if !missing.is_empty() {
556                        return Err(RepositoryError::MissingRelationshipTarget {
557                            operation: "set_relationship_multi",
558                            ids: missing,
559                        });
560                    }
561                }
562            }
563        }
564        self.table
565            .set_relationship_multi(field, relationships.clone())?;
566        for (left_id, right_ids) in relationships {
567            event_buffer.push(Event {
568                origin: Origin::DirectAccess(DirectAccessEntity::Document(EntityEvent::Updated)),
569                ids: vec![left_id],
570                data: Some(format!(
571                    "{}:{}",
572                    field,
573                    right_ids
574                        .iter()
575                        .map(|id| id.to_string())
576                        .collect::<Vec<_>>()
577                        .join(",")
578                )),
579            });
580        }
581        Ok(())
582    }
583
584    pub fn set_relationship(
585        &mut self,
586        event_buffer: &mut EventBuffer,
587        id: &EntityId,
588        field: &DocumentRelationshipField,
589        right_ids: &[EntityId],
590    ) -> Result<(), RepositoryError> {
591        // Validate that all right_ids exist
592        if !right_ids.is_empty() {
593            match field {
594                DocumentRelationshipField::Frames => {
595                    let child_repo =
596                        repository_factory::write::create_frame_repository(self.transaction)?;
597                    let found = child_repo.get_multi(right_ids)?;
598                    let missing: Vec<_> = right_ids
599                        .iter()
600                        .zip(found.iter())
601                        .filter(|(_, entity)| entity.is_none())
602                        .map(|(id, _)| *id)
603                        .collect();
604                    if !missing.is_empty() {
605                        return Err(RepositoryError::MissingRelationshipTarget {
606                            operation: "set_relationship",
607                            ids: missing,
608                        });
609                    }
610                }
611                DocumentRelationshipField::Lists => {
612                    let child_repo =
613                        repository_factory::write::create_list_repository(self.transaction)?;
614                    let found = child_repo.get_multi(right_ids)?;
615                    let missing: Vec<_> = right_ids
616                        .iter()
617                        .zip(found.iter())
618                        .filter(|(_, entity)| entity.is_none())
619                        .map(|(id, _)| *id)
620                        .collect();
621                    if !missing.is_empty() {
622                        return Err(RepositoryError::MissingRelationshipTarget {
623                            operation: "set_relationship",
624                            ids: missing,
625                        });
626                    }
627                }
628                DocumentRelationshipField::Resources => {
629                    let child_repo =
630                        repository_factory::write::create_resource_repository(self.transaction)?;
631                    let found = child_repo.get_multi(right_ids)?;
632                    let missing: Vec<_> = right_ids
633                        .iter()
634                        .zip(found.iter())
635                        .filter(|(_, entity)| entity.is_none())
636                        .map(|(id, _)| *id)
637                        .collect();
638                    if !missing.is_empty() {
639                        return Err(RepositoryError::MissingRelationshipTarget {
640                            operation: "set_relationship",
641                            ids: missing,
642                        });
643                    }
644                }
645                DocumentRelationshipField::Tables => {
646                    let child_repo =
647                        repository_factory::write::create_table_repository(self.transaction)?;
648                    let found = child_repo.get_multi(right_ids)?;
649                    let missing: Vec<_> = right_ids
650                        .iter()
651                        .zip(found.iter())
652                        .filter(|(_, entity)| entity.is_none())
653                        .map(|(id, _)| *id)
654                        .collect();
655                    if !missing.is_empty() {
656                        return Err(RepositoryError::MissingRelationshipTarget {
657                            operation: "set_relationship",
658                            ids: missing,
659                        });
660                    }
661                }
662            }
663        }
664        self.table.set_relationship(id, field, right_ids)?;
665        event_buffer.push(Event {
666            origin: Origin::DirectAccess(DirectAccessEntity::Document(EntityEvent::Updated)),
667            ids: vec![*id],
668            data: Some(format!(
669                "{}:{}",
670                field,
671                right_ids
672                    .iter()
673                    .map(|id| id.to_string())
674                    .collect::<Vec<_>>()
675                    .join(",")
676            )),
677        });
678        Ok(())
679    }
680
681    pub fn move_relationship_ids(
682        &mut self,
683        event_buffer: &mut EventBuffer,
684        id: &EntityId,
685        field: &DocumentRelationshipField,
686        ids_to_move: &[EntityId],
687        new_index: i32,
688    ) -> Result<Vec<EntityId>, RepositoryError> {
689        let reordered = self
690            .table
691            .move_relationship_ids(id, field, ids_to_move, new_index)?;
692        event_buffer.push(Event {
693            origin: Origin::DirectAccess(DirectAccessEntity::Document(EntityEvent::Updated)),
694            ids: vec![*id],
695            data: Some(format!(
696                "{}:{}",
697                field,
698                reordered
699                    .iter()
700                    .map(|id| id.to_string())
701                    .collect::<Vec<_>>()
702                    .join(",")
703            )),
704        });
705        Ok(reordered)
706    }
707    pub fn get_relationships_from_owner(
708        &self,
709        owner_id: &EntityId,
710    ) -> Result<Vec<EntityId>, RepositoryError> {
711        let repo = repository_factory::write::create_root_repository(self.transaction)?;
712        repo.get_relationship(owner_id, &RootRelationshipField::Document)
713    }
714
715    pub fn set_relationships_in_owner(
716        &mut self,
717        event_buffer: &mut EventBuffer,
718        owner_id: &EntityId,
719        ids: &[EntityId],
720    ) -> Result<(), RepositoryError> {
721        let mut repo = repository_factory::write::create_root_repository(self.transaction)?;
722        repo.set_relationship(
723            event_buffer,
724            owner_id,
725            &RootRelationshipField::Document,
726            ids,
727        )
728    }
729
730    pub fn snapshot(&self, _ids: &[EntityId]) -> Result<EntityTreeSnapshot, RepositoryError> {
731        let store_snap = self.transaction.snapshot_store();
732        Ok(EntityTreeSnapshot {
733            store_snapshot: Some(store_snap),
734        })
735    }
736
737    pub fn restore(
738        &mut self,
739        event_buffer: &mut EventBuffer,
740        snap: &EntityTreeSnapshot,
741    ) -> Result<(), RepositoryError> {
742        let store_snap = snap
743            .store_snapshot
744            .as_ref()
745            .ok_or_else(|| RepositoryError::Serialization("missing store snapshot".into()))?;
746        self.transaction.restore_store(store_snap);
747
748        let store = self.transaction.get_store();
749
750        let mut emit = |entity: DirectAccessEntity, ids: Vec<EntityId>| {
751            if !ids.is_empty() {
752                event_buffer.push(Event {
753                    origin: Origin::DirectAccess(entity),
754                    ids,
755                    data: None,
756                });
757            }
758        };
759
760        // Emit Created events for this entity
761        let document_ids: Vec<_> = store.documents.read().unwrap().keys().copied().collect();
762        emit(
763            DirectAccessEntity::Document(EntityEvent::Created),
764            document_ids.clone(),
765        );
766        emit(
767            DirectAccessEntity::Document(EntityEvent::Updated),
768            document_ids,
769        );
770
771        // Emit Created events for strong children
772
773        {
774            let child_ids: Vec<_> = store.frames.read().unwrap().keys().copied().collect();
775            emit(
776                DirectAccessEntity::Frame(EntityEvent::Created),
777                child_ids.clone(),
778            );
779            emit(DirectAccessEntity::Frame(EntityEvent::Updated), child_ids);
780        }
781        {
782            let child_ids: Vec<_> = store.resources.read().unwrap().keys().copied().collect();
783            emit(
784                DirectAccessEntity::Resource(EntityEvent::Created),
785                child_ids.clone(),
786            );
787        }
788        {
789            let child_ids: Vec<_> = store.lists.read().unwrap().keys().copied().collect();
790            emit(
791                DirectAccessEntity::List(EntityEvent::Created),
792                child_ids.clone(),
793            );
794        }
795        {
796            let child_ids: Vec<_> = store.tables.read().unwrap().keys().copied().collect();
797            emit(
798                DirectAccessEntity::Table(EntityEvent::Created),
799                child_ids.clone(),
800            );
801            emit(DirectAccessEntity::Table(EntityEvent::Updated), child_ids);
802        }
803
804        Ok(())
805    }
806}
807
808pub struct DocumentRepositoryRO<'a> {
809    table: Box<dyn DocumentTableRO + 'a>,
810}
811impl<'a> DocumentRepositoryRO<'a> {
812    pub fn new(table: Box<dyn DocumentTableRO + 'a>) -> Self {
813        DocumentRepositoryRO { table }
814    }
815    pub fn get(&self, id: &EntityId) -> Result<Option<Document>, RepositoryError> {
816        self.table.get(id)
817    }
818    pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Document>>, RepositoryError> {
819        self.table.get_multi(ids)
820    }
821    pub fn get_all(&self) -> Result<Vec<Document>, RepositoryError> {
822        self.table.get_all()
823    }
824    pub fn get_relationship(
825        &self,
826        id: &EntityId,
827        field: &DocumentRelationshipField,
828    ) -> Result<Vec<EntityId>, RepositoryError> {
829        self.table.get_relationship(id, field)
830    }
831    pub fn get_relationship_many(
832        &self,
833        ids: &[EntityId],
834        field: &DocumentRelationshipField,
835    ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
836        self.table.get_relationship_many(ids, field)
837    }
838    pub fn get_relationship_count(
839        &self,
840        id: &EntityId,
841        field: &DocumentRelationshipField,
842    ) -> Result<usize, RepositoryError> {
843        self.table.get_relationship_count(id, field)
844    }
845    pub fn get_relationship_in_range(
846        &self,
847        id: &EntityId,
848        field: &DocumentRelationshipField,
849        offset: usize,
850        limit: usize,
851    ) -> Result<Vec<EntityId>, RepositoryError> {
852        self.table
853            .get_relationship_in_range(id, field, offset, limit)
854    }
855    pub fn get_relationships_from_right_ids(
856        &self,
857        field: &DocumentRelationshipField,
858        right_ids: &[EntityId],
859    ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
860        self.table
861            .get_relationships_from_right_ids(field, right_ids)
862    }
863}