koatty_store 1.5.4 → 1.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,1149 +1,1886 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MemoryCache = exports.messages = void 0;
4
- const tslib_1 = require("tslib");
5
- /*
6
- * @Description:
7
- * @Usage:
8
- * @Author: richen
9
- * @Date: 2021-12-02 11:03:20
10
- * @LastEditTime: 2021-12-02 14:36:11
11
- */
12
- const lodash_1 = require("lodash");
13
- const Helper = (0, tslib_1.__importStar)(require("koatty_lib"));
14
- const events_1 = require("events");
15
- /**
16
- *
17
- *
18
- * @enum {number}
19
- */
20
- var messages;
21
- (function (messages) {
22
- messages["ok"] = "OK";
23
- messages["queued"] = "QUEUED";
24
- messages["pong"] = "PONG";
25
- messages["noint"] = "ERR value is not an integer or out of range";
26
- messages["nofloat"] = "ERR value is not an float or out of range";
27
- messages["nokey"] = "ERR no such key";
28
- messages["nomultiinmulti"] = "ERR MULTI calls can not be nested";
29
- messages["nomultiexec"] = "ERR EXEC without MULTI";
30
- messages["nomultidiscard"] = "ERR DISCARD without MULTI";
31
- messages["busykey"] = "ERR target key name is busy";
32
- messages["syntax"] = "ERR syntax error";
33
- messages["unsupported"] = "MemoryCache does not support that operation";
34
- messages["wrongTypeOp"] = "WRONGTYPE Operation against a key holding the wrong kind of value";
35
- messages["wrongPayload"] = "DUMP payload version or checksum are wrong";
36
- messages["wrongArgCount"] = "ERR wrong number of arguments for '%0' command";
37
- messages["bitopnotWrongCount"] = "ERR BITOP NOT must be called with a single source key";
38
- messages["indexOutOfRange"] = "ERR index out of range";
39
- messages["invalidLexRange"] = "ERR min or max not valid string range item";
40
- messages["invalidDBIndex"] = "ERR invalid DB index";
41
- messages["invalidDBIndexNX"] = "ERR invalid DB index, '%0' does not exist";
42
- messages["mutuallyExclusiveNXXX"] = "ERR XX and NX options at the same time are not compatible";
43
- })(messages = exports.messages || (exports.messages = {}));
44
- class MemoryCache extends events_1.EventEmitter {
45
- /**
46
- * Creates an instance of MemoryCache.
47
- * @param {*} options
48
- * @memberof MemoryCache
49
- */
50
- constructor(options) {
51
- super();
52
- this.databases = Object.create({});
53
- this.options = { ...{ database: "0" }, ...options };
54
- this.currentDBIndex = 0;
55
- this.connected = false;
56
- this.lastSave = Date.now();
57
- this.multiMode = false;
58
- }
59
- /**
60
- *
61
- *
62
- * @returns {*}
63
- * @memberof MemoryCache
64
- */
65
- createClient() {
66
- this.databases[this.options.database] = Object.create({});
67
- this.cache = this.databases[this.options.database];
68
- this.connected = true;
69
- // exit multi mode if we are in it
70
- this.discard(null, true);
71
- this.emit('connect');
72
- this.emit('ready');
73
- return this;
74
- }
75
- /**
76
- *
77
- *
78
- * @returns {*}
79
- * @memberof MemoryCache
80
- */
81
- quit() {
82
- this.connected = false;
83
- // exit multi mode if we are in it
84
- this.discard(null, true);
85
- this.emit('end');
86
- return this;
87
- }
88
- /**
89
- *
90
- *
91
- * @returns {*}
92
- * @memberof MemoryCache
93
- */
94
- end() {
95
- return this.quit();
96
- }
97
- /**
98
- *
99
- *
100
- * @param {string} message
101
- * @param {Function} [callback]
102
- * @returns {*}
103
- * @memberof MemoryCache
104
- */
105
- echo(message, callback) {
106
- return this._handleCallback(callback, message);
107
- }
108
- /**
109
- *
110
- *
111
- * @param {string} message
112
- * @param {Function} [callback]
113
- * @returns {*}
114
- * @memberof MemoryCache
115
- */
116
- ping(message, callback) {
117
- message = message || messages.pong;
118
- return this._handleCallback(callback, message);
119
- }
120
- /**
121
- *
122
- *
123
- * @param {string} password
124
- * @param {Function} [callback]
125
- * @returns {*}
126
- * @memberof MemoryCache
127
- */
128
- auth(password, callback) {
129
- return this._handleCallback(callback, messages.ok);
130
- }
131
- /**
132
- *
133
- *
134
- * @param {number} dbIndex
135
- * @param {Function} [callback]
136
- * @returns {*}
137
- * @memberof MemoryCache
138
- */
139
- select(dbIndex, callback) {
140
- if (!Helper.isNumber(dbIndex)) {
141
- return this._handleCallback(callback, null, messages.invalidDBIndex);
142
- }
143
- if (!this.databases.hasOwnProperty(dbIndex)) {
144
- this.databases[dbIndex] = Object.create({});
145
- }
146
- this.multiMode = false;
147
- this.currentDBIndex = dbIndex;
148
- this.cache = this.databases[dbIndex];
149
- return this._handleCallback(callback, messages.ok);
150
- }
151
- // ---------------------------------------
152
- // Keys
153
- // ---------------------------------------
154
- get(key, callback) {
155
- let retVal = null;
156
- if (this._hasKey(key)) {
157
- this._testType(key, 'string', true, callback);
158
- retVal = this._getKey(key);
159
- }
160
- return this._handleCallback(callback, retVal);
161
- }
162
- /**
163
- * set(key, value, ttl, pttl, notexist, onlyexist, callback)
164
- *
165
- * @param {string} key
166
- * @param {(string | number)} value
167
- * @param {...any[]} params
168
- * @returns {*}
169
- * @memberof MemoryCache
170
- */
171
- set(key, value, ...params) {
172
- const retVal = null;
173
- params = (0, lodash_1.flatten)(params);
174
- const callback = this._retrieveCallback(params);
175
- let ttl, pttl, notexist, onlyexist;
176
- // parse parameters
177
- while (params.length > 0) {
178
- const param = params.shift();
179
- switch (param.toString().toLowerCase()) {
180
- case 'nx':
181
- notexist = true;
182
- break;
183
- case 'xx':
184
- onlyexist = true;
185
- break;
186
- case 'ex':
187
- if (params.length === 0) {
188
- return this._handleCallback(callback, null, messages.syntax);
189
- }
190
- ttl = parseInt(params.shift());
191
- if (isNaN(ttl)) {
192
- return this._handleCallback(callback, null, messages.noint);
193
- }
194
- break;
195
- case 'px':
196
- if (params.length === 0) {
197
- return this._handleCallback(callback, null, messages.syntax);
198
- }
199
- pttl = parseInt(params.shift());
200
- if (isNaN(pttl)) {
201
- return this._handleCallback(callback, null, messages.noint);
202
- }
203
- break;
204
- default:
205
- return this._handleCallback(callback, null, messages.syntax);
206
- }
207
- }
208
- if (!(0, lodash_1.isNil)(ttl) && !(0, lodash_1.isNil)(pttl)) {
209
- return this._handleCallback(callback, null, messages.syntax);
210
- }
211
- if (notexist && onlyexist) {
212
- return this._handleCallback(callback, null, messages.syntax);
213
- }
214
- pttl = pttl || ttl * 1000 || null;
215
- if (!(0, lodash_1.isNil)(pttl)) {
216
- pttl = Date.now() + pttl;
217
- }
218
- if (this._hasKey(key)) {
219
- this._testType(key, 'string', true, callback);
220
- if (notexist) {
221
- return this._handleCallback(callback, retVal);
222
- }
223
- }
224
- else if (onlyexist) {
225
- return this._handleCallback(callback, retVal);
226
- }
227
- this.cache[key] = this._makeKey(value.toString(), 'string', pttl);
228
- return this._handleCallback(callback, messages.ok);
229
- }
230
- /**
231
- *
232
- *
233
- * @param {string} key
234
- * @param {Function} [callback]
235
- * @returns {*}
236
- * @memberof MemoryCache
237
- */
238
- ttl(key, callback) {
239
- let retVal = this.pttl(key);
240
- if (retVal >= 0 || retVal <= -3) {
241
- retVal = Math.floor(retVal / 1000);
242
- }
243
- return this._handleCallback(callback, retVal);
244
- }
245
- /**
246
- *
247
- *
248
- * @param {string} key
249
- * @param {number} seconds
250
- * @param {Function} [callback]
251
- * @returns {*}
252
- * @memberof MemoryCache
253
- */
254
- expire(key, seconds, callback) {
255
- let retVal = 0;
256
- if (this._hasKey(key)) {
257
- this.cache[key].timeout = Date.now() + seconds * 1000;
258
- retVal = 1;
259
- }
260
- return this._handleCallback(callback, retVal);
261
- }
262
- /**
263
- *
264
- *
265
- * @param {...any[]} keys
266
- * @returns {*}
267
- * @memberof MemoryCache
268
- */
269
- del(...keys) {
270
- let retVal = 0;
271
- const callback = this._retrieveCallback(keys);
272
- // Flatten the array in case an array was passed
273
- keys = (0, lodash_1.flatten)(keys);
274
- for (let itr = 0; itr < keys.length; itr++) {
275
- const key = keys[itr];
276
- if (this._hasKey(key)) {
277
- delete this.cache[key];
278
- retVal++;
279
- }
280
- }
281
- return this._handleCallback(callback, retVal);
282
- }
283
- /**
284
- *
285
- *
286
- * @param {...any[]} keys
287
- * @returns {*}
288
- * @memberof MemoryCache
289
- */
290
- exists(...keys) {
291
- let retVal = 0;
292
- const callback = this._retrieveCallback(keys);
293
- for (let itr = 0; itr < keys.length; itr++) {
294
- const key = keys[itr];
295
- if (this._hasKey(key)) {
296
- retVal++;
297
- }
298
- }
299
- return this._handleCallback(callback, retVal);
300
- }
301
- /**
302
- *
303
- *
304
- * @param {string} key
305
- * @param {Function} [callback]
306
- * @returns {*}
307
- * @memberof MemoryCache
308
- */
309
- incr(key, callback) {
310
- let retVal = null;
311
- try {
312
- retVal = this._addToKey(key, 1);
313
- }
314
- catch (err) {
315
- return this._handleCallback(callback, null, err);
316
- }
317
- return this._handleCallback(callback, retVal);
318
- }
319
- /**
320
- *
321
- *
322
- * @param {string} key
323
- * @param {number} amount
324
- * @param {Function} [callback]
325
- * @returns {*}
326
- * @memberof MemoryCache
327
- */
328
- incrby(key, amount, callback) {
329
- let retVal = null;
330
- try {
331
- retVal = this._addToKey(key, amount);
332
- }
333
- catch (err) {
334
- return this._handleCallback(callback, null, err);
335
- }
336
- return this._handleCallback(callback, retVal);
337
- }
338
- /**
339
- *
340
- *
341
- * @param {string} key
342
- * @param {Function} [callback]
343
- * @returns {*}
344
- * @memberof MemoryCache
345
- */
346
- decr(key, callback) {
347
- let retVal = null;
348
- try {
349
- retVal = this._addToKey(key, -1);
350
- }
351
- catch (err) {
352
- return this._handleCallback(callback, null, err);
353
- }
354
- return this._handleCallback(callback, retVal);
355
- }
356
- /**
357
- *
358
- *
359
- * @param {string} key
360
- * @param {number} amount
361
- * @param {Function} [callback]
362
- * @returns {*}
363
- * @memberof MemoryCache
364
- */
365
- decrby(key, amount, callback) {
366
- let retVal = null;
367
- try {
368
- retVal = this._addToKey(key, -amount);
369
- }
370
- catch (err) {
371
- return this._handleCallback(callback, null, err);
372
- }
373
- return this._handleCallback(callback, retVal);
374
- }
375
- // ---------------------------------------
376
- // ## Hash ##
377
- // ---------------------------------------
378
- hset(key, field, value, callback) {
379
- let retVal = 0;
380
- if (this._hasKey(key)) {
381
- this._testType(key, 'hash', true, callback);
382
- }
383
- else {
384
- this.cache[key] = this._makeKey({}, 'hash');
385
- }
386
- if (!this._hasField(key, field)) {
387
- retVal = 1;
388
- }
389
- this._setField(key, field, value.toString());
390
- this.persist(key);
391
- return this._handleCallback(callback, retVal);
392
- }
393
- /**
394
- *
395
- *
396
- * @param {string} key
397
- * @param {string} field
398
- * @param {Function} [callback]
399
- * @returns {*}
400
- * @memberof MemoryCache
401
- */
402
- hget(key, field, callback) {
403
- let retVal = null;
404
- if (this._hasKey(key)) {
405
- this._testType(key, 'hash', true, callback);
406
- if (this._hasField(key, field)) {
407
- retVal = this._getKey(key)[field];
408
- }
409
- }
410
- return this._handleCallback(callback, retVal);
411
- }
412
- /**
413
- *
414
- *
415
- * @param {string} key
416
- * @param {string} field
417
- * @param {Function} [callback]
418
- * @returns {*}
419
- * @memberof MemoryCache
420
- */
421
- hexists(key, field, callback) {
422
- let retVal = 0;
423
- if (this._hasKey(key)) {
424
- this._testType(key, 'hash', true, callback);
425
- if (this._hasField(key, field)) {
426
- retVal = 1;
427
- }
428
- }
429
- return this._handleCallback(callback, retVal);
430
- }
431
- /**
432
- *
433
- *
434
- * @param {string} key
435
- * @param {...any[]} fields
436
- * @returns {*}
437
- * @memberof MemoryCache
438
- */
439
- hdel(key, ...fields) {
440
- let retVal = 0;
441
- const callback = this._retrieveCallback(fields);
442
- if (this._hasKey(key)) {
443
- this._testType(key, 'hash', true, callback);
444
- for (let itr = 0; itr < fields.length; itr++) {
445
- const field = fields[itr];
446
- if (this._hasField(key, field)) {
447
- delete this.cache[key].value[field];
448
- retVal++;
449
- }
450
- }
451
- }
452
- return this._handleCallback(callback, retVal);
453
- }
454
- /**
455
- *
456
- *
457
- * @param {string} key
458
- * @param {Function} [callback]
459
- * @returns {*}
460
- * @memberof MemoryCache
461
- */
462
- hlen(key, callback) {
463
- const retVal = this.hkeys(key).length;
464
- return this._handleCallback(callback, retVal);
465
- }
466
- /**
467
- *
468
- *
469
- * @param {string} key
470
- * @param {string} field
471
- * @param {*} value
472
- * @param {Function} [callback]
473
- * @returns {*}
474
- * @memberof MemoryCache
475
- */
476
- hincrby(key, field, value, callback) {
477
- let retVal;
478
- try {
479
- retVal = this._addToField(key, field, value, false);
480
- }
481
- catch (err) {
482
- return this._handleCallback(callback, null, err);
483
- }
484
- return this._handleCallback(callback, retVal);
485
- }
486
- /**
487
- *
488
- *
489
- * @param {string} key
490
- * @param {Function} [callback]
491
- * @returns {*}
492
- * @memberof MemoryCache
493
- */
494
- hgetall(key, callback) {
495
- let retVals = {};
496
- if (this._hasKey(key)) {
497
- this._testType(key, 'hash', true, callback);
498
- retVals = this._getKey(key);
499
- }
500
- return this._handleCallback(callback, retVals);
501
- }
502
- /**
503
- *
504
- *
505
- * @param {string} key
506
- * @param {Function} [callback]
507
- * @returns {*}
508
- * @memberof MemoryCache
509
- */
510
- hkeys(key, callback) {
511
- let retVals = [];
512
- if (this._hasKey(key)) {
513
- this._testType(key, 'hash', true, callback);
514
- retVals = Object.keys(this._getKey(key));
515
- }
516
- return this._handleCallback(callback, retVals);
517
- }
518
- /**
519
- *
520
- *
521
- * @param {string} key
522
- * @param {Function} [callback]
523
- * @returns {*}
524
- * @memberof MemoryCache
525
- */
526
- hvals(key, callback) {
527
- let retVals = [];
528
- if (this._hasKey(key)) {
529
- this._testType(key, 'hash', true, callback);
530
- retVals = Object.values(this._getKey(key));
531
- }
532
- return this._handleCallback(callback, retVals);
533
- }
534
- // ---------------------------------------
535
- // Lists (Array / Queue / Stack)
536
- // ---------------------------------------
537
- /**
538
- *
539
- *
540
- * @param {string} key
541
- * @param {Function} [callback]
542
- * @returns {*}
543
- * @memberof MemoryCache
544
- */
545
- llen(key, callback) {
546
- let retVal = 0;
547
- if (this._hasKey(key)) {
548
- this._testType(key, 'list', true, callback);
549
- retVal = this._getKey(key).length || 0;
550
- }
551
- return this._handleCallback(callback, retVal);
552
- }
553
- /**
554
- *
555
- *
556
- * @param {string} key
557
- * @param {(string | number)} value
558
- * @param {Function} [callback]
559
- * @returns {*}
560
- * @memberof MemoryCache
561
- */
562
- rpush(key, value, callback) {
563
- let retVal = 0;
564
- if (this._hasKey(key)) {
565
- this._testType(key, 'list', true, callback);
566
- }
567
- else {
568
- this.cache[key] = this._makeKey([], 'list');
569
- }
570
- const val = this._getKey(key);
571
- val.push(value);
572
- this._setKey(key, val);
573
- retVal = val.length;
574
- return this._handleCallback(callback, retVal);
575
- }
576
- /**
577
- *
578
- *
579
- * @param {string} key
580
- * @param {(string | number)} value
581
- * @param {Function} [callback]
582
- * @returns {*}
583
- * @memberof MemoryCache
584
- */
585
- lpush(key, value, callback) {
586
- let retVal = 0;
587
- if (this._hasKey(key)) {
588
- this._testType(key, 'list', true, callback);
589
- }
590
- else {
591
- this.cache[key] = this._makeKey([], 'list');
592
- }
593
- const val = this._getKey(key);
594
- val.splice(0, 0, value);
595
- this._setKey(key, val);
596
- retVal = val.length;
597
- return this._handleCallback(callback, retVal);
598
- }
599
- /**
600
- *
601
- *
602
- * @param {string} key
603
- * @param {Function} [callback]
604
- * @returns {*}
605
- * @memberof MemoryCache
606
- */
607
- lpop(key, callback) {
608
- let retVal = null;
609
- if (this._hasKey(key)) {
610
- this._testType(key, 'list', true, callback);
611
- const val = this._getKey(key);
612
- retVal = val.shift();
613
- this._setKey(key, val);
614
- }
615
- return this._handleCallback(callback, retVal);
616
- }
617
- /**
618
- *
619
- *
620
- * @param {string} key
621
- * @param {Function} [callback]
622
- * @returns {*}
623
- * @memberof MemoryCache
624
- */
625
- rpop(key, callback) {
626
- let retVal = null;
627
- if (this._hasKey(key)) {
628
- this._testType(key, 'list', true, callback);
629
- const val = this._getKey(key);
630
- retVal = val.pop();
631
- this._setKey(key, val);
632
- }
633
- return this._handleCallback(callback, retVal);
634
- }
635
- /**
636
- *
637
- *
638
- * @param {string} key
639
- * @param {number} start
640
- * @param {number} stop
641
- * @param {Function} [callback]
642
- * @returns {*}
643
- * @memberof MemoryCache
644
- */
645
- lrange(key, start, stop, callback) {
646
- const retVal = [];
647
- if (this._hasKey(key)) {
648
- this._testType(key, 'list', true, callback);
649
- const val = this._getKey(key);
650
- const length = val.length;
651
- if (stop < 0) {
652
- stop = length + stop;
653
- }
654
- if (start < 0) {
655
- start = length + start;
656
- }
657
- if (start < 0) {
658
- start = 0;
659
- }
660
- if (stop >= length) {
661
- stop = length - 1;
662
- }
663
- if (stop >= 0 && stop >= start) {
664
- const size = stop - start + 1;
665
- for (let itr = start; itr < size; itr++) {
666
- retVal.push(val[itr]);
667
- }
668
- }
669
- }
670
- return this._handleCallback(callback, retVal);
671
- }
672
- // ---------------------------------------
673
- // ## Sets (Unique Lists)##
674
- // ---------------------------------------
675
- /**
676
- *
677
- *
678
- * @param {string} key
679
- * @param {...any[]} members
680
- * @returns {*}
681
- * @memberof MemoryCache
682
- */
683
- sadd(key, ...members) {
684
- let retVal = 0;
685
- const callback = this._retrieveCallback(members);
686
- if (this._hasKey(key)) {
687
- this._testType(key, 'set', true, callback);
688
- }
689
- else {
690
- this.cache[key] = this._makeKey([], 'set');
691
- }
692
- const val = this._getKey(key);
693
- const length = val.length;
694
- const nval = (0, lodash_1.union)(val, members);
695
- const newlength = nval.length;
696
- retVal = newlength - length;
697
- this._setKey(key, nval);
698
- return this._handleCallback(callback, retVal);
699
- }
700
- /**
701
- *
702
- *
703
- * @param {string} key
704
- * @param {Function} [callback]
705
- * @returns {*}
706
- * @memberof MemoryCache
707
- */
708
- scard(key, callback) {
709
- let retVal = 0;
710
- if (this._hasKey(key)) {
711
- this._testType(key, 'set', true, callback);
712
- retVal = this._getKey(key).length;
713
- }
714
- return this._handleCallback(callback, retVal);
715
- }
716
- /**
717
- *
718
- *
719
- * @param {string} key
720
- * @param {string} member
721
- * @param {Function} [callback]
722
- * @returns {*}
723
- * @memberof MemoryCache
724
- */
725
- sismember(key, member, callback) {
726
- let retVal = 0;
727
- if (this._hasKey(key)) {
728
- this._testType(key, 'set', true, callback);
729
- const val = this._getKey(key);
730
- if (val.includes(member)) {
731
- retVal = 1;
732
- }
733
- }
734
- return this._handleCallback(callback, retVal);
735
- }
736
- /**
737
- *
738
- *
739
- * @param {string} key
740
- * @param {Function} [callback]
741
- * @returns {*}
742
- * @memberof MemoryCache
743
- */
744
- smembers(key, callback) {
745
- let retVal = [];
746
- if (this._hasKey(key)) {
747
- this._testType(key, 'set', true, callback);
748
- retVal = this._getKey(key);
749
- }
750
- return this._handleCallback(callback, retVal);
751
- }
752
- /**
753
- *
754
- *
755
- * @param {string} key
756
- * @param {number} [count]
757
- * @param {Function} [callback]
758
- * @returns {*}
759
- * @memberof MemoryCache
760
- */
761
- spop(key, count, callback) {
762
- let retVal = null;
763
- count = count || 1;
764
- if (isNaN(count)) {
765
- return this._handleCallback(callback, null, messages.noint);
766
- }
767
- if (this._hasKey(key)) {
768
- retVal = [];
769
- this._testType(key, 'set', true, callback);
770
- const val = this._getKey(key);
771
- const length = val.length;
772
- count = count > length ? length : count;
773
- for (let itr = 0; itr < count; itr++) {
774
- retVal.push(val.pop());
775
- }
776
- }
777
- return this._handleCallback(callback, retVal);
778
- }
779
- /**
780
- *
781
- *
782
- * @param {string} key
783
- * @param {...any[]} members
784
- * @returns {*}
785
- * @memberof MemoryCache
786
- */
787
- srem(key, ...members) {
788
- let retVal = 0;
789
- const callback = this._retrieveCallback(members);
790
- if (this._hasKey(key)) {
791
- this._testType(key, 'set', true, callback);
792
- const val = this._getKey(key);
793
- for (const index in members) {
794
- if (members.hasOwnProperty(index)) {
795
- const member = members[index];
796
- const idx = val.indexOf(member);
797
- if (idx !== -1) {
798
- val.splice(idx, 1);
799
- retVal++;
800
- }
801
- }
802
- }
803
- this._setKey(key, val);
804
- }
805
- return this._handleCallback(callback, retVal);
806
- }
807
- /**
808
- *
809
- *
810
- * @param {string} sourcekey
811
- * @param {string} destkey
812
- * @param {string} member
813
- * @param {Function} [callback]
814
- * @returns {*}
815
- * @memberof MemoryCache
816
- */
817
- smove(sourcekey, destkey, member, callback) {
818
- let retVal = 0;
819
- if (this._hasKey(sourcekey)) {
820
- this._testType(sourcekey, 'set', true, callback);
821
- const val = this._getKey(sourcekey);
822
- const idx = val.indexOf(member);
823
- if (idx !== -1) {
824
- this.sadd(destkey, member);
825
- val.splice(idx, 1);
826
- retVal = 1;
827
- }
828
- }
829
- return this._handleCallback(callback, retVal);
830
- }
831
- // ---------------------------------------
832
- // ## Transactions (Atomic) ##
833
- // ---------------------------------------
834
- // TODO: Transaction Queues watch and unwatch
835
- // https://redis.io/topics/transactions
836
- // This can be accomplished by temporarily swapping this.cache to a temporary copy of the current statement
837
- // holding and then using __.merge on actual this.cache with the temp storage.
838
- discard(callback, silent) {
839
- // Clear the queue mode, drain the queue, empty the watch list
840
- if (this.multiMode) {
841
- this.cache = this.databases[this.currentDBIndex];
842
- this.tempCache = {};
843
- this.multiMode = false;
844
- this.responseMessages = [];
845
- }
846
- else if (!silent) {
847
- return this._handleCallback(callback, null, messages.nomultidiscard);
848
- }
849
- return this._handleCallback(callback, messages.ok);
850
- }
851
- // ---------------------------------------
852
- // ## Internal - Key ##
853
- // ---------------------------------------
854
- /**
855
- *
856
- *
857
- * @param {string} key
858
- * @param {Function} [callback]
859
- * @returns {*}
860
- * @memberof MemoryCache
861
- */
862
- pttl(key, callback) {
863
- let retVal = -2;
864
- if (this._hasKey(key)) {
865
- if (!(0, lodash_1.isNil)(this.cache[key].timeout)) {
866
- retVal = this.cache[key].timeout - Date.now();
867
- // Prevent unexpected errors if the actual ttl just happens to be -2 or -1
868
- if (retVal < 0 && retVal > -3) {
869
- retVal = -3;
870
- }
871
- }
872
- else {
873
- retVal = -1;
874
- }
875
- }
876
- return this._handleCallback(callback, retVal);
877
- }
878
- /**
879
- *
880
- *
881
- * @private
882
- * @param {string} key
883
- * @param {Function} [callback]
884
- * @returns {*}
885
- * @memberof MemoryCache
886
- */
887
- persist(key, callback) {
888
- let retVal = 0;
889
- if (this._hasKey(key)) {
890
- if (!(0, lodash_1.isNil)(this._key(key).timeout)) {
891
- this._key(key).timeout = null;
892
- retVal = 1;
893
- }
894
- }
895
- return this._handleCallback(callback, retVal);
896
- }
897
- /**
898
- *
899
- *
900
- * @private
901
- * @param {string} key
902
- * @returns {*} {boolean}
903
- * @memberof MemoryCache
904
- */
905
- _hasKey(key) {
906
- return this.cache.hasOwnProperty(key);
907
- }
908
- /**
909
- *
910
- *
911
- * @private
912
- * @param {*} value
913
- * @param {string} type
914
- * @param {number} timeout
915
- * @returns {*}
916
- * @memberof MemoryCache
917
- */
918
- _makeKey(value, type, timeout) {
919
- return { value: value, type: type, timeout: timeout || null, lastAccess: Date.now() };
920
- }
921
- /**
922
- *
923
- *
924
- * @private
925
- * @param {string} key
926
- * @returns {*}
927
- * @memberof MemoryCache
928
- */
929
- _key(key) {
930
- this.cache[key].lastAccess = Date.now();
931
- return this.cache[key];
932
- }
933
- /**
934
- *
935
- *
936
- * @private
937
- * @param {string} key
938
- * @param {number} amount
939
- * @param {Function} [callback]
940
- * @returns {*}
941
- * @memberof MemoryCache
942
- */
943
- _addToKey(key, amount, callback) {
944
- let keyValue = 0;
945
- if (isNaN(amount) || (0, lodash_1.isNil)(amount)) {
946
- return this._handleCallback(callback, null, messages.noint);
947
- }
948
- if (this._hasKey(key)) {
949
- this._testType(key, 'string', true, callback);
950
- keyValue = parseInt(this._getKey(key));
951
- if (isNaN(keyValue) || (0, lodash_1.isNil)(keyValue)) {
952
- return this._handleCallback(callback, null, messages.noint);
953
- }
954
- }
955
- else {
956
- this.cache[key] = this._makeKey('0', 'string');
957
- }
958
- const val = keyValue + amount;
959
- this._setKey(key, val.toString());
960
- return val;
961
- }
962
- /**
963
- *
964
- *
965
- * @private
966
- * @param {string} key
967
- * @param {string} type
968
- * @param {boolean} [throwError]
969
- * @param {Function} [callback]
970
- * @returns {*}
971
- * @memberof MemoryCache
972
- */
973
- _testType(key, type, throwError, callback) {
974
- throwError = !!throwError;
975
- const keyType = this._key(key).type;
976
- if (keyType !== type) {
977
- if (throwError) {
978
- return this._handleCallback(callback, null, messages.wrongTypeOp);
979
- }
980
- return false;
981
- }
982
- return true;
983
- }
984
- /**
985
- *
986
- *
987
- * @private
988
- * @param {string} key
989
- * @returns {*}
990
- * @memberof MemoryCache
991
- */
992
- _getKey(key) {
993
- const _key = this._key(key) || {};
994
- if (_key.timeout && _key.timeout <= Date.now()) {
995
- this.del(key);
996
- return null;
997
- }
998
- return _key.value;
999
- }
1000
- /**
1001
- *
1002
- *
1003
- * @private
1004
- * @param {string} key
1005
- * @param {(number | string)} value
1006
- * @memberof MemoryCache
1007
- */
1008
- _setKey(key, value) {
1009
- this.cache[key].value = value;
1010
- this.cache[key].lastAccess = Date.now();
1011
- }
1012
- /**
1013
- *
1014
- *
1015
- * @private
1016
- * @param {string} key
1017
- * @param {string} field
1018
- * @param {number} [amount]
1019
- * @param {boolean} [useFloat]
1020
- * @param {Function} [callback]
1021
- * @returns {*}
1022
- * @memberof MemoryCache
1023
- */
1024
- _addToField(key, field, amount, useFloat, callback) {
1025
- useFloat = useFloat || false;
1026
- let fieldValue = useFloat ? 0.0 : 0;
1027
- let value = 0;
1028
- if (isNaN(amount) || (0, lodash_1.isNil)(amount)) {
1029
- return this._handleCallback(callback, null, useFloat ? messages.nofloat : messages.noint);
1030
- }
1031
- if (this._hasKey(key)) {
1032
- this._testType(key, 'hash', true, callback);
1033
- if (this._hasField(key, field)) {
1034
- value = this._getField(key, field);
1035
- }
1036
- }
1037
- else {
1038
- this.cache[key] = this._makeKey({}, 'hash');
1039
- }
1040
- fieldValue = useFloat ? parseFloat(`${value}`) : parseInt(`${value}`);
1041
- amount = useFloat ? parseFloat(`${amount}`) : parseInt(`${amount}`);
1042
- if (isNaN(fieldValue) || (0, lodash_1.isNil)(fieldValue)) {
1043
- return this._handleCallback(callback, null, useFloat ? messages.nofloat : messages.noint);
1044
- }
1045
- fieldValue += amount;
1046
- this._setField(key, field, fieldValue.toString());
1047
- return fieldValue;
1048
- }
1049
- /**
1050
- *
1051
- *
1052
- * @private
1053
- * @param {string} key
1054
- * @param {string} field
1055
- * @returns {*}
1056
- * @memberof MemoryCache
1057
- */
1058
- _getField(key, field) {
1059
- return this._getKey(key)[field];
1060
- }
1061
- /**
1062
- *
1063
- *
1064
- * @private
1065
- * @param {string} key
1066
- * @param {string} field
1067
- * @returns {*} {boolean}
1068
- * @memberof MemoryCache
1069
- */
1070
- _hasField(key, field) {
1071
- let retVal = false;
1072
- if (key && field) {
1073
- const ky = this._getKey(key);
1074
- if (ky) {
1075
- retVal = ky.hasOwnProperty(field);
1076
- }
1077
- }
1078
- return retVal;
1079
- }
1080
- /**
1081
- *
1082
- *
1083
- * @param {string} key
1084
- * @param {string} field
1085
- * @param {*} value
1086
- * @memberof MemoryCache
1087
- */
1088
- _setField(key, field, value) {
1089
- this._getKey(key)[field] = value;
1090
- }
1091
- /**
1092
- *
1093
- *
1094
- * @private
1095
- * @param {Function} [callback]
1096
- * @param {(any)} [message]
1097
- * @param {*} [error]
1098
- * @param {boolean} [nolog]
1099
- * @returns {*}
1100
- * @memberof MemoryCache
1101
- */
1102
- _handleCallback(callback, message, error, nolog) {
1103
- let err = error;
1104
- let msg = message;
1105
- nolog = (0, lodash_1.isNil)(nolog) ? true : nolog;
1106
- if (nolog) {
1107
- err = this._logReturn(error);
1108
- msg = this._logReturn(message);
1109
- }
1110
- if (typeof callback === 'function') {
1111
- callback(err, msg);
1112
- return;
1113
- }
1114
- if (err) {
1115
- throw new Error(err);
1116
- }
1117
- return msg;
1118
- }
1119
- _logReturn(message) {
1120
- if (!(0, lodash_1.isUndefined)(message)) {
1121
- if (this.multiMode) {
1122
- if (!(0, lodash_1.isNil)(this.responseMessages)) {
1123
- this.responseMessages.push(message);
1124
- if (message === messages.ok) {
1125
- message = messages.queued;
1126
- }
1127
- }
1128
- }
1129
- return message;
1130
- }
1131
- return;
1132
- }
1133
- /**
1134
- *
1135
- *
1136
- * @private
1137
- * @param {any[]} [params]
1138
- * @returns {*}
1139
- * @memberof MemoryCache
1140
- */
1141
- _retrieveCallback(params) {
1142
- if (Array.isArray(params) && params.length > 0 && typeof params[params.length - 1] === 'function') {
1143
- return params.pop();
1144
- }
1145
- return;
1146
- }
1
+ /*!
2
+ * @Author: richen
3
+ * @Date: 2022-11-03 16:31:15
4
+ * @License: BSD (3-Clause)
5
+ * @Copyright (c) - <richenlin(at)gmail.com>
6
+ * @HomePage: https://koatty.org/
7
+ */
8
+ import { flatten, isNil, union, isUndefined } from 'lodash';
9
+ import * as helper from 'koatty_lib';
10
+ import { EventEmitter } from 'events';
11
+ import { DefaultLogger } from 'koatty_logger';
12
+ import IORedis from 'ioredis';
13
+ import genericPool from 'generic-pool';
14
+
15
+ /*
16
+ * @Description:
17
+ * @Usage:
18
+ * @Author: richen
19
+ * @Date: 2021-12-02 15:26:55
20
+ * @LastEditTime: 2021-12-02 15:33:22
21
+ */
22
+ /**
23
+ *
24
+ *
25
+ * @export
26
+ * @class Store
27
+ */
28
+ class CacheStore {
29
+ /**
30
+ * Creates an instance of CacheStore.
31
+ * @param {StoreOptions} options
32
+ * @memberof CacheStore
33
+ */
34
+ constructor(options) {
35
+ this.options = options;
36
+ this.pool = null;
37
+ this.client = null;
38
+ }
39
+ getConnection() {
40
+ throw new Error("Method not implemented.");
41
+ }
42
+ close() {
43
+ throw new Error("Method not implemented.");
44
+ }
45
+ release(conn) {
46
+ throw new Error("Method not implemented.");
47
+ }
48
+ defineCommand(name, scripts) {
49
+ throw new Error("Method not implemented.");
50
+ }
51
+ getCompare(name, value) {
52
+ throw new Error("Method not implemented.");
53
+ }
54
+ /**
55
+ * handler for native client
56
+ *
57
+ * @param {string} name
58
+ * @param {any[]} data
59
+ * @returns {*}
60
+ * @memberof RedisStore
61
+ */
62
+ async wrap(name, data) {
63
+ let conn;
64
+ try {
65
+ conn = await this.getConnection();
66
+ const res = await conn[name](...data);
67
+ return res;
68
+ }
69
+ catch (err) {
70
+ throw err;
71
+ }
72
+ finally {
73
+ this.release(conn);
74
+ }
75
+ }
76
+ /**
77
+ * 字符串获取
78
+ * @param name
79
+ */
80
+ get(name) {
81
+ return this.wrap('get', [`${this.options.keyPrefix}${name}`]);
82
+ }
83
+ /**
84
+ * 字符串写入
85
+ * @param name
86
+ * @param value
87
+ * @param timeout
88
+ * @returns {Promise}
89
+ */
90
+ set(name, value, timeout) {
91
+ if (typeof timeout !== 'number') {
92
+ timeout = this.options.timeout;
93
+ }
94
+ return this.wrap('set', [`${this.options.keyPrefix}${name}`, value, 'ex', timeout]);
95
+ }
96
+ /**
97
+ * 以秒为单位,返回给定 key 的剩余生存时间
98
+ * @param name
99
+ * @returns {*}
100
+ */
101
+ ttl(name) {
102
+ return this.wrap('ttl', [`${this.options.keyPrefix}${name}`]);
103
+ }
104
+ /**
105
+ * 设置key超时属性
106
+ * @param name
107
+ * @param timeout
108
+ */
109
+ expire(name, timeout) {
110
+ return this.wrap('expire', [`${this.options.keyPrefix}${name}`, timeout]);
111
+ }
112
+ /**
113
+ * 删除key
114
+ * @param name
115
+ */
116
+ rm(name) {
117
+ return this.wrap('del', [`${this.options.keyPrefix}${name}`]);
118
+ }
119
+ /**
120
+ *
121
+ *
122
+ * @param {*} name
123
+ * @returns
124
+ */
125
+ del(name) {
126
+ return this.wrap('del', [`${this.options.keyPrefix}${name}`]);
127
+ }
128
+ /**
129
+ * 判断key是否存在
130
+ * @param name
131
+ */
132
+ exists(name) {
133
+ return this.wrap('exists', [`${this.options.keyPrefix}${name}`]);
134
+ }
135
+ /**
136
+ * 自增
137
+ * @param name
138
+ */
139
+ incr(name) {
140
+ return this.wrap('incr', [`${this.options.keyPrefix}${name}`]);
141
+ }
142
+ /**
143
+ * 自减
144
+ * @param name
145
+ * @returns {*}
146
+ */
147
+ decr(name) {
148
+ return this.wrap('decr', [`${this.options.keyPrefix}${name}`]);
149
+ }
150
+ /**
151
+ * 将 key 所储存的值增加增量
152
+ * @param name
153
+ * @param incr
154
+ * @returns {*}
155
+ */
156
+ incrby(name, incr = 1) {
157
+ return this.wrap('incrby', [`${this.options.keyPrefix}${name}`, incr]);
158
+ }
159
+ /**
160
+ * key 所储存的值减去减量
161
+ *
162
+ * @param {any} name
163
+ * @param {any} decr
164
+ */
165
+ decrby(name, decr = 1) {
166
+ return this.wrap('decrby', [`${this.options.keyPrefix}${name}`, decr]);
167
+ }
168
+ /**
169
+ * 哈希写入
170
+ * @param name
171
+ * @param key
172
+ * @param value
173
+ * @param timeout
174
+ */
175
+ hset(name, key, value, timeout) {
176
+ const setP = [this.wrap('hset', [`${this.options.keyPrefix}${name}`, key, value])];
177
+ if (typeof timeout !== 'number') {
178
+ timeout = this.options.timeout;
179
+ }
180
+ setP.push(this.set(`${name}:${key}_ex`, 1, timeout));
181
+ return Promise.all(setP);
182
+ }
183
+ /**
184
+ * 哈希获取
185
+ * @param name
186
+ * @param key
187
+ * @returns {*}
188
+ */
189
+ hget(name, key) {
190
+ const setP = [this.get(`${name}:${key}_ex`)];
191
+ setP.push(this.wrap('hget', [`${this.options.keyPrefix}${name}`, key]));
192
+ return Promise.all(setP).then(dataArr => {
193
+ if (dataArr[0] === null) {
194
+ this.hdel(name, key);
195
+ return null;
196
+ }
197
+ return dataArr[1] || null;
198
+ });
199
+ }
200
+ /**
201
+ * 查看哈希表 hashKey 中,给定域 key 是否存在
202
+ * @param name
203
+ * @param key
204
+ * @returns {*}
205
+ */
206
+ hexists(name, key) {
207
+ const setP = [this.get(`${name}:${key}_ex`)];
208
+ setP.push(this.wrap('hexists', [`${this.options.keyPrefix}${name}`, key]));
209
+ return Promise.all(setP).then(dataArr => {
210
+ if (dataArr[0] === null) {
211
+ this.hdel(name, key);
212
+ return 0;
213
+ }
214
+ return dataArr[1] || 0;
215
+ });
216
+ }
217
+ /**
218
+ * 哈希删除
219
+ * @param name
220
+ * @param key
221
+ * @returns {*}
222
+ */
223
+ hdel(name, key) {
224
+ const setP = [this.del(`${name}:${key}_ex`)];
225
+ setP.push(this.wrap('hdel', [`${this.options.keyPrefix}${name}`, key]));
226
+ return Promise.all(setP);
227
+ }
228
+ /**
229
+ * 返回哈希表 key 中域的数量
230
+ * @param name
231
+ * @returns {*}
232
+ */
233
+ hlen(name) {
234
+ return this.wrap('hlen', [`${this.options.keyPrefix}${name}`]);
235
+ }
236
+ /**
237
+ * 给哈希表指定key,增加increment
238
+ * @param name
239
+ * @param key
240
+ * @param incr
241
+ * @returns {*}
242
+ */
243
+ hincrby(name, key, incr = 1) {
244
+ return this.wrap('hincrby', [`${this.options.keyPrefix}${name}`, key, incr]);
245
+ }
246
+ /**
247
+ * 返回哈希表所有key-value
248
+ * @param name
249
+ * @returns {*}
250
+ */
251
+ hgetall(name) {
252
+ return this.wrap('hgetall', [`${this.options.keyPrefix}${name}`]);
253
+ }
254
+ /**
255
+ * 返回哈希表所有key
256
+ * @param name
257
+ * @returns {*}
258
+ */
259
+ hkeys(name) {
260
+ return this.wrap('hkeys', [`${this.options.keyPrefix}${name}`]);
261
+ }
262
+ /**
263
+ * 返回哈希表所有value
264
+ * @param name
265
+ * @returns {*}
266
+ */
267
+ hvals(name) {
268
+ return this.wrap('hvals', [`${this.options.keyPrefix}${name}`]);
269
+ }
270
+ /**
271
+ * 判断列表长度,若不存在则表示为空
272
+ * @param name
273
+ * @returns {*}
274
+ */
275
+ llen(name) {
276
+ return this.wrap('llen', [`${this.options.keyPrefix}${name}`]);
277
+ }
278
+ /**
279
+ * 将值插入列表表尾
280
+ * @param name
281
+ * @param value
282
+ * @returns {*}
283
+ */
284
+ rpush(name, value) {
285
+ return this.wrap('rpush', [`${this.options.keyPrefix}${name}`, value]);
286
+ }
287
+ /**
288
+ *
289
+ *
290
+ * @param {string} name
291
+ * @param {(string | number)} value
292
+ * @returns {*}
293
+ * @memberof RedisStore
294
+ */
295
+ lpush(name, value) {
296
+ return this.wrap('lpush', [`${this.options.keyPrefix}${name}`, value]);
297
+ }
298
+ /**
299
+ * 将列表表头取出,并去除
300
+ * @param name
301
+ * @returns {*}
302
+ */
303
+ lpop(name) {
304
+ return this.wrap('lpop', [`${this.options.keyPrefix}${name}`]);
305
+ }
306
+ /**
307
+ *
308
+ *
309
+ * @param {string} name
310
+ * @returns {*}
311
+ * @memberof RedisStore
312
+ */
313
+ rpop(name) {
314
+ return this.wrap('rpop', [`${this.options.keyPrefix}${name}`]);
315
+ }
316
+ /**
317
+ * 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定
318
+ * @param name
319
+ * @param start
320
+ * @param stop
321
+ * @returns {*}
322
+ */
323
+ lrange(name, start, stop) {
324
+ return this.wrap('lrange', [`${this.options.keyPrefix}${name}`, start, stop]);
325
+ }
326
+ /**
327
+ * 集合新增
328
+ * @param name
329
+ * @param value
330
+ * @param timeout
331
+ * @returns {*}
332
+ */
333
+ sadd(name, value, timeout) {
334
+ const setP = [this.wrap('sadd', [`${this.options.keyPrefix}${name}`, value])];
335
+ if (typeof timeout !== 'number') {
336
+ setP.push(this.wrap('expire', [`${this.options.keyPrefix}${name}`, timeout]));
337
+ }
338
+ return Promise.all(setP);
339
+ }
340
+ /**
341
+ * 返回集合的基数(集合中元素的数量)
342
+ * @param name
343
+ * @returns {*}
344
+ */
345
+ scard(name) {
346
+ return this.wrap('scard', [`${this.options.keyPrefix}${name}`]);
347
+ }
348
+ /**
349
+ * 判断 member 元素是否集合的成员
350
+ * @param name
351
+ * @param key
352
+ * @returns {*}
353
+ */
354
+ sismember(name, key) {
355
+ return this.wrap('sismember', [`${this.options.keyPrefix}${name}`, key]);
356
+ }
357
+ /**
358
+ * 返回集合中的所有成员
359
+ * @param name
360
+ * @returns {*}
361
+ */
362
+ smembers(name) {
363
+ return this.wrap('smembers', [`${this.options.keyPrefix}${name}`]);
364
+ }
365
+ /**
366
+ * 移除并返回集合中的一个随机元素
367
+ * @param name
368
+ * @returns {*}
369
+ */
370
+ spop(name) {
371
+ return this.wrap('spop', [`${this.options.keyPrefix}${name}`]);
372
+ }
373
+ /**
374
+ * 移除集合 key 中的一个 member 元素
375
+ * @param name
376
+ * @param key
377
+ * @returns {*}
378
+ */
379
+ srem(name, key) {
380
+ return this.wrap('srem', [`${this.options.keyPrefix}${name}`, key]);
381
+ }
382
+ /**
383
+ * 将 member 元素从 source 集合移动到 destination 集合
384
+ * @param source
385
+ * @param destination
386
+ * @param member
387
+ * @returns {*}
388
+ */
389
+ smove(source, destination, member) {
390
+ return this.wrap('smove', [`${this.options.keyPrefix}${source}`, `${this.options.keyPrefix}${destination}`, member]);
391
+ }
1147
392
  }
1148
- exports.MemoryCache = MemoryCache;
1149
- //# sourceMappingURL=memory_cache.js.map
393
+
394
+ /*
395
+ * @Description:
396
+ * @Usage:
397
+ * @Author: richen
398
+ * @Date: 2021-12-02 11:03:20
399
+ * @LastEditTime: 2021-12-02 14:36:11
400
+ */
401
+ /**
402
+ *
403
+ *
404
+ * @enum {number}
405
+ */
406
+ var messages;
407
+ (function (messages) {
408
+ messages["ok"] = "OK";
409
+ messages["queued"] = "QUEUED";
410
+ messages["pong"] = "PONG";
411
+ messages["noint"] = "ERR value is not an integer or out of range";
412
+ messages["nofloat"] = "ERR value is not an float or out of range";
413
+ messages["nokey"] = "ERR no such key";
414
+ messages["nomultiinmulti"] = "ERR MULTI calls can not be nested";
415
+ messages["nomultiexec"] = "ERR EXEC without MULTI";
416
+ messages["nomultidiscard"] = "ERR DISCARD without MULTI";
417
+ messages["busykey"] = "ERR target key name is busy";
418
+ messages["syntax"] = "ERR syntax error";
419
+ messages["unsupported"] = "MemoryCache does not support that operation";
420
+ messages["wrongTypeOp"] = "WRONGTYPE Operation against a key holding the wrong kind of value";
421
+ messages["wrongPayload"] = "DUMP payload version or checksum are wrong";
422
+ messages["wrongArgCount"] = "ERR wrong number of arguments for '%0' command";
423
+ messages["bitopnotWrongCount"] = "ERR BITOP NOT must be called with a single source key";
424
+ messages["indexOutOfRange"] = "ERR index out of range";
425
+ messages["invalidLexRange"] = "ERR min or max not valid string range item";
426
+ messages["invalidDBIndex"] = "ERR invalid DB index";
427
+ messages["invalidDBIndexNX"] = "ERR invalid DB index, '%0' does not exist";
428
+ messages["mutuallyExclusiveNXXX"] = "ERR XX and NX options at the same time are not compatible";
429
+ })(messages || (messages = {}));
430
+ class MemoryCache extends EventEmitter {
431
+ /**
432
+ * Creates an instance of MemoryCache.
433
+ * @param {*} options
434
+ * @memberof MemoryCache
435
+ */
436
+ constructor(options) {
437
+ super();
438
+ this.databases = Object.create({});
439
+ this.options = { ...{ database: "0" }, ...options };
440
+ this.currentDBIndex = 0;
441
+ this.connected = false;
442
+ this.lastSave = Date.now();
443
+ this.multiMode = false;
444
+ }
445
+ /**
446
+ *
447
+ *
448
+ * @returns {*}
449
+ * @memberof MemoryCache
450
+ */
451
+ createClient() {
452
+ this.databases[this.options.database] = Object.create({});
453
+ this.cache = this.databases[this.options.database];
454
+ this.connected = true;
455
+ // exit multi mode if we are in it
456
+ this.discard(null, true);
457
+ this.emit('connect');
458
+ this.emit('ready');
459
+ return this;
460
+ }
461
+ /**
462
+ *
463
+ *
464
+ * @returns {*}
465
+ * @memberof MemoryCache
466
+ */
467
+ quit() {
468
+ this.connected = false;
469
+ // exit multi mode if we are in it
470
+ this.discard(null, true);
471
+ this.emit('end');
472
+ return this;
473
+ }
474
+ /**
475
+ *
476
+ *
477
+ * @returns {*}
478
+ * @memberof MemoryCache
479
+ */
480
+ end() {
481
+ return this.quit();
482
+ }
483
+ /**
484
+ *
485
+ *
486
+ * @param {string} message
487
+ * @param {Function} [callback]
488
+ * @returns {*}
489
+ * @memberof MemoryCache
490
+ */
491
+ echo(message, callback) {
492
+ return this._handleCallback(callback, message);
493
+ }
494
+ /**
495
+ *
496
+ *
497
+ * @param {string} message
498
+ * @param {Function} [callback]
499
+ * @returns {*}
500
+ * @memberof MemoryCache
501
+ */
502
+ ping(message, callback) {
503
+ message = message || messages.pong;
504
+ return this._handleCallback(callback, message);
505
+ }
506
+ /**
507
+ *
508
+ *
509
+ * @param {string} password
510
+ * @param {Function} [callback]
511
+ * @returns {*}
512
+ * @memberof MemoryCache
513
+ */
514
+ auth(password, callback) {
515
+ return this._handleCallback(callback, messages.ok);
516
+ }
517
+ /**
518
+ *
519
+ *
520
+ * @param {number} dbIndex
521
+ * @param {Function} [callback]
522
+ * @returns {*}
523
+ * @memberof MemoryCache
524
+ */
525
+ select(dbIndex, callback) {
526
+ if (!helper.isNumber(dbIndex)) {
527
+ return this._handleCallback(callback, null, messages.invalidDBIndex);
528
+ }
529
+ if (!this.databases.hasOwnProperty(dbIndex)) {
530
+ this.databases[dbIndex] = Object.create({});
531
+ }
532
+ this.multiMode = false;
533
+ this.currentDBIndex = dbIndex;
534
+ this.cache = this.databases[dbIndex];
535
+ return this._handleCallback(callback, messages.ok);
536
+ }
537
+ // ---------------------------------------
538
+ // Keys
539
+ // ---------------------------------------
540
+ get(key, callback) {
541
+ let retVal = null;
542
+ if (this._hasKey(key)) {
543
+ this._testType(key, 'string', true, callback);
544
+ retVal = this._getKey(key);
545
+ }
546
+ return this._handleCallback(callback, retVal);
547
+ }
548
+ /**
549
+ * set(key, value, ttl, pttl, notexist, onlyexist, callback)
550
+ *
551
+ * @param {string} key
552
+ * @param {(string | number)} value
553
+ * @param {...any[]} params
554
+ * @returns {*}
555
+ * @memberof MemoryCache
556
+ */
557
+ set(key, value, ...params) {
558
+ const retVal = null;
559
+ params = flatten(params);
560
+ const callback = this._retrieveCallback(params);
561
+ let ttl, pttl, notexist, onlyexist;
562
+ // parse parameters
563
+ while (params.length > 0) {
564
+ const param = params.shift();
565
+ switch (param.toString().toLowerCase()) {
566
+ case 'nx':
567
+ notexist = true;
568
+ break;
569
+ case 'xx':
570
+ onlyexist = true;
571
+ break;
572
+ case 'ex':
573
+ if (params.length === 0) {
574
+ return this._handleCallback(callback, null, messages.syntax);
575
+ }
576
+ ttl = parseInt(params.shift());
577
+ if (isNaN(ttl)) {
578
+ return this._handleCallback(callback, null, messages.noint);
579
+ }
580
+ break;
581
+ case 'px':
582
+ if (params.length === 0) {
583
+ return this._handleCallback(callback, null, messages.syntax);
584
+ }
585
+ pttl = parseInt(params.shift());
586
+ if (isNaN(pttl)) {
587
+ return this._handleCallback(callback, null, messages.noint);
588
+ }
589
+ break;
590
+ default:
591
+ return this._handleCallback(callback, null, messages.syntax);
592
+ }
593
+ }
594
+ if (!isNil(ttl) && !isNil(pttl)) {
595
+ return this._handleCallback(callback, null, messages.syntax);
596
+ }
597
+ if (notexist && onlyexist) {
598
+ return this._handleCallback(callback, null, messages.syntax);
599
+ }
600
+ pttl = pttl || ttl * 1000 || null;
601
+ if (!isNil(pttl)) {
602
+ pttl = Date.now() + pttl;
603
+ }
604
+ if (this._hasKey(key)) {
605
+ this._testType(key, 'string', true, callback);
606
+ if (notexist) {
607
+ return this._handleCallback(callback, retVal);
608
+ }
609
+ }
610
+ else if (onlyexist) {
611
+ return this._handleCallback(callback, retVal);
612
+ }
613
+ this.cache[key] = this._makeKey(value.toString(), 'string', pttl);
614
+ return this._handleCallback(callback, messages.ok);
615
+ }
616
+ /**
617
+ *
618
+ *
619
+ * @param {string} key
620
+ * @param {Function} [callback]
621
+ * @returns {*}
622
+ * @memberof MemoryCache
623
+ */
624
+ ttl(key, callback) {
625
+ let retVal = this.pttl(key);
626
+ if (retVal >= 0 || retVal <= -3) {
627
+ retVal = Math.floor(retVal / 1000);
628
+ }
629
+ return this._handleCallback(callback, retVal);
630
+ }
631
+ /**
632
+ *
633
+ *
634
+ * @param {string} key
635
+ * @param {number} seconds
636
+ * @param {Function} [callback]
637
+ * @returns {*}
638
+ * @memberof MemoryCache
639
+ */
640
+ expire(key, seconds, callback) {
641
+ let retVal = 0;
642
+ if (this._hasKey(key)) {
643
+ this.cache[key].timeout = Date.now() + seconds * 1000;
644
+ retVal = 1;
645
+ }
646
+ return this._handleCallback(callback, retVal);
647
+ }
648
+ /**
649
+ *
650
+ *
651
+ * @param {...any[]} keys
652
+ * @returns {*}
653
+ * @memberof MemoryCache
654
+ */
655
+ del(...keys) {
656
+ let retVal = 0;
657
+ const callback = this._retrieveCallback(keys);
658
+ // Flatten the array in case an array was passed
659
+ keys = flatten(keys);
660
+ for (let itr = 0; itr < keys.length; itr++) {
661
+ const key = keys[itr];
662
+ if (this._hasKey(key)) {
663
+ delete this.cache[key];
664
+ retVal++;
665
+ }
666
+ }
667
+ return this._handleCallback(callback, retVal);
668
+ }
669
+ /**
670
+ *
671
+ *
672
+ * @param {...any[]} keys
673
+ * @returns {*}
674
+ * @memberof MemoryCache
675
+ */
676
+ exists(...keys) {
677
+ let retVal = 0;
678
+ const callback = this._retrieveCallback(keys);
679
+ for (let itr = 0; itr < keys.length; itr++) {
680
+ const key = keys[itr];
681
+ if (this._hasKey(key)) {
682
+ retVal++;
683
+ }
684
+ }
685
+ return this._handleCallback(callback, retVal);
686
+ }
687
+ /**
688
+ *
689
+ *
690
+ * @param {string} key
691
+ * @param {Function} [callback]
692
+ * @returns {*}
693
+ * @memberof MemoryCache
694
+ */
695
+ incr(key, callback) {
696
+ let retVal = null;
697
+ try {
698
+ retVal = this._addToKey(key, 1);
699
+ }
700
+ catch (err) {
701
+ return this._handleCallback(callback, null, err);
702
+ }
703
+ return this._handleCallback(callback, retVal);
704
+ }
705
+ /**
706
+ *
707
+ *
708
+ * @param {string} key
709
+ * @param {number} amount
710
+ * @param {Function} [callback]
711
+ * @returns {*}
712
+ * @memberof MemoryCache
713
+ */
714
+ incrby(key, amount, callback) {
715
+ let retVal = null;
716
+ try {
717
+ retVal = this._addToKey(key, amount);
718
+ }
719
+ catch (err) {
720
+ return this._handleCallback(callback, null, err);
721
+ }
722
+ return this._handleCallback(callback, retVal);
723
+ }
724
+ /**
725
+ *
726
+ *
727
+ * @param {string} key
728
+ * @param {Function} [callback]
729
+ * @returns {*}
730
+ * @memberof MemoryCache
731
+ */
732
+ decr(key, callback) {
733
+ let retVal = null;
734
+ try {
735
+ retVal = this._addToKey(key, -1);
736
+ }
737
+ catch (err) {
738
+ return this._handleCallback(callback, null, err);
739
+ }
740
+ return this._handleCallback(callback, retVal);
741
+ }
742
+ /**
743
+ *
744
+ *
745
+ * @param {string} key
746
+ * @param {number} amount
747
+ * @param {Function} [callback]
748
+ * @returns {*}
749
+ * @memberof MemoryCache
750
+ */
751
+ decrby(key, amount, callback) {
752
+ let retVal = null;
753
+ try {
754
+ retVal = this._addToKey(key, -amount);
755
+ }
756
+ catch (err) {
757
+ return this._handleCallback(callback, null, err);
758
+ }
759
+ return this._handleCallback(callback, retVal);
760
+ }
761
+ // ---------------------------------------
762
+ // ## Hash ##
763
+ // ---------------------------------------
764
+ hset(key, field, value, callback) {
765
+ let retVal = 0;
766
+ if (this._hasKey(key)) {
767
+ this._testType(key, 'hash', true, callback);
768
+ }
769
+ else {
770
+ this.cache[key] = this._makeKey({}, 'hash');
771
+ }
772
+ if (!this._hasField(key, field)) {
773
+ retVal = 1;
774
+ }
775
+ this._setField(key, field, value.toString());
776
+ this.persist(key);
777
+ return this._handleCallback(callback, retVal);
778
+ }
779
+ /**
780
+ *
781
+ *
782
+ * @param {string} key
783
+ * @param {string} field
784
+ * @param {Function} [callback]
785
+ * @returns {*}
786
+ * @memberof MemoryCache
787
+ */
788
+ hget(key, field, callback) {
789
+ let retVal = null;
790
+ if (this._hasKey(key)) {
791
+ this._testType(key, 'hash', true, callback);
792
+ if (this._hasField(key, field)) {
793
+ retVal = this._getKey(key)[field];
794
+ }
795
+ }
796
+ return this._handleCallback(callback, retVal);
797
+ }
798
+ /**
799
+ *
800
+ *
801
+ * @param {string} key
802
+ * @param {string} field
803
+ * @param {Function} [callback]
804
+ * @returns {*}
805
+ * @memberof MemoryCache
806
+ */
807
+ hexists(key, field, callback) {
808
+ let retVal = 0;
809
+ if (this._hasKey(key)) {
810
+ this._testType(key, 'hash', true, callback);
811
+ if (this._hasField(key, field)) {
812
+ retVal = 1;
813
+ }
814
+ }
815
+ return this._handleCallback(callback, retVal);
816
+ }
817
+ /**
818
+ *
819
+ *
820
+ * @param {string} key
821
+ * @param {...any[]} fields
822
+ * @returns {*}
823
+ * @memberof MemoryCache
824
+ */
825
+ hdel(key, ...fields) {
826
+ let retVal = 0;
827
+ const callback = this._retrieveCallback(fields);
828
+ if (this._hasKey(key)) {
829
+ this._testType(key, 'hash', true, callback);
830
+ for (let itr = 0; itr < fields.length; itr++) {
831
+ const field = fields[itr];
832
+ if (this._hasField(key, field)) {
833
+ delete this.cache[key].value[field];
834
+ retVal++;
835
+ }
836
+ }
837
+ }
838
+ return this._handleCallback(callback, retVal);
839
+ }
840
+ /**
841
+ *
842
+ *
843
+ * @param {string} key
844
+ * @param {Function} [callback]
845
+ * @returns {*}
846
+ * @memberof MemoryCache
847
+ */
848
+ hlen(key, callback) {
849
+ const retVal = this.hkeys(key).length;
850
+ return this._handleCallback(callback, retVal);
851
+ }
852
+ /**
853
+ *
854
+ *
855
+ * @param {string} key
856
+ * @param {string} field
857
+ * @param {*} value
858
+ * @param {Function} [callback]
859
+ * @returns {*}
860
+ * @memberof MemoryCache
861
+ */
862
+ hincrby(key, field, value, callback) {
863
+ let retVal;
864
+ try {
865
+ retVal = this._addToField(key, field, value, false);
866
+ }
867
+ catch (err) {
868
+ return this._handleCallback(callback, null, err);
869
+ }
870
+ return this._handleCallback(callback, retVal);
871
+ }
872
+ /**
873
+ *
874
+ *
875
+ * @param {string} key
876
+ * @param {Function} [callback]
877
+ * @returns {*}
878
+ * @memberof MemoryCache
879
+ */
880
+ hgetall(key, callback) {
881
+ let retVals = {};
882
+ if (this._hasKey(key)) {
883
+ this._testType(key, 'hash', true, callback);
884
+ retVals = this._getKey(key);
885
+ }
886
+ return this._handleCallback(callback, retVals);
887
+ }
888
+ /**
889
+ *
890
+ *
891
+ * @param {string} key
892
+ * @param {Function} [callback]
893
+ * @returns {*}
894
+ * @memberof MemoryCache
895
+ */
896
+ hkeys(key, callback) {
897
+ let retVals = [];
898
+ if (this._hasKey(key)) {
899
+ this._testType(key, 'hash', true, callback);
900
+ retVals = Object.keys(this._getKey(key));
901
+ }
902
+ return this._handleCallback(callback, retVals);
903
+ }
904
+ /**
905
+ *
906
+ *
907
+ * @param {string} key
908
+ * @param {Function} [callback]
909
+ * @returns {*}
910
+ * @memberof MemoryCache
911
+ */
912
+ hvals(key, callback) {
913
+ let retVals = [];
914
+ if (this._hasKey(key)) {
915
+ this._testType(key, 'hash', true, callback);
916
+ retVals = Object.values(this._getKey(key));
917
+ }
918
+ return this._handleCallback(callback, retVals);
919
+ }
920
+ // ---------------------------------------
921
+ // Lists (Array / Queue / Stack)
922
+ // ---------------------------------------
923
+ /**
924
+ *
925
+ *
926
+ * @param {string} key
927
+ * @param {Function} [callback]
928
+ * @returns {*}
929
+ * @memberof MemoryCache
930
+ */
931
+ llen(key, callback) {
932
+ let retVal = 0;
933
+ if (this._hasKey(key)) {
934
+ this._testType(key, 'list', true, callback);
935
+ retVal = this._getKey(key).length || 0;
936
+ }
937
+ return this._handleCallback(callback, retVal);
938
+ }
939
+ /**
940
+ *
941
+ *
942
+ * @param {string} key
943
+ * @param {(string | number)} value
944
+ * @param {Function} [callback]
945
+ * @returns {*}
946
+ * @memberof MemoryCache
947
+ */
948
+ rpush(key, value, callback) {
949
+ let retVal = 0;
950
+ if (this._hasKey(key)) {
951
+ this._testType(key, 'list', true, callback);
952
+ }
953
+ else {
954
+ this.cache[key] = this._makeKey([], 'list');
955
+ }
956
+ const val = this._getKey(key);
957
+ val.push(value);
958
+ this._setKey(key, val);
959
+ retVal = val.length;
960
+ return this._handleCallback(callback, retVal);
961
+ }
962
+ /**
963
+ *
964
+ *
965
+ * @param {string} key
966
+ * @param {(string | number)} value
967
+ * @param {Function} [callback]
968
+ * @returns {*}
969
+ * @memberof MemoryCache
970
+ */
971
+ lpush(key, value, callback) {
972
+ let retVal = 0;
973
+ if (this._hasKey(key)) {
974
+ this._testType(key, 'list', true, callback);
975
+ }
976
+ else {
977
+ this.cache[key] = this._makeKey([], 'list');
978
+ }
979
+ const val = this._getKey(key);
980
+ val.splice(0, 0, value);
981
+ this._setKey(key, val);
982
+ retVal = val.length;
983
+ return this._handleCallback(callback, retVal);
984
+ }
985
+ /**
986
+ *
987
+ *
988
+ * @param {string} key
989
+ * @param {Function} [callback]
990
+ * @returns {*}
991
+ * @memberof MemoryCache
992
+ */
993
+ lpop(key, callback) {
994
+ let retVal = null;
995
+ if (this._hasKey(key)) {
996
+ this._testType(key, 'list', true, callback);
997
+ const val = this._getKey(key);
998
+ retVal = val.shift();
999
+ this._setKey(key, val);
1000
+ }
1001
+ return this._handleCallback(callback, retVal);
1002
+ }
1003
+ /**
1004
+ *
1005
+ *
1006
+ * @param {string} key
1007
+ * @param {Function} [callback]
1008
+ * @returns {*}
1009
+ * @memberof MemoryCache
1010
+ */
1011
+ rpop(key, callback) {
1012
+ let retVal = null;
1013
+ if (this._hasKey(key)) {
1014
+ this._testType(key, 'list', true, callback);
1015
+ const val = this._getKey(key);
1016
+ retVal = val.pop();
1017
+ this._setKey(key, val);
1018
+ }
1019
+ return this._handleCallback(callback, retVal);
1020
+ }
1021
+ /**
1022
+ *
1023
+ *
1024
+ * @param {string} key
1025
+ * @param {number} start
1026
+ * @param {number} stop
1027
+ * @param {Function} [callback]
1028
+ * @returns {*}
1029
+ * @memberof MemoryCache
1030
+ */
1031
+ lrange(key, start, stop, callback) {
1032
+ const retVal = [];
1033
+ if (this._hasKey(key)) {
1034
+ this._testType(key, 'list', true, callback);
1035
+ const val = this._getKey(key);
1036
+ const length = val.length;
1037
+ if (stop < 0) {
1038
+ stop = length + stop;
1039
+ }
1040
+ if (start < 0) {
1041
+ start = length + start;
1042
+ }
1043
+ if (start < 0) {
1044
+ start = 0;
1045
+ }
1046
+ if (stop >= length) {
1047
+ stop = length - 1;
1048
+ }
1049
+ if (stop >= 0 && stop >= start) {
1050
+ const size = stop - start + 1;
1051
+ for (let itr = start; itr < size; itr++) {
1052
+ retVal.push(val[itr]);
1053
+ }
1054
+ }
1055
+ }
1056
+ return this._handleCallback(callback, retVal);
1057
+ }
1058
+ // ---------------------------------------
1059
+ // ## Sets (Unique Lists)##
1060
+ // ---------------------------------------
1061
+ /**
1062
+ *
1063
+ *
1064
+ * @param {string} key
1065
+ * @param {...any[]} members
1066
+ * @returns {*}
1067
+ * @memberof MemoryCache
1068
+ */
1069
+ sadd(key, ...members) {
1070
+ let retVal = 0;
1071
+ const callback = this._retrieveCallback(members);
1072
+ if (this._hasKey(key)) {
1073
+ this._testType(key, 'set', true, callback);
1074
+ }
1075
+ else {
1076
+ this.cache[key] = this._makeKey([], 'set');
1077
+ }
1078
+ const val = this._getKey(key);
1079
+ const length = val.length;
1080
+ const nval = union(val, members);
1081
+ const newlength = nval.length;
1082
+ retVal = newlength - length;
1083
+ this._setKey(key, nval);
1084
+ return this._handleCallback(callback, retVal);
1085
+ }
1086
+ /**
1087
+ *
1088
+ *
1089
+ * @param {string} key
1090
+ * @param {Function} [callback]
1091
+ * @returns {*}
1092
+ * @memberof MemoryCache
1093
+ */
1094
+ scard(key, callback) {
1095
+ let retVal = 0;
1096
+ if (this._hasKey(key)) {
1097
+ this._testType(key, 'set', true, callback);
1098
+ retVal = this._getKey(key).length;
1099
+ }
1100
+ return this._handleCallback(callback, retVal);
1101
+ }
1102
+ /**
1103
+ *
1104
+ *
1105
+ * @param {string} key
1106
+ * @param {string} member
1107
+ * @param {Function} [callback]
1108
+ * @returns {*}
1109
+ * @memberof MemoryCache
1110
+ */
1111
+ sismember(key, member, callback) {
1112
+ let retVal = 0;
1113
+ if (this._hasKey(key)) {
1114
+ this._testType(key, 'set', true, callback);
1115
+ const val = this._getKey(key);
1116
+ if (val.includes(member)) {
1117
+ retVal = 1;
1118
+ }
1119
+ }
1120
+ return this._handleCallback(callback, retVal);
1121
+ }
1122
+ /**
1123
+ *
1124
+ *
1125
+ * @param {string} key
1126
+ * @param {Function} [callback]
1127
+ * @returns {*}
1128
+ * @memberof MemoryCache
1129
+ */
1130
+ smembers(key, callback) {
1131
+ let retVal = [];
1132
+ if (this._hasKey(key)) {
1133
+ this._testType(key, 'set', true, callback);
1134
+ retVal = this._getKey(key);
1135
+ }
1136
+ return this._handleCallback(callback, retVal);
1137
+ }
1138
+ /**
1139
+ *
1140
+ *
1141
+ * @param {string} key
1142
+ * @param {number} [count]
1143
+ * @param {Function} [callback]
1144
+ * @returns {*}
1145
+ * @memberof MemoryCache
1146
+ */
1147
+ spop(key, count, callback) {
1148
+ let retVal = null;
1149
+ count = count || 1;
1150
+ if (isNaN(count)) {
1151
+ return this._handleCallback(callback, null, messages.noint);
1152
+ }
1153
+ if (this._hasKey(key)) {
1154
+ retVal = [];
1155
+ this._testType(key, 'set', true, callback);
1156
+ const val = this._getKey(key);
1157
+ const length = val.length;
1158
+ count = count > length ? length : count;
1159
+ for (let itr = 0; itr < count; itr++) {
1160
+ retVal.push(val.pop());
1161
+ }
1162
+ }
1163
+ return this._handleCallback(callback, retVal);
1164
+ }
1165
+ /**
1166
+ *
1167
+ *
1168
+ * @param {string} key
1169
+ * @param {...any[]} members
1170
+ * @returns {*}
1171
+ * @memberof MemoryCache
1172
+ */
1173
+ srem(key, ...members) {
1174
+ let retVal = 0;
1175
+ const callback = this._retrieveCallback(members);
1176
+ if (this._hasKey(key)) {
1177
+ this._testType(key, 'set', true, callback);
1178
+ const val = this._getKey(key);
1179
+ for (const index in members) {
1180
+ if (members.hasOwnProperty(index)) {
1181
+ const member = members[index];
1182
+ const idx = val.indexOf(member);
1183
+ if (idx !== -1) {
1184
+ val.splice(idx, 1);
1185
+ retVal++;
1186
+ }
1187
+ }
1188
+ }
1189
+ this._setKey(key, val);
1190
+ }
1191
+ return this._handleCallback(callback, retVal);
1192
+ }
1193
+ /**
1194
+ *
1195
+ *
1196
+ * @param {string} sourcekey
1197
+ * @param {string} destkey
1198
+ * @param {string} member
1199
+ * @param {Function} [callback]
1200
+ * @returns {*}
1201
+ * @memberof MemoryCache
1202
+ */
1203
+ smove(sourcekey, destkey, member, callback) {
1204
+ let retVal = 0;
1205
+ if (this._hasKey(sourcekey)) {
1206
+ this._testType(sourcekey, 'set', true, callback);
1207
+ const val = this._getKey(sourcekey);
1208
+ const idx = val.indexOf(member);
1209
+ if (idx !== -1) {
1210
+ this.sadd(destkey, member);
1211
+ val.splice(idx, 1);
1212
+ retVal = 1;
1213
+ }
1214
+ }
1215
+ return this._handleCallback(callback, retVal);
1216
+ }
1217
+ // ---------------------------------------
1218
+ // ## Transactions (Atomic) ##
1219
+ // ---------------------------------------
1220
+ // TODO: Transaction Queues watch and unwatch
1221
+ // https://redis.io/topics/transactions
1222
+ // This can be accomplished by temporarily swapping this.cache to a temporary copy of the current statement
1223
+ // holding and then using __.merge on actual this.cache with the temp storage.
1224
+ discard(callback, silent) {
1225
+ // Clear the queue mode, drain the queue, empty the watch list
1226
+ if (this.multiMode) {
1227
+ this.cache = this.databases[this.currentDBIndex];
1228
+ this.tempCache = {};
1229
+ this.multiMode = false;
1230
+ this.responseMessages = [];
1231
+ }
1232
+ else if (!silent) {
1233
+ return this._handleCallback(callback, null, messages.nomultidiscard);
1234
+ }
1235
+ return this._handleCallback(callback, messages.ok);
1236
+ }
1237
+ // ---------------------------------------
1238
+ // ## Internal - Key ##
1239
+ // ---------------------------------------
1240
+ /**
1241
+ *
1242
+ *
1243
+ * @param {string} key
1244
+ * @param {Function} [callback]
1245
+ * @returns {*}
1246
+ * @memberof MemoryCache
1247
+ */
1248
+ pttl(key, callback) {
1249
+ let retVal = -2;
1250
+ if (this._hasKey(key)) {
1251
+ if (!isNil(this.cache[key].timeout)) {
1252
+ retVal = this.cache[key].timeout - Date.now();
1253
+ // Prevent unexpected errors if the actual ttl just happens to be -2 or -1
1254
+ if (retVal < 0 && retVal > -3) {
1255
+ retVal = -3;
1256
+ }
1257
+ }
1258
+ else {
1259
+ retVal = -1;
1260
+ }
1261
+ }
1262
+ return this._handleCallback(callback, retVal);
1263
+ }
1264
+ /**
1265
+ *
1266
+ *
1267
+ * @private
1268
+ * @param {string} key
1269
+ * @param {Function} [callback]
1270
+ * @returns {*}
1271
+ * @memberof MemoryCache
1272
+ */
1273
+ persist(key, callback) {
1274
+ let retVal = 0;
1275
+ if (this._hasKey(key)) {
1276
+ if (!isNil(this._key(key).timeout)) {
1277
+ this._key(key).timeout = null;
1278
+ retVal = 1;
1279
+ }
1280
+ }
1281
+ return this._handleCallback(callback, retVal);
1282
+ }
1283
+ /**
1284
+ *
1285
+ *
1286
+ * @private
1287
+ * @param {string} key
1288
+ * @returns {*} {boolean}
1289
+ * @memberof MemoryCache
1290
+ */
1291
+ _hasKey(key) {
1292
+ return this.cache.hasOwnProperty(key);
1293
+ }
1294
+ /**
1295
+ *
1296
+ *
1297
+ * @private
1298
+ * @param {*} value
1299
+ * @param {string} type
1300
+ * @param {number} timeout
1301
+ * @returns {*}
1302
+ * @memberof MemoryCache
1303
+ */
1304
+ _makeKey(value, type, timeout) {
1305
+ return { value: value, type: type, timeout: timeout || null, lastAccess: Date.now() };
1306
+ }
1307
+ /**
1308
+ *
1309
+ *
1310
+ * @private
1311
+ * @param {string} key
1312
+ * @returns {*}
1313
+ * @memberof MemoryCache
1314
+ */
1315
+ _key(key) {
1316
+ this.cache[key].lastAccess = Date.now();
1317
+ return this.cache[key];
1318
+ }
1319
+ /**
1320
+ *
1321
+ *
1322
+ * @private
1323
+ * @param {string} key
1324
+ * @param {number} amount
1325
+ * @param {Function} [callback]
1326
+ * @returns {*}
1327
+ * @memberof MemoryCache
1328
+ */
1329
+ _addToKey(key, amount, callback) {
1330
+ let keyValue = 0;
1331
+ if (isNaN(amount) || isNil(amount)) {
1332
+ return this._handleCallback(callback, null, messages.noint);
1333
+ }
1334
+ if (this._hasKey(key)) {
1335
+ this._testType(key, 'string', true, callback);
1336
+ keyValue = parseInt(this._getKey(key));
1337
+ if (isNaN(keyValue) || isNil(keyValue)) {
1338
+ return this._handleCallback(callback, null, messages.noint);
1339
+ }
1340
+ }
1341
+ else {
1342
+ this.cache[key] = this._makeKey('0', 'string');
1343
+ }
1344
+ const val = keyValue + amount;
1345
+ this._setKey(key, val.toString());
1346
+ return val;
1347
+ }
1348
+ /**
1349
+ *
1350
+ *
1351
+ * @private
1352
+ * @param {string} key
1353
+ * @param {string} type
1354
+ * @param {boolean} [throwError]
1355
+ * @param {Function} [callback]
1356
+ * @returns {*}
1357
+ * @memberof MemoryCache
1358
+ */
1359
+ _testType(key, type, throwError, callback) {
1360
+ throwError = !!throwError;
1361
+ const keyType = this._key(key).type;
1362
+ if (keyType !== type) {
1363
+ if (throwError) {
1364
+ return this._handleCallback(callback, null, messages.wrongTypeOp);
1365
+ }
1366
+ return false;
1367
+ }
1368
+ return true;
1369
+ }
1370
+ /**
1371
+ *
1372
+ *
1373
+ * @private
1374
+ * @param {string} key
1375
+ * @returns {*}
1376
+ * @memberof MemoryCache
1377
+ */
1378
+ _getKey(key) {
1379
+ const _key = this._key(key) || {};
1380
+ if (_key.timeout && _key.timeout <= Date.now()) {
1381
+ this.del(key);
1382
+ return null;
1383
+ }
1384
+ return _key.value;
1385
+ }
1386
+ /**
1387
+ *
1388
+ *
1389
+ * @private
1390
+ * @param {string} key
1391
+ * @param {(number | string)} value
1392
+ * @memberof MemoryCache
1393
+ */
1394
+ _setKey(key, value) {
1395
+ this.cache[key].value = value;
1396
+ this.cache[key].lastAccess = Date.now();
1397
+ }
1398
+ /**
1399
+ *
1400
+ *
1401
+ * @private
1402
+ * @param {string} key
1403
+ * @param {string} field
1404
+ * @param {number} [amount]
1405
+ * @param {boolean} [useFloat]
1406
+ * @param {Function} [callback]
1407
+ * @returns {*}
1408
+ * @memberof MemoryCache
1409
+ */
1410
+ _addToField(key, field, amount, useFloat, callback) {
1411
+ useFloat = useFloat || false;
1412
+ let fieldValue = useFloat ? 0.0 : 0;
1413
+ let value = 0;
1414
+ if (isNaN(amount) || isNil(amount)) {
1415
+ return this._handleCallback(callback, null, useFloat ? messages.nofloat : messages.noint);
1416
+ }
1417
+ if (this._hasKey(key)) {
1418
+ this._testType(key, 'hash', true, callback);
1419
+ if (this._hasField(key, field)) {
1420
+ value = this._getField(key, field);
1421
+ }
1422
+ }
1423
+ else {
1424
+ this.cache[key] = this._makeKey({}, 'hash');
1425
+ }
1426
+ fieldValue = useFloat ? parseFloat(`${value}`) : parseInt(`${value}`);
1427
+ amount = useFloat ? parseFloat(`${amount}`) : parseInt(`${amount}`);
1428
+ if (isNaN(fieldValue) || isNil(fieldValue)) {
1429
+ return this._handleCallback(callback, null, useFloat ? messages.nofloat : messages.noint);
1430
+ }
1431
+ fieldValue += amount;
1432
+ this._setField(key, field, fieldValue.toString());
1433
+ return fieldValue;
1434
+ }
1435
+ /**
1436
+ *
1437
+ *
1438
+ * @private
1439
+ * @param {string} key
1440
+ * @param {string} field
1441
+ * @returns {*}
1442
+ * @memberof MemoryCache
1443
+ */
1444
+ _getField(key, field) {
1445
+ return this._getKey(key)[field];
1446
+ }
1447
+ /**
1448
+ *
1449
+ *
1450
+ * @private
1451
+ * @param {string} key
1452
+ * @param {string} field
1453
+ * @returns {*} {boolean}
1454
+ * @memberof MemoryCache
1455
+ */
1456
+ _hasField(key, field) {
1457
+ let retVal = false;
1458
+ if (key && field) {
1459
+ const ky = this._getKey(key);
1460
+ if (ky) {
1461
+ retVal = ky.hasOwnProperty(field);
1462
+ }
1463
+ }
1464
+ return retVal;
1465
+ }
1466
+ /**
1467
+ *
1468
+ *
1469
+ * @param {string} key
1470
+ * @param {string} field
1471
+ * @param {*} value
1472
+ * @memberof MemoryCache
1473
+ */
1474
+ _setField(key, field, value) {
1475
+ this._getKey(key)[field] = value;
1476
+ }
1477
+ /**
1478
+ *
1479
+ *
1480
+ * @private
1481
+ * @param {Function} [callback]
1482
+ * @param {(any)} [message]
1483
+ * @param {*} [error]
1484
+ * @param {boolean} [nolog]
1485
+ * @returns {*}
1486
+ * @memberof MemoryCache
1487
+ */
1488
+ _handleCallback(callback, message, error, nolog) {
1489
+ let err = error;
1490
+ let msg = message;
1491
+ nolog = isNil(nolog) ? true : nolog;
1492
+ if (nolog) {
1493
+ err = this._logReturn(error);
1494
+ msg = this._logReturn(message);
1495
+ }
1496
+ if (typeof callback === 'function') {
1497
+ callback(err, msg);
1498
+ return;
1499
+ }
1500
+ if (err) {
1501
+ throw new Error(err);
1502
+ }
1503
+ return msg;
1504
+ }
1505
+ _logReturn(message) {
1506
+ if (!isUndefined(message)) {
1507
+ if (this.multiMode) {
1508
+ if (!isNil(this.responseMessages)) {
1509
+ this.responseMessages.push(message);
1510
+ if (message === messages.ok) {
1511
+ message = messages.queued;
1512
+ }
1513
+ }
1514
+ }
1515
+ return message;
1516
+ }
1517
+ return;
1518
+ }
1519
+ /**
1520
+ *
1521
+ *
1522
+ * @private
1523
+ * @param {any[]} [params]
1524
+ * @returns {*}
1525
+ * @memberof MemoryCache
1526
+ */
1527
+ _retrieveCallback(params) {
1528
+ if (Array.isArray(params) && params.length > 0 && typeof params[params.length - 1] === 'function') {
1529
+ return params.pop();
1530
+ }
1531
+ return;
1532
+ }
1533
+ }
1534
+
1535
+ // const MemoryCache = require('@outofsync/memory-cache');
1536
+ /*
1537
+ * @Description:
1538
+ * @Usage:
1539
+ * @Author: richen
1540
+ * @Date: 2021-06-29 19:07:57
1541
+ * @LastEditTime: 2021-12-02 15:30:12
1542
+ */
1543
+ class MemoryStore extends CacheStore {
1544
+ /**
1545
+ * Creates an instance of MemoryStore.
1546
+ * @param {StoreOptions} options
1547
+ * @memberof MemoryStore
1548
+ */
1549
+ constructor(options) {
1550
+ super(options);
1551
+ this.options = options;
1552
+ this.client = null;
1553
+ }
1554
+ /**
1555
+ * getConnection
1556
+ *
1557
+ * @returns {*}
1558
+ * @memberof MemoryStore
1559
+ */
1560
+ getConnection() {
1561
+ if (!this.pool) {
1562
+ this.pool = new MemoryCache({
1563
+ database: this.options.db
1564
+ });
1565
+ }
1566
+ if (!this.client) {
1567
+ this.client = this.pool.createClient();
1568
+ this.client.status = "ready";
1569
+ }
1570
+ return this.client;
1571
+ }
1572
+ /**
1573
+ * close
1574
+ *
1575
+ * @returns {*} {Promise<void>}
1576
+ * @memberof MemoryStore
1577
+ */
1578
+ async close() {
1579
+ this.client.end();
1580
+ this.client = null;
1581
+ }
1582
+ /**
1583
+ * release
1584
+ *
1585
+ * @param {*} conn
1586
+ * @returns {*} {Promise<void>}
1587
+ * @memberof MemoryStore
1588
+ */
1589
+ async release(conn) {
1590
+ return;
1591
+ }
1592
+ /**
1593
+ * defineCommand
1594
+ *
1595
+ * @param {string} name
1596
+ * @param {*} scripts
1597
+ * @memberof MemoryStore
1598
+ */
1599
+ async defineCommand(name, scripts) {
1600
+ throw new Error(messages.unsupported);
1601
+ }
1602
+ /**
1603
+ * get and compare value
1604
+ *
1605
+ * @param {string} name
1606
+ * @param {(string | number)} value
1607
+ * @returns {*} {Promise<any>}
1608
+ * @memberof MemoryStore
1609
+ */
1610
+ async getCompare(name, value) {
1611
+ const client = this.getConnection();
1612
+ const val = client.get(`${this.options.keyPrefix}${name}`);
1613
+ if (!val) {
1614
+ return 0;
1615
+ }
1616
+ else if (val == value) {
1617
+ return client.del(`${this.options.keyPrefix}${name}`);
1618
+ }
1619
+ else {
1620
+ return -1;
1621
+ }
1622
+ }
1623
+ }
1624
+
1625
+ /*
1626
+ * @Author: richen
1627
+ * @Date: 2020-11-30 15:56:08
1628
+ * @LastEditors: Please set LastEditors
1629
+ * @LastEditTime: 2021-12-02 15:30:11
1630
+ * @License: BSD (3-Clause)
1631
+ * @Copyright (c) - <richenlin(at)gmail.com>
1632
+ */
1633
+ /**
1634
+ *
1635
+ *
1636
+ * @export
1637
+ * @class RedisStore
1638
+ */
1639
+ class RedisStore extends CacheStore {
1640
+ /**
1641
+ * Creates an instance of RedisStore.
1642
+ * @param {StoreOptions} options
1643
+ * @memberof RedisStore
1644
+ */
1645
+ constructor(options) {
1646
+ super(options);
1647
+ this.options = this.parseOpt(options);
1648
+ this.pool = null;
1649
+ this.client = null;
1650
+ }
1651
+ // parseOpt
1652
+ parseOpt(options) {
1653
+ const opt = {
1654
+ host: options.host || '127.0.0.1',
1655
+ port: options.port || 3306,
1656
+ username: options.username || "",
1657
+ password: options.password || "",
1658
+ db: options.db || 0,
1659
+ timeout: options.timeout,
1660
+ keyPrefix: options.keyPrefix || '',
1661
+ poolSize: options.poolSize || 10,
1662
+ connectTimeout: options.connectTimeout || 500,
1663
+ };
1664
+ if (helper.isArray(options.host)) {
1665
+ const hosts = [];
1666
+ for (let i = 0; i < options.host.length; i++) {
1667
+ const h = options.host[i];
1668
+ if (!helper.isEmpty(options.host[i])) {
1669
+ let p;
1670
+ if (helper.isArray(options.port)) {
1671
+ p = options.port[i];
1672
+ }
1673
+ else {
1674
+ p = options.port || 6379;
1675
+ }
1676
+ hosts.push({
1677
+ host: h,
1678
+ port: helper.toNumber(p),
1679
+ });
1680
+ }
1681
+ }
1682
+ // sentinel
1683
+ if (!helper.isEmpty(options.name)) {
1684
+ opt.host = "";
1685
+ opt.port = null;
1686
+ opt.sentinels = [...hosts];
1687
+ opt.sentinelUsername = options.username;
1688
+ opt.sentinelPassword = options.password;
1689
+ }
1690
+ else {
1691
+ // cluster
1692
+ opt.host = "";
1693
+ opt.port = null;
1694
+ opt.clusters = [...hosts];
1695
+ }
1696
+ }
1697
+ return opt;
1698
+ }
1699
+ /**
1700
+ * create connection by native
1701
+ *
1702
+ * @param {number} [connNum=0]
1703
+ * @returns {*} {Promise<IORedis.Redis | IORedis.Cluster>}
1704
+ * @memberof RedisStore
1705
+ */
1706
+ async connect(connNum = 0) {
1707
+ if (this.client && this.client.status === 'ready') {
1708
+ return this.client;
1709
+ }
1710
+ const defer = helper.getDefer();
1711
+ let connection;
1712
+ if (!helper.isEmpty(this.options.clusters)) {
1713
+ connection = new IORedis.Cluster([...this.options.clusters], { redisOptions: this.options });
1714
+ }
1715
+ else {
1716
+ connection = new IORedis(this.options);
1717
+ }
1718
+ connection.on('end', () => {
1719
+ if (connNum < 3) {
1720
+ connNum++;
1721
+ defer.resolve(this.connect(connNum));
1722
+ }
1723
+ else {
1724
+ this.close();
1725
+ defer.reject('redis connection end');
1726
+ }
1727
+ });
1728
+ connection.on('ready', () => {
1729
+ this.client = connection;
1730
+ defer.resolve(connection);
1731
+ });
1732
+ return defer.promise;
1733
+ }
1734
+ /**
1735
+ * get connection from pool
1736
+ *
1737
+ * @returns {*}
1738
+ * @memberof RedisStore
1739
+ */
1740
+ getConnection() {
1741
+ if (!this.pool || !this.pool.acquire) {
1742
+ const factory = {
1743
+ create: () => {
1744
+ return this.connect();
1745
+ },
1746
+ destroy: () => {
1747
+ return this.close();
1748
+ },
1749
+ validate: (resource) => {
1750
+ return Promise.resolve(resource.status === 'ready');
1751
+ }
1752
+ };
1753
+ this.pool = genericPool.createPool(factory, {
1754
+ max: this.options.poolSize || 10,
1755
+ min: 2 // minimum size of the pool
1756
+ });
1757
+ this.pool.on('factoryCreateError', function (err) {
1758
+ DefaultLogger.Error(err);
1759
+ });
1760
+ this.pool.on('factoryDestroyError', function (err) {
1761
+ DefaultLogger.Error(err);
1762
+ });
1763
+ }
1764
+ return this.pool.acquire();
1765
+ }
1766
+ /**
1767
+ * close connection
1768
+ *
1769
+ * @returns {*}
1770
+ * @memberof RedisStore
1771
+ */
1772
+ async close() {
1773
+ this.client.disconnect();
1774
+ this.client = null;
1775
+ this.pool.destroy(this.client);
1776
+ this.pool = null;
1777
+ return;
1778
+ }
1779
+ /**
1780
+ *
1781
+ *
1782
+ * @param {*} conn
1783
+ * @returns {*}
1784
+ * @memberof RedisStore
1785
+ */
1786
+ async release(conn) {
1787
+ if (this.pool.isBorrowedResource(conn)) {
1788
+ return this.pool.release(conn);
1789
+ }
1790
+ return Promise.resolve();
1791
+ }
1792
+ /**
1793
+ * defineCommand
1794
+ *
1795
+ * @param {string} name
1796
+ * @param {{ numberOfKeys?: number; lua?: string; }} scripts
1797
+ * @returns {*}
1798
+ * @memberof RedisStore
1799
+ */
1800
+ async defineCommand(name, scripts) {
1801
+ const conn = await this.getConnection();
1802
+ if (!conn[name]) {
1803
+ conn.defineCommand(name, scripts);
1804
+ }
1805
+ return conn;
1806
+ }
1807
+ /**
1808
+ * get and compare value
1809
+ *
1810
+ * @param {string} name
1811
+ * @param {(string | number)} value
1812
+ * @returns {*} {Promise<any>}
1813
+ * @memberof RedisStore
1814
+ */
1815
+ async getCompare(name, value) {
1816
+ let conn;
1817
+ try {
1818
+ conn = await this.defineCommand("getCompare", {
1819
+ numberOfKeys: 1,
1820
+ lua: `
1821
+ local remote_value = redis.call("get",KEYS[1])
1822
+
1823
+ if (not remote_value) then
1824
+ return 0
1825
+ elseif (remote_value == ARGV[1]) then
1826
+ return redis.call("del",KEYS[1])
1827
+ else
1828
+ return -1
1829
+ end
1830
+ `
1831
+ });
1832
+ return conn.getCompare(name, value);
1833
+ }
1834
+ catch (error) {
1835
+ throw error;
1836
+ }
1837
+ finally {
1838
+ this.release(conn);
1839
+ }
1840
+ }
1841
+ }
1842
+
1843
+ /**
1844
+ *
1845
+ *
1846
+ * @export
1847
+ * @class Store
1848
+ */
1849
+ class Store {
1850
+ /**
1851
+ *
1852
+ *
1853
+ * @static
1854
+ * @returns
1855
+ * @memberof ValidateUtil
1856
+ */
1857
+ static getInstance(options) {
1858
+ if (this.instance) {
1859
+ return this.instance;
1860
+ }
1861
+ options = {
1862
+ ...{
1863
+ type: 'memory',
1864
+ host: '',
1865
+ port: 0,
1866
+ keyPrefix: 'Koatty',
1867
+ timeout: 600,
1868
+ poolSize: 10,
1869
+ connectTimeout: 500,
1870
+ db: 0
1871
+ }, ...options
1872
+ };
1873
+ switch (options.type) {
1874
+ case "redis":
1875
+ this.instance = new RedisStore(options);
1876
+ break;
1877
+ case "memory":
1878
+ default:
1879
+ this.instance = new MemoryStore(options);
1880
+ break;
1881
+ }
1882
+ return this.instance;
1883
+ }
1884
+ }
1885
+
1886
+ export { CacheStore, MemoryStore, Store };