UNPKG

10.3 kBJavaScriptView Raw
1/**
2 * Module dependencies
3 */
4var Item = require("./item.js");
5var patternToRegex = require('./helpers').patternToRegex;
6
7/**
8 * Hget
9 */
10exports.hget = function (mockInstance, hash, key, callback) {
11
12 var value = null;
13 var err = null;
14
15 if (mockInstance.storage[hash]) {
16 if (mockInstance.storage[hash].type === "hash") {
17 value = mockInstance.storage[hash].value[key];
18 } else {
19 err = new Error("ERR Operation against a key holding the wrong kind of value");
20 }
21 }
22
23 mockInstance._callCallback(callback, err, value);
24}
25
26/**
27 * Hexists
28 */
29exports.hexists = function (mockInstance, hash, key, callback) {
30
31 var b = 0;
32 var err = null;
33
34 if (mockInstance.storage[hash]) {
35 if (mockInstance.storage[hash].type === "hash") {
36 b = mockInstance.storage[hash].value[key] === undefined ? 0 : 1;
37 } else {
38 err = new Error("ERR Operation against a key holding the wrong kind of value");
39 }
40 }
41
42 mockInstance._callCallback(callback, err, b);
43}
44
45/**
46 * Hdel
47 */
48exports.hdel = function (mockInstance, hash) {
49
50 var nb = 0;
51 var err = null;
52
53 // We require at least 3 arguments:
54 // 0: mockInstance
55 // 1: hash name
56 // 2..N-1: key
57 // N: callback (optional)
58
59 var len = arguments.length;
60 if (len < 3) {
61 return;
62 }
63
64 var callback;
65 if ('function' === typeof arguments[len - 1]) {
66 callback = arguments[len-1];
67 }
68
69 if (mockInstance.storage[hash]) {
70 if (mockInstance.storage[hash].type === "hash") {
71 for (var i = 2; i < len; i += 1) {
72 if (len <= (i + 1)) {
73 // should skip the callback here
74 break;
75 }
76 var k = arguments[i];
77 if (mockInstance.storage[hash].value[k]) {
78 delete mockInstance.storage[hash].value[k];
79 nb++;
80 }
81 }
82 } else {
83 err = new Error("ERR Operation against a key holding the wrong kind of value");
84 }
85 }
86
87 // Do we have a callback?
88 if (callback) {
89 mockInstance._callCallback(callback, err, nb);
90 }
91}
92
93/*
94 * Hset
95 */
96exports.hset = function (mockInstance, hash, key, value, callback) {
97 var update = false;
98
99 if (mockInstance.storage[hash]) {
100 if (mockInstance.storage[hash].type !== "hash") {
101 return mockInstance._callCallback(callback,
102 new Error("ERR Operation against a key holding the wrong kind of value"));
103 }
104 if (mockInstance.storage[hash].value[key]) {
105 update = true;
106 }
107 } else {
108 mockInstance.storage[hash] = Item.createHash();
109 }
110
111 mockInstance.storage[hash].value[key] = value.toString();
112
113 mockInstance._callCallback(callback, null, update ? 0 : 1);
114};
115
116/**
117 * Hsetnx
118 */
119exports.hsetnx = function (mockInstance, hash, key, value, callback) {
120 if (!mockInstance.storage[hash]
121 || mockInstance.storage[hash].type !== "hash"
122 || !mockInstance.storage[hash].value[key]) {
123 exports.hset(mockInstance, hash, key, value, callback);
124 } else {
125 mockInstance._callCallback(callback, null, 0);
126 }
127
128};
129
130/**
131 * Hincrby
132 */
133exports.hincrby = function (mockInstance, hash, key, increment, callback) {
134
135 if (mockInstance.storage[hash]) {
136 if (mockInstance.storage[hash].type !== "hash") {
137 return mockInstance._callCallback(callback,
138 new Error("ERR Operation against a key holding the wrong kind of value"));
139 }
140 } else {
141 mockInstance.storage[hash] = Item.createHash();
142 }
143
144 if (mockInstance.storage[hash].value[key] && !/^\d+$/.test(mockInstance.storage[hash].value[key])) {
145 return mockInstance._callCallback(callback,
146 new Error("ERR hash value is not an integer"));
147 }
148
149 mockInstance.storage[hash].value[key] = parseInt(mockInstance.storage[hash].value[key]) || 0;
150
151 mockInstance.storage[hash].value[key] += increment;
152
153 mockInstance.storage[hash].value[key] += ""; //Because HGET returns Strings
154
155 mockInstance._callCallback(callback, null, parseInt(mockInstance.storage[hash].value[key])); //Because HINCRBY returns integers
156};
157
158/**
159 * Hincrbyfloat
160 */
161exports.hincrbyfloat = function (mockInstance, hash, key, increment, callback) {
162
163 if (mockInstance.storage[hash]) {
164 if (mockInstance.storage[hash].type !== "hash") {
165 return mockInstance._callCallback(callback,
166 new Error("ERR Operation against a key holding the wrong kind of value"));
167 }
168 } else {
169 mockInstance.storage[hash] = Item.createHash();
170 }
171
172 function isFloat(n) {
173 return n === +n && n !== (n|0);
174 }
175
176 if (mockInstance.storage[hash].value[key] && !isFloat(parseFloat(mockInstance.storage[hash].value[key]))) {
177 return mockInstance._callCallback(callback,
178 new Error("ERR value is not a valid float"));
179 }
180
181 mockInstance.storage[hash].value[key] = parseFloat(mockInstance.storage[hash].value[key]) || 0;
182 mockInstance.storage[hash].value[key] += parseFloat(increment);
183 //convert to string
184 mockInstance.storage[hash].value[key] = mockInstance.storage[hash].value[key].toString();
185
186 mockInstance._callCallback(callback, null, mockInstance.storage[hash].value[key]);
187};
188
189/**
190 * Hgetall
191 */
192exports.hgetall = function (mockInstance, hash, callback) {
193
194 // TODO: Confirm if this should return null or empty obj when key does not exist
195 var obj = {};
196 var nb = 0;
197
198 if (mockInstance.storage[hash] && mockInstance.storage[hash].type !== "hash") {
199 return mockInstance._callCallback(callback,
200 new Error("ERR Operation against a key holding the wrong kind of value"));
201 }
202 if (mockInstance.storage[hash]) {
203 for (var k in mockInstance.storage[hash].value) {
204 nb++;
205 obj[k] = mockInstance.storage[hash].value[k];
206 }
207 }
208
209 mockInstance._callCallback(callback, null, nb === 0 ? null : obj);
210}
211
212/**
213 * Hscan
214 */
215
216exports.hscan = function (mockInstance, hash, index, pattern, count, callback) {
217 var regex = patternToRegex(pattern);
218 var keyvals = [];
219 var idx = 1;
220 var resIdx = 0;
221 count = count || 10;
222
223 if (mockInstance.storage[hash] && mockInstance.storage[hash].type !== "hash") {
224 return mockInstance._callCallback(callback, null, ['0',[]]);
225 }
226 if (mockInstance.storage[hash]) {
227 for (var key in mockInstance.storage[hash].value) {
228 if (idx >= index && regex.test(key)) {
229 keyvals.push(key);
230 keyvals.push(mockInstance.storage[hash].value[key]);
231 count--;
232 if(count === 0) {
233 resIdx = idx+1;
234 break;
235 }
236 }
237 idx++;
238 }
239 }
240
241 mockInstance._callCallback(callback, null, [resIdx.toString(), keyvals]);
242}
243
244/**
245 * Hkeys
246 */
247exports.hkeys = function (mockInstance, hash, callback) {
248
249 var list = [];
250
251 if (mockInstance.storage[hash] && mockInstance.storage[hash].type !== "hash") {
252 return mockInstance._callCallback(callback,
253 new Error("ERR Operation against a key holding the wrong kind of value"));
254 }
255 if (mockInstance.storage[hash]) {
256 for (var k in mockInstance.storage[hash].value) {
257 list.push(k);
258 }
259 }
260
261 mockInstance._callCallback(callback, null, list);
262}
263
264/**
265 * Hvals
266 */
267exports.hvals = function (mockInstance, hash, callback) {
268
269 var list = [];
270
271 if (mockInstance.storage[hash] && mockInstance.storage[hash].type !== "hash") {
272 return mockInstance._callCallback(callback,
273 new Error("ERR Operation against a key holding the wrong kind of value"));
274 }
275 if (mockInstance.storage[hash]) {
276 for (var k in mockInstance.storage[hash].value) {
277 list.push(mockInstance.storage[hash].value[k]);
278 }
279 }
280
281 mockInstance._callCallback(callback, null, list);
282}
283
284/**
285 * Hmset
286 */
287exports.hmset = function (mockInstance, hash) {
288
289 // We require at least 3 arguments
290 // 0: mockInstance
291 // 1: hash name
292 // 2..N-2: key
293 // 3..N-1: value
294 // N: callback (optional)
295
296 var len = arguments.length;
297 if (len <= 3) {
298 return;
299 }
300
301 var callback;
302 if ('function' === typeof arguments[len - 1]) {
303 callback = arguments[len-1];
304 }
305
306 // check to see if this hash exists
307 if (mockInstance.storage[hash]) {
308 if (mockInstance.storage[hash].type !== "hash" && callback) {
309 return mockInstance._callCallback(callback,
310 new Error("ERR Operation against a key holding the wrong kind of value"));
311 }
312 } else {
313 mockInstance.storage[hash] = Item.createHash();
314 }
315
316 for (var i = 2; i < len; i += 2) {
317 if (len <= (i + 1)) {
318 // should skip the callback here
319 break;
320 }
321 var k = arguments[i];
322 var v = arguments[i + 1];
323 mockInstance.storage[hash].value[k] = v.toString();
324 }
325
326 // Do we have a callback?
327 if (callback) {
328 mockInstance._callCallback(callback, null, "OK");
329 }
330}
331
332/**
333 * Hmget
334 */
335exports.hmget = function (mockInstance) {
336
337 // We require at least 3 arguments
338 // 0: mockInstance
339 // 1: hash name
340 // 2: key/value object or first key name
341 if (arguments.length <= 3) {
342 return;
343 }
344
345 var keyValuesToGet = [];
346
347 for (var i = 2; i < arguments.length; i++) {
348
349 // Neither key nor value is a callback
350 if ('function' !== typeof arguments[i] && 'function' !== typeof arguments[i]) {
351
352 keyValuesToGet.push(arguments[i]);
353
354 } else {
355 break;
356 }
357 }
358
359 var err = null
360 var keyValues = null;
361 var hash = arguments[1];
362
363 if (mockInstance.storage[hash]) {
364 if (mockInstance.storage[hash].type !== "hash") {
365 err = new Error("ERR Operation against a key holding the wrong kind of value");
366 } else {
367 keyValues = []
368 for (var k in keyValuesToGet) {
369 keyValues.push(mockInstance.storage[hash].value[keyValuesToGet[k]] || null)
370 }
371 }
372 } else {
373 keyValues = []
374 for (k in keyValuesToGet) {
375 keyValues.push(null)
376 }
377 }
378
379 // Do we have a callback?
380 if ('function' === typeof arguments[arguments.length - 1]) {
381 mockInstance._callCallback(arguments[arguments.length - 1], err, keyValues);
382 }
383}
384
385/**
386 * Hlen
387 */
388exports.hlen = function (mockInstance, hash, callback) {
389
390 if (!mockInstance.storage[hash]) {
391 return mockInstance._callCallback(callback, null, 0);
392 }
393 if (mockInstance.storage[hash].type !== "hash") {
394 return mockInstance._callCallback(callback,
395 new Error("ERR Operation against a key holding the wrong kind of value"));
396 }
397 var cnt = 0;
398 for (var p in mockInstance.storage[hash].value) {
399 if (mockInstance.storage[hash].value.hasOwnProperty(p)) {
400 cnt++;
401 }
402 }
403
404 mockInstance._callCallback(callback, null, cnt);
405}