Skip to main content

text_document_common/direct_access/frame/
frame_repository.rs

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