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