1use std::fmt::Display;
4
5use crate::{
6 database::transactions::Transaction,
7 direct_access::repository_factory,
8 entities::Root,
9 event::{DirectAccessEntity, EntityEvent, Event, EventBuffer, Origin},
10 snapshot::EntityTreeSnapshot,
11 types::EntityId,
12};
13
14use crate::error::RepositoryError;
15use serde::{Deserialize, Serialize};
16
17#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
18pub enum RootRelationshipField {
19 Document,
20}
21
22impl Display for RootRelationshipField {
23 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
24 write!(f, "{:?}", self)
25 }
26}
27
28pub trait RootTable {
29 fn create(&mut self, entity: &Root) -> Result<Root, RepositoryError>;
30 fn create_multi(&mut self, entities: &[Root]) -> Result<Vec<Root>, RepositoryError>;
31 fn get(&self, id: &EntityId) -> Result<Option<Root>, RepositoryError>;
32 fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Root>>, RepositoryError>;
33 fn get_all(&self) -> Result<Vec<Root>, RepositoryError>;
34 fn update(&mut self, entity: &Root) -> Result<Root, RepositoryError>;
35 fn update_multi(&mut self, entities: &[Root]) -> Result<Vec<Root>, RepositoryError>;
36 fn update_with_relationships(&mut self, entity: &Root) -> Result<Root, RepositoryError>;
37 fn update_with_relationships_multi(
38 &mut self,
39 entities: &[Root],
40 ) -> Result<Vec<Root>, RepositoryError>;
41 fn remove(&mut self, id: &EntityId) -> Result<(), RepositoryError>;
42 fn remove_multi(&mut self, ids: &[EntityId]) -> Result<(), RepositoryError>;
43 fn get_relationship(
44 &self,
45 id: &EntityId,
46 field: &RootRelationshipField,
47 ) -> Result<Vec<EntityId>, RepositoryError>;
48 fn get_relationship_many(
49 &self,
50 ids: &[EntityId],
51 field: &RootRelationshipField,
52 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError>;
53 fn get_relationship_count(
54 &self,
55 id: &EntityId,
56 field: &RootRelationshipField,
57 ) -> Result<usize, RepositoryError>;
58 fn get_relationship_in_range(
59 &self,
60 id: &EntityId,
61 field: &RootRelationshipField,
62 offset: usize,
63 limit: usize,
64 ) -> Result<Vec<EntityId>, RepositoryError>;
65 fn get_relationships_from_right_ids(
66 &self,
67 field: &RootRelationshipField,
68 right_ids: &[EntityId],
69 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError>;
70 fn set_relationship_multi(
71 &mut self,
72 field: &RootRelationshipField,
73 relationships: Vec<(EntityId, Vec<EntityId>)>,
74 ) -> Result<(), RepositoryError>;
75 fn set_relationship(
76 &mut self,
77 id: &EntityId,
78 field: &RootRelationshipField,
79 right_ids: &[EntityId],
80 ) -> Result<(), RepositoryError>;
81 fn move_relationship_ids(
82 &mut self,
83 id: &EntityId,
84 field: &RootRelationshipField,
85 ids_to_move: &[EntityId],
86 new_index: i32,
87 ) -> Result<Vec<EntityId>, RepositoryError>;
88}
89
90pub trait RootTableRO {
91 fn get(&self, id: &EntityId) -> Result<Option<Root>, RepositoryError>;
92 fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Root>>, RepositoryError>;
93 fn get_all(&self) -> Result<Vec<Root>, RepositoryError>;
94 fn get_relationship(
95 &self,
96 id: &EntityId,
97 field: &RootRelationshipField,
98 ) -> Result<Vec<EntityId>, RepositoryError>;
99 fn get_relationship_many(
100 &self,
101 ids: &[EntityId],
102 field: &RootRelationshipField,
103 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError>;
104 fn get_relationship_count(
105 &self,
106 id: &EntityId,
107 field: &RootRelationshipField,
108 ) -> Result<usize, RepositoryError>;
109 fn get_relationship_in_range(
110 &self,
111 id: &EntityId,
112 field: &RootRelationshipField,
113 offset: usize,
114 limit: usize,
115 ) -> Result<Vec<EntityId>, RepositoryError>;
116 fn get_relationships_from_right_ids(
117 &self,
118 field: &RootRelationshipField,
119 right_ids: &[EntityId],
120 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError>;
121}
122
123pub struct RootRepository<'a> {
124 table: Box<dyn RootTable + 'a>,
125 transaction: &'a Transaction,
126}
127
128impl<'a> RootRepository<'a> {
129 pub fn new(table: Box<dyn RootTable + 'a>, transaction: &'a Transaction) -> Self {
130 RootRepository { table, transaction }
131 }
132
133 pub fn create_orphan(
134 &mut self,
135 event_buffer: &mut EventBuffer,
136 entity: &Root,
137 ) -> Result<Root, RepositoryError> {
138 let new = self.table.create(entity)?;
139 event_buffer.push(Event {
140 origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Created)),
141 ids: vec![new.id],
142 data: None,
143 });
144 Ok(new)
145 }
146
147 pub fn create_orphan_multi(
148 &mut self,
149 event_buffer: &mut EventBuffer,
150 entities: &[Root],
151 ) -> Result<Vec<Root>, RepositoryError> {
152 let new_entities = self.table.create_multi(entities)?;
153 event_buffer.push(Event {
154 origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Created)),
155 ids: new_entities.iter().map(|e| e.id).collect(),
156 data: None,
157 });
158 Ok(new_entities)
159 }
160
161 pub fn get(&self, id: &EntityId) -> Result<Option<Root>, RepositoryError> {
162 self.table.get(id)
163 }
164 pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Root>>, RepositoryError> {
165 self.table.get_multi(ids)
166 }
167 pub fn get_all(&self) -> Result<Vec<Root>, RepositoryError> {
168 self.table.get_all()
169 }
170
171 pub fn update(
172 &mut self,
173 event_buffer: &mut EventBuffer,
174 entity: &Root,
175 ) -> Result<Root, RepositoryError> {
176 let updated = self.table.update(entity)?;
177 event_buffer.push(Event {
178 origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
179 ids: vec![updated.id],
180 data: None,
181 });
182 Ok(updated)
183 }
184
185 pub fn update_multi(
186 &mut self,
187 event_buffer: &mut EventBuffer,
188 entities: &[Root],
189 ) -> Result<Vec<Root>, RepositoryError> {
190 let updated = self.table.update_multi(entities)?;
191 event_buffer.push(Event {
192 origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
193 ids: updated.iter().map(|e| e.id).collect(),
194 data: None,
195 });
196 Ok(updated)
197 }
198
199 pub fn update_with_relationships(
200 &mut self,
201 event_buffer: &mut EventBuffer,
202 entity: &Root,
203 ) -> Result<Root, RepositoryError> {
204 let updated = self.table.update_with_relationships(entity)?;
205 event_buffer.push(Event {
206 origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
207 ids: vec![updated.id],
208 data: None,
209 });
210 Ok(updated)
211 }
212
213 pub fn update_with_relationships_multi(
214 &mut self,
215 event_buffer: &mut EventBuffer,
216 entities: &[Root],
217 ) -> Result<Vec<Root>, RepositoryError> {
218 let updated = self.table.update_with_relationships_multi(entities)?;
219 event_buffer.push(Event {
220 origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
221 ids: updated.iter().map(|e| e.id).collect(),
222 data: None,
223 });
224 Ok(updated)
225 }
226
227 pub fn remove(
228 &mut self,
229 event_buffer: &mut EventBuffer,
230 id: &EntityId,
231 ) -> Result<(), RepositoryError> {
232 let entity = match self.table.get(id)? {
233 Some(e) => e,
234 None => return Ok(()),
235 };
236 let document = entity.document;
239
240 repository_factory::write::create_document_repository(self.transaction)?
243 .remove(event_buffer, &document)?;
244
245 self.table.remove(id)?;
247 event_buffer.push(Event {
248 origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Removed)),
249 ids: vec![*id],
250 data: None,
251 });
252
253 Ok(())
254 }
255
256 pub fn remove_multi(
257 &mut self,
258 event_buffer: &mut EventBuffer,
259 ids: &[EntityId],
260 ) -> Result<(), RepositoryError> {
261 let entities = self.table.get_multi(ids)?;
262 if entities.is_empty() || entities.iter().all(|e| e.is_none()) {
263 return Ok(());
264 }
265
266 let document_ids: Vec<EntityId> = entities
269 .iter()
270 .filter_map(|entity| entity.as_ref().map(|entity| entity.document))
271 .collect();
272
273 repository_factory::write::create_document_repository(self.transaction)?
276 .remove_multi(event_buffer, &document_ids)?;
277
278 self.table.remove_multi(ids)?;
279 event_buffer.push(Event {
280 origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Removed)),
281 ids: ids.into(),
282 data: None,
283 });
284
285 Ok(())
286 }
287 pub fn get_relationship(
288 &self,
289 id: &EntityId,
290 field: &RootRelationshipField,
291 ) -> Result<Vec<EntityId>, RepositoryError> {
292 self.table.get_relationship(id, field)
293 }
294 pub fn get_relationship_many(
295 &self,
296 ids: &[EntityId],
297 field: &RootRelationshipField,
298 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
299 self.table.get_relationship_many(ids, field)
300 }
301 pub fn get_relationship_count(
302 &self,
303 id: &EntityId,
304 field: &RootRelationshipField,
305 ) -> Result<usize, RepositoryError> {
306 self.table.get_relationship_count(id, field)
307 }
308 pub fn get_relationship_in_range(
309 &self,
310 id: &EntityId,
311 field: &RootRelationshipField,
312 offset: usize,
313 limit: usize,
314 ) -> Result<Vec<EntityId>, RepositoryError> {
315 self.table
316 .get_relationship_in_range(id, field, offset, limit)
317 }
318 pub fn get_relationships_from_right_ids(
319 &self,
320 field: &RootRelationshipField,
321 right_ids: &[EntityId],
322 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
323 self.table
324 .get_relationships_from_right_ids(field, right_ids)
325 }
326
327 pub fn set_relationship_multi(
328 &mut self,
329 event_buffer: &mut EventBuffer,
330 field: &RootRelationshipField,
331 relationships: Vec<(EntityId, Vec<EntityId>)>,
332 ) -> Result<(), RepositoryError> {
333 let all_right_ids: Vec<EntityId> = relationships
335 .iter()
336 .flat_map(|(_, ids)| ids.iter().copied())
337 .collect();
338 if !all_right_ids.is_empty() {
339 match field {
340 RootRelationshipField::Document => {
341 let child_repo =
342 repository_factory::write::create_document_repository(self.transaction)?;
343 let found = child_repo.get_multi(&all_right_ids)?;
344 let missing: Vec<_> = all_right_ids
345 .iter()
346 .zip(found.iter())
347 .filter(|(_, entity)| entity.is_none())
348 .map(|(id, _)| *id)
349 .collect();
350 if !missing.is_empty() {
351 return Err(RepositoryError::MissingRelationshipTarget {
352 operation: "set_relationship_multi",
353 ids: missing,
354 });
355 }
356 }
357 }
358 }
359 self.table
360 .set_relationship_multi(field, relationships.clone())?;
361 for (left_id, right_ids) in relationships {
362 event_buffer.push(Event {
363 origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
364 ids: vec![left_id],
365 data: Some(format!(
366 "{}:{}",
367 field,
368 right_ids
369 .iter()
370 .map(|id| id.to_string())
371 .collect::<Vec<_>>()
372 .join(",")
373 )),
374 });
375 }
376 Ok(())
377 }
378
379 pub fn set_relationship(
380 &mut self,
381 event_buffer: &mut EventBuffer,
382 id: &EntityId,
383 field: &RootRelationshipField,
384 right_ids: &[EntityId],
385 ) -> Result<(), RepositoryError> {
386 if !right_ids.is_empty() {
388 match field {
389 RootRelationshipField::Document => {
390 let child_repo =
391 repository_factory::write::create_document_repository(self.transaction)?;
392 let found = child_repo.get_multi(right_ids)?;
393 let missing: Vec<_> = right_ids
394 .iter()
395 .zip(found.iter())
396 .filter(|(_, entity)| entity.is_none())
397 .map(|(id, _)| *id)
398 .collect();
399 if !missing.is_empty() {
400 return Err(RepositoryError::MissingRelationshipTarget {
401 operation: "set_relationship",
402 ids: missing,
403 });
404 }
405 }
406 }
407 }
408 self.table.set_relationship(id, field, right_ids)?;
409 event_buffer.push(Event {
410 origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
411 ids: vec![*id],
412 data: Some(format!(
413 "{}:{}",
414 field,
415 right_ids
416 .iter()
417 .map(|id| id.to_string())
418 .collect::<Vec<_>>()
419 .join(",")
420 )),
421 });
422 Ok(())
423 }
424
425 pub fn move_relationship_ids(
426 &mut self,
427 event_buffer: &mut EventBuffer,
428 id: &EntityId,
429 field: &RootRelationshipField,
430 ids_to_move: &[EntityId],
431 new_index: i32,
432 ) -> Result<Vec<EntityId>, RepositoryError> {
433 let reordered = self
434 .table
435 .move_relationship_ids(id, field, ids_to_move, new_index)?;
436 event_buffer.push(Event {
437 origin: Origin::DirectAccess(DirectAccessEntity::Root(EntityEvent::Updated)),
438 ids: vec![*id],
439 data: Some(format!(
440 "{}:{}",
441 field,
442 reordered
443 .iter()
444 .map(|id| id.to_string())
445 .collect::<Vec<_>>()
446 .join(",")
447 )),
448 });
449 Ok(reordered)
450 }
451
452 pub fn snapshot(&self, _ids: &[EntityId]) -> Result<EntityTreeSnapshot, RepositoryError> {
453 let store_snap = self.transaction.snapshot_store();
454 Ok(EntityTreeSnapshot {
455 store_snapshot: Some(store_snap),
456 })
457 }
458
459 pub fn restore(
460 &mut self,
461 event_buffer: &mut EventBuffer,
462 snap: &EntityTreeSnapshot,
463 ) -> Result<(), RepositoryError> {
464 let store_snap = snap
465 .store_snapshot
466 .as_ref()
467 .ok_or_else(|| RepositoryError::Serialization("missing store snapshot".into()))?;
468 self.transaction.restore_store(store_snap);
469
470 let store = self.transaction.get_store();
471
472 let mut emit = |entity: DirectAccessEntity, ids: Vec<EntityId>| {
473 if !ids.is_empty() {
474 event_buffer.push(Event {
475 origin: Origin::DirectAccess(entity),
476 ids,
477 data: None,
478 });
479 }
480 };
481
482 let root_ids: Vec<_> = store.roots.read().unwrap().keys().copied().collect();
484 emit(
485 DirectAccessEntity::Root(EntityEvent::Created),
486 root_ids.clone(),
487 );
488 emit(DirectAccessEntity::Root(EntityEvent::Updated), root_ids);
489
490 {
493 let child_ids: Vec<_> = store.documents.read().unwrap().keys().copied().collect();
494 emit(
495 DirectAccessEntity::Document(EntityEvent::Created),
496 child_ids.clone(),
497 );
498 emit(
499 DirectAccessEntity::Document(EntityEvent::Updated),
500 child_ids,
501 );
502 }
503
504 Ok(())
505 }
506}
507
508pub struct RootRepositoryRO<'a> {
509 table: Box<dyn RootTableRO + 'a>,
510}
511impl<'a> RootRepositoryRO<'a> {
512 pub fn new(table: Box<dyn RootTableRO + 'a>) -> Self {
513 RootRepositoryRO { table }
514 }
515 pub fn get(&self, id: &EntityId) -> Result<Option<Root>, RepositoryError> {
516 self.table.get(id)
517 }
518 pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Root>>, RepositoryError> {
519 self.table.get_multi(ids)
520 }
521 pub fn get_all(&self) -> Result<Vec<Root>, RepositoryError> {
522 self.table.get_all()
523 }
524 pub fn get_relationship(
525 &self,
526 id: &EntityId,
527 field: &RootRelationshipField,
528 ) -> Result<Vec<EntityId>, RepositoryError> {
529 self.table.get_relationship(id, field)
530 }
531 pub fn get_relationship_many(
532 &self,
533 ids: &[EntityId],
534 field: &RootRelationshipField,
535 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
536 self.table.get_relationship_many(ids, field)
537 }
538 pub fn get_relationship_count(
539 &self,
540 id: &EntityId,
541 field: &RootRelationshipField,
542 ) -> Result<usize, RepositoryError> {
543 self.table.get_relationship_count(id, field)
544 }
545 pub fn get_relationship_in_range(
546 &self,
547 id: &EntityId,
548 field: &RootRelationshipField,
549 offset: usize,
550 limit: usize,
551 ) -> Result<Vec<EntityId>, RepositoryError> {
552 self.table
553 .get_relationship_in_range(id, field, offset, limit)
554 }
555 pub fn get_relationships_from_right_ids(
556 &self,
557 field: &RootRelationshipField,
558 right_ids: &[EntityId],
559 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
560 self.table
561 .get_relationships_from_right_ids(field, right_ids)
562 }
563}