koatty_store 1.6.2 → 1.7.0

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