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