Skip to main content

common/direct_access/root/
root_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::Root,
9    event::{DirectAccessEntity, EntityEvent, Event, EventBuffer, Origin},
10    snapshot::EntityTreeSnapshot,
11    types::EntityId,
12};
13
14use crate::error::RepositoryError;
15use serde::{Deserialize, Serialize};
16
17#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
18pub enum RootRelationshipField {
19    System,
20    Workspace,
21}
22
23impl Display for RootRelationshipField {
24    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
25        write!(f, "{:?}", self)
26    }
27}
28
29pub trait RootTable {
30    fn create(&mut self, entity: &Root) -> Result<Root, RepositoryError>;
31    fn create_multi(&mut self, entities: &[Root]) -> Result<Vec<Root>, RepositoryError>;
32    fn get(&self, id: &EntityId) -> Result<Option<Root>, RepositoryError>;
33    fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Root>>, RepositoryError>;
34    fn get_all(&self) -> Result<Vec<Root>, RepositoryError>;
35    fn update(&mut self, entity: &Root) -> Result<Root, RepositoryError>;
36    fn update_multi(&mut self, entities: &[Root]) -> Result<Vec<Root>, RepositoryError>;
37    fn update_with_relationships(&mut self, entity: &Root) -> Result<Root, RepositoryError>;
38    fn update_with_relationships_multi(
39        &mut self,
40        entities: &[Root],
41    ) -> Result<Vec<Root>, RepositoryError>;
42    fn remove(&mut self, id: &EntityId) -> Result<(), RepositoryError>;
43    fn remove_multi(&mut self, ids: &[EntityId]) -> Result<(), RepositoryError>;
44    fn get_relationship(
45        &self,
46        id: &EntityId,
47        field: &RootRelationshipField,
48    ) -> Result<Vec<EntityId>, RepositoryError>;
49    fn get_relationship_many(
50        &self,
51        ids: &[EntityId],
52        field: &RootRelationshipField,
53    ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError>;
54    fn get_relationship_count(
55        &self,
56        id: &EntityId,
57        field: &RootRelationshipField,
58    ) -> Result<usize, RepositoryError>;
59    fn get_relationship_in_range(
60        &self,
61        id: &EntityId,
62        field: &RootRelationshipField,
63        offset: usize,
64        limit: usize,
65    ) -> Result<Vec<EntityId>, RepositoryError>;
66    fn get_relationships_from_right_ids(
67        &self,
68        field: &RootRelationshipField,
69        right_ids: &[EntityId],
70    ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError>;
71    fn set_relationship_multi(
72        &mut self,
73        field: &RootRelationshipField,
74        relationships: Vec<(EntityId, Vec<EntityId>)>,
75    ) -> Result<(), RepositoryError>;
76    fn set_relationship(
77        &mut self,
78        id: &EntityId,
79        field: &RootRelationshipField,
80        right_ids: &[EntityId],
81    ) -> Result<(), RepositoryError>;
82    fn move_relationship_ids(
83        &mut self,
84        id: &EntityId,
85        field: &RootRelationshipField,
86        ids_to_move: &[EntityId],
87        new_index: i32,
88    ) -> Result<Vec<EntityId>, RepositoryError>;
89}
90
91pub trait RootTableRO {
92    fn get(&self, id: &EntityId) -> Result<Option<Root>, RepositoryError>;
93    fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Root>>, RepositoryError>;
94    fn get_all(&self) -> Result<Vec<Root>, RepositoryError>;
95    fn get_relationship(
96        &self,
97        id: &EntityId,
98        field: &RootRelationshipField,
99    ) -> Result<Vec<EntityId>, RepositoryError>;
100    fn get_relationship_many(
101        &self,
102        ids: &[EntityId],
103        field: &RootRelationshipField,
104    ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError>;
105    fn get_relationship_count(
106        &self,
107        id: &EntityId,
108        field: &RootRelationshipField,
109    ) -> Result<usize, RepositoryError>;
110    fn get_relationship_in_range(
111        &self,
112        id: &EntityId,
113        field: &RootRelationshipField,
114        offset: usize,
115        limit: usize,
116    ) -> Result<Vec<EntityId>, RepositoryError>;
117    fn get_relationships_from_right_ids(
118        &self,
119        field: &RootRelationshipField,
120        right_ids: &[EntityId],
121    ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError>;
122}
123
124pub struct RootRepository<'a> {
125    table: Box<dyn RootTable + 'a>,
126    transaction: &'a Transaction,
127}
128
129impl<'a> RootRepository<'a> {
130    pub fn new(table: Box<dyn RootTable + 'a>, transaction: &'a Transaction) -> Self {
131        RootRepository { table, transaction }
132    }
133
134    pub fn create_orphan(
135        &mut self,
136        event_buffer: &mut EventBuffer,
137        entity: &Root,
138    ) -> Result<Root, RepositoryError> {
139        let new = self.table.create(entity)?;
140        event_buffer.push(Event {
141            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Created)),
142            ids: vec![new.id],
143            data: None,
144        });
145        Ok(new)
146    }
147
148    pub fn create_orphan_multi(
149        &mut self,
150        event_buffer: &mut EventBuffer,
151        entities: &[Root],
152    ) -> Result<Vec<Root>, RepositoryError> {
153        let new_entities = self.table.create_multi(entities)?;
154        event_buffer.push(Event {
155            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Created)),
156            ids: new_entities.iter().map(|e| e.id).collect(),
157            data: None,
158        });
159        Ok(new_entities)
160    }
161
162    pub fn get(&self, id: &EntityId) -> Result<Option<Root>, RepositoryError> {
163        self.table.get(id)
164    }
165    pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Root>>, RepositoryError> {
166        self.table.get_multi(ids)
167    }
168    pub fn get_all(&self) -> Result<Vec<Root>, RepositoryError> {
169        self.table.get_all()
170    }
171
172    pub fn update(
173        &mut self,
174        event_buffer: &mut EventBuffer,
175        entity: &Root,
176    ) -> Result<Root, RepositoryError> {
177        let updated = self.table.update(entity)?;
178        event_buffer.push(Event {
179            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
180            ids: vec![updated.id],
181            data: None,
182        });
183        Ok(updated)
184    }
185
186    pub fn update_multi(
187        &mut self,
188        event_buffer: &mut EventBuffer,
189        entities: &[Root],
190    ) -> Result<Vec<Root>, RepositoryError> {
191        let updated = self.table.update_multi(entities)?;
192        event_buffer.push(Event {
193            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
194            ids: updated.iter().map(|e| e.id).collect(),
195            data: None,
196        });
197        Ok(updated)
198    }
199
200    pub fn update_with_relationships(
201        &mut self,
202        event_buffer: &mut EventBuffer,
203        entity: &Root,
204    ) -> Result<Root, RepositoryError> {
205        let updated = self.table.update_with_relationships(entity)?;
206        event_buffer.push(Event {
207            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
208            ids: vec![updated.id],
209            data: None,
210        });
211        Ok(updated)
212    }
213
214    pub fn update_with_relationships_multi(
215        &mut self,
216        event_buffer: &mut EventBuffer,
217        entities: &[Root],
218    ) -> Result<Vec<Root>, RepositoryError> {
219        let updated = self.table.update_with_relationships_multi(entities)?;
220        event_buffer.push(Event {
221            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
222            ids: updated.iter().map(|e| e.id).collect(),
223            data: None,
224        });
225        Ok(updated)
226    }
227
228    pub fn remove(
229        &mut self,
230        event_buffer: &mut EventBuffer,
231        id: &EntityId,
232    ) -> Result<(), RepositoryError> {
233        let entity = match self.table.get(id)? {
234            Some(e) => e,
235            None => return Ok(()),
236        };
237        // get all strong forward relationship fields
238
239        let workspace = entity.workspace;
240        let system = entity.system;
241
242        // remove all strong relationships, initiating a cascade remove
243
244        if let Some(workspace_id) = workspace {
245            repository_factory::write::create_workspace_repository(self.transaction)?
246                .remove(event_buffer, &workspace_id)?;
247        }
248        if let Some(system_id) = system {
249            repository_factory::write::create_system_repository(self.transaction)?
250                .remove(event_buffer, &system_id)?;
251        }
252
253        // remove entity
254        self.table.remove(id)?;
255        event_buffer.push(Event {
256            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Removed)),
257            ids: vec![*id],
258            data: None,
259        });
260
261        Ok(())
262    }
263
264    pub fn remove_multi(
265        &mut self,
266        event_buffer: &mut EventBuffer,
267        ids: &[EntityId],
268    ) -> Result<(), RepositoryError> {
269        let entities = self.table.get_multi(ids)?;
270        if entities.is_empty() || entities.iter().all(|e| e.is_none()) {
271            return Ok(());
272        }
273
274        // get all strong forward relationship fields
275
276        let workspace_ids: Vec<EntityId> = entities
277            .iter()
278            .filter_map(|entity| entity.as_ref().and_then(|entity| entity.workspace))
279            .collect();
280        let system_ids: Vec<EntityId> = entities
281            .iter()
282            .filter_map(|entity| entity.as_ref().and_then(|entity| entity.system))
283            .collect();
284
285        // remove all strong relationships, initiating a cascade remove
286
287        repository_factory::write::create_workspace_repository(self.transaction)?
288            .remove_multi(event_buffer, &workspace_ids)?;
289        repository_factory::write::create_system_repository(self.transaction)?
290            .remove_multi(event_buffer, &system_ids)?;
291
292        self.table.remove_multi(ids)?;
293        event_buffer.push(Event {
294            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Removed)),
295            ids: ids.into(),
296            data: None,
297        });
298
299        Ok(())
300    }
301    pub fn get_relationship(
302        &self,
303        id: &EntityId,
304        field: &RootRelationshipField,
305    ) -> Result<Vec<EntityId>, RepositoryError> {
306        self.table.get_relationship(id, field)
307    }
308    pub fn get_relationship_many(
309        &self,
310        ids: &[EntityId],
311        field: &RootRelationshipField,
312    ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
313        self.table.get_relationship_many(ids, field)
314    }
315    pub fn get_relationship_count(
316        &self,
317        id: &EntityId,
318        field: &RootRelationshipField,
319    ) -> Result<usize, RepositoryError> {
320        self.table.get_relationship_count(id, field)
321    }
322    pub fn get_relationship_in_range(
323        &self,
324        id: &EntityId,
325        field: &RootRelationshipField,
326        offset: usize,
327        limit: usize,
328    ) -> Result<Vec<EntityId>, RepositoryError> {
329        self.table
330            .get_relationship_in_range(id, field, offset, limit)
331    }
332    pub fn get_relationships_from_right_ids(
333        &self,
334        field: &RootRelationshipField,
335        right_ids: &[EntityId],
336    ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
337        self.table
338            .get_relationships_from_right_ids(field, right_ids)
339    }
340
341    pub fn set_relationship_multi(
342        &mut self,
343        event_buffer: &mut EventBuffer,
344        field: &RootRelationshipField,
345        relationships: Vec<(EntityId, Vec<EntityId>)>,
346    ) -> Result<(), RepositoryError> {
347        // Validate that all right_ids exist
348        let all_right_ids: Vec<EntityId> = relationships
349            .iter()
350            .flat_map(|(_, ids)| ids.iter().copied())
351            .collect();
352        if !all_right_ids.is_empty() {
353            match field {
354                RootRelationshipField::System => {
355                    let child_repo =
356                        repository_factory::write::create_system_repository(self.transaction)?;
357                    let found = child_repo.get_multi(&all_right_ids)?;
358                    let missing: Vec<_> = all_right_ids
359                        .iter()
360                        .zip(found.iter())
361                        .filter(|(_, entity)| entity.is_none())
362                        .map(|(id, _)| *id)
363                        .collect();
364                    if !missing.is_empty() {
365                        return Err(RepositoryError::MissingRelationshipTarget {
366                            operation: "set_relationship_multi",
367                            ids: missing,
368                        });
369                    }
370                }
371                RootRelationshipField::Workspace => {
372                    let child_repo =
373                        repository_factory::write::create_workspace_repository(self.transaction)?;
374                    let found = child_repo.get_multi(&all_right_ids)?;
375                    let missing: Vec<_> = all_right_ids
376                        .iter()
377                        .zip(found.iter())
378                        .filter(|(_, entity)| entity.is_none())
379                        .map(|(id, _)| *id)
380                        .collect();
381                    if !missing.is_empty() {
382                        return Err(RepositoryError::MissingRelationshipTarget {
383                            operation: "set_relationship_multi",
384                            ids: missing,
385                        });
386                    }
387                }
388            }
389        }
390        self.table
391            .set_relationship_multi(field, relationships.clone())?;
392        for (left_id, right_ids) in relationships {
393            event_buffer.push(Event {
394                origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
395                ids: vec![left_id],
396                data: Some(format!(
397                    "{}:{}",
398                    field,
399                    right_ids
400                        .iter()
401                        .map(|id| id.to_string())
402                        .collect::<Vec<_>>()
403                        .join(",")
404                )),
405            });
406        }
407        Ok(())
408    }
409
410    pub fn set_relationship(
411        &mut self,
412        event_buffer: &mut EventBuffer,
413        id: &EntityId,
414        field: &RootRelationshipField,
415        right_ids: &[EntityId],
416    ) -> Result<(), RepositoryError> {
417        // Validate that all right_ids exist
418        if !right_ids.is_empty() {
419            match field {
420                RootRelationshipField::System => {
421                    let child_repo =
422                        repository_factory::write::create_system_repository(self.transaction)?;
423                    let found = child_repo.get_multi(right_ids)?;
424                    let missing: Vec<_> = right_ids
425                        .iter()
426                        .zip(found.iter())
427                        .filter(|(_, entity)| entity.is_none())
428                        .map(|(id, _)| *id)
429                        .collect();
430                    if !missing.is_empty() {
431                        return Err(RepositoryError::MissingRelationshipTarget {
432                            operation: "set_relationship",
433                            ids: missing,
434                        });
435                    }
436                }
437                RootRelationshipField::Workspace => {
438                    let child_repo =
439                        repository_factory::write::create_workspace_repository(self.transaction)?;
440                    let found = child_repo.get_multi(right_ids)?;
441                    let missing: Vec<_> = right_ids
442                        .iter()
443                        .zip(found.iter())
444                        .filter(|(_, entity)| entity.is_none())
445                        .map(|(id, _)| *id)
446                        .collect();
447                    if !missing.is_empty() {
448                        return Err(RepositoryError::MissingRelationshipTarget {
449                            operation: "set_relationship",
450                            ids: missing,
451                        });
452                    }
453                }
454            }
455        }
456        self.table.set_relationship(id, field, right_ids)?;
457        event_buffer.push(Event {
458            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
459            ids: vec![*id],
460            data: Some(format!(
461                "{}:{}",
462                field,
463                right_ids
464                    .iter()
465                    .map(|id| id.to_string())
466                    .collect::<Vec<_>>()
467                    .join(",")
468            )),
469        });
470        Ok(())
471    }
472
473    pub fn move_relationship_ids(
474        &mut self,
475        event_buffer: &mut EventBuffer,
476        id: &EntityId,
477        field: &RootRelationshipField,
478        ids_to_move: &[EntityId],
479        new_index: i32,
480    ) -> Result<Vec<EntityId>, RepositoryError> {
481        let reordered = self
482            .table
483            .move_relationship_ids(id, field, ids_to_move, new_index)?;
484        event_buffer.push(Event {
485            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
486            ids: vec![*id],
487            data: Some(format!(
488                "{}:{}",
489                field,
490                reordered
491                    .iter()
492                    .map(|id| id.to_string())
493                    .collect::<Vec<_>>()
494                    .join(",")
495            )),
496        });
497        Ok(reordered)
498    }
499
500    pub fn snapshot(&self, _ids: &[EntityId]) -> Result<EntityTreeSnapshot, RepositoryError> {
501        let store_snap = self.transaction.snapshot_store();
502        Ok(EntityTreeSnapshot {
503            store_snapshot: Some(store_snap),
504        })
505    }
506
507    pub fn restore(
508        &mut self,
509        event_buffer: &mut EventBuffer,
510        snap: &EntityTreeSnapshot,
511    ) -> Result<(), RepositoryError> {
512        let store_snap = snap
513            .store_snapshot
514            .as_ref()
515            .ok_or_else(|| RepositoryError::Serialization("missing store snapshot".into()))?;
516        self.transaction.restore_store(store_snap);
517
518        let store = self.transaction.get_store();
519
520        let mut emit = |entity: DirectAccessEntity, ids: Vec<EntityId>| {
521            if !ids.is_empty() {
522                event_buffer.push(Event {
523                    origin: Origin::DirectAccess(entity),
524                    ids,
525                    data: None,
526                });
527            }
528        };
529
530        // Emit Created events for this entity
531        let root_ids: Vec<_> = store.roots.read().unwrap().keys().copied().collect();
532        emit(
533            DirectAccessEntity::Root(EntityEvent::Created),
534            root_ids.clone(),
535        );
536        emit(DirectAccessEntity::Root(EntityEvent::Updated), root_ids);
537
538        // Emit Created events for strong children
539
540        {
541            let child_ids: Vec<_> = store.workspaces.read().unwrap().keys().copied().collect();
542            emit(
543                DirectAccessEntity::Workspace(EntityEvent::Created),
544                child_ids.clone(),
545            );
546            emit(
547                DirectAccessEntity::Workspace(EntityEvent::Updated),
548                child_ids,
549            );
550        }
551        {
552            let child_ids: Vec<_> = store.systems.read().unwrap().keys().copied().collect();
553            emit(
554                DirectAccessEntity::System(EntityEvent::Created),
555                child_ids.clone(),
556            );
557            emit(DirectAccessEntity::System(EntityEvent::Updated), child_ids);
558        }
559
560        Ok(())
561    }
562}
563
564pub struct RootRepositoryRO<'a> {
565    table: Box<dyn RootTableRO + 'a>,
566}
567impl<'a> RootRepositoryRO<'a> {
568    pub fn new(table: Box<dyn RootTableRO + 'a>) -> Self {
569        RootRepositoryRO { table }
570    }
571    pub fn get(&self, id: &EntityId) -> Result<Option<Root>, RepositoryError> {
572        self.table.get(id)
573    }
574    pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Root>>, RepositoryError> {
575        self.table.get_multi(ids)
576    }
577    pub fn get_all(&self) -> Result<Vec<Root>, RepositoryError> {
578        self.table.get_all()
579    }
580    pub fn get_relationship(
581        &self,
582        id: &EntityId,
583        field: &RootRelationshipField,
584    ) -> Result<Vec<EntityId>, RepositoryError> {
585        self.table.get_relationship(id, field)
586    }
587    pub fn get_relationship_many(
588        &self,
589        ids: &[EntityId],
590        field: &RootRelationshipField,
591    ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
592        self.table.get_relationship_many(ids, field)
593    }
594    pub fn get_relationship_count(
595        &self,
596        id: &EntityId,
597        field: &RootRelationshipField,
598    ) -> Result<usize, RepositoryError> {
599        self.table.get_relationship_count(id, field)
600    }
601    pub fn get_relationship_in_range(
602        &self,
603        id: &EntityId,
604        field: &RootRelationshipField,
605        offset: usize,
606        limit: usize,
607    ) -> Result<Vec<EntityId>, RepositoryError> {
608        self.table
609            .get_relationship_in_range(id, field, offset, limit)
610    }
611    pub fn get_relationships_from_right_ids(
612        &self,
613        field: &RootRelationshipField,
614        right_ids: &[EntityId],
615    ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
616        self.table
617            .get_relationships_from_right_ids(field, right_ids)
618    }
619}