1use crate::{DataAcc, DataConn, DataHub};
6
7impl DataAcc for DataHub {
8 fn get_data_conn<C: DataConn + 'static>(
9 &mut self,
10 name: impl AsRef<str>,
11 ) -> errs::Result<&mut C> {
12 DataHub::get_data_conn(self, name)
13 }
14}
15
16#[cfg(test)]
17mod tests_of_data_acc {
18 use super::*;
19 use crate::{AsyncGroup, DataConn, DataSrc};
20 use std::cell::RefCell;
21 use std::rc::Rc;
22 use std::sync::{Arc, Mutex};
23
24 struct FooDataConn {
25 id: i8,
26 text: String,
27 committed: bool,
28 logger: Arc<Mutex<Vec<String>>>,
29 }
30
31 impl FooDataConn {
32 fn new(id: i8, s: &str, logger: Arc<Mutex<Vec<String>>>) -> Self {
33 {
34 let mut logger = logger.lock().unwrap();
35 logger.push(format!("FooDataConn::new {}", id));
36 }
37 Self {
38 id,
39 text: s.to_string(),
40 logger,
41 committed: false,
42 }
43 }
44 fn get_text(&self) -> String {
45 let mut logger = self.logger.lock().unwrap();
46 logger.push(format!("FooDataConn::get_text {}", self.id));
47 self.text.clone()
48 }
49 }
50 impl Drop for FooDataConn {
51 fn drop(&mut self) {
52 let mut logger = self.logger.lock().unwrap();
53 logger.push(format!("FooDataConn::drop {}", self.id));
54 }
55 }
56 impl DataConn for FooDataConn {
57 fn commit(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
58 self.committed = true;
59 let mut logger = self.logger.lock().unwrap();
60 logger.push(format!("FooDataConn::commit {}", self.id));
61 Ok(())
62 }
63 fn pre_commit(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
64 let mut logger = self.logger.lock().unwrap();
65 logger.push(format!("FooDataConn::pre_commit {}", self.id));
66 Ok(())
67 }
68 fn post_commit(&mut self, _ag: &mut AsyncGroup) {
69 let mut logger = self.logger.lock().unwrap();
70 logger.push(format!("FooDataConn::post_commit {}", self.id));
71 }
72 fn should_force_back(&self) -> bool {
73 self.committed
74 }
75 fn rollback(&mut self, _ag: &mut AsyncGroup) {
76 let mut logger = self.logger.lock().unwrap();
77 logger.push(format!("FooDataConn::rollback {}", self.id));
78 }
79 fn force_back(&mut self, _ag: &mut AsyncGroup) {
80 let mut logger = self.logger.lock().unwrap();
81 logger.push(format!("FooDataConn::force_back {}", self.id));
82 }
83 fn close(&mut self) {
84 let mut logger = self.logger.lock().unwrap();
85 logger.push(format!("FooDataConn::close {}", self.id));
86 }
87 }
88
89 struct FooDataSrc {
90 id: i8,
91 logger: Arc<Mutex<Vec<String>>>,
92 fail: bool,
93 text: String,
94 }
95 impl FooDataSrc {
96 fn new(id: i8, s: &str, logger: Arc<Mutex<Vec<String>>>, fail: bool) -> Self {
97 {
98 let mut logger = logger.lock().unwrap();
99 logger.push(format!("FooDataSrc::new {}", id));
100 }
101 Self {
102 id,
103 logger,
104 fail,
105 text: s.to_string(),
106 }
107 }
108 }
109 impl Drop for FooDataSrc {
110 fn drop(&mut self) {
111 let mut logger = self.logger.lock().unwrap();
112 logger.push(format!("FooDataSrc::drop {}", self.id));
113 }
114 }
115 impl DataSrc<FooDataConn> for FooDataSrc {
116 fn setup(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
117 if self.fail {
118 {
119 let mut logger = self.logger.lock().unwrap();
120 logger.push(format!("FooDataSrc::setup {} failed", self.id));
121 }
122 return Err(errs::Err::new("XXX".to_string()));
123 }
124 {
125 let mut logger = self.logger.lock().unwrap();
126 logger.push(format!("FooDataSrc::setup {}", self.id));
127 }
128 Ok(())
129 }
130 fn close(&mut self) {
131 let mut logger = self.logger.lock().unwrap();
132 logger.push(format!("FooDataSrc::close {}", self.id));
133 }
134 fn create_data_conn(&mut self) -> errs::Result<Box<FooDataConn>> {
135 {
136 let mut logger = self.logger.lock().unwrap();
137 logger.push(format!("FooDataSrc::create_data_src {}", self.id));
138 }
139 let conn = FooDataConn::new(self.id, &self.text, self.logger.clone());
140 Ok(Box::new(conn))
141 }
142 }
143
144 struct BarDataConn {
145 id: i8,
146 text: Option<String>,
147 ds_text: Rc<RefCell<String>>,
148 committed: bool,
149 logger: Arc<Mutex<Vec<String>>>,
150 }
151 impl BarDataConn {
152 fn new(id: i8, ds_text: Rc<RefCell<String>>, logger: Arc<Mutex<Vec<String>>>) -> Self {
153 {
154 let mut logger = logger.lock().unwrap();
155 logger.push(format!("BarDataConn::new {}", id));
156 }
157 Self {
158 id,
159 text: None,
160 ds_text,
161 logger,
162 committed: false,
163 }
164 }
165 fn set_text(&mut self, s: &str) {
166 let mut logger = self.logger.lock().unwrap();
167 logger.push(format!("BarDataConn::set_text {}", self.id));
168 self.text = Some(s.to_string());
169 }
170 }
171 impl Drop for BarDataConn {
172 fn drop(&mut self) {
173 let mut logger = self.logger.lock().unwrap();
174 logger.push(format!("BarDataConn::drop {}", self.id));
175 }
176 }
177 impl DataConn for BarDataConn {
178 fn commit(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
179 self.committed = true;
180 match &self.text {
181 Some(s) => {
182 *self.ds_text.borrow_mut() = s.to_string();
183 }
184 None => {
185 *self.ds_text.borrow_mut() = "".to_string();
186 }
187 }
188 self.logger
189 .lock()
190 .unwrap()
191 .push(format!("BarDataConn::commit {}", self.id));
192 Ok(())
193 }
194 fn pre_commit(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
195 let mut logger = self.logger.lock().unwrap();
196 logger.push(format!("BarDataConn::pre_commit {}", self.id));
197 Ok(())
198 }
199 fn post_commit(&mut self, _ag: &mut AsyncGroup) {
200 let mut logger = self.logger.lock().unwrap();
201 logger.push(format!("BarDataConn::post_commit {}", self.id));
202 }
203 fn should_force_back(&self) -> bool {
204 self.committed
205 }
206 fn rollback(&mut self, _ag: &mut AsyncGroup) {
207 let mut logger = self.logger.lock().unwrap();
208 logger.push(format!("BarDataConn::rollback {}", self.id));
209 }
210 fn force_back(&mut self, _ag: &mut AsyncGroup) {
211 let mut logger = self.logger.lock().unwrap();
212 logger.push(format!("BarDataConn::force_back {}", self.id));
213 }
214 fn close(&mut self) {
215 let mut logger = self.logger.lock().unwrap();
216 logger.push(format!("BarDataConn.text = {}", self.text.clone().unwrap()));
217 logger.push(format!("BarDataConn::close {}", self.id));
218 }
219 }
220
221 struct BarDataSrc {
222 id: i8,
223 text: Rc<RefCell<String>>,
224 logger: Arc<Mutex<Vec<String>>>,
225 }
226 impl BarDataSrc {
227 fn new(id: i8, logger: Arc<Mutex<Vec<String>>>) -> Self {
228 {
229 let mut logger = logger.lock().unwrap();
230 logger.push(format!("BarDataSrc::new {}", id));
231 }
232 Self {
233 id,
234 text: Rc::new(RefCell::new(String::new())),
235 logger,
236 }
237 }
238 }
239 impl Drop for BarDataSrc {
240 fn drop(&mut self) {
241 let mut logger = self.logger.lock().unwrap();
242 logger.push(format!("BarDataSrc::drop {}", self.id));
243 }
244 }
245 impl DataSrc<BarDataConn> for BarDataSrc {
246 fn setup(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
247 let mut logger = self.logger.lock().unwrap();
248 logger.push(format!("BarDataSrc::setup {}", self.id));
249 Ok(())
250 }
251 fn close(&mut self) {
252 let mut logger = self.logger.lock().unwrap();
253 logger.push(format!("BarDataSrc.text = {}", self.text.borrow()));
254 logger.push(format!("BarDataSrc::close {}", self.id));
255 }
256 fn create_data_conn(&mut self) -> errs::Result<Box<BarDataConn>> {
257 {
258 let mut logger = self.logger.lock().unwrap();
259 logger.push(format!("BarDataSrc::create_data_src {}", self.id));
260 }
261 let conn = BarDataConn::new(self.id, self.text.clone(), self.logger.clone());
262 Ok(Box::new(conn))
263 }
264 }
265
266 mod test_run_method {
267 use super::*;
268 use override_macro::{overridable, override_with};
269
270 #[overridable(mod = test_run_method)]
271 trait SampleData {
272 fn get_value(&mut self) -> errs::Result<String>;
273 fn set_value(&mut self, v: &str) -> errs::Result<()>;
274 }
275
276 fn sample_logic(data: &mut impl SampleData) -> errs::Result<()> {
277 let v = data.get_value()?;
278 let _ = data.set_value(&v);
279 let v = data.get_value()?;
280 let _ = data.set_value(&v);
281 Ok(())
282 }
283
284 #[overridable(mod = test_run_method)]
285 trait FooDataAcc: DataAcc {
286 fn get_value(&mut self) -> errs::Result<String> {
287 let conn = self.get_data_conn::<FooDataConn>("foo")?;
288 Ok(conn.get_text())
289 }
290 }
291
292 impl FooDataAcc for DataHub {}
293
294 #[overridable(mod = test_run_method)]
295 trait BarDataAcc: DataAcc {
296 fn set_value(&mut self, text: &str) -> errs::Result<()> {
297 let conn = self.get_data_conn::<BarDataConn>("bar")?;
298 conn.set_text(text);
299 Ok(())
300 }
301 }
302
303 impl BarDataAcc for DataHub {}
304
305 #[override_with(test_run_method::FooDataAcc, test_run_method::BarDataAcc)]
306 impl SampleData for DataHub {}
307
308 #[test]
309 fn test() {
310 let logger = Arc::new(Mutex::new(Vec::new()));
311
312 {
313 let mut data = DataHub::new();
314
315 data.uses("foo", FooDataSrc::new(1, "hello", logger.clone(), false));
316 data.uses("bar", BarDataSrc::new(2, logger.clone()));
317
318 if let Err(_) = data.run(sample_logic) {
319 panic!();
320 }
321 }
322
323 assert_eq!(
324 *logger.lock().unwrap(),
325 vec![
326 "FooDataSrc::new 1",
327 "BarDataSrc::new 2",
328 "FooDataSrc::setup 1",
329 "BarDataSrc::setup 2",
330 "FooDataSrc::create_data_src 1",
331 "FooDataConn::new 1",
332 "FooDataConn::get_text 1",
333 "BarDataSrc::create_data_src 2",
334 "BarDataConn::new 2",
335 "BarDataConn::set_text 2",
336 "FooDataConn::get_text 1",
337 "BarDataConn::set_text 2",
338 "FooDataConn::close 1",
339 "FooDataConn::drop 1",
340 "BarDataConn.text = hello",
341 "BarDataConn::close 2",
342 "BarDataConn::drop 2",
343 "BarDataSrc.text = ", "BarDataSrc::close 2",
345 "BarDataSrc::drop 2",
346 "FooDataSrc::close 1",
347 "FooDataSrc::drop 1",
348 ],
349 );
350 }
351 }
352
353 mod test_txn_method {
354 use super::*;
355 use override_macro::{overridable, override_with};
356
357 #[overridable(mod = test_txn_method)]
358 trait SampleData {
359 fn get_value(&mut self) -> errs::Result<String>;
360 fn set_value(&mut self, v: &str) -> errs::Result<()>;
361 }
362
363 fn sample_logic(data: &mut impl SampleData) -> errs::Result<()> {
364 let v = data.get_value()?;
365 let _ = data.set_value(&v);
366 let v = data.get_value()?;
367 let _ = data.set_value(&v);
368 Ok(())
369 }
370
371 #[overridable(mod = test_txn_method)]
372 trait FooDataAcc: DataAcc {
373 fn get_value(&mut self) -> errs::Result<String> {
374 let conn = self.get_data_conn::<FooDataConn>("foo")?;
375 Ok(conn.get_text())
376 }
377 }
378
379 impl FooDataAcc for DataHub {}
380
381 #[overridable(mod = test_txn_method)]
382 trait BarDataAcc: DataAcc {
383 fn set_value(&mut self, text: &str) -> errs::Result<()> {
384 let conn = self.get_data_conn::<BarDataConn>("bar")?;
385 conn.set_text(text);
386 Ok(())
387 }
388 }
389
390 impl BarDataAcc for DataHub {}
391
392 #[override_with(test_txn_method::FooDataAcc, test_txn_method::BarDataAcc)]
393 impl test_txn_method::SampleData for DataHub {}
394
395 #[test]
396 fn test() {
397 let logger = Arc::new(Mutex::new(Vec::new()));
398
399 {
400 let mut data = DataHub::new();
401
402 data.uses("foo", FooDataSrc::new(1, "hello", logger.clone(), false));
403 data.uses("bar", BarDataSrc::new(2, logger.clone()));
404
405 if let Err(_) = data.txn(sample_logic) {
406 panic!();
407 }
408 }
409
410 assert_eq!(
411 *logger.lock().unwrap(),
412 vec![
413 "FooDataSrc::new 1",
414 "BarDataSrc::new 2",
415 "FooDataSrc::setup 1",
416 "BarDataSrc::setup 2",
417 "FooDataSrc::create_data_src 1",
418 "FooDataConn::new 1",
419 "FooDataConn::get_text 1",
420 "BarDataSrc::create_data_src 2",
421 "BarDataConn::new 2",
422 "BarDataConn::set_text 2",
423 "FooDataConn::get_text 1",
424 "BarDataConn::set_text 2",
425 "FooDataConn::pre_commit 1",
426 "BarDataConn::pre_commit 2",
427 "FooDataConn::commit 1",
428 "BarDataConn::commit 2",
429 "FooDataConn::post_commit 1",
430 "BarDataConn::post_commit 2",
431 "FooDataConn::close 1",
432 "FooDataConn::drop 1",
433 "BarDataConn.text = hello",
434 "BarDataConn::close 2",
435 "BarDataConn::drop 2",
436 "BarDataSrc.text = hello", "BarDataSrc::close 2",
438 "BarDataSrc::drop 2",
439 "FooDataSrc::close 1",
440 "FooDataSrc::drop 1",
441 ],
442 );
443 }
444 }
445}