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