Skip to main content

common/direct_access/frame/
frame_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::Frame,
9    event::{DirectAccessEntity, EntityEvent, Event, EventBuffer, Origin},
10    snapshot::EntityTreeSnapshot,
11    types::EntityId,
12};
13
14use crate::direct_access::document::DocumentRelationshipField;
15use crate::error::RepositoryError;
16use serde::{Deserialize, Serialize};
17
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
19pub enum FrameRelationshipField {
20    Blocks,
21    ParentFrame,
22    Table,
23}
24
25impl Display for FrameRelationshipField {
26    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
27        write!(f, "{:?}", self)
28    }
29}
30
31pub trait FrameTable {
32    fn create(&mut self, entity: &Frame) -> Result<Frame, RepositoryError>;
33    fn create_multi(&mut self, entities: &[Frame]) -> Result<Vec<Frame>, RepositoryError>;
34    fn get(&self, id: &EntityId) -> Result<Option<Frame>, RepositoryError>;
35    fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Frame>>, RepositoryError>;
36    fn get_all(&self) -> Result<Vec<Frame>, RepositoryError>;
37    fn update(&mut self, entity: &Frame) -> Result<Frame, RepositoryError>;
38    fn update_multi(&mut self, entities: &[Frame]) -> Result<Vec<Frame>, RepositoryError>;
39    fn update_with_relationships(&mut self, entity: &Frame) -> Result<Frame, RepositoryError>;
40    fn update_with_relationships_multi(
41        &mut self,
42        entities: &[Frame],
43    ) -> Result<Vec<Frame>, RepositoryError>;
44    fn remove(&mut self, id: &EntityId) -> Result<(), RepositoryError>;
45    fn remove_multi(&mut self, ids: &[EntityId]) -> Result<(), RepositoryError>;
46    fn get_relationship(
47        &self,
48        id: &EntityId,
49        field: &FrameRelationshipField,
50    ) -> Result<Vec<EntityId>, RepositoryError>;
51    fn get_relationship_many(
52        &self,
53        ids: &[EntityId],
54        field: &FrameRelationshipField,
55    ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError>;
56    fn get_relationship_count(
57        &self,
58        id: &EntityId,
59        field: &FrameRelationshipField,
60    ) -> Result<usize, RepositoryError>;
61    fn get_relationship_in_range(
62        &self,
63        id: &EntityId,
64        field: &FrameRelationshipField,
65        offset: usize,
66        limit: usize,
67    ) -> Result<Vec<EntityId>, RepositoryError>;
68    fn get_relationships_from_right_ids(
69        &self,
70        field: &FrameRelationshipField,
71        right_ids: &[EntityId],
72    ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError>;
73    fn set_relationship_multi(
74        &mut self,
75        field: &FrameRelationshipField,
76        relationships: Vec<(EntityId, Vec<EntityId>)>,
77    ) -> Result<(), RepositoryError>;
78    fn set_relationship(
79        &mut self,
80        id: &EntityId,
81        field: &FrameRelationshipField,
82        right_ids: &[EntityId],
83    ) -> Result<(), RepositoryError>;
84    fn move_relationship_ids(
85        &mut self,
86        id: &EntityId,
87        field: &FrameRelationshipField,
88        ids_to_move: &[EntityId],
89        new_index: i32,
90    ) -> Result<Vec<EntityId>, RepositoryError>;
91}
92
93pub trait FrameTableRO {
94    fn get(&self, id: &EntityId) -> Result<Option<Frame>, RepositoryError>;
95    fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Frame>>, RepositoryError>;
96    fn get_all(&self) -> Result<Vec<Frame>, RepositoryError>;
97    fn get_relationship(
98        &self,
99        id: &EntityId,
100        field: &FrameRelationshipField,
101    ) -> Result<Vec<EntityId>, RepositoryError>;
102    fn get_relationship_many(
103        &self,
104        ids: &[EntityId],
105        field: &FrameRelationshipField,
106    ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError>;
107    fn get_relationship_count(
108        &self,
109        id: &EntityId,
110        field: &FrameRelationshipField,
111    ) -> Result<usize, RepositoryError>;
112    fn get_relationship_in_range(
113        &self,
114        id: &EntityId,
115        field: &FrameRelationshipField,
116        offset: usize,
117        limit: usize,
118    ) -> Result<Vec<EntityId>, RepositoryError>;
119    fn get_relationships_from_right_ids(
120        &self,
121        field: &FrameRelationshipField,
122        right_ids: &[EntityId],
123    ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError>;
124}
125
126pub struct FrameRepository<'a> {
127    table: Box<dyn FrameTable + 'a>,
128    transaction: &'a Transaction,
129}
130
131impl<'a> FrameRepository<'a> {
132    pub fn new(table: Box<dyn FrameTable + 'a>, transaction: &'a Transaction) -> Self {
133        FrameRepository { table, transaction }
134    }
135
136    pub fn create_orphan(
137        &mut self,
138        event_buffer: &mut EventBuffer,
139        entity: &Frame,
140    ) -> Result<Frame, RepositoryError> {
141        let new = self.table.create(entity)?;
142        event_buffer.push(Event {
143            origin: Origin::DirectAccess(DirectAccessEntity::Frame(EntityEvent::Created)),
144            ids: vec![new.id],
145            data: None,
146        });
147        Ok(new)
148    }
149
150    pub fn create_orphan_multi(
151        &mut self,
152        event_buffer: &mut EventBuffer,
153        entities: &[Frame],
154    ) -> Result<Vec<Frame>, RepositoryError> {
155        let new_entities = self.table.create_multi(entities)?;
156        event_buffer.push(Event {
157            origin: Origin::DirectAccess(DirectAccessEntity::Frame(EntityEvent::Created)),
158            ids: new_entities.iter().map(|e| e.id).collect(),
159            data: None,
160        });
161        Ok(new_entities)
162    }
163    pub fn create(
164        &mut self,
165        event_buffer: &mut EventBuffer,
166        entity: &Frame,
167        owner_id: EntityId,
168        index: i32,
169    ) -> Result<Frame, RepositoryError> {
170        let new = self.table.create(entity)?;
171        let created_id = new.id;
172
173        let mut relationship_ids = self.get_relationships_from_owner(&owner_id)?;
174        // Insert at index
175        if index >= 0 && (index as usize) < relationship_ids.len() {
176            relationship_ids.insert(index as usize, created_id);
177        } else {
178            relationship_ids.push(created_id);
179        }
180
181        self.set_relationships_in_owner(event_buffer, &owner_id, &relationship_ids)?;
182        event_buffer.push(Event {
183            origin: Origin::DirectAccess(DirectAccessEntity::Frame(EntityEvent::Created)),
184            ids: vec![created_id],
185            data: None,
186        });
187        Ok(new)
188    }
189
190    pub fn create_multi(
191        &mut self,
192        event_buffer: &mut EventBuffer,
193        entities: &[Frame],
194        owner_id: EntityId,
195        index: i32,
196    ) -> Result<Vec<Frame>, RepositoryError> {
197        let new_entities = self.table.create_multi(entities)?;
198        let created_ids: Vec<EntityId> = new_entities.iter().map(|e| e.id).collect();
199
200        let mut relationship_ids = self.get_relationships_from_owner(&owner_id)?;
201        if index >= 0 && (index as usize) < relationship_ids.len() {
202            for (i, id) in created_ids.iter().enumerate() {
203                relationship_ids.insert(index as usize + i, *id);
204            }
205        } else {
206            relationship_ids.extend(created_ids.iter());
207        }
208
209        self.set_relationships_in_owner(event_buffer, &owner_id, &relationship_ids)?;
210        event_buffer.push(Event {
211            origin: Origin::DirectAccess(DirectAccessEntity::Frame(EntityEvent::Created)),
212            ids: created_ids,
213            data: None,
214        });
215        Ok(new_entities)
216    }
217
218    pub fn get(&self, id: &EntityId) -> Result<Option<Frame>, RepositoryError> {
219        self.table.get(id)
220    }
221    pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Frame>>, RepositoryError> {
222        self.table.get_multi(ids)
223    }
224    pub fn get_all(&self) -> Result<Vec<Frame>, RepositoryError> {
225        self.table.get_all()
226    }
227
228    pub fn update(
229        &mut self,
230        event_buffer: &mut EventBuffer,
231        entity: &Frame,
232    ) -> Result<Frame, RepositoryError> {
233        let updated = self.table.update(entity)?;
234        event_buffer.push(Event {
235            origin: Origin::DirectAccess(DirectAccessEntity::Frame(EntityEvent::Updated)),
236            ids: vec![updated.id],
237            data: None,
238        });
239        Ok(updated)
240    }
241
242    pub fn update_multi(
243        &mut self,
244        event_buffer: &mut EventBuffer,
245        entities: &[Frame],
246    ) -> Result<Vec<Frame>, RepositoryError> {
247        let updated = self.table.update_multi(entities)?;
248        event_buffer.push(Event {
249            origin: Origin::DirectAccess(DirectAccessEntity::Frame(EntityEvent::Updated)),
250            ids: updated.iter().map(|e| e.id).collect(),
251            data: None,
252        });
253        Ok(updated)
254    }
255
256    pub fn update_with_relationships(
257        &mut self,
258        event_buffer: &mut EventBuffer,
259        entity: &Frame,
260    ) -> Result<Frame, RepositoryError> {
261        let updated = self.table.update_with_relationships(entity)?;
262        event_buffer.push(Event {
263            origin: Origin::DirectAccess(DirectAccessEntity::Frame(EntityEvent::Updated)),
264            ids: vec![updated.id],
265            data: None,
266        });
267        Ok(updated)
268    }
269
270    pub fn update_with_relationships_multi(
271        &mut self,
272        event_buffer: &mut EventBuffer,
273        entities: &[Frame],
274    ) -> Result<Vec<Frame>, RepositoryError> {
275        let updated = self.table.update_with_relationships_multi(entities)?;
276        event_buffer.push(Event {
277            origin: Origin::DirectAccess(DirectAccessEntity::Frame(EntityEvent::Updated)),
278            ids: updated.iter().map(|e| e.id).collect(),
279            data: None,
280        });
281        Ok(updated)
282    }
283
284    pub fn remove(
285        &mut self,
286        event_buffer: &mut EventBuffer,
287        id: &EntityId,
288    ) -> Result<(), RepositoryError> {
289        let entity = match self.table.get(id)? {
290            Some(e) => e,
291            None => return Ok(()),
292        };
293        // get all strong forward relationship fields
294
295        let blocks = entity.blocks.clone();
296
297        // remove all strong relationships, initiating a cascade remove
298
299        repository_factory::write::create_block_repository(self.transaction)?
300            .remove_multi(event_buffer, &blocks)?;
301        // Before removal, find which owner(s) reference this entity
302        let affected_owner_ids: Vec<EntityId> = {
303            let owner_repo =
304                repository_factory::write::create_document_repository(self.transaction)?;
305            owner_repo
306                .get_relationships_from_right_ids(&DocumentRelationshipField::Frames, &[*id])?
307                .into_iter()
308                .map(|(owner_id, _)| owner_id)
309                .collect()
310        };
311        // Save each owner's current relationship IDs (properly ordered via get_relationships_from_owner)
312        let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
313            std::collections::HashMap::new();
314        for owner_id in &affected_owner_ids {
315            owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
316        }
317
318        // remove entity
319        self.table.remove(id)?;
320        event_buffer.push(Event {
321            origin: Origin::DirectAccess(DirectAccessEntity::Frame(EntityEvent::Removed)),
322            ids: vec![*id],
323            data: None,
324        });
325        // Update each affected owner's relationship to exclude removed ID (emits Updated event)
326        for owner_id in &affected_owner_ids {
327            if let Some(rel_ids) = owner_rel_before.get(owner_id) {
328                let updated: Vec<EntityId> =
329                    rel_ids.iter().copied().filter(|rid| *rid != *id).collect();
330                self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
331            }
332        }
333
334        Ok(())
335    }
336
337    pub fn remove_multi(
338        &mut self,
339        event_buffer: &mut EventBuffer,
340        ids: &[EntityId],
341    ) -> Result<(), RepositoryError> {
342        let entities = self.table.get_multi(ids)?;
343        if entities.is_empty() || entities.iter().all(|e| e.is_none()) {
344            return Ok(());
345        }
346
347        // get all strong forward relationship fields
348
349        let mut blocks_ids: Vec<EntityId> = entities
350            .iter()
351            .flat_map(|entity| entity.as_ref().map(|entity| entity.blocks.clone()))
352            .flatten()
353            .collect();
354        // remove duplicates
355        blocks_ids.sort();
356        blocks_ids.dedup();
357
358        // remove all strong relationships, initiating a cascade remove
359
360        repository_factory::write::create_block_repository(self.transaction)?
361            .remove_multi(event_buffer, &blocks_ids)?;
362        // Before removal, find which owner(s) reference these entities
363        let affected_owner_ids: Vec<EntityId> = {
364            let owner_repo =
365                repository_factory::write::create_document_repository(self.transaction)?;
366            owner_repo
367                .get_relationships_from_right_ids(&DocumentRelationshipField::Frames, ids)?
368                .into_iter()
369                .map(|(owner_id, _)| owner_id)
370                .collect()
371        };
372        // Save each owner's current relationship IDs (properly ordered via get_relationships_from_owner)
373        let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
374            std::collections::HashMap::new();
375        for owner_id in &affected_owner_ids {
376            owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
377        }
378
379        self.table.remove_multi(ids)?;
380        event_buffer.push(Event {
381            origin: Origin::DirectAccess(DirectAccessEntity::Frame(EntityEvent::Removed)),
382            ids: ids.into(),
383            data: None,
384        });
385        // Update each affected owner's relationship to exclude removed IDs (emits Updated event)
386        {
387            let removed_set: std::collections::HashSet<EntityId> = ids.iter().copied().collect();
388            for owner_id in &affected_owner_ids {
389                if let Some(rel_ids) = owner_rel_before.get(owner_id) {
390                    let updated: Vec<EntityId> = rel_ids
391                        .iter()
392                        .copied()
393                        .filter(|rid| !removed_set.contains(rid))
394                        .collect();
395                    self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
396                }
397            }
398        }
399
400        Ok(())
401    }
402    pub fn get_relationship(
403        &self,
404        id: &EntityId,
405        field: &FrameRelationshipField,
406    ) -> Result<Vec<EntityId>, RepositoryError> {
407        self.table.get_relationship(id, field)
408    }
409    pub fn get_relationship_many(
410        &self,
411        ids: &[EntityId],
412        field: &FrameRelationshipField,
413    ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
414        self.table.get_relationship_many(ids, field)
415    }
416    pub fn get_relationship_count(
417        &self,
418        id: &EntityId,
419        field: &FrameRelationshipField,
420    ) -> Result<usize, RepositoryError> {
421        self.table.get_relationship_count(id, field)
422    }
423    pub fn get_relationship_in_range(
424        &self,
425        id: &EntityId,
426        field: &FrameRelationshipField,
427        offset: usize,
428        limit: usize,
429    ) -> Result<Vec<EntityId>, RepositoryError> {
430        self.table
431            .get_relationship_in_range(id, field, offset, limit)
432    }
433    pub fn get_relationships_from_right_ids(
434        &self,
435        field: &FrameRelationshipField,
436        right_ids: &[EntityId],
437    ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
438        self.table
439            .get_relationships_from_right_ids(field, right_ids)
440    }
441
442    pub fn set_relationship_multi(
443        &mut self,
444        event_buffer: &mut EventBuffer,
445        field: &FrameRelationshipField,
446        relationships: Vec<(EntityId, Vec<EntityId>)>,
447    ) -> Result<(), RepositoryError> {
448        // Validate that all right_ids exist
449        let all_right_ids: Vec<EntityId> = relationships
450            .iter()
451            .flat_map(|(_, ids)| ids.iter().copied())
452            .collect();
453        if !all_right_ids.is_empty() {
454            match field {
455                FrameRelationshipField::Blocks => {
456                    let child_repo =
457                        repository_factory::write::create_block_repository(self.transaction)?;
458                    let found = child_repo.get_multi(&all_right_ids)?;
459                    let missing: Vec<_> = all_right_ids
460                        .iter()
461                        .zip(found.iter())
462                        .filter(|(_, entity)| entity.is_none())
463                        .map(|(id, _)| *id)
464                        .collect();
465                    if !missing.is_empty() {
466                        return Err(RepositoryError::MissingRelationshipTarget {
467                            operation: "set_relationship_multi",
468                            ids: missing,
469                        });
470                    }
471                }
472                FrameRelationshipField::ParentFrame => {
473                    let child_repo =
474                        repository_factory::write::create_frame_repository(self.transaction)?;
475                    let found = child_repo.get_multi(&all_right_ids)?;
476                    let missing: Vec<_> = all_right_ids
477                        .iter()
478                        .zip(found.iter())
479                        .filter(|(_, entity)| entity.is_none())
480                        .map(|(id, _)| *id)
481                        .collect();
482                    if !missing.is_empty() {
483                        return Err(RepositoryError::MissingRelationshipTarget {
484                            operation: "set_relationship_multi",
485                            ids: missing,
486                        });
487                    }
488                }
489                FrameRelationshipField::Table => {
490                    let child_repo =
491                        repository_factory::write::create_table_repository(self.transaction)?;
492                    let found = child_repo.get_multi(&all_right_ids)?;
493                    let missing: Vec<_> = all_right_ids
494                        .iter()
495                        .zip(found.iter())
496                        .filter(|(_, entity)| entity.is_none())
497                        .map(|(id, _)| *id)
498                        .collect();
499                    if !missing.is_empty() {
500                        return Err(RepositoryError::MissingRelationshipTarget {
501                            operation: "set_relationship_multi",
502                            ids: missing,
503                        });
504                    }
505                }
506            }
507        }
508        self.table
509            .set_relationship_multi(field, relationships.clone())?;
510        for (left_id, right_ids) in relationships {
511            event_buffer.push(Event {
512                origin: Origin::DirectAccess(DirectAccessEntity::Frame(EntityEvent::Updated)),
513                ids: vec![left_id],
514                data: Some(format!(
515                    "{}:{}",
516                    field,
517                    right_ids
518                        .iter()
519                        .map(|id| id.to_string())
520                        .collect::<Vec<_>>()
521                        .join(",")
522                )),
523            });
524        }
525        Ok(())
526    }
527
528    pub fn set_relationship(
529        &mut self,
530        event_buffer: &mut EventBuffer,
531        id: &EntityId,
532        field: &FrameRelationshipField,
533        right_ids: &[EntityId],
534    ) -> Result<(), RepositoryError> {
535        // Validate that all right_ids exist
536        if !right_ids.is_empty() {
537            match field {
538                FrameRelationshipField::Blocks => {
539                    let child_repo =
540                        repository_factory::write::create_block_repository(self.transaction)?;
541                    let found = child_repo.get_multi(right_ids)?;
542                    let missing: Vec<_> = right_ids
543                        .iter()
544                        .zip(found.iter())
545                        .filter(|(_, entity)| entity.is_none())
546                        .map(|(id, _)| *id)
547                        .collect();
548                    if !missing.is_empty() {
549                        return Err(RepositoryError::MissingRelationshipTarget {
550                            operation: "set_relationship",
551                            ids: missing,
552                        });
553                    }
554                }
555                FrameRelationshipField::ParentFrame => {
556                    let child_repo =
557                        repository_factory::write::create_frame_repository(self.transaction)?;
558                    let found = child_repo.get_multi(right_ids)?;
559                    let missing: Vec<_> = right_ids
560                        .iter()
561                        .zip(found.iter())
562                        .filter(|(_, entity)| entity.is_none())
563                        .map(|(id, _)| *id)
564                        .collect();
565                    if !missing.is_empty() {
566                        return Err(RepositoryError::MissingRelationshipTarget {
567                            operation: "set_relationship",
568                            ids: missing,
569                        });
570                    }
571                }
572                FrameRelationshipField::Table => {
573                    let child_repo =
574                        repository_factory::write::create_table_repository(self.transaction)?;
575                    let found = child_repo.get_multi(right_ids)?;
576                    let missing: Vec<_> = right_ids
577                        .iter()
578                        .zip(found.iter())
579                        .filter(|(_, entity)| entity.is_none())
580                        .map(|(id, _)| *id)
581                        .collect();
582                    if !missing.is_empty() {
583                        return Err(RepositoryError::MissingRelationshipTarget {
584                            operation: "set_relationship",
585                            ids: missing,
586                        });
587                    }
588                }
589            }
590        }
591        self.table.set_relationship(id, field, right_ids)?;
592        event_buffer.push(Event {
593            origin: Origin::DirectAccess(DirectAccessEntity::Frame(EntityEvent::Updated)),
594            ids: vec![*id],
595            data: Some(format!(
596                "{}:{}",
597                field,
598                right_ids
599                    .iter()
600                    .map(|id| id.to_string())
601                    .collect::<Vec<_>>()
602                    .join(",")
603            )),
604        });
605        Ok(())
606    }
607
608    pub fn move_relationship_ids(
609        &mut self,
610        event_buffer: &mut EventBuffer,
611        id: &EntityId,
612        field: &FrameRelationshipField,
613        ids_to_move: &[EntityId],
614        new_index: i32,
615    ) -> Result<Vec<EntityId>, RepositoryError> {
616        let reordered = self
617            .table
618            .move_relationship_ids(id, field, ids_to_move, new_index)?;
619        event_buffer.push(Event {
620            origin: Origin::DirectAccess(DirectAccessEntity::Frame(EntityEvent::Updated)),
621            ids: vec![*id],
622            data: Some(format!(
623                "{}:{}",
624                field,
625                reordered
626                    .iter()
627                    .map(|id| id.to_string())
628                    .collect::<Vec<_>>()
629                    .join(",")
630            )),
631        });
632        Ok(reordered)
633    }
634    pub fn get_relationships_from_owner(
635        &self,
636        owner_id: &EntityId,
637    ) -> Result<Vec<EntityId>, RepositoryError> {
638        let repo = repository_factory::write::create_document_repository(self.transaction)?;
639        repo.get_relationship(owner_id, &DocumentRelationshipField::Frames)
640    }
641
642    pub fn set_relationships_in_owner(
643        &mut self,
644        event_buffer: &mut EventBuffer,
645        owner_id: &EntityId,
646        ids: &[EntityId],
647    ) -> Result<(), RepositoryError> {
648        let mut repo = repository_factory::write::create_document_repository(self.transaction)?;
649        repo.set_relationship(
650            event_buffer,
651            owner_id,
652            &DocumentRelationshipField::Frames,
653            ids,
654        )
655    }
656
657    pub fn snapshot(&self, _ids: &[EntityId]) -> Result<EntityTreeSnapshot, RepositoryError> {
658        let store_snap = self.transaction.snapshot_store();
659        Ok(EntityTreeSnapshot {
660            store_snapshot: Some(store_snap),
661        })
662    }
663
664    pub fn restore(
665        &mut self,
666        event_buffer: &mut EventBuffer,
667        snap: &EntityTreeSnapshot,
668    ) -> Result<(), RepositoryError> {
669        let store_snap = snap
670            .store_snapshot
671            .as_ref()
672            .ok_or_else(|| RepositoryError::Serialization("missing store snapshot".into()))?;
673        self.transaction.restore_store(store_snap);
674
675        let store = self.transaction.get_store();
676
677        let mut emit = |entity: DirectAccessEntity, ids: Vec<EntityId>| {
678            if !ids.is_empty() {
679                event_buffer.push(Event {
680                    origin: Origin::DirectAccess(entity),
681                    ids,
682                    data: None,
683                });
684            }
685        };
686
687        // Emit Created events for this entity
688        let frame_ids: Vec<_> = store.frames.read().unwrap().keys().copied().collect();
689        emit(
690            DirectAccessEntity::Frame(EntityEvent::Created),
691            frame_ids.clone(),
692        );
693        emit(DirectAccessEntity::Frame(EntityEvent::Updated), frame_ids);
694
695        // Emit Created events for strong children
696
697        {
698            let child_ids: Vec<_> = store.blocks.read().unwrap().keys().copied().collect();
699            emit(
700                DirectAccessEntity::Block(EntityEvent::Created),
701                child_ids.clone(),
702            );
703            emit(DirectAccessEntity::Block(EntityEvent::Updated), child_ids);
704        }
705
706        Ok(())
707    }
708}
709
710pub struct FrameRepositoryRO<'a> {
711    table: Box<dyn FrameTableRO + 'a>,
712}
713impl<'a> FrameRepositoryRO<'a> {
714    pub fn new(table: Box<dyn FrameTableRO + 'a>) -> Self {
715        FrameRepositoryRO { table }
716    }
717    pub fn get(&self, id: &EntityId) -> Result<Option<Frame>, RepositoryError> {
718        self.table.get(id)
719    }
720    pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Frame>>, RepositoryError> {
721        self.table.get_multi(ids)
722    }
723    pub fn get_all(&self) -> Result<Vec<Frame>, RepositoryError> {
724        self.table.get_all()
725    }
726    pub fn get_relationship(
727        &self,
728        id: &EntityId,
729        field: &FrameRelationshipField,
730    ) -> Result<Vec<EntityId>, RepositoryError> {
731        self.table.get_relationship(id, field)
732    }
733    pub fn get_relationship_many(
734        &self,
735        ids: &[EntityId],
736        field: &FrameRelationshipField,
737    ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
738        self.table.get_relationship_many(ids, field)
739    }
740    pub fn get_relationship_count(
741        &self,
742        id: &EntityId,
743        field: &FrameRelationshipField,
744    ) -> Result<usize, RepositoryError> {
745        self.table.get_relationship_count(id, field)
746    }
747    pub fn get_relationship_in_range(
748        &self,
749        id: &EntityId,
750        field: &FrameRelationshipField,
751        offset: usize,
752        limit: usize,
753    ) -> Result<Vec<EntityId>, RepositoryError> {
754        self.table
755            .get_relationship_in_range(id, field, offset, limit)
756    }
757    pub fn get_relationships_from_right_ids(
758        &self,
759        field: &FrameRelationshipField,
760        right_ids: &[EntityId],
761    ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
762        self.table
763            .get_relationships_from_right_ids(field, right_ids)
764    }
765}