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