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