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