Skip to main content

common/direct_access/list/
list_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::List,
9    event::{DirectAccessEntity, EntityEvent, Event, EventBuffer, Origin},
10    snapshot::EntityTreeSnapshot,
11    types::EntityId,
12};
13
14use crate::direct_access::document::DocumentRelationshipField;
15use crate::error::RepositoryError;
16use serde::{Deserialize, Serialize};
17
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
19pub enum ListRelationshipField {}
20
21impl Display for ListRelationshipField {
22    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
23        write!(f, "{:?}", self)
24    }
25}
26
27pub trait ListTable {
28    fn create(&mut self, entity: &List) -> Result<List, RepositoryError>;
29    fn create_multi(&mut self, entities: &[List]) -> Result<Vec<List>, RepositoryError>;
30    fn get(&self, id: &EntityId) -> Result<Option<List>, RepositoryError>;
31    fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<List>>, RepositoryError>;
32    fn get_all(&self) -> Result<Vec<List>, RepositoryError>;
33    fn update(&mut self, entity: &List) -> Result<List, RepositoryError>;
34    fn update_multi(&mut self, entities: &[List]) -> Result<Vec<List>, RepositoryError>;
35    fn update_with_relationships(&mut self, entity: &List) -> Result<List, RepositoryError>;
36    fn update_with_relationships_multi(
37        &mut self,
38        entities: &[List],
39    ) -> Result<Vec<List>, RepositoryError>;
40    fn remove(&mut self, id: &EntityId) -> Result<(), RepositoryError>;
41    fn remove_multi(&mut self, ids: &[EntityId]) -> Result<(), RepositoryError>;
42}
43
44pub trait ListTableRO {
45    fn get(&self, id: &EntityId) -> Result<Option<List>, RepositoryError>;
46    fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<List>>, RepositoryError>;
47    fn get_all(&self) -> Result<Vec<List>, RepositoryError>;
48}
49
50pub struct ListRepository<'a> {
51    table: Box<dyn ListTable + 'a>,
52    transaction: &'a Transaction,
53}
54
55impl<'a> ListRepository<'a> {
56    pub fn new(table: Box<dyn ListTable + 'a>, transaction: &'a Transaction) -> Self {
57        ListRepository { table, transaction }
58    }
59
60    pub fn create_orphan(
61        &mut self,
62        event_buffer: &mut EventBuffer,
63        entity: &List,
64    ) -> Result<List, RepositoryError> {
65        let new = self.table.create(entity)?;
66        event_buffer.push(Event {
67            origin: Origin::DirectAccess(DirectAccessEntity::List(EntityEvent::Created)),
68            ids: vec![new.id],
69            data: None,
70        });
71        Ok(new)
72    }
73
74    pub fn create_orphan_multi(
75        &mut self,
76        event_buffer: &mut EventBuffer,
77        entities: &[List],
78    ) -> Result<Vec<List>, RepositoryError> {
79        let new_entities = self.table.create_multi(entities)?;
80        event_buffer.push(Event {
81            origin: Origin::DirectAccess(DirectAccessEntity::List(EntityEvent::Created)),
82            ids: new_entities.iter().map(|e| e.id).collect(),
83            data: None,
84        });
85        Ok(new_entities)
86    }
87    pub fn create(
88        &mut self,
89        event_buffer: &mut EventBuffer,
90        entity: &List,
91        owner_id: EntityId,
92        index: i32,
93    ) -> Result<List, RepositoryError> {
94        let new = self.table.create(entity)?;
95        let created_id = new.id;
96
97        let mut relationship_ids = self.get_relationships_from_owner(&owner_id)?;
98        // Insert at index
99        if index >= 0 && (index as usize) < relationship_ids.len() {
100            relationship_ids.insert(index as usize, created_id);
101        } else {
102            relationship_ids.push(created_id);
103        }
104
105        self.set_relationships_in_owner(event_buffer, &owner_id, &relationship_ids)?;
106        event_buffer.push(Event {
107            origin: Origin::DirectAccess(DirectAccessEntity::List(EntityEvent::Created)),
108            ids: vec![created_id],
109            data: None,
110        });
111        Ok(new)
112    }
113
114    pub fn create_multi(
115        &mut self,
116        event_buffer: &mut EventBuffer,
117        entities: &[List],
118        owner_id: EntityId,
119        index: i32,
120    ) -> Result<Vec<List>, RepositoryError> {
121        let new_entities = self.table.create_multi(entities)?;
122        let created_ids: Vec<EntityId> = new_entities.iter().map(|e| e.id).collect();
123
124        let mut relationship_ids = self.get_relationships_from_owner(&owner_id)?;
125        if index >= 0 && (index as usize) < relationship_ids.len() {
126            for (i, id) in created_ids.iter().enumerate() {
127                relationship_ids.insert(index as usize + i, *id);
128            }
129        } else {
130            relationship_ids.extend(created_ids.iter());
131        }
132
133        self.set_relationships_in_owner(event_buffer, &owner_id, &relationship_ids)?;
134        event_buffer.push(Event {
135            origin: Origin::DirectAccess(DirectAccessEntity::List(EntityEvent::Created)),
136            ids: created_ids,
137            data: None,
138        });
139        Ok(new_entities)
140    }
141
142    pub fn get(&self, id: &EntityId) -> Result<Option<List>, RepositoryError> {
143        self.table.get(id)
144    }
145    pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<List>>, RepositoryError> {
146        self.table.get_multi(ids)
147    }
148    pub fn get_all(&self) -> Result<Vec<List>, RepositoryError> {
149        self.table.get_all()
150    }
151
152    pub fn update(
153        &mut self,
154        event_buffer: &mut EventBuffer,
155        entity: &List,
156    ) -> Result<List, RepositoryError> {
157        let updated = self.table.update(entity)?;
158        event_buffer.push(Event {
159            origin: Origin::DirectAccess(DirectAccessEntity::List(EntityEvent::Updated)),
160            ids: vec![updated.id],
161            data: None,
162        });
163        Ok(updated)
164    }
165
166    pub fn update_multi(
167        &mut self,
168        event_buffer: &mut EventBuffer,
169        entities: &[List],
170    ) -> Result<Vec<List>, RepositoryError> {
171        let updated = self.table.update_multi(entities)?;
172        event_buffer.push(Event {
173            origin: Origin::DirectAccess(DirectAccessEntity::List(EntityEvent::Updated)),
174            ids: updated.iter().map(|e| e.id).collect(),
175            data: None,
176        });
177        Ok(updated)
178    }
179
180    pub fn update_with_relationships(
181        &mut self,
182        event_buffer: &mut EventBuffer,
183        entity: &List,
184    ) -> Result<List, RepositoryError> {
185        let updated = self.table.update_with_relationships(entity)?;
186        event_buffer.push(Event {
187            origin: Origin::DirectAccess(DirectAccessEntity::List(EntityEvent::Updated)),
188            ids: vec![updated.id],
189            data: None,
190        });
191        Ok(updated)
192    }
193
194    pub fn update_with_relationships_multi(
195        &mut self,
196        event_buffer: &mut EventBuffer,
197        entities: &[List],
198    ) -> Result<Vec<List>, RepositoryError> {
199        let updated = self.table.update_with_relationships_multi(entities)?;
200        event_buffer.push(Event {
201            origin: Origin::DirectAccess(DirectAccessEntity::List(EntityEvent::Updated)),
202            ids: updated.iter().map(|e| e.id).collect(),
203            data: None,
204        });
205        Ok(updated)
206    }
207
208    pub fn remove(
209        &mut self,
210        event_buffer: &mut EventBuffer,
211        id: &EntityId,
212    ) -> Result<(), RepositoryError> {
213        let _entity = match self.table.get(id)? {
214            Some(e) => e,
215            None => return Ok(()),
216        };
217        // get all strong forward relationship fields
218
219        // remove all strong relationships, initiating a cascade remove
220
221        // Before removal, find which owner(s) reference this entity
222        let affected_owner_ids: Vec<EntityId> = {
223            let owner_repo =
224                repository_factory::write::create_document_repository(self.transaction)?;
225            owner_repo
226                .get_relationships_from_right_ids(&DocumentRelationshipField::Lists, &[*id])?
227                .into_iter()
228                .map(|(owner_id, _)| owner_id)
229                .collect()
230        };
231        // Save each owner's current relationship IDs (properly ordered via get_relationships_from_owner)
232        let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
233            std::collections::HashMap::new();
234        for owner_id in &affected_owner_ids {
235            owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
236        }
237
238        // remove entity
239        self.table.remove(id)?;
240        event_buffer.push(Event {
241            origin: Origin::DirectAccess(DirectAccessEntity::List(EntityEvent::Removed)),
242            ids: vec![*id],
243            data: None,
244        });
245        // Update each affected owner's relationship to exclude removed ID (emits Updated event)
246        for owner_id in &affected_owner_ids {
247            if let Some(rel_ids) = owner_rel_before.get(owner_id) {
248                let updated: Vec<EntityId> =
249                    rel_ids.iter().copied().filter(|rid| *rid != *id).collect();
250                self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
251            }
252        }
253
254        Ok(())
255    }
256
257    pub fn remove_multi(
258        &mut self,
259        event_buffer: &mut EventBuffer,
260        ids: &[EntityId],
261    ) -> Result<(), RepositoryError> {
262        let entities = self.table.get_multi(ids)?;
263        if entities.is_empty() || entities.iter().all(|e| e.is_none()) {
264            return Ok(());
265        }
266
267        // get all strong forward relationship fields
268
269        // remove all strong relationships, initiating a cascade remove
270
271        // Before removal, find which owner(s) reference these entities
272        let affected_owner_ids: Vec<EntityId> = {
273            let owner_repo =
274                repository_factory::write::create_document_repository(self.transaction)?;
275            owner_repo
276                .get_relationships_from_right_ids(&DocumentRelationshipField::Lists, ids)?
277                .into_iter()
278                .map(|(owner_id, _)| owner_id)
279                .collect()
280        };
281        // Save each owner's current relationship IDs (properly ordered via get_relationships_from_owner)
282        let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
283            std::collections::HashMap::new();
284        for owner_id in &affected_owner_ids {
285            owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
286        }
287
288        self.table.remove_multi(ids)?;
289        event_buffer.push(Event {
290            origin: Origin::DirectAccess(DirectAccessEntity::List(EntityEvent::Removed)),
291            ids: ids.into(),
292            data: None,
293        });
294        // Update each affected owner's relationship to exclude removed IDs (emits Updated event)
295        {
296            let removed_set: std::collections::HashSet<EntityId> = ids.iter().copied().collect();
297            for owner_id in &affected_owner_ids {
298                if let Some(rel_ids) = owner_rel_before.get(owner_id) {
299                    let updated: Vec<EntityId> = rel_ids
300                        .iter()
301                        .copied()
302                        .filter(|rid| !removed_set.contains(rid))
303                        .collect();
304                    self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
305                }
306            }
307        }
308
309        Ok(())
310    }
311    pub fn get_relationships_from_owner(
312        &self,
313        owner_id: &EntityId,
314    ) -> Result<Vec<EntityId>, RepositoryError> {
315        let repo = repository_factory::write::create_document_repository(self.transaction)?;
316        repo.get_relationship(owner_id, &DocumentRelationshipField::Lists)
317    }
318
319    pub fn set_relationships_in_owner(
320        &mut self,
321        event_buffer: &mut EventBuffer,
322        owner_id: &EntityId,
323        ids: &[EntityId],
324    ) -> Result<(), RepositoryError> {
325        let mut repo = repository_factory::write::create_document_repository(self.transaction)?;
326        repo.set_relationship(
327            event_buffer,
328            owner_id,
329            &DocumentRelationshipField::Lists,
330            ids,
331        )
332    }
333
334    pub fn snapshot(&self, _ids: &[EntityId]) -> Result<EntityTreeSnapshot, RepositoryError> {
335        let store_snap = self.transaction.snapshot_store();
336        Ok(EntityTreeSnapshot {
337            store_snapshot: Some(store_snap),
338        })
339    }
340
341    pub fn restore(
342        &mut self,
343        event_buffer: &mut EventBuffer,
344        snap: &EntityTreeSnapshot,
345    ) -> Result<(), RepositoryError> {
346        let store_snap = snap
347            .store_snapshot
348            .as_ref()
349            .ok_or_else(|| RepositoryError::Serialization("missing store snapshot".into()))?;
350        self.transaction.restore_store(store_snap);
351
352        let store = self.transaction.get_store();
353
354        let mut emit = |entity: DirectAccessEntity, ids: Vec<EntityId>| {
355            if !ids.is_empty() {
356                event_buffer.push(Event {
357                    origin: Origin::DirectAccess(entity),
358                    ids,
359                    data: None,
360                });
361            }
362        };
363
364        // Emit Created events for this entity
365        let list_ids: Vec<_> = store.lists.read().unwrap().keys().copied().collect();
366        emit(
367            DirectAccessEntity::List(EntityEvent::Created),
368            list_ids.clone(),
369        );
370
371        // Emit Created events for strong children
372
373        Ok(())
374    }
375}
376
377pub struct ListRepositoryRO<'a> {
378    table: Box<dyn ListTableRO + 'a>,
379}
380impl<'a> ListRepositoryRO<'a> {
381    pub fn new(table: Box<dyn ListTableRO + 'a>) -> Self {
382        ListRepositoryRO { table }
383    }
384    pub fn get(&self, id: &EntityId) -> Result<Option<List>, RepositoryError> {
385        self.table.get(id)
386    }
387    pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<List>>, RepositoryError> {
388        self.table.get_multi(ids)
389    }
390    pub fn get_all(&self) -> Result<Vec<List>, RepositoryError> {
391        self.table.get_all()
392    }
393}