1use std::fmt::Display;
4
5use crate::{
6 database::transactions::Transaction,
7 direct_access::repository_factory,
8 entities::Table,
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 TableRelationshipField {
20 Cells,
21}
22
23impl Display for TableRelationshipField {
24 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
25 write!(f, "{:?}", self)
26 }
27}
28
29pub trait TableTable {
30 fn create(&mut self, entity: &Table) -> Result<Table, RepositoryError>;
31 fn create_multi(&mut self, entities: &[Table]) -> Result<Vec<Table>, RepositoryError>;
32 fn get(&self, id: &EntityId) -> Result<Option<Table>, RepositoryError>;
33 fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Table>>, RepositoryError>;
34 fn get_all(&self) -> Result<Vec<Table>, RepositoryError>;
35 fn update(&mut self, entity: &Table) -> Result<Table, RepositoryError>;
36 fn update_multi(&mut self, entities: &[Table]) -> Result<Vec<Table>, RepositoryError>;
37 fn update_with_relationships(&mut self, entity: &Table) -> Result<Table, RepositoryError>;
38 fn update_with_relationships_multi(
39 &mut self,
40 entities: &[Table],
41 ) -> Result<Vec<Table>, RepositoryError>;
42 fn remove(&mut self, id: &EntityId) -> Result<(), RepositoryError>;
43 fn remove_multi(&mut self, ids: &[EntityId]) -> Result<(), RepositoryError>;
44 fn get_relationship(
45 &self,
46 id: &EntityId,
47 field: &TableRelationshipField,
48 ) -> Result<Vec<EntityId>, RepositoryError>;
49 fn get_relationship_many(
50 &self,
51 ids: &[EntityId],
52 field: &TableRelationshipField,
53 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError>;
54 fn get_relationship_count(
55 &self,
56 id: &EntityId,
57 field: &TableRelationshipField,
58 ) -> Result<usize, RepositoryError>;
59 fn get_relationship_in_range(
60 &self,
61 id: &EntityId,
62 field: &TableRelationshipField,
63 offset: usize,
64 limit: usize,
65 ) -> Result<Vec<EntityId>, RepositoryError>;
66 fn get_relationships_from_right_ids(
67 &self,
68 field: &TableRelationshipField,
69 right_ids: &[EntityId],
70 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError>;
71 fn set_relationship_multi(
72 &mut self,
73 field: &TableRelationshipField,
74 relationships: Vec<(EntityId, Vec<EntityId>)>,
75 ) -> Result<(), RepositoryError>;
76 fn set_relationship(
77 &mut self,
78 id: &EntityId,
79 field: &TableRelationshipField,
80 right_ids: &[EntityId],
81 ) -> Result<(), RepositoryError>;
82 fn move_relationship_ids(
83 &mut self,
84 id: &EntityId,
85 field: &TableRelationshipField,
86 ids_to_move: &[EntityId],
87 new_index: i32,
88 ) -> Result<Vec<EntityId>, RepositoryError>;
89}
90
91pub trait TableTableRO {
92 fn get(&self, id: &EntityId) -> Result<Option<Table>, RepositoryError>;
93 fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Table>>, RepositoryError>;
94 fn get_all(&self) -> Result<Vec<Table>, RepositoryError>;
95 fn get_relationship(
96 &self,
97 id: &EntityId,
98 field: &TableRelationshipField,
99 ) -> Result<Vec<EntityId>, RepositoryError>;
100 fn get_relationship_many(
101 &self,
102 ids: &[EntityId],
103 field: &TableRelationshipField,
104 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError>;
105 fn get_relationship_count(
106 &self,
107 id: &EntityId,
108 field: &TableRelationshipField,
109 ) -> Result<usize, RepositoryError>;
110 fn get_relationship_in_range(
111 &self,
112 id: &EntityId,
113 field: &TableRelationshipField,
114 offset: usize,
115 limit: usize,
116 ) -> Result<Vec<EntityId>, RepositoryError>;
117 fn get_relationships_from_right_ids(
118 &self,
119 field: &TableRelationshipField,
120 right_ids: &[EntityId],
121 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError>;
122}
123
124pub struct TableRepository<'a> {
125 redb_table: Box<dyn TableTable + 'a>,
126 transaction: &'a Transaction,
127}
128
129impl<'a> TableRepository<'a> {
130 pub fn new(redb_table: Box<dyn TableTable + 'a>, transaction: &'a Transaction) -> Self {
131 TableRepository {
132 redb_table,
133 transaction,
134 }
135 }
136
137 pub fn create_orphan(
138 &mut self,
139 event_buffer: &mut EventBuffer,
140 entity: &Table,
141 ) -> Result<Table, RepositoryError> {
142 let new = self.redb_table.create(entity)?;
143 event_buffer.push(Event {
144 origin: Origin::DirectAccess(DirectAccessEntity::Table(EntityEvent::Created)),
145 ids: vec![new.id],
146 data: None,
147 });
148 Ok(new)
149 }
150
151 pub fn create_orphan_multi(
152 &mut self,
153 event_buffer: &mut EventBuffer,
154 entities: &[Table],
155 ) -> Result<Vec<Table>, RepositoryError> {
156 let new_entities = self.redb_table.create_multi(entities)?;
157 event_buffer.push(Event {
158 origin: Origin::DirectAccess(DirectAccessEntity::Table(EntityEvent::Created)),
159 ids: new_entities.iter().map(|e| e.id).collect(),
160 data: None,
161 });
162 Ok(new_entities)
163 }
164 pub fn create(
165 &mut self,
166 event_buffer: &mut EventBuffer,
167 entity: &Table,
168 owner_id: EntityId,
169 index: i32,
170 ) -> Result<Table, RepositoryError> {
171 let new = self.redb_table.create(entity)?;
172 let created_id = new.id;
173
174 let mut relationship_ids = self.get_relationships_from_owner(&owner_id)?;
175 if index >= 0 && (index as usize) < relationship_ids.len() {
177 relationship_ids.insert(index as usize, created_id);
178 } else {
179 relationship_ids.push(created_id);
180 }
181
182 self.set_relationships_in_owner(event_buffer, &owner_id, &relationship_ids)?;
183 event_buffer.push(Event {
184 origin: Origin::DirectAccess(DirectAccessEntity::Table(EntityEvent::Created)),
185 ids: vec![created_id],
186 data: None,
187 });
188 Ok(new)
189 }
190
191 pub fn create_multi(
192 &mut self,
193 event_buffer: &mut EventBuffer,
194 entities: &[Table],
195 owner_id: EntityId,
196 index: i32,
197 ) -> Result<Vec<Table>, RepositoryError> {
198 let new_entities = self.redb_table.create_multi(entities)?;
199 let created_ids: Vec<EntityId> = new_entities.iter().map(|e| e.id).collect();
200
201 let mut relationship_ids = self.get_relationships_from_owner(&owner_id)?;
202 if index >= 0 && (index as usize) < relationship_ids.len() {
203 for (i, id) in created_ids.iter().enumerate() {
204 relationship_ids.insert(index as usize + i, *id);
205 }
206 } else {
207 relationship_ids.extend(created_ids.iter());
208 }
209
210 self.set_relationships_in_owner(event_buffer, &owner_id, &relationship_ids)?;
211 event_buffer.push(Event {
212 origin: Origin::DirectAccess(DirectAccessEntity::Table(EntityEvent::Created)),
213 ids: created_ids,
214 data: None,
215 });
216 Ok(new_entities)
217 }
218
219 pub fn get(&self, id: &EntityId) -> Result<Option<Table>, RepositoryError> {
220 self.redb_table.get(id)
221 }
222 pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Table>>, RepositoryError> {
223 self.redb_table.get_multi(ids)
224 }
225 pub fn get_all(&self) -> Result<Vec<Table>, RepositoryError> {
226 self.redb_table.get_all()
227 }
228
229 pub fn update(
230 &mut self,
231 event_buffer: &mut EventBuffer,
232 entity: &Table,
233 ) -> Result<Table, RepositoryError> {
234 let updated = self.redb_table.update(entity)?;
235 event_buffer.push(Event {
236 origin: Origin::DirectAccess(DirectAccessEntity::Table(EntityEvent::Updated)),
237 ids: vec![updated.id],
238 data: None,
239 });
240 Ok(updated)
241 }
242
243 pub fn update_multi(
244 &mut self,
245 event_buffer: &mut EventBuffer,
246 entities: &[Table],
247 ) -> Result<Vec<Table>, RepositoryError> {
248 let updated = self.redb_table.update_multi(entities)?;
249 event_buffer.push(Event {
250 origin: Origin::DirectAccess(DirectAccessEntity::Table(EntityEvent::Updated)),
251 ids: updated.iter().map(|e| e.id).collect(),
252 data: None,
253 });
254 Ok(updated)
255 }
256
257 pub fn update_with_relationships(
258 &mut self,
259 event_buffer: &mut EventBuffer,
260 entity: &Table,
261 ) -> Result<Table, RepositoryError> {
262 let updated = self.redb_table.update_with_relationships(entity)?;
263 event_buffer.push(Event {
264 origin: Origin::DirectAccess(DirectAccessEntity::Table(EntityEvent::Updated)),
265 ids: vec![updated.id],
266 data: None,
267 });
268 Ok(updated)
269 }
270
271 pub fn update_with_relationships_multi(
272 &mut self,
273 event_buffer: &mut EventBuffer,
274 entities: &[Table],
275 ) -> Result<Vec<Table>, RepositoryError> {
276 let updated = self.redb_table.update_with_relationships_multi(entities)?;
277 event_buffer.push(Event {
278 origin: Origin::DirectAccess(DirectAccessEntity::Table(EntityEvent::Updated)),
279 ids: updated.iter().map(|e| e.id).collect(),
280 data: None,
281 });
282 Ok(updated)
283 }
284
285 pub fn remove(
286 &mut self,
287 event_buffer: &mut EventBuffer,
288 id: &EntityId,
289 ) -> Result<(), RepositoryError> {
290 let entity = match self.redb_table.get(id)? {
291 Some(e) => e,
292 None => return Ok(()),
293 };
294 let cells = entity.cells.clone();
297
298 repository_factory::write::create_table_cell_repository(self.transaction)
301 .remove_multi(event_buffer, &cells)?;
302 let affected_owner_ids: Vec<EntityId> = {
304 let owner_repo =
305 repository_factory::write::create_document_repository(self.transaction);
306 owner_repo
307 .get_relationships_from_right_ids(&DocumentRelationshipField::Tables, &[*id])?
308 .into_iter()
309 .map(|(owner_id, _)| owner_id)
310 .collect()
311 };
312 let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
314 std::collections::HashMap::new();
315 for owner_id in &affected_owner_ids {
316 owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
317 }
318
319 self.redb_table.remove(id)?;
321 event_buffer.push(Event {
322 origin: Origin::DirectAccess(DirectAccessEntity::Table(EntityEvent::Removed)),
323 ids: vec![*id],
324 data: None,
325 });
326 for owner_id in &affected_owner_ids {
328 if let Some(rel_ids) = owner_rel_before.get(owner_id) {
329 let updated: Vec<EntityId> =
330 rel_ids.iter().copied().filter(|rid| *rid != *id).collect();
331 self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
332 }
333 }
334
335 Ok(())
336 }
337
338 pub fn remove_multi(
339 &mut self,
340 event_buffer: &mut EventBuffer,
341 ids: &[EntityId],
342 ) -> Result<(), RepositoryError> {
343 let entities = self.redb_table.get_multi(ids)?;
344 if entities.is_empty() || entities.iter().all(|e| e.is_none()) {
345 return Ok(());
346 }
347
348 let mut cells_ids: Vec<EntityId> = entities
351 .iter()
352 .flat_map(|entity| entity.as_ref().map(|entity| entity.cells.clone()))
353 .flatten()
354 .collect();
355 cells_ids.sort();
357 cells_ids.dedup();
358
359 repository_factory::write::create_table_cell_repository(self.transaction)
362 .remove_multi(event_buffer, &cells_ids)?;
363 let affected_owner_ids: Vec<EntityId> = {
365 let owner_repo =
366 repository_factory::write::create_document_repository(self.transaction);
367 owner_repo
368 .get_relationships_from_right_ids(&DocumentRelationshipField::Tables, ids)?
369 .into_iter()
370 .map(|(owner_id, _)| owner_id)
371 .collect()
372 };
373 let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
375 std::collections::HashMap::new();
376 for owner_id in &affected_owner_ids {
377 owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
378 }
379
380 self.redb_table.remove_multi(ids)?;
381 event_buffer.push(Event {
382 origin: Origin::DirectAccess(DirectAccessEntity::Table(EntityEvent::Removed)),
383 ids: ids.into(),
384 data: None,
385 });
386 {
388 let removed_set: std::collections::HashSet<EntityId> = ids.iter().copied().collect();
389 for owner_id in &affected_owner_ids {
390 if let Some(rel_ids) = owner_rel_before.get(owner_id) {
391 let updated: Vec<EntityId> = rel_ids
392 .iter()
393 .copied()
394 .filter(|rid| !removed_set.contains(rid))
395 .collect();
396 self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
397 }
398 }
399 }
400
401 Ok(())
402 }
403 pub fn get_relationship(
404 &self,
405 id: &EntityId,
406 field: &TableRelationshipField,
407 ) -> Result<Vec<EntityId>, RepositoryError> {
408 self.redb_table.get_relationship(id, field)
409 }
410 pub fn get_relationship_many(
411 &self,
412 ids: &[EntityId],
413 field: &TableRelationshipField,
414 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
415 self.redb_table.get_relationship_many(ids, field)
416 }
417 pub fn get_relationship_count(
418 &self,
419 id: &EntityId,
420 field: &TableRelationshipField,
421 ) -> Result<usize, RepositoryError> {
422 self.redb_table.get_relationship_count(id, field)
423 }
424 pub fn get_relationship_in_range(
425 &self,
426 id: &EntityId,
427 field: &TableRelationshipField,
428 offset: usize,
429 limit: usize,
430 ) -> Result<Vec<EntityId>, RepositoryError> {
431 self.redb_table
432 .get_relationship_in_range(id, field, offset, limit)
433 }
434 pub fn get_relationships_from_right_ids(
435 &self,
436 field: &TableRelationshipField,
437 right_ids: &[EntityId],
438 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
439 self.redb_table
440 .get_relationships_from_right_ids(field, right_ids)
441 }
442
443 pub fn set_relationship_multi(
444 &mut self,
445 event_buffer: &mut EventBuffer,
446 field: &TableRelationshipField,
447 relationships: Vec<(EntityId, Vec<EntityId>)>,
448 ) -> Result<(), RepositoryError> {
449 let all_right_ids: Vec<EntityId> = relationships
451 .iter()
452 .flat_map(|(_, ids)| ids.iter().copied())
453 .collect();
454 if !all_right_ids.is_empty() {
455 match field {
456 TableRelationshipField::Cells => {
457 let child_repo =
458 repository_factory::write::create_table_cell_repository(self.transaction);
459 let found = child_repo.get_multi(&all_right_ids)?;
460 let missing: Vec<_> = all_right_ids
461 .iter()
462 .zip(found.iter())
463 .filter(|(_, entity)| entity.is_none())
464 .map(|(id, _)| *id)
465 .collect();
466 if !missing.is_empty() {
467 return Err(RepositoryError::MissingRelationshipTarget {
468 operation: "set_relationship_multi",
469 ids: missing,
470 });
471 }
472 }
473 }
474 }
475 self.redb_table
476 .set_relationship_multi(field, relationships.clone())?;
477 for (left_id, right_ids) in relationships {
478 event_buffer.push(Event {
479 origin: Origin::DirectAccess(DirectAccessEntity::Table(EntityEvent::Updated)),
480 ids: vec![left_id],
481 data: Some(format!(
482 "{}:{}",
483 field,
484 right_ids
485 .iter()
486 .map(|id| id.to_string())
487 .collect::<Vec<_>>()
488 .join(",")
489 )),
490 });
491 }
492 Ok(())
493 }
494
495 pub fn set_relationship(
496 &mut self,
497 event_buffer: &mut EventBuffer,
498 id: &EntityId,
499 field: &TableRelationshipField,
500 right_ids: &[EntityId],
501 ) -> Result<(), RepositoryError> {
502 if !right_ids.is_empty() {
504 match field {
505 TableRelationshipField::Cells => {
506 let child_repo =
507 repository_factory::write::create_table_cell_repository(self.transaction);
508 let found = child_repo.get_multi(right_ids)?;
509 let missing: Vec<_> = right_ids
510 .iter()
511 .zip(found.iter())
512 .filter(|(_, entity)| entity.is_none())
513 .map(|(id, _)| *id)
514 .collect();
515 if !missing.is_empty() {
516 return Err(RepositoryError::MissingRelationshipTarget {
517 operation: "set_relationship",
518 ids: missing,
519 });
520 }
521 }
522 }
523 }
524 self.redb_table.set_relationship(id, field, right_ids)?;
525 event_buffer.push(Event {
526 origin: Origin::DirectAccess(DirectAccessEntity::Table(EntityEvent::Updated)),
527 ids: vec![*id],
528 data: Some(format!(
529 "{}:{}",
530 field,
531 right_ids
532 .iter()
533 .map(|id| id.to_string())
534 .collect::<Vec<_>>()
535 .join(",")
536 )),
537 });
538 Ok(())
539 }
540
541 pub fn move_relationship_ids(
542 &mut self,
543 event_buffer: &mut EventBuffer,
544 id: &EntityId,
545 field: &TableRelationshipField,
546 ids_to_move: &[EntityId],
547 new_index: i32,
548 ) -> Result<Vec<EntityId>, RepositoryError> {
549 let reordered = self
550 .redb_table
551 .move_relationship_ids(id, field, ids_to_move, new_index)?;
552 event_buffer.push(Event {
553 origin: Origin::DirectAccess(DirectAccessEntity::Table(EntityEvent::Updated)),
554 ids: vec![*id],
555 data: Some(format!(
556 "{}:{}",
557 field,
558 reordered
559 .iter()
560 .map(|id| id.to_string())
561 .collect::<Vec<_>>()
562 .join(",")
563 )),
564 });
565 Ok(reordered)
566 }
567 pub fn get_relationships_from_owner(
568 &self,
569 owner_id: &EntityId,
570 ) -> Result<Vec<EntityId>, RepositoryError> {
571 let repo = repository_factory::write::create_document_repository(self.transaction);
572 repo.get_relationship(owner_id, &DocumentRelationshipField::Tables)
573 }
574
575 pub fn set_relationships_in_owner(
576 &mut self,
577 event_buffer: &mut EventBuffer,
578 owner_id: &EntityId,
579 ids: &[EntityId],
580 ) -> Result<(), RepositoryError> {
581 let mut repo = repository_factory::write::create_document_repository(self.transaction);
582 repo.set_relationship(
583 event_buffer,
584 owner_id,
585 &DocumentRelationshipField::Tables,
586 ids,
587 )
588 }
589
590 pub fn snapshot(&self, _ids: &[EntityId]) -> Result<EntityTreeSnapshot, RepositoryError> {
591 let store_snap = self.transaction.snapshot_store();
592 Ok(EntityTreeSnapshot {
593 store_snapshot: Some(store_snap),
594 })
595 }
596
597 pub fn restore(
598 &mut self,
599 event_buffer: &mut EventBuffer,
600 snap: &EntityTreeSnapshot,
601 ) -> Result<(), RepositoryError> {
602 let store_snap = snap
603 .store_snapshot
604 .as_ref()
605 .ok_or_else(|| RepositoryError::Serialization("missing store snapshot".into()))?;
606 self.transaction.restore_store(store_snap);
607
608 let store = self.transaction.get_store();
609
610 let mut emit = |entity: DirectAccessEntity, ids: Vec<EntityId>| {
611 if !ids.is_empty() {
612 event_buffer.push(Event {
613 origin: Origin::DirectAccess(entity),
614 ids,
615 data: None,
616 });
617 }
618 };
619
620 let table_ids: Vec<_> = store.tables.read().unwrap().keys().copied().collect();
622 emit(
623 DirectAccessEntity::Table(EntityEvent::Created),
624 table_ids.clone(),
625 );
626 emit(DirectAccessEntity::Table(EntityEvent::Updated), table_ids);
627
628 let tc_ids: Vec<_> = store.table_cells.read().unwrap().keys().copied().collect();
630 emit(
631 DirectAccessEntity::TableCell(EntityEvent::Created),
632 tc_ids.clone(),
633 );
634 emit(DirectAccessEntity::TableCell(EntityEvent::Updated), tc_ids);
635
636 Ok(())
637 }
638}
639
640pub struct TableRepositoryRO<'a> {
641 redb_table: Box<dyn TableTableRO + 'a>,
642}
643impl<'a> TableRepositoryRO<'a> {
644 pub fn new(redb_table: Box<dyn TableTableRO + 'a>) -> Self {
645 TableRepositoryRO { redb_table }
646 }
647 pub fn get(&self, id: &EntityId) -> Result<Option<Table>, RepositoryError> {
648 self.redb_table.get(id)
649 }
650 pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Table>>, RepositoryError> {
651 self.redb_table.get_multi(ids)
652 }
653 pub fn get_all(&self) -> Result<Vec<Table>, RepositoryError> {
654 self.redb_table.get_all()
655 }
656 pub fn get_relationship(
657 &self,
658 id: &EntityId,
659 field: &TableRelationshipField,
660 ) -> Result<Vec<EntityId>, RepositoryError> {
661 self.redb_table.get_relationship(id, field)
662 }
663 pub fn get_relationship_many(
664 &self,
665 ids: &[EntityId],
666 field: &TableRelationshipField,
667 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
668 self.redb_table.get_relationship_many(ids, field)
669 }
670 pub fn get_relationship_count(
671 &self,
672 id: &EntityId,
673 field: &TableRelationshipField,
674 ) -> Result<usize, RepositoryError> {
675 self.redb_table.get_relationship_count(id, field)
676 }
677 pub fn get_relationship_in_range(
678 &self,
679 id: &EntityId,
680 field: &TableRelationshipField,
681 offset: usize,
682 limit: usize,
683 ) -> Result<Vec<EntityId>, RepositoryError> {
684 self.redb_table
685 .get_relationship_in_range(id, field, offset, limit)
686 }
687 pub fn get_relationships_from_right_ids(
688 &self,
689 field: &TableRelationshipField,
690 right_ids: &[EntityId],
691 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
692 self.redb_table
693 .get_relationships_from_right_ids(field, right_ids)
694 }
695}