Skip to main content

common/direct_access/use_case/
use_case_repository.rs

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