Skip to main content

text_document_common/direct_access/list/
list_repository.rs

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