1 /*
2  * Hunt - A redis client library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11  
12 module hunt.redis.Transaction;
13 
14 import hunt.redis.Client;
15 import hunt.redis.MultiKeyPipelineBase;
16 import hunt.redis.Response;
17 
18 import hunt.Exceptions;
19 import hunt.logging.ConsoleLogger;
20 import hunt.util.Common;
21 import hunt.collection.ArrayList;
22 import hunt.collection.List;
23 
24 import hunt.redis.Exceptions;
25 
26 /**
27  * Transaction is nearly identical to Pipeline, only differences are the multi/discard behaviors
28  */
29 class Transaction : MultiKeyPipelineBase, Closeable {
30 
31     protected bool inTransaction = true;
32 
33     protected this() {
34         // client will be set later in transaction block
35     }
36 
37     this(Client client) {
38         this.client = client;
39     }
40 
41     override protected Client getClient(string key) {
42         return client;
43     }
44 
45     override protected Client getClient(const(ubyte)[] key) {
46         return client;
47     }    
48 
49     void clear() {
50         if (inTransaction) {
51             discard();
52         }
53     }
54 
55     List!(Object) exec() {
56         // Discard QUEUED or ERROR
57         client.getMany(getPipelinedResponseLength());
58         client.exec();
59         inTransaction = false;
60 
61         List!(Object) unformatted = client.getObjectMultiBulkReply();
62         if (unformatted is null) {
63             return null;
64         }
65         List!(Object) formatted = new ArrayList!(Object)();
66         foreach (Object o; unformatted) {
67             try {
68                 implementationMissing(false);
69                 trace(typeid(generateResponse(o)));
70                 
71 
72                 // formatted.add(generateResponse(o).get());
73                 // FIXME: Needing refactor or cleanup -@zxp at 7/17/2019, 11:21:20 AM
74                 // 
75             } catch (RedisDataException e) {
76                 formatted.add(e);
77             }
78         }
79         return formatted;
80     }
81 
82     List!(AbstractResponse) execGetResponse() {
83         // Discard QUEUED or ERROR
84         client.getMany(getPipelinedResponseLength());
85         client.exec();
86         inTransaction = false;
87 
88         List!(Object) unformatted = client.getObjectMultiBulkReply();
89         if (unformatted is null) {
90             return null;
91         }
92         List!AbstractResponse response = new ArrayList!AbstractResponse();
93         foreach (Object o; unformatted) {
94             response.add(generateResponse(o));
95         }
96         return response;
97     }
98 
99     string discard() {
100         client.getMany(getPipelinedResponseLength());
101         client.discard();
102         inTransaction = false;
103         clean();
104         return client.getStatusCodeReply();
105     }
106 
107     void setClient(Client client) {
108         this.client = client;
109     }
110 
111     override void close() {
112         clear();
113     }
114 }