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