Skip to main content

common/direct_access/use_cases/
set_relationship.rs

1// Generated by Qleany v1.11.0 from common_da_use_cases_set_relationship.tera
2
3use super::traits::WriteRelUoWFactory;
4use crate::types::EntityId;
5use crate::undo_redo::UndoRedoCommand;
6use anyhow::Result;
7use std::any::Any;
8use std::collections::VecDeque;
9
10// ---------------------------------------------------------------------------
11// Non-undoable set-relationship
12// ---------------------------------------------------------------------------
13
14pub struct SetRelationshipUseCase<RF, F: WriteRelUoWFactory<RF>> {
15    uow_factory: F,
16    _phantom: std::marker::PhantomData<RF>,
17}
18
19impl<RF, F: WriteRelUoWFactory<RF>> SetRelationshipUseCase<RF, F> {
20    pub fn new(uow_factory: F) -> Self {
21        SetRelationshipUseCase {
22            uow_factory,
23            _phantom: std::marker::PhantomData,
24        }
25    }
26
27    pub fn execute(&mut self, id: &EntityId, field: &RF, right_ids: &[EntityId]) -> Result<()> {
28        let mut uow = self.uow_factory.create();
29        uow.begin_transaction()?;
30        uow.set_relationship(id, field, right_ids)?;
31        uow.commit()?;
32        Ok(())
33    }
34}
35
36// ---------------------------------------------------------------------------
37// Undoable set-relationship
38// ---------------------------------------------------------------------------
39
40pub struct UndoableSetRelationshipUseCase<RF: Clone, F: WriteRelUoWFactory<RF>> {
41    uow_factory: F,
42    // Scoped inverse: (id, field, before_list) restored on undo — touches only this junction
43    // row, never the whole store, so undo cannot revert other trunks.
44    undo_stack: VecDeque<(EntityId, RF, Vec<EntityId>)>,
45    redo_stack: VecDeque<(EntityId, RF, Vec<EntityId>)>,
46}
47
48impl<RF: Clone, F: WriteRelUoWFactory<RF>> UndoableSetRelationshipUseCase<RF, F> {
49    pub fn new(uow_factory: F) -> Self {
50        UndoableSetRelationshipUseCase {
51            uow_factory,
52            undo_stack: VecDeque::new(),
53            redo_stack: VecDeque::new(),
54        }
55    }
56
57    pub fn execute(&mut self, id: &EntityId, field: &RF, right_ids: &[EntityId]) -> Result<()> {
58        let mut uow = self.uow_factory.create();
59        uow.begin_transaction()?;
60        let before = uow.get_relationship(id, field)?;
61        uow.set_relationship(id, field, right_ids)?;
62        uow.commit()?;
63        self.undo_stack.push_back((*id, field.clone(), before));
64        self.redo_stack
65            .push_back((*id, field.clone(), right_ids.to_vec()));
66        Ok(())
67    }
68}
69
70impl<RF: Clone + Send + 'static, F: WriteRelUoWFactory<RF> + Send + 'static> UndoRedoCommand
71    for UndoableSetRelationshipUseCase<RF, F>
72{
73    fn undo(&mut self) -> Result<()> {
74        if let Some((id, field, before)) = self.undo_stack.pop_back() {
75            let mut uow = self.uow_factory.create();
76            uow.begin_transaction()?;
77            uow.set_relationship(&id, &field, &before)?;
78            uow.commit()?;
79        }
80        Ok(())
81    }
82
83    fn redo(&mut self) -> Result<()> {
84        if let Some((id, field, right_ids)) = self.redo_stack.pop_back() {
85            let mut uow = self.uow_factory.create();
86            uow.begin_transaction()?;
87            let before = uow.get_relationship(&id, &field)?;
88            uow.set_relationship(&id, &field, &right_ids)?;
89            uow.commit()?;
90            self.undo_stack.push_back((id, field, before));
91        }
92        Ok(())
93    }
94
95    fn as_any(&self) -> &dyn Any {
96        self
97    }
98}