Skip to main content

text_document_common/direct_access/root/
root_repository.rs

1// Generated by Qleany v1.5.1 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    redb_table: Box<dyn RootTable + 'a>,
125    transaction: &'a Transaction,
126}
127
128impl<'a> RootRepository<'a> {
129    pub fn new(redb_table: Box<dyn RootTable + 'a>, transaction: &'a Transaction) -> Self {
130        RootRepository {
131            redb_table,
132            transaction,
133        }
134    }
135
136    pub fn create_orphan(
137        &mut self,
138        event_buffer: &mut EventBuffer,
139        entity: &Root,
140    ) -> Result<Root, RepositoryError> {
141        let new = self.redb_table.create(entity)?;
142        event_buffer.push(Event {
143            origin: Origin::DirectAccess(DirectAccessEntity::Root(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: &[Root],
154    ) -> Result<Vec<Root>, RepositoryError> {
155        let new_entities = self.redb_table.create_multi(entities)?;
156        event_buffer.push(Event {
157            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Created)),
158            ids: new_entities.iter().map(|e| e.id).collect(),
159            data: None,
160        });
161        Ok(new_entities)
162    }
163
164    pub fn get(&self, id: &EntityId) -> Result<Option<Root>, RepositoryError> {
165        self.redb_table.get(id)
166    }
167    pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Root>>, RepositoryError> {
168        self.redb_table.get_multi(ids)
169    }
170    pub fn get_all(&self) -> Result<Vec<Root>, RepositoryError> {
171        self.redb_table.get_all()
172    }
173
174    pub fn update(
175        &mut self,
176        event_buffer: &mut EventBuffer,
177        entity: &Root,
178    ) -> Result<Root, RepositoryError> {
179        let updated = self.redb_table.update(entity)?;
180        event_buffer.push(Event {
181            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
182            ids: vec![updated.id],
183            data: None,
184        });
185        Ok(updated)
186    }
187
188    pub fn update_multi(
189        &mut self,
190        event_buffer: &mut EventBuffer,
191        entities: &[Root],
192    ) -> Result<Vec<Root>, RepositoryError> {
193        let updated = self.redb_table.update_multi(entities)?;
194        event_buffer.push(Event {
195            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
196            ids: updated.iter().map(|e| e.id).collect(),
197            data: None,
198        });
199        Ok(updated)
200    }
201
202    pub fn update_with_relationships(
203        &mut self,
204        event_buffer: &mut EventBuffer,
205        entity: &Root,
206    ) -> Result<Root, RepositoryError> {
207        let updated = self.redb_table.update_with_relationships(entity)?;
208        event_buffer.push(Event {
209            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
210            ids: vec![updated.id],
211            data: None,
212        });
213        Ok(updated)
214    }
215
216    pub fn update_with_relationships_multi(
217        &mut self,
218        event_buffer: &mut EventBuffer,
219        entities: &[Root],
220    ) -> Result<Vec<Root>, RepositoryError> {
221        let updated = self.redb_table.update_with_relationships_multi(entities)?;
222        event_buffer.push(Event {
223            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
224            ids: updated.iter().map(|e| e.id).collect(),
225            data: None,
226        });
227        Ok(updated)
228    }
229
230    pub fn remove(
231        &mut self,
232        event_buffer: &mut EventBuffer,
233        id: &EntityId,
234    ) -> Result<(), RepositoryError> {
235        let entity = match self.redb_table.get(id)? {
236            Some(e) => e,
237            None => return Ok(()),
238        };
239        // get all strong forward relationship fields
240
241        let document = entity.document;
242
243        // remove all strong relationships, initiating a cascade remove
244
245        repository_factory::write::create_document_repository(self.transaction)
246            .remove(event_buffer, &document)?;
247
248        // remove entity
249        self.redb_table.remove(id)?;
250        event_buffer.push(Event {
251            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Removed)),
252            ids: vec![*id],
253            data: None,
254        });
255
256        Ok(())
257    }
258
259    pub fn remove_multi(
260        &mut self,
261        event_buffer: &mut EventBuffer,
262        ids: &[EntityId],
263    ) -> Result<(), RepositoryError> {
264        let entities = self.redb_table.get_multi(ids)?;
265        if entities.is_empty() || entities.iter().all(|e| e.is_none()) {
266            return Ok(());
267        }
268
269        // get all strong forward relationship fields
270
271        let document_ids: Vec<EntityId> = entities
272            .iter()
273            .filter_map(|entity| entity.as_ref().map(|entity| entity.document))
274            .collect();
275
276        // remove all strong relationships, initiating a cascade remove
277
278        repository_factory::write::create_document_repository(self.transaction)
279            .remove_multi(event_buffer, &document_ids)?;
280
281        self.redb_table.remove_multi(ids)?;
282        event_buffer.push(Event {
283            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Removed)),
284            ids: ids.into(),
285            data: None,
286        });
287
288        Ok(())
289    }
290    pub fn get_relationship(
291        &self,
292        id: &EntityId,
293        field: &RootRelationshipField,
294    ) -> Result<Vec<EntityId>, RepositoryError> {
295        self.redb_table.get_relationship(id, field)
296    }
297    pub fn get_relationship_many(
298        &self,
299        ids: &[EntityId],
300        field: &RootRelationshipField,
301    ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
302        self.redb_table.get_relationship_many(ids, field)
303    }
304    pub fn get_relationship_count(
305        &self,
306        id: &EntityId,
307        field: &RootRelationshipField,
308    ) -> Result<usize, RepositoryError> {
309        self.redb_table.get_relationship_count(id, field)
310    }
311    pub fn get_relationship_in_range(
312        &self,
313        id: &EntityId,
314        field: &RootRelationshipField,
315        offset: usize,
316        limit: usize,
317    ) -> Result<Vec<EntityId>, RepositoryError> {
318        self.redb_table
319            .get_relationship_in_range(id, field, offset, limit)
320    }
321    pub fn get_relationships_from_right_ids(
322        &self,
323        field: &RootRelationshipField,
324        right_ids: &[EntityId],
325    ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
326        self.redb_table
327            .get_relationships_from_right_ids(field, right_ids)
328    }
329
330    pub fn set_relationship_multi(
331        &mut self,
332        event_buffer: &mut EventBuffer,
333        field: &RootRelationshipField,
334        relationships: Vec<(EntityId, Vec<EntityId>)>,
335    ) -> Result<(), RepositoryError> {
336        // Validate that all right_ids exist
337        let all_right_ids: Vec<EntityId> = relationships
338            .iter()
339            .flat_map(|(_, ids)| ids.iter().copied())
340            .collect();
341        if !all_right_ids.is_empty() {
342            match field {
343                RootRelationshipField::Document => {
344                    let child_repo =
345                        repository_factory::write::create_document_repository(self.transaction);
346                    let found = child_repo.get_multi(&all_right_ids)?;
347                    let missing: Vec<_> = all_right_ids
348                        .iter()
349                        .zip(found.iter())
350                        .filter(|(_, entity)| entity.is_none())
351                        .map(|(id, _)| *id)
352                        .collect();
353                    if !missing.is_empty() {
354                        return Err(RepositoryError::MissingRelationshipTarget {
355                            operation: "set_relationship_multi",
356                            ids: missing,
357                        });
358                    }
359                }
360            }
361        }
362        self.redb_table
363            .set_relationship_multi(field, relationships.clone())?;
364        for (left_id, right_ids) in relationships {
365            event_buffer.push(Event {
366                origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
367                ids: vec![left_id],
368                data: Some(format!(
369                    "{}:{}",
370                    field,
371                    right_ids
372                        .iter()
373                        .map(|id| id.to_string())
374                        .collect::<Vec<_>>()
375                        .join(",")
376                )),
377            });
378        }
379        Ok(())
380    }
381
382    pub fn set_relationship(
383        &mut self,
384        event_buffer: &mut EventBuffer,
385        id: &EntityId,
386        field: &RootRelationshipField,
387        right_ids: &[EntityId],
388    ) -> Result<(), RepositoryError> {
389        // Validate that all right_ids exist
390        if !right_ids.is_empty() {
391            match field {
392                RootRelationshipField::Document => {
393                    let child_repo =
394                        repository_factory::write::create_document_repository(self.transaction);
395                    let found = child_repo.get_multi(right_ids)?;
396                    let missing: Vec<_> = right_ids
397                        .iter()
398                        .zip(found.iter())
399                        .filter(|(_, entity)| entity.is_none())
400                        .map(|(id, _)| *id)
401                        .collect();
402                    if !missing.is_empty() {
403                        return Err(RepositoryError::MissingRelationshipTarget {
404                            operation: "set_relationship",
405                            ids: missing,
406                        });
407                    }
408                }
409            }
410        }
411        self.redb_table.set_relationship(id, field, right_ids)?;
412        event_buffer.push(Event {
413            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
414            ids: vec![*id],
415            data: Some(format!(
416                "{}:{}",
417                field,
418                right_ids
419                    .iter()
420                    .map(|id| id.to_string())
421                    .collect::<Vec<_>>()
422                    .join(",")
423            )),
424        });
425        Ok(())
426    }
427
428    pub fn move_relationship_ids(
429        &mut self,
430        event_buffer: &mut EventBuffer,
431        id: &EntityId,
432        field: &RootRelationshipField,
433        ids_to_move: &[EntityId],
434        new_index: i32,
435    ) -> Result<Vec<EntityId>, RepositoryError> {
436        let reordered = self
437            .redb_table
438            .move_relationship_ids(id, field, ids_to_move, new_index)?;
439        event_buffer.push(Event {
440            origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
441            ids: vec![*id],
442            data: Some(format!(
443                "{}:{}",
444                field,
445                reordered
446                    .iter()
447                    .map(|id| id.to_string())
448                    .collect::<Vec<_>>()
449                    .join(",")
450            )),
451        });
452        Ok(reordered)
453    }
454
455    pub fn snapshot(&self, _ids: &[EntityId]) -> Result<EntityTreeSnapshot, RepositoryError> {
456        let store_snap = self.transaction.snapshot_store();
457        Ok(EntityTreeSnapshot {
458            store_snapshot: Some(store_snap),
459        })
460    }
461
462    pub fn restore(
463        &mut self,
464        event_buffer: &mut EventBuffer,
465        snap: &EntityTreeSnapshot,
466    ) -> Result<(), RepositoryError> {
467        let store_snap = snap
468            .store_snapshot
469            .as_ref()
470            .ok_or_else(|| RepositoryError::Serialization("missing store snapshot".into()))?;
471        self.transaction.restore_store(store_snap);
472
473        let store = self.transaction.get_store();
474
475        let mut emit = |entity: DirectAccessEntity, ids: Vec<EntityId>| {
476            if !ids.is_empty() {
477                event_buffer.push(Event {
478                    origin: Origin::DirectAccess(entity),
479                    ids,
480                    data: None,
481                });
482            }
483        };
484
485        // Root: Created + Updated (has Document relationship)
486        let root_ids: Vec<_> = store.roots.read().unwrap().keys().copied().collect();
487        emit(
488            DirectAccessEntity::Root(EntityEvent::Created),
489            root_ids.clone(),
490        );
491        emit(DirectAccessEntity::Root(EntityEvent::Updated), root_ids);
492
493        // Document: Created + Updated (strong child, has relationships)
494        let doc_ids: Vec<_> = store.documents.read().unwrap().keys().copied().collect();
495        emit(
496            DirectAccessEntity::Document(EntityEvent::Created),
497            doc_ids.clone(),
498        );
499        emit(DirectAccessEntity::Document(EntityEvent::Updated), doc_ids);
500
501        // Frame: Created + Updated
502        let frame_ids: Vec<_> = store.frames.read().unwrap().keys().copied().collect();
503        emit(
504            DirectAccessEntity::Frame(EntityEvent::Created),
505            frame_ids.clone(),
506        );
507        emit(DirectAccessEntity::Frame(EntityEvent::Updated), frame_ids);
508
509        // Block: Created + Updated
510        let block_ids: Vec<_> = store.blocks.read().unwrap().keys().copied().collect();
511        emit(
512            DirectAccessEntity::Block(EntityEvent::Created),
513            block_ids.clone(),
514        );
515        emit(DirectAccessEntity::Block(EntityEvent::Updated), block_ids);
516
517        // InlineElement: Created only (leaf)
518        let elem_ids: Vec<_> = store
519            .inline_elements
520            .read()
521            .unwrap()
522            .keys()
523            .copied()
524            .collect();
525        emit(
526            DirectAccessEntity::InlineElement(EntityEvent::Created),
527            elem_ids,
528        );
529
530        // List: Created only (leaf)
531        let list_ids: Vec<_> = store.lists.read().unwrap().keys().copied().collect();
532        emit(DirectAccessEntity::List(EntityEvent::Created), list_ids);
533
534        // Resource: Created only (leaf)
535        let res_ids: Vec<_> = store.resources.read().unwrap().keys().copied().collect();
536        emit(DirectAccessEntity::Resource(EntityEvent::Created), res_ids);
537
538        // Table: Created + Updated
539        let table_ids: Vec<_> = store.tables.read().unwrap().keys().copied().collect();
540        emit(
541            DirectAccessEntity::Table(EntityEvent::Created),
542            table_ids.clone(),
543        );
544        emit(DirectAccessEntity::Table(EntityEvent::Updated), table_ids);
545
546        // TableCell: Created + Updated
547        let tc_ids: Vec<_> = store.table_cells.read().unwrap().keys().copied().collect();
548        emit(
549            DirectAccessEntity::TableCell(EntityEvent::Created),
550            tc_ids.clone(),
551        );
552        emit(DirectAccessEntity::TableCell(EntityEvent::Updated), tc_ids);
553
554        Ok(())
555    }
556}
557
558pub struct RootRepositoryRO<'a> {
559    redb_table: Box<dyn RootTableRO + 'a>,
560}
561impl<'a> RootRepositoryRO<'a> {
562    pub fn new(redb_table: Box<dyn RootTableRO + 'a>) -> Self {
563        RootRepositoryRO { redb_table }
564    }
565    pub fn get(&self, id: &EntityId) -> Result<Option<Root>, RepositoryError> {
566        self.redb_table.get(id)
567    }
568    pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Root>>, RepositoryError> {
569        self.redb_table.get_multi(ids)
570    }
571    pub fn get_all(&self) -> Result<Vec<Root>, RepositoryError> {
572        self.redb_table.get_all()
573    }
574    pub fn get_relationship(
575        &self,
576        id: &EntityId,
577        field: &RootRelationshipField,
578    ) -> Result<Vec<EntityId>, RepositoryError> {
579        self.redb_table.get_relationship(id, field)
580    }
581    pub fn get_relationship_many(
582        &self,
583        ids: &[EntityId],
584        field: &RootRelationshipField,
585    ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
586        self.redb_table.get_relationship_many(ids, field)
587    }
588    pub fn get_relationship_count(
589        &self,
590        id: &EntityId,
591        field: &RootRelationshipField,
592    ) -> Result<usize, RepositoryError> {
593        self.redb_table.get_relationship_count(id, field)
594    }
595    pub fn get_relationship_in_range(
596        &self,
597        id: &EntityId,
598        field: &RootRelationshipField,
599        offset: usize,
600        limit: usize,
601    ) -> Result<Vec<EntityId>, RepositoryError> {
602        self.redb_table
603            .get_relationship_in_range(id, field, offset, limit)
604    }
605    pub fn get_relationships_from_right_ids(
606        &self,
607        field: &RootRelationshipField,
608        right_ids: &[EntityId],
609    ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
610        self.redb_table
611            .get_relationships_from_right_ids(field, right_ids)
612    }
613}