1 module hunt.database.base.impl.command.CommandResponse; 2 3 import hunt.database.base.impl.command.CommandBase; 4 import hunt.database.base.impl.command.CommandScheduler; 5 6 import hunt.database.base.AsyncResult; 7 import hunt.database.base.Common; 8 import hunt.database.base.Exceptions; 9 import hunt.database.base.impl.TxStatus; 10 11 import hunt.logging; 12 import hunt.Object; 13 import hunt.util.TypeUtils; 14 15 alias ResponseHandler(R) = EventHandler!(CommandResponse!(R)); 16 // alias CommandHandler = EventHandler!(ICommandResponse); 17 // alias VoidResponseHandler = ResponseHandler!(Void); 18 19 20 interface ICommandResponse : IAsyncResult { 21 TxStatus txStatus(); 22 23 void notifyCommandResponse(); 24 25 bool isCommandAttatched(); 26 27 void attachCommand(ICommand cmd); 28 } 29 30 /** 31 * 32 */ 33 abstract class CommandResponse(R) : AsyncResult!(R), ICommandResponse { 34 35 // The connection that executed the command 36 CommandScheduler scheduler; 37 ICommand cmd; 38 private TxStatus _txStatus; 39 40 this(TxStatus txStatus) { 41 this._txStatus = txStatus; 42 } 43 44 TxStatus txStatus() { 45 return _txStatus; 46 } 47 48 void notifyCommandResponse() { 49 if(cmd !is null) { 50 version(HUNT_DB_DEBUG_MORE) trace("response command:", typeid(cast(Object)cmd)); 51 cmd.notifyResponse(this); 52 } else { 53 version(HUNT_DB_DEBUG) warning("No command set."); 54 } 55 } 56 57 bool isCommandAttatched() { 58 return cmd !is null; 59 } 60 61 void attachCommand(ICommand cmd) { 62 CommandBase!(R) c = cast(CommandBase!(R))cmd; 63 version(HUNT_DB_DEBUG) { 64 if(c is null) { 65 warningf("Can't cast cmd from %s to %s", 66 (typeid(cast(Object)cmd)), // TypeUtils.getSimpleName 67 typeid(CommandBase!(R))); 68 } 69 } 70 this.cmd = c; 71 } 72 73 } 74 75 /** 76 * 77 */ 78 template failedResponse(R) { 79 CommandResponse!(R) failedResponse(string msg) { 80 return failedResponse!R(new NoStackTraceThrowable(msg), TxStatus.FAILED); 81 } 82 83 CommandResponse!(R) failedResponse(string msg, TxStatus txStatus) { 84 return failedResponse!R(new NoStackTraceThrowable(msg), txStatus); 85 } 86 87 CommandResponse!(R) failedResponse(Throwable cause) { 88 return failedResponse!R(cause, TxStatus.FAILED); 89 } 90 91 CommandResponse!(R) failedResponse(Throwable r, TxStatus txStatus) { 92 return new class CommandResponse!(R) { 93 this() { 94 super(_txStatus); 95 } 96 97 R result() { 98 static if(is(R == class) || is(R == interface)) { 99 return null; 100 } else { 101 return R.init; 102 } 103 } 104 105 Throwable cause() { 106 return r; 107 } 108 109 bool succeeded() { 110 return false; 111 } 112 113 bool failed() { 114 return true; 115 } 116 }; 117 } 118 } 119 120 /** 121 * 122 */ 123 template succeededResponse(R) { 124 125 CommandResponse!(R) succeededResponse(R result) { 126 return succeededResponse(result, TxStatus.IDLE); 127 } 128 129 CommandResponse!(R) succeededResponse(R r, TxStatus txStatus) { 130 return new class CommandResponse!(R) { 131 this() { 132 super(txStatus); 133 } 134 135 R result() { 136 return r; 137 } 138 139 Throwable cause() { 140 return null; 141 } 142 143 bool succeeded() { 144 return true; 145 } 146 147 bool failed() { 148 return false; 149 } 150 }; 151 } 152 }