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 table: Box<dyn TableCellTable + 'a>,
129 transaction: &'a Transaction,
130}
131
132impl<'a> TableCellRepository<'a> {
133 pub fn new(table: Box<dyn TableCellTable + 'a>, transaction: &'a Transaction) -> Self {
134 TableCellRepository { table, transaction }
135 }
136
137 pub fn create_orphan(
138 &mut self,
139 event_buffer: &mut EventBuffer,
140 entity: &TableCell,
141 ) -> Result<TableCell, RepositoryError> {
142 let new = self.table.create(entity)?;
143 event_buffer.push(Event {
144 origin: Origin::DirectAccess(DirectAccessEntity::TableCell(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: &[TableCell],
155 ) -> Result<Vec<TableCell>, RepositoryError> {
156 let new_entities = self.table.create_multi(entities)?;
157 event_buffer.push(Event {
158 origin: Origin::DirectAccess(DirectAccessEntity::TableCell(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: &TableCell,
168 owner_id: EntityId,
169 index: i32,
170 ) -> Result<TableCell, RepositoryError> {
171 let new = self.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::TableCell(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: &[TableCell],
195 owner_id: EntityId,
196 index: i32,
197 ) -> Result<Vec<TableCell>, RepositoryError> {
198 let new_entities = self.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::TableCell(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<TableCell>, RepositoryError> {
220 self.table.get(id)
221 }
222 pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<TableCell>>, RepositoryError> {
223 self.table.get_multi(ids)
224 }
225 pub fn get_all(&self) -> Result<Vec<TableCell>, RepositoryError> {
226 self.table.get_all()
227 }
228
229 pub fn update(
230 &mut self,
231 event_buffer: &mut EventBuffer,
232 entity: &TableCell,
233 ) -> Result<TableCell, RepositoryError> {
234 let updated = self.table.update(entity)?;
235 event_buffer.push(Event {
236 origin: Origin::DirectAccess(DirectAccessEntity::TableCell(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: &[TableCell],
247 ) -> Result<Vec<TableCell>, RepositoryError> {
248 let updated = self.table.update_multi(entities)?;
249 event_buffer.push(Event {
250 origin: Origin::DirectAccess(DirectAccessEntity::TableCell(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: &TableCell,
261 ) -> Result<TableCell, RepositoryError> {
262 let updated = self.table.update_with_relationships(entity)?;
263 event_buffer.push(Event {
264 origin: Origin::DirectAccess(DirectAccessEntity::TableCell(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: &[TableCell],
275 ) -> Result<Vec<TableCell>, RepositoryError> {
276 let updated = self.table.update_with_relationships_multi(entities)?;
277 event_buffer.push(Event {
278 origin: Origin::DirectAccess(DirectAccessEntity::TableCell(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.table.get(id)? {
291 Some(e) => e,
292 None => return Ok(()),
293 };
294 let affected_owner_ids: Vec<EntityId> = {
300 let owner_repo = repository_factory::write::create_table_repository(self.transaction)?;
301 owner_repo
302 .get_relationships_from_right_ids(&TableRelationshipField::Cells, &[*id])?
303 .into_iter()
304 .map(|(owner_id, _)| owner_id)
305 .collect()
306 };
307 let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
309 std::collections::HashMap::new();
310 for owner_id in &affected_owner_ids {
311 owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
312 }
313
314 self.table.remove(id)?;
316 event_buffer.push(Event {
317 origin: Origin::DirectAccess(DirectAccessEntity::TableCell(EntityEvent::Removed)),
318 ids: vec![*id],
319 data: None,
320 });
321 for owner_id in &affected_owner_ids {
323 if let Some(rel_ids) = owner_rel_before.get(owner_id) {
324 let updated: Vec<EntityId> =
325 rel_ids.iter().copied().filter(|rid| *rid != *id).collect();
326 self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
327 }
328 }
329
330 Ok(())
331 }
332
333 pub fn remove_multi(
334 &mut self,
335 event_buffer: &mut EventBuffer,
336 ids: &[EntityId],
337 ) -> Result<(), RepositoryError> {
338 let entities = self.table.get_multi(ids)?;
339 if entities.is_empty() || entities.iter().all(|e| e.is_none()) {
340 return Ok(());
341 }
342
343 let affected_owner_ids: Vec<EntityId> = {
349 let owner_repo = repository_factory::write::create_table_repository(self.transaction)?;
350 owner_repo
351 .get_relationships_from_right_ids(&TableRelationshipField::Cells, ids)?
352 .into_iter()
353 .map(|(owner_id, _)| owner_id)
354 .collect()
355 };
356 let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
358 std::collections::HashMap::new();
359 for owner_id in &affected_owner_ids {
360 owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
361 }
362
363 self.table.remove_multi(ids)?;
364 event_buffer.push(Event {
365 origin: Origin::DirectAccess(DirectAccessEntity::TableCell(EntityEvent::Removed)),
366 ids: ids.into(),
367 data: None,
368 });
369 {
371 let removed_set: std::collections::HashSet<EntityId> = ids.iter().copied().collect();
372 for owner_id in &affected_owner_ids {
373 if let Some(rel_ids) = owner_rel_before.get(owner_id) {
374 let updated: Vec<EntityId> = rel_ids
375 .iter()
376 .copied()
377 .filter(|rid| !removed_set.contains(rid))
378 .collect();
379 self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
380 }
381 }
382 }
383
384 Ok(())
385 }
386 pub fn get_relationship(
387 &self,
388 id: &EntityId,
389 field: &TableCellRelationshipField,
390 ) -> Result<Vec<EntityId>, RepositoryError> {
391 self.table.get_relationship(id, field)
392 }
393 pub fn get_relationship_many(
394 &self,
395 ids: &[EntityId],
396 field: &TableCellRelationshipField,
397 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
398 self.table.get_relationship_many(ids, field)
399 }
400 pub fn get_relationship_count(
401 &self,
402 id: &EntityId,
403 field: &TableCellRelationshipField,
404 ) -> Result<usize, RepositoryError> {
405 self.table.get_relationship_count(id, field)
406 }
407 pub fn get_relationship_in_range(
408 &self,
409 id: &EntityId,
410 field: &TableCellRelationshipField,
411 offset: usize,
412 limit: usize,
413 ) -> Result<Vec<EntityId>, RepositoryError> {
414 self.table
415 .get_relationship_in_range(id, field, offset, limit)
416 }
417 pub fn get_relationships_from_right_ids(
418 &self,
419 field: &TableCellRelationshipField,
420 right_ids: &[EntityId],
421 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
422 self.table
423 .get_relationships_from_right_ids(field, right_ids)
424 }
425
426 pub fn set_relationship_multi(
427 &mut self,
428 event_buffer: &mut EventBuffer,
429 field: &TableCellRelationshipField,
430 relationships: Vec<(EntityId, Vec<EntityId>)>,
431 ) -> Result<(), RepositoryError> {
432 let all_right_ids: Vec<EntityId> = relationships
434 .iter()
435 .flat_map(|(_, ids)| ids.iter().copied())
436 .collect();
437 if !all_right_ids.is_empty() {
438 match field {
439 TableCellRelationshipField::CellFrame => {
440 let child_repo =
441 repository_factory::write::create_frame_repository(self.transaction)?;
442 let found = child_repo.get_multi(&all_right_ids)?;
443 let missing: Vec<_> = all_right_ids
444 .iter()
445 .zip(found.iter())
446 .filter(|(_, entity)| entity.is_none())
447 .map(|(id, _)| *id)
448 .collect();
449 if !missing.is_empty() {
450 return Err(RepositoryError::MissingRelationshipTarget {
451 operation: "set_relationship_multi",
452 ids: missing,
453 });
454 }
455 }
456 }
457 }
458 self.table
459 .set_relationship_multi(field, relationships.clone())?;
460 for (left_id, right_ids) in relationships {
461 event_buffer.push(Event {
462 origin: Origin::DirectAccess(DirectAccessEntity::TableCell(EntityEvent::Updated)),
463 ids: vec![left_id],
464 data: Some(format!(
465 "{}:{}",
466 field,
467 right_ids
468 .iter()
469 .map(|id| id.to_string())
470 .collect::<Vec<_>>()
471 .join(",")
472 )),
473 });
474 }
475 Ok(())
476 }
477
478 pub fn set_relationship(
479 &mut self,
480 event_buffer: &mut EventBuffer,
481 id: &EntityId,
482 field: &TableCellRelationshipField,
483 right_ids: &[EntityId],
484 ) -> Result<(), RepositoryError> {
485 if !right_ids.is_empty() {
487 match field {
488 TableCellRelationshipField::CellFrame => {
489 let child_repo =
490 repository_factory::write::create_frame_repository(self.transaction)?;
491 let found = child_repo.get_multi(right_ids)?;
492 let missing: Vec<_> = right_ids
493 .iter()
494 .zip(found.iter())
495 .filter(|(_, entity)| entity.is_none())
496 .map(|(id, _)| *id)
497 .collect();
498 if !missing.is_empty() {
499 return Err(RepositoryError::MissingRelationshipTarget {
500 operation: "set_relationship",
501 ids: missing,
502 });
503 }
504 }
505 }
506 }
507 self.table.set_relationship(id, field, right_ids)?;
508 event_buffer.push(Event {
509 origin: Origin::DirectAccess(DirectAccessEntity::TableCell(EntityEvent::Updated)),
510 ids: vec![*id],
511 data: Some(format!(
512 "{}:{}",
513 field,
514 right_ids
515 .iter()
516 .map(|id| id.to_string())
517 .collect::<Vec<_>>()
518 .join(",")
519 )),
520 });
521 Ok(())
522 }
523
524 pub fn move_relationship_ids(
525 &mut self,
526 event_buffer: &mut EventBuffer,
527 id: &EntityId,
528 field: &TableCellRelationshipField,
529 ids_to_move: &[EntityId],
530 new_index: i32,
531 ) -> Result<Vec<EntityId>, RepositoryError> {
532 let reordered = self
533 .table
534 .move_relationship_ids(id, field, ids_to_move, new_index)?;
535 event_buffer.push(Event {
536 origin: Origin::DirectAccess(DirectAccessEntity::TableCell(EntityEvent::Updated)),
537 ids: vec![*id],
538 data: Some(format!(
539 "{}:{}",
540 field,
541 reordered
542 .iter()
543 .map(|id| id.to_string())
544 .collect::<Vec<_>>()
545 .join(",")
546 )),
547 });
548 Ok(reordered)
549 }
550 pub fn get_relationships_from_owner(
551 &self,
552 owner_id: &EntityId,
553 ) -> Result<Vec<EntityId>, RepositoryError> {
554 let repo = repository_factory::write::create_table_repository(self.transaction)?;
555 repo.get_relationship(owner_id, &TableRelationshipField::Cells)
556 }
557
558 pub fn set_relationships_in_owner(
559 &mut self,
560 event_buffer: &mut EventBuffer,
561 owner_id: &EntityId,
562 ids: &[EntityId],
563 ) -> Result<(), RepositoryError> {
564 let mut repo = repository_factory::write::create_table_repository(self.transaction)?;
565 repo.set_relationship(event_buffer, owner_id, &TableRelationshipField::Cells, ids)
566 }
567
568 pub fn snapshot(&self, _ids: &[EntityId]) -> Result<EntityTreeSnapshot, RepositoryError> {
569 let store_snap = self.transaction.snapshot_store();
570 Ok(EntityTreeSnapshot {
571 store_snapshot: Some(store_snap),
572 })
573 }
574
575 pub fn restore(
576 &mut self,
577 event_buffer: &mut EventBuffer,
578 snap: &EntityTreeSnapshot,
579 ) -> Result<(), RepositoryError> {
580 let store_snap = snap
581 .store_snapshot
582 .as_ref()
583 .ok_or_else(|| RepositoryError::Serialization("missing store snapshot".into()))?;
584 self.transaction.restore_store(store_snap);
585
586 let store = self.transaction.get_store();
587
588 let mut emit = |entity: DirectAccessEntity, ids: Vec<EntityId>| {
589 if !ids.is_empty() {
590 event_buffer.push(Event {
591 origin: Origin::DirectAccess(entity),
592 ids,
593 data: None,
594 });
595 }
596 };
597
598 let table_cell_ids: Vec<_> = store.table_cells.read().unwrap().keys().copied().collect();
600 emit(
601 DirectAccessEntity::TableCell(EntityEvent::Created),
602 table_cell_ids.clone(),
603 );
604 emit(
605 DirectAccessEntity::TableCell(EntityEvent::Updated),
606 table_cell_ids,
607 );
608
609 Ok(())
612 }
613}
614
615pub struct TableCellRepositoryRO<'a> {
616 table: Box<dyn TableCellTableRO + 'a>,
617}
618impl<'a> TableCellRepositoryRO<'a> {
619 pub fn new(table: Box<dyn TableCellTableRO + 'a>) -> Self {
620 TableCellRepositoryRO { table }
621 }
622 pub fn get(&self, id: &EntityId) -> Result<Option<TableCell>, RepositoryError> {
623 self.table.get(id)
624 }
625 pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<TableCell>>, RepositoryError> {
626 self.table.get_multi(ids)
627 }
628 pub fn get_all(&self) -> Result<Vec<TableCell>, RepositoryError> {
629 self.table.get_all()
630 }
631 pub fn get_relationship(
632 &self,
633 id: &EntityId,
634 field: &TableCellRelationshipField,
635 ) -> Result<Vec<EntityId>, RepositoryError> {
636 self.table.get_relationship(id, field)
637 }
638 pub fn get_relationship_many(
639 &self,
640 ids: &[EntityId],
641 field: &TableCellRelationshipField,
642 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
643 self.table.get_relationship_many(ids, field)
644 }
645 pub fn get_relationship_count(
646 &self,
647 id: &EntityId,
648 field: &TableCellRelationshipField,
649 ) -> Result<usize, RepositoryError> {
650 self.table.get_relationship_count(id, field)
651 }
652 pub fn get_relationship_in_range(
653 &self,
654 id: &EntityId,
655 field: &TableCellRelationshipField,
656 offset: usize,
657 limit: usize,
658 ) -> Result<Vec<EntityId>, RepositoryError> {
659 self.table
660 .get_relationship_in_range(id, field, offset, limit)
661 }
662 pub fn get_relationships_from_right_ids(
663 &self,
664 field: &TableCellRelationshipField,
665 right_ids: &[EntityId],
666 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
667 self.table
668 .get_relationships_from_right_ids(field, right_ids)
669 }
670}