1 |
|
2 | var Multi = function(client, MockInterface) {
|
3 | this._MockInterface = MockInterface
|
4 | this._client = client;
|
5 | this._commands = [];
|
6 | this._results = [];
|
7 | this._errors = [];
|
8 | this._discarded = false;
|
9 | this._callbacks = [];
|
10 | this._batch = false;
|
11 | };
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | Multi.prototype._command = function(name, argList) {
|
17 | var self = this;
|
18 | var index = self._commands.length;
|
19 |
|
20 | var callBack;
|
21 | var args = argList;
|
22 |
|
23 | var lastArg = args[args.length -1];
|
24 | if(typeof lastArg === 'function') {
|
25 | callBack = lastArg;
|
26 | args = args.slice(0, args.length-1);
|
27 | }
|
28 |
|
29 |
|
30 |
|
31 | var command = args.concat(function (err, result) {
|
32 | if(callBack) {
|
33 | self._callbacks.push(function() {
|
34 | callBack(err, result);
|
35 | if (self._callbacks.length !== 0) {
|
36 | self._MockInterface._callCallback(self._callbacks.shift());
|
37 | }
|
38 | });
|
39 | }
|
40 |
|
41 | self._errors[index] = err;
|
42 | self._results[index] = result;
|
43 |
|
44 | var nextIndex = index + 1;
|
45 |
|
46 | if (self._commands.length === nextIndex) {
|
47 | self._callbacks.push(function() {
|
48 | self._done();
|
49 | });
|
50 | self._MockInterface._callCallback(self._callbacks.shift());
|
51 | } else {
|
52 | var next = function() {
|
53 | self._commands[nextIndex]();
|
54 | }
|
55 | self._MockInterface._callCallback(next)
|
56 | }
|
57 | });
|
58 |
|
59 | self._commands.push(function () {
|
60 | self._client[name].apply(self, command)
|
61 | });
|
62 | };
|
63 |
|
64 |
|
65 |
|
66 |
|
67 | Multi.prototype._done = function () {
|
68 | var callBack = this._doneCallback;
|
69 | if (callBack) {
|
70 | var errs = this._errors.filter(function (err) {
|
71 | return err !== null;
|
72 | });
|
73 |
|
74 | if (errs.length === 0) {
|
75 | errs = null;
|
76 | }
|
77 |
|
78 | callBack(errs, this._results);
|
79 | }
|
80 | };
|
81 |
|
82 |
|
83 |
|
84 |
|
85 | Multi.prototype.exec = Multi.prototype.exec_atomic = function(callback) {
|
86 | this._doneCallback = callback;
|
87 | if (this._discarded) {
|
88 | var err = new Error('ERR EXEC without MULTI');
|
89 |
|
90 | if (this._batch) {
|
91 | this._MockInterface._callCallback(callback, null, [err]);
|
92 | } else {
|
93 | this._MockInterface._callCallback(callback, err);
|
94 | }
|
95 | } else {
|
96 | if (this._commands.length == 0) {
|
97 | this._MockInterface._callCallback(callback, null, []);
|
98 | } else {
|
99 | this._commands[0]();
|
100 | }
|
101 | }
|
102 | return this;
|
103 | };
|
104 |
|
105 |
|
106 |
|
107 |
|
108 | Multi.prototype.discard = function (callback) {
|
109 | this._doneCallback = callback;
|
110 | this._commands.length = 0;
|
111 | this._discarded = true;
|
112 | return this;
|
113 | };
|
114 |
|
115 |
|
116 |
|
117 |
|
118 | var makeCommands = function(names) {
|
119 | names.forEach(function (name) {
|
120 | Multi.prototype[name] = Multi.prototype[name.toUpperCase()] = function () {
|
121 | this._command(name, Array.prototype.slice.call(arguments));
|
122 |
|
123 | return this;
|
124 | };
|
125 | });
|
126 | };
|
127 |
|
128 |
|
129 |
|
130 |
|
131 | makeCommands([
|
132 | 'blpop',
|
133 | 'brpop',
|
134 | 'del',
|
135 | 'decr',
|
136 | 'decrby',
|
137 | 'exists',
|
138 | 'expire',
|
139 | 'get',
|
140 | 'getset',
|
141 | 'hdel',
|
142 | 'hexists',
|
143 | 'hget',
|
144 | 'hgetall',
|
145 | 'hincrby',
|
146 | 'hincrbyfloat',
|
147 | 'hkeys',
|
148 | 'hlen',
|
149 | 'hmget',
|
150 | 'hmset',
|
151 | 'hset',
|
152 | 'hsetnx',
|
153 | 'incr',
|
154 | 'incrby',
|
155 | 'incrbyfloat',
|
156 | 'keys',
|
157 | 'lindex',
|
158 | 'llen',
|
159 | 'lpop',
|
160 | 'lpush',
|
161 | 'lpushx',
|
162 | 'lrange',
|
163 | 'lrem',
|
164 | 'lset',
|
165 | 'ltrim',
|
166 | 'mget',
|
167 | 'mset',
|
168 | 'msetnx',
|
169 | 'pexpire',
|
170 | 'ping',
|
171 | 'pttl',
|
172 | 'rpop',
|
173 | 'rpoplpush',
|
174 | 'rpush',
|
175 | 'rpushx',
|
176 | 'sadd',
|
177 | 'sismember',
|
178 | 'scard',
|
179 | 'send_command',
|
180 | 'set',
|
181 | 'set',
|
182 | 'setex',
|
183 | 'setnx',
|
184 | 'smembers',
|
185 | 'smove',
|
186 | 'srem',
|
187 | 'ttl',
|
188 | 'zadd',
|
189 | 'zcard',
|
190 | 'zcount',
|
191 | 'zincrby',
|
192 | 'zrange',
|
193 | 'zrangebyscore',
|
194 | 'zrank',
|
195 | 'zrem',
|
196 | 'zremrangebyrank',
|
197 | 'zremrangebyscore',
|
198 | 'zrevrange',
|
199 | 'zrevrangebyscore',
|
200 | 'zrevrank',
|
201 | 'zscore'
|
202 | ]);
|
203 |
|
204 | var multi = function (client, MockInterface, commands, isBatch) {
|
205 | var result = new Multi(client, MockInterface);
|
206 | result._batch = isBatch;
|
207 | if(commands) {
|
208 | commands.forEach(function (command) {
|
209 | result._command(command[0], command.slice(1));
|
210 | });
|
211 | }
|
212 | return result;
|
213 | };
|
214 |
|
215 | module.exports.multi = multi;
|
216 | module.exports.Multi = Multi; |
\ | No newline at end of file |