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