Skip to main content

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