Skip to main content

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