1use std::fmt::Display;
4
5use crate::{
6 database::transactions::Transaction,
7 direct_access::repository_factory,
8 entities::Workspace,
9 event::{DirectAccessEntity, EntityEvent, Event, EventBuffer, Origin},
10 snapshot::EntityTreeSnapshot,
11 types::EntityId,
12};
13
14use crate::direct_access::root::RootRelationshipField;
15use crate::error::RepositoryError;
16use serde::{Deserialize, Serialize};
17
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
19pub enum WorkspaceRelationshipField {
20 Entities,
21 Features,
22 Global,
23 UserInterface,
24}
25
26impl Display for WorkspaceRelationshipField {
27 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
28 write!(f, "{:?}", self)
29 }
30}
31
32pub trait WorkspaceTable {
33 fn create(&mut self, entity: &Workspace) -> Result<Workspace, RepositoryError>;
34 fn create_multi(&mut self, entities: &[Workspace]) -> Result<Vec<Workspace>, RepositoryError>;
35 fn get(&self, id: &EntityId) -> Result<Option<Workspace>, RepositoryError>;
36 fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Workspace>>, RepositoryError>;
37 fn get_all(&self) -> Result<Vec<Workspace>, RepositoryError>;
38 fn update(&mut self, entity: &Workspace) -> Result<Workspace, RepositoryError>;
39 fn update_multi(&mut self, entities: &[Workspace]) -> Result<Vec<Workspace>, RepositoryError>;
40 fn update_with_relationships(
41 &mut self,
42 entity: &Workspace,
43 ) -> Result<Workspace, RepositoryError>;
44 fn update_with_relationships_multi(
45 &mut self,
46 entities: &[Workspace],
47 ) -> Result<Vec<Workspace>, RepositoryError>;
48 fn remove(&mut self, id: &EntityId) -> Result<(), RepositoryError>;
49 fn remove_multi(&mut self, ids: &[EntityId]) -> Result<(), RepositoryError>;
50 fn get_relationship(
51 &self,
52 id: &EntityId,
53 field: &WorkspaceRelationshipField,
54 ) -> Result<Vec<EntityId>, RepositoryError>;
55 fn get_relationship_many(
56 &self,
57 ids: &[EntityId],
58 field: &WorkspaceRelationshipField,
59 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError>;
60 fn get_relationship_count(
61 &self,
62 id: &EntityId,
63 field: &WorkspaceRelationshipField,
64 ) -> Result<usize, RepositoryError>;
65 fn get_relationship_in_range(
66 &self,
67 id: &EntityId,
68 field: &WorkspaceRelationshipField,
69 offset: usize,
70 limit: usize,
71 ) -> Result<Vec<EntityId>, RepositoryError>;
72 fn get_relationships_from_right_ids(
73 &self,
74 field: &WorkspaceRelationshipField,
75 right_ids: &[EntityId],
76 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError>;
77 fn set_relationship_multi(
78 &mut self,
79 field: &WorkspaceRelationshipField,
80 relationships: Vec<(EntityId, Vec<EntityId>)>,
81 ) -> Result<(), RepositoryError>;
82 fn set_relationship(
83 &mut self,
84 id: &EntityId,
85 field: &WorkspaceRelationshipField,
86 right_ids: &[EntityId],
87 ) -> Result<(), RepositoryError>;
88 fn move_relationship_ids(
89 &mut self,
90 id: &EntityId,
91 field: &WorkspaceRelationshipField,
92 ids_to_move: &[EntityId],
93 new_index: i32,
94 ) -> Result<Vec<EntityId>, RepositoryError>;
95}
96
97pub trait WorkspaceTableRO {
98 fn get(&self, id: &EntityId) -> Result<Option<Workspace>, RepositoryError>;
99 fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Workspace>>, RepositoryError>;
100 fn get_all(&self) -> Result<Vec<Workspace>, RepositoryError>;
101 fn get_relationship(
102 &self,
103 id: &EntityId,
104 field: &WorkspaceRelationshipField,
105 ) -> Result<Vec<EntityId>, RepositoryError>;
106 fn get_relationship_many(
107 &self,
108 ids: &[EntityId],
109 field: &WorkspaceRelationshipField,
110 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError>;
111 fn get_relationship_count(
112 &self,
113 id: &EntityId,
114 field: &WorkspaceRelationshipField,
115 ) -> Result<usize, RepositoryError>;
116 fn get_relationship_in_range(
117 &self,
118 id: &EntityId,
119 field: &WorkspaceRelationshipField,
120 offset: usize,
121 limit: usize,
122 ) -> Result<Vec<EntityId>, RepositoryError>;
123 fn get_relationships_from_right_ids(
124 &self,
125 field: &WorkspaceRelationshipField,
126 right_ids: &[EntityId],
127 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError>;
128}
129
130pub struct WorkspaceRepository<'a> {
131 table: Box<dyn WorkspaceTable + 'a>,
132 transaction: &'a Transaction,
133}
134
135impl<'a> WorkspaceRepository<'a> {
136 pub fn new(table: Box<dyn WorkspaceTable + 'a>, transaction: &'a Transaction) -> Self {
137 WorkspaceRepository { table, transaction }
138 }
139
140 pub fn create_orphan(
141 &mut self,
142 event_buffer: &mut EventBuffer,
143 entity: &Workspace,
144 ) -> Result<Workspace, RepositoryError> {
145 let new = self.table.create(entity)?;
146 event_buffer.push(Event {
147 origin: Origin::DirectAccess(DirectAccessEntity::Workspace(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: &[Workspace],
158 ) -> Result<Vec<Workspace>, RepositoryError> {
159 let new_entities = self.table.create_multi(entities)?;
160 event_buffer.push(Event {
161 origin: Origin::DirectAccess(DirectAccessEntity::Workspace(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: &Workspace,
171 owner_id: EntityId,
172 _index: i32,
173 ) -> Result<Workspace, RepositoryError> {
174 let new = self.table.create(entity)?;
175 let created_id = new.id;
176
177 let mut relationship_ids = self.get_relationships_from_owner(&owner_id)?;
178 if relationship_ids.is_empty() {
179 relationship_ids = vec![created_id];
180 } else {
181 self.remove_multi(event_buffer, &relationship_ids)?;
183 relationship_ids = vec![created_id];
184 }
185
186 self.set_relationships_in_owner(event_buffer, &owner_id, &relationship_ids)?;
187 event_buffer.push(Event {
188 origin: Origin::DirectAccess(DirectAccessEntity::Workspace(EntityEvent::Created)),
189 ids: vec![created_id],
190 data: None,
191 });
192 Ok(new)
193 }
194
195 pub fn create_multi(
196 &mut self,
197 event_buffer: &mut EventBuffer,
198 entities: &[Workspace],
199 owner_id: EntityId,
200 _index: i32,
201 ) -> Result<Vec<Workspace>, RepositoryError> {
202 let new_entities = self.table.create_multi(entities)?;
203 let created_ids: Vec<EntityId> = new_entities.iter().map(|e| e.id).collect();
204
205 let mut relationship_ids = self.get_relationships_from_owner(&owner_id)?;
206 if relationship_ids.is_empty() {
207 relationship_ids = created_ids.clone();
208 } else {
209 self.remove_multi(event_buffer, &relationship_ids)?;
210 relationship_ids = created_ids.clone();
211 }
212
213 self.set_relationships_in_owner(event_buffer, &owner_id, &relationship_ids)?;
214 event_buffer.push(Event {
215 origin: Origin::DirectAccess(DirectAccessEntity::Workspace(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<Workspace>, RepositoryError> {
223 self.table.get(id)
224 }
225 pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Workspace>>, RepositoryError> {
226 self.table.get_multi(ids)
227 }
228 pub fn get_all(&self) -> Result<Vec<Workspace>, RepositoryError> {
229 self.table.get_all()
230 }
231
232 pub fn update(
233 &mut self,
234 event_buffer: &mut EventBuffer,
235 entity: &Workspace,
236 ) -> Result<Workspace, RepositoryError> {
237 let updated = self.table.update(entity)?;
238 event_buffer.push(Event {
239 origin: Origin::DirectAccess(DirectAccessEntity::Workspace(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: &[Workspace],
250 ) -> Result<Vec<Workspace>, RepositoryError> {
251 let updated = self.table.update_multi(entities)?;
252 event_buffer.push(Event {
253 origin: Origin::DirectAccess(DirectAccessEntity::Workspace(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: &Workspace,
264 ) -> Result<Workspace, RepositoryError> {
265 let updated = self.table.update_with_relationships(entity)?;
266 event_buffer.push(Event {
267 origin: Origin::DirectAccess(DirectAccessEntity::Workspace(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: &[Workspace],
278 ) -> Result<Vec<Workspace>, RepositoryError> {
279 let updated = self.table.update_with_relationships_multi(entities)?;
280 event_buffer.push(Event {
281 origin: Origin::DirectAccess(DirectAccessEntity::Workspace(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.table.get(id)? {
294 Some(e) => e,
295 None => return Ok(()),
296 };
297 let global = entity.global;
300 let entities = entity.entities.clone();
301 let features = entity.features.clone();
302 let user_interface = entity.user_interface;
303
304 repository_factory::write::create_global_repository(self.transaction)?
307 .remove(event_buffer, &global)?;
308 repository_factory::write::create_entity_repository(self.transaction)?
309 .remove_multi(event_buffer, &entities)?;
310 repository_factory::write::create_feature_repository(self.transaction)?
311 .remove_multi(event_buffer, &features)?;
312 repository_factory::write::create_user_interface_repository(self.transaction)?
313 .remove(event_buffer, &user_interface)?;
314 let affected_owner_ids: Vec<EntityId> = {
316 let owner_repo = repository_factory::write::create_root_repository(self.transaction)?;
317 owner_repo
318 .get_relationships_from_right_ids(&RootRelationshipField::Workspace, &[*id])?
319 .into_iter()
320 .map(|(owner_id, _)| owner_id)
321 .collect()
322 };
323 let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
325 std::collections::HashMap::new();
326 for owner_id in &affected_owner_ids {
327 owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
328 }
329
330 self.table.remove(id)?;
332 event_buffer.push(Event {
333 origin: Origin::DirectAccess(DirectAccessEntity::Workspace(EntityEvent::Removed)),
334 ids: vec![*id],
335 data: None,
336 });
337 for owner_id in &affected_owner_ids {
339 if let Some(rel_ids) = owner_rel_before.get(owner_id) {
340 let updated: Vec<EntityId> =
341 rel_ids.iter().copied().filter(|rid| *rid != *id).collect();
342 self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
343 }
344 }
345
346 Ok(())
347 }
348
349 pub fn remove_multi(
350 &mut self,
351 event_buffer: &mut EventBuffer,
352 ids: &[EntityId],
353 ) -> Result<(), RepositoryError> {
354 let entities = self.table.get_multi(ids)?;
355 if entities.is_empty() || entities.iter().all(|e| e.is_none()) {
356 return Ok(());
357 }
358
359 let global_ids: Vec<EntityId> = entities
362 .iter()
363 .filter_map(|entity| entity.as_ref().map(|entity| entity.global))
364 .collect();
365 let mut entities_ids: Vec<EntityId> = entities
366 .iter()
367 .flat_map(|entity| entity.as_ref().map(|entity| entity.entities.clone()))
368 .flatten()
369 .collect();
370 entities_ids.sort();
372 entities_ids.dedup();
373 let mut features_ids: Vec<EntityId> = entities
374 .iter()
375 .flat_map(|entity| entity.as_ref().map(|entity| entity.features.clone()))
376 .flatten()
377 .collect();
378 features_ids.sort();
380 features_ids.dedup();
381 let user_interface_ids: Vec<EntityId> = entities
382 .iter()
383 .filter_map(|entity| entity.as_ref().map(|entity| entity.user_interface))
384 .collect();
385
386 repository_factory::write::create_global_repository(self.transaction)?
389 .remove_multi(event_buffer, &global_ids)?;
390 repository_factory::write::create_entity_repository(self.transaction)?
391 .remove_multi(event_buffer, &entities_ids)?;
392 repository_factory::write::create_feature_repository(self.transaction)?
393 .remove_multi(event_buffer, &features_ids)?;
394 repository_factory::write::create_user_interface_repository(self.transaction)?
395 .remove_multi(event_buffer, &user_interface_ids)?;
396 let affected_owner_ids: Vec<EntityId> = {
398 let owner_repo = repository_factory::write::create_root_repository(self.transaction)?;
399 owner_repo
400 .get_relationships_from_right_ids(&RootRelationshipField::Workspace, ids)?
401 .into_iter()
402 .map(|(owner_id, _)| owner_id)
403 .collect()
404 };
405 let mut owner_rel_before: std::collections::HashMap<EntityId, Vec<EntityId>> =
407 std::collections::HashMap::new();
408 for owner_id in &affected_owner_ids {
409 owner_rel_before.insert(*owner_id, self.get_relationships_from_owner(owner_id)?);
410 }
411
412 self.table.remove_multi(ids)?;
413 event_buffer.push(Event {
414 origin: Origin::DirectAccess(DirectAccessEntity::Workspace(EntityEvent::Removed)),
415 ids: ids.into(),
416 data: None,
417 });
418 {
420 let removed_set: std::collections::HashSet<EntityId> = ids.iter().copied().collect();
421 for owner_id in &affected_owner_ids {
422 if let Some(rel_ids) = owner_rel_before.get(owner_id) {
423 let updated: Vec<EntityId> = rel_ids
424 .iter()
425 .copied()
426 .filter(|rid| !removed_set.contains(rid))
427 .collect();
428 self.set_relationships_in_owner(event_buffer, owner_id, &updated)?;
429 }
430 }
431 }
432
433 Ok(())
434 }
435 pub fn get_relationship(
436 &self,
437 id: &EntityId,
438 field: &WorkspaceRelationshipField,
439 ) -> Result<Vec<EntityId>, RepositoryError> {
440 self.table.get_relationship(id, field)
441 }
442 pub fn get_relationship_many(
443 &self,
444 ids: &[EntityId],
445 field: &WorkspaceRelationshipField,
446 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
447 self.table.get_relationship_many(ids, field)
448 }
449 pub fn get_relationship_count(
450 &self,
451 id: &EntityId,
452 field: &WorkspaceRelationshipField,
453 ) -> Result<usize, RepositoryError> {
454 self.table.get_relationship_count(id, field)
455 }
456 pub fn get_relationship_in_range(
457 &self,
458 id: &EntityId,
459 field: &WorkspaceRelationshipField,
460 offset: usize,
461 limit: usize,
462 ) -> Result<Vec<EntityId>, RepositoryError> {
463 self.table
464 .get_relationship_in_range(id, field, offset, limit)
465 }
466 pub fn get_relationships_from_right_ids(
467 &self,
468 field: &WorkspaceRelationshipField,
469 right_ids: &[EntityId],
470 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
471 self.table
472 .get_relationships_from_right_ids(field, right_ids)
473 }
474
475 pub fn set_relationship_multi(
476 &mut self,
477 event_buffer: &mut EventBuffer,
478 field: &WorkspaceRelationshipField,
479 relationships: Vec<(EntityId, Vec<EntityId>)>,
480 ) -> Result<(), RepositoryError> {
481 let all_right_ids: Vec<EntityId> = relationships
483 .iter()
484 .flat_map(|(_, ids)| ids.iter().copied())
485 .collect();
486 if !all_right_ids.is_empty() {
487 match field {
488 WorkspaceRelationshipField::Entities => {
489 let child_repo =
490 repository_factory::write::create_entity_repository(self.transaction)?;
491 let found = child_repo.get_multi(&all_right_ids)?;
492 let missing: Vec<_> = all_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_multi",
501 ids: missing,
502 });
503 }
504 }
505 WorkspaceRelationshipField::Features => {
506 let child_repo =
507 repository_factory::write::create_feature_repository(self.transaction)?;
508 let found = child_repo.get_multi(&all_right_ids)?;
509 let missing: Vec<_> = all_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_multi",
518 ids: missing,
519 });
520 }
521 }
522 WorkspaceRelationshipField::Global => {
523 let child_repo =
524 repository_factory::write::create_global_repository(self.transaction)?;
525 let found = child_repo.get_multi(&all_right_ids)?;
526 let missing: Vec<_> = all_right_ids
527 .iter()
528 .zip(found.iter())
529 .filter(|(_, entity)| entity.is_none())
530 .map(|(id, _)| *id)
531 .collect();
532 if !missing.is_empty() {
533 return Err(RepositoryError::MissingRelationshipTarget {
534 operation: "set_relationship_multi",
535 ids: missing,
536 });
537 }
538 }
539 WorkspaceRelationshipField::UserInterface => {
540 let child_repo = repository_factory::write::create_user_interface_repository(
541 self.transaction,
542 )?;
543 let found = child_repo.get_multi(&all_right_ids)?;
544 let missing: Vec<_> = all_right_ids
545 .iter()
546 .zip(found.iter())
547 .filter(|(_, entity)| entity.is_none())
548 .map(|(id, _)| *id)
549 .collect();
550 if !missing.is_empty() {
551 return Err(RepositoryError::MissingRelationshipTarget {
552 operation: "set_relationship_multi",
553 ids: missing,
554 });
555 }
556 }
557 }
558 }
559 self.table
560 .set_relationship_multi(field, relationships.clone())?;
561 for (left_id, right_ids) in relationships {
562 event_buffer.push(Event {
563 origin: Origin::DirectAccess(DirectAccessEntity::Workspace(EntityEvent::Updated)),
564 ids: vec![left_id],
565 data: Some(format!(
566 "{}:{}",
567 field,
568 right_ids
569 .iter()
570 .map(|id| id.to_string())
571 .collect::<Vec<_>>()
572 .join(",")
573 )),
574 });
575 }
576 Ok(())
577 }
578
579 pub fn set_relationship(
580 &mut self,
581 event_buffer: &mut EventBuffer,
582 id: &EntityId,
583 field: &WorkspaceRelationshipField,
584 right_ids: &[EntityId],
585 ) -> Result<(), RepositoryError> {
586 if !right_ids.is_empty() {
588 match field {
589 WorkspaceRelationshipField::Entities => {
590 let child_repo =
591 repository_factory::write::create_entity_repository(self.transaction)?;
592 let found = child_repo.get_multi(right_ids)?;
593 let missing: Vec<_> = right_ids
594 .iter()
595 .zip(found.iter())
596 .filter(|(_, entity)| entity.is_none())
597 .map(|(id, _)| *id)
598 .collect();
599 if !missing.is_empty() {
600 return Err(RepositoryError::MissingRelationshipTarget {
601 operation: "set_relationship",
602 ids: missing,
603 });
604 }
605 }
606 WorkspaceRelationshipField::Features => {
607 let child_repo =
608 repository_factory::write::create_feature_repository(self.transaction)?;
609 let found = child_repo.get_multi(right_ids)?;
610 let missing: Vec<_> = right_ids
611 .iter()
612 .zip(found.iter())
613 .filter(|(_, entity)| entity.is_none())
614 .map(|(id, _)| *id)
615 .collect();
616 if !missing.is_empty() {
617 return Err(RepositoryError::MissingRelationshipTarget {
618 operation: "set_relationship",
619 ids: missing,
620 });
621 }
622 }
623 WorkspaceRelationshipField::Global => {
624 let child_repo =
625 repository_factory::write::create_global_repository(self.transaction)?;
626 let found = child_repo.get_multi(right_ids)?;
627 let missing: Vec<_> = right_ids
628 .iter()
629 .zip(found.iter())
630 .filter(|(_, entity)| entity.is_none())
631 .map(|(id, _)| *id)
632 .collect();
633 if !missing.is_empty() {
634 return Err(RepositoryError::MissingRelationshipTarget {
635 operation: "set_relationship",
636 ids: missing,
637 });
638 }
639 }
640 WorkspaceRelationshipField::UserInterface => {
641 let child_repo = repository_factory::write::create_user_interface_repository(
642 self.transaction,
643 )?;
644 let found = child_repo.get_multi(right_ids)?;
645 let missing: Vec<_> = right_ids
646 .iter()
647 .zip(found.iter())
648 .filter(|(_, entity)| entity.is_none())
649 .map(|(id, _)| *id)
650 .collect();
651 if !missing.is_empty() {
652 return Err(RepositoryError::MissingRelationshipTarget {
653 operation: "set_relationship",
654 ids: missing,
655 });
656 }
657 }
658 }
659 }
660 self.table.set_relationship(id, field, right_ids)?;
661 event_buffer.push(Event {
662 origin: Origin::DirectAccess(DirectAccessEntity::Workspace(EntityEvent::Updated)),
663 ids: vec![*id],
664 data: Some(format!(
665 "{}:{}",
666 field,
667 right_ids
668 .iter()
669 .map(|id| id.to_string())
670 .collect::<Vec<_>>()
671 .join(",")
672 )),
673 });
674 Ok(())
675 }
676
677 pub fn move_relationship_ids(
678 &mut self,
679 event_buffer: &mut EventBuffer,
680 id: &EntityId,
681 field: &WorkspaceRelationshipField,
682 ids_to_move: &[EntityId],
683 new_index: i32,
684 ) -> Result<Vec<EntityId>, RepositoryError> {
685 let reordered = self
686 .table
687 .move_relationship_ids(id, field, ids_to_move, new_index)?;
688 event_buffer.push(Event {
689 origin: Origin::DirectAccess(DirectAccessEntity::Workspace(EntityEvent::Updated)),
690 ids: vec![*id],
691 data: Some(format!(
692 "{}:{}",
693 field,
694 reordered
695 .iter()
696 .map(|id| id.to_string())
697 .collect::<Vec<_>>()
698 .join(",")
699 )),
700 });
701 Ok(reordered)
702 }
703 pub fn get_relationships_from_owner(
704 &self,
705 owner_id: &EntityId,
706 ) -> Result<Vec<EntityId>, RepositoryError> {
707 let repo = repository_factory::write::create_root_repository(self.transaction)?;
708 repo.get_relationship(owner_id, &RootRelationshipField::Workspace)
709 }
710
711 pub fn set_relationships_in_owner(
712 &mut self,
713 event_buffer: &mut EventBuffer,
714 owner_id: &EntityId,
715 ids: &[EntityId],
716 ) -> Result<(), RepositoryError> {
717 let mut repo = repository_factory::write::create_root_repository(self.transaction)?;
718 repo.set_relationship(
719 event_buffer,
720 owner_id,
721 &RootRelationshipField::Workspace,
722 ids,
723 )
724 }
725
726 pub fn snapshot(&self, _ids: &[EntityId]) -> Result<EntityTreeSnapshot, RepositoryError> {
727 let store_snap = self.transaction.snapshot_store();
728 Ok(EntityTreeSnapshot {
729 store_snapshot: Some(store_snap),
730 })
731 }
732
733 pub fn restore(
734 &mut self,
735 event_buffer: &mut EventBuffer,
736 snap: &EntityTreeSnapshot,
737 ) -> Result<(), RepositoryError> {
738 let store_snap = snap
739 .store_snapshot
740 .as_ref()
741 .ok_or_else(|| RepositoryError::Serialization("missing store snapshot".into()))?;
742 self.transaction.restore_store(store_snap);
743
744 let store = self.transaction.get_store();
745
746 let mut emit = |entity: DirectAccessEntity, ids: Vec<EntityId>| {
747 if !ids.is_empty() {
748 event_buffer.push(Event {
749 origin: Origin::DirectAccess(entity),
750 ids,
751 data: None,
752 });
753 }
754 };
755
756 let workspace_ids: Vec<_> = store.workspaces.read().unwrap().keys().copied().collect();
758 emit(
759 DirectAccessEntity::Workspace(EntityEvent::Created),
760 workspace_ids.clone(),
761 );
762 emit(
763 DirectAccessEntity::Workspace(EntityEvent::Updated),
764 workspace_ids,
765 );
766
767 {
770 let child_ids: Vec<_> = store.globals.read().unwrap().keys().copied().collect();
771 emit(
772 DirectAccessEntity::Global(EntityEvent::Created),
773 child_ids.clone(),
774 );
775 }
776 {
777 let child_ids: Vec<_> = store.entitys.read().unwrap().keys().copied().collect();
778 emit(
779 DirectAccessEntity::Entity(EntityEvent::Created),
780 child_ids.clone(),
781 );
782 emit(DirectAccessEntity::Entity(EntityEvent::Updated), child_ids);
783 }
784 {
785 let child_ids: Vec<_> = store.features.read().unwrap().keys().copied().collect();
786 emit(
787 DirectAccessEntity::Feature(EntityEvent::Created),
788 child_ids.clone(),
789 );
790 emit(DirectAccessEntity::Feature(EntityEvent::Updated), child_ids);
791 }
792 {
793 let child_ids: Vec<_> = store
794 .user_interfaces
795 .read()
796 .unwrap()
797 .keys()
798 .copied()
799 .collect();
800 emit(
801 DirectAccessEntity::UserInterface(EntityEvent::Created),
802 child_ids.clone(),
803 );
804 }
805
806 Ok(())
807 }
808}
809
810pub struct WorkspaceRepositoryRO<'a> {
811 table: Box<dyn WorkspaceTableRO + 'a>,
812}
813impl<'a> WorkspaceRepositoryRO<'a> {
814 pub fn new(table: Box<dyn WorkspaceTableRO + 'a>) -> Self {
815 WorkspaceRepositoryRO { table }
816 }
817 pub fn get(&self, id: &EntityId) -> Result<Option<Workspace>, RepositoryError> {
818 self.table.get(id)
819 }
820 pub fn get_multi(&self, ids: &[EntityId]) -> Result<Vec<Option<Workspace>>, RepositoryError> {
821 self.table.get_multi(ids)
822 }
823 pub fn get_all(&self) -> Result<Vec<Workspace>, RepositoryError> {
824 self.table.get_all()
825 }
826 pub fn get_relationship(
827 &self,
828 id: &EntityId,
829 field: &WorkspaceRelationshipField,
830 ) -> Result<Vec<EntityId>, RepositoryError> {
831 self.table.get_relationship(id, field)
832 }
833 pub fn get_relationship_many(
834 &self,
835 ids: &[EntityId],
836 field: &WorkspaceRelationshipField,
837 ) -> Result<std::collections::HashMap<EntityId, Vec<EntityId>>, RepositoryError> {
838 self.table.get_relationship_many(ids, field)
839 }
840 pub fn get_relationship_count(
841 &self,
842 id: &EntityId,
843 field: &WorkspaceRelationshipField,
844 ) -> Result<usize, RepositoryError> {
845 self.table.get_relationship_count(id, field)
846 }
847 pub fn get_relationship_in_range(
848 &self,
849 id: &EntityId,
850 field: &WorkspaceRelationshipField,
851 offset: usize,
852 limit: usize,
853 ) -> Result<Vec<EntityId>, RepositoryError> {
854 self.table
855 .get_relationship_in_range(id, field, offset, limit)
856 }
857 pub fn get_relationships_from_right_ids(
858 &self,
859 field: &WorkspaceRelationshipField,
860 right_ids: &[EntityId],
861 ) -> Result<Vec<(EntityId, Vec<EntityId>)>, RepositoryError> {
862 self.table
863 .get_relationships_from_right_ids(field, right_ids)
864 }
865}