Skip to main content

text_document_common/direct_access/use_cases/
update.rs

1// Generated by Qleany v1.5.0 from common_da_use_cases_update.tera
2
3use super::traits::WriteUoWFactory;
4use crate::types::HasId;
5use crate::undo_redo::UndoRedoCommand;
6use anyhow::{Ok, Result};
7use std::any::Any;
8use std::collections::VecDeque;
9
10// ---------------------------------------------------------------------------
11// Non-undoable update
12// ---------------------------------------------------------------------------
13
14pub struct UpdateUseCase<F: WriteUoWFactory> {
15    uow_factory: F,
16}
17
18impl<F: WriteUoWFactory> UpdateUseCase<F> {
19    pub fn new(uow_factory: F) -> Self {
20        UpdateUseCase { uow_factory }
21    }
22
23    pub fn execute(&mut self, entity: &F::Entity) -> Result<F::Entity> {
24        let results = self.execute_multi(std::slice::from_ref(entity))?;
25        results
26            .into_iter()
27            .next()
28            .ok_or_else(|| anyhow::anyhow!("Update returned empty"))
29    }
30
31    pub fn execute_multi(&mut self, entities: &[F::Entity]) -> Result<Vec<F::Entity>> {
32        let mut uow = self.uow_factory.create();
33        uow.begin_transaction()?;
34        // existence check
35        for entity in entities {
36            if uow.get(&entity.id())?.is_none() {
37                return Err(anyhow::anyhow!(
38                    "Entity with id {} does not exist",
39                    entity.id()
40                ));
41            }
42        }
43        let updated = uow.update_multi(entities)?;
44        uow.commit()?;
45        Ok(updated)
46    }
47}
48
49// ---------------------------------------------------------------------------
50// Undoable update
51// ---------------------------------------------------------------------------
52
53pub struct UndoableUpdateUseCase<F: WriteUoWFactory> {
54    uow_factory: F,
55    undo_stack: VecDeque<Vec<F::Entity>>,
56    redo_stack: VecDeque<Vec<F::Entity>>,
57}
58
59impl<F: WriteUoWFactory> UndoableUpdateUseCase<F> {
60    pub fn new(uow_factory: F) -> Self {
61        UndoableUpdateUseCase {
62            uow_factory,
63            undo_stack: VecDeque::new(),
64            redo_stack: VecDeque::new(),
65        }
66    }
67
68    pub fn execute(&mut self, entity: &F::Entity) -> Result<F::Entity> {
69        let results = self.execute_multi(std::slice::from_ref(entity))?;
70        results
71            .into_iter()
72            .next()
73            .ok_or_else(|| anyhow::anyhow!("Update returned empty"))
74    }
75
76    pub fn execute_multi(&mut self, entities: &[F::Entity]) -> Result<Vec<F::Entity>> {
77        let mut uow = self.uow_factory.create();
78        uow.begin_transaction()?;
79        // existence check
80        for entity in entities {
81            if uow.get(&entity.id())?.is_none() {
82                return Err(anyhow::anyhow!(
83                    "Entity with id {} does not exist",
84                    entity.id()
85                ));
86            }
87        }
88        // fetch old entities for undo
89        let ids: Vec<_> = entities.iter().map(|e| e.id()).collect();
90        let old_entities: Vec<F::Entity> = uow.get_multi(&ids)?.into_iter().flatten().collect();
91
92        let updated = uow.update_multi(entities)?;
93        uow.commit()?;
94
95        self.undo_stack.push_back(old_entities);
96        self.redo_stack.clear();
97        Ok(updated)
98    }
99}
100
101impl<F: WriteUoWFactory + Send + 'static> UndoRedoCommand for UndoableUpdateUseCase<F>
102where
103    F::Entity: 'static,
104{
105    fn undo(&mut self) -> Result<()> {
106        if let Some(last_entities) = self.undo_stack.pop_back() {
107            let mut uow = self.uow_factory.create();
108            uow.begin_transaction()?;
109            // Capture current state before restoring, for redo
110            let ids: Vec<_> = last_entities.iter().map(|e| e.id()).collect();
111            let current: Vec<F::Entity> = uow.get_multi(&ids)?.into_iter().flatten().collect();
112            uow.update_multi(&last_entities)?;
113            uow.commit()?;
114            self.redo_stack.push_back(current);
115        }
116        Ok(())
117    }
118
119    fn redo(&mut self) -> Result<()> {
120        if let Some(entities) = self.redo_stack.pop_back() {
121            let mut uow = self.uow_factory.create();
122            uow.begin_transaction()?;
123            // Capture current state before restoring, for undo
124            let ids: Vec<_> = entities.iter().map(|e| e.id()).collect();
125            let current: Vec<F::Entity> = uow.get_multi(&ids)?.into_iter().flatten().collect();
126            uow.update_multi(&entities)?;
127            uow.commit()?;
128            self.undo_stack.push_back(current);
129        }
130        Ok(())
131    }
132
133    fn as_any(&self) -> &dyn Any {
134        self
135    }
136}
137
138// ---------------------------------------------------------------------------
139// Non-undoable update with relationships
140// ---------------------------------------------------------------------------
141
142pub struct UpdateWithRelationshipsUseCase<F: WriteUoWFactory> {
143    uow_factory: F,
144}
145
146impl<F: WriteUoWFactory> UpdateWithRelationshipsUseCase<F> {
147    pub fn new(uow_factory: F) -> Self {
148        UpdateWithRelationshipsUseCase { uow_factory }
149    }
150
151    pub fn execute(&mut self, entity: &F::Entity) -> Result<F::Entity> {
152        let results = self.execute_multi(std::slice::from_ref(entity))?;
153        results
154            .into_iter()
155            .next()
156            .ok_or_else(|| anyhow::anyhow!("Update returned empty"))
157    }
158
159    pub fn execute_multi(&mut self, entities: &[F::Entity]) -> Result<Vec<F::Entity>> {
160        let mut uow = self.uow_factory.create();
161        uow.begin_transaction()?;
162        // existence check
163        for entity in entities {
164            if uow.get(&entity.id())?.is_none() {
165                return Err(anyhow::anyhow!(
166                    "Entity with id {} does not exist",
167                    entity.id()
168                ));
169            }
170        }
171        let updated = uow.update_with_relationships_multi(entities)?;
172        uow.commit()?;
173        Ok(updated)
174    }
175}
176
177// ---------------------------------------------------------------------------
178// Undoable update with relationships
179// ---------------------------------------------------------------------------
180
181pub struct UndoableUpdateWithRelationshipsUseCase<F: WriteUoWFactory> {
182    uow_factory: F,
183    undo_stack: VecDeque<Vec<F::Entity>>,
184    redo_stack: VecDeque<Vec<F::Entity>>,
185}
186
187impl<F: WriteUoWFactory> UndoableUpdateWithRelationshipsUseCase<F> {
188    pub fn new(uow_factory: F) -> Self {
189        UndoableUpdateWithRelationshipsUseCase {
190            uow_factory,
191            undo_stack: VecDeque::new(),
192            redo_stack: VecDeque::new(),
193        }
194    }
195
196    pub fn execute(&mut self, entity: &F::Entity) -> Result<F::Entity> {
197        let results = self.execute_multi(std::slice::from_ref(entity))?;
198        results
199            .into_iter()
200            .next()
201            .ok_or_else(|| anyhow::anyhow!("Update returned empty"))
202    }
203
204    pub fn execute_multi(&mut self, entities: &[F::Entity]) -> Result<Vec<F::Entity>> {
205        let mut uow = self.uow_factory.create();
206        uow.begin_transaction()?;
207        // existence check
208        for entity in entities {
209            if uow.get(&entity.id())?.is_none() {
210                return Err(anyhow::anyhow!(
211                    "Entity with id {} does not exist",
212                    entity.id()
213                ));
214            }
215        }
216        // fetch old entities for undo
217        let ids: Vec<_> = entities.iter().map(|e| e.id()).collect();
218        let old_entities: Vec<F::Entity> = uow.get_multi(&ids)?.into_iter().flatten().collect();
219
220        let updated = uow.update_with_relationships_multi(entities)?;
221        uow.commit()?;
222
223        self.undo_stack.push_back(old_entities);
224        self.redo_stack.clear();
225        Ok(updated)
226    }
227}
228
229impl<F: WriteUoWFactory + Send + 'static> UndoRedoCommand
230    for UndoableUpdateWithRelationshipsUseCase<F>
231where
232    F::Entity: 'static,
233{
234    fn undo(&mut self) -> Result<()> {
235        if let Some(last_entities) = self.undo_stack.pop_back() {
236            let mut uow = self.uow_factory.create();
237            uow.begin_transaction()?;
238            // Capture current state before restoring, for redo
239            let ids: Vec<_> = last_entities.iter().map(|e| e.id()).collect();
240            let current: Vec<F::Entity> = uow.get_multi(&ids)?.into_iter().flatten().collect();
241            uow.update_with_relationships_multi(&last_entities)?;
242            uow.commit()?;
243            self.redo_stack.push_back(current);
244        }
245        Ok(())
246    }
247
248    fn redo(&mut self) -> Result<()> {
249        if let Some(entities) = self.redo_stack.pop_back() {
250            let mut uow = self.uow_factory.create();
251            uow.begin_transaction()?;
252            // Capture current state before restoring, for undo
253            let ids: Vec<_> = entities.iter().map(|e| e.id()).collect();
254            let current: Vec<F::Entity> = uow.get_multi(&ids)?.into_iter().flatten().collect();
255            uow.update_with_relationships_multi(&entities)?;
256            uow.commit()?;
257            self.undo_stack.push_back(current);
258        }
259        Ok(())
260    }
261
262    fn as_any(&self) -> &dyn Any {
263        self
264    }
265}