text_document_common/direct_access/use_cases/
update.rs1use 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
10pub 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 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
49pub 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 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 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 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 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
138pub 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 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
177pub 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 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 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 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 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}