1 /** 2 * Copyright © DiamondMVC 2019 3 * License: MIT (https://github.com/DiamondMVC/Diamond/blob/master/LICENSE) 4 * Author: Jacob Jensen (bausshf) 5 */ 6 module diamond.data.transaction; 7 8 /// Wrapper for transactional data management. 9 final class Transaction(T) 10 if (is(T == struct) || isScalarType!T) 11 { 12 private: 13 /// The commit delegate. 14 void delegate(Snapshot!T) _commit; 15 /// The success delegate. 16 void delegate(Snapshot!T) _success; 17 /// The failure delegate. 18 bool delegate(Snapshot!T, Throwable, size_t) _failure; 19 20 public: 21 final: 22 /// Creates a new transactional data manager. 23 this() { } 24 25 /** 26 * Creates a new transactional data manager. 27 * Params: 28 * onCommit = The delegate called when committing. 29 * onSuccess = The delegate called when a commit succeeded. 30 * onFailure = The delegate called when a commit failed. 31 */ 32 this 33 ( 34 void delegate(Snapshot!T) onCommit, 35 void delegate(Snapshot!T) onSuccess, 36 bool delegate(Snapshot!T, Throwable, size_t) onFailure 37 ) 38 { 39 _exec = onExec; 40 _success = onSuccess; 41 _failure = onFailure; 42 } 43 44 @property 45 { 46 /// Sets the delegate called when comitting. 47 void commit(void delegate(Snapshot!T) onCommit) 48 { 49 _commit = onCommit; 50 } 51 52 /// Sets the delegate called when a commit succeeded. 53 void success(void delegate(Snapshot!T) onSuccess) 54 { 55 _success = onSuccess; 56 } 57 58 /// Sets the delegate called when a commit failed. 59 void failure(bool delegate(Snapshot!T, Throwable, size_t) onFailure) 60 { 61 _failure = onFailure; 62 } 63 } 64 65 66 /** 67 * Commits the transaction. 68 * Params: 69 * snapshot = The snapshot to commit. 70 * retries = The amount of retries a commit has had. 71 */ 72 private void call(Snapshot!T snapshot, size_t retries) 73 { 74 try 75 { 76 if (_commit) _commit(snapshot); 77 if (_success) _success(snapshot); 78 } 79 catch (Throwable t) 80 { 81 if (_failure && _failure(snapshot, t, retries)) 82 { 83 call(snapshot, retries + 1); 84 } 85 else 86 { 87 throw t; 88 } 89 } 90 } 91 92 /// Operator overload for calling the transaction and committing it. 93 void opCall(Snapshot!T snapshot) 94 { 95 call(snapshot, 0); 96 } 97 }