Skip to main content

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