1use 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 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 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 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 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 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 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 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 {
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 #[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 self.redb_table.restore_rows(&snap.table_data)?;
371
372 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}