@maiyunnet/kebab 3.2.36 → 4.0.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/index.d.ts +1 -1
- package/index.js +1 -1
- package/lib/core.js +1 -1
- package/lib/db.js +2 -2
- package/lib/jwt.d.ts +5 -5
- package/lib/jwt.js +1 -1
- package/lib/kv.d.ts +32 -290
- package/lib/kv.js +138 -855
- package/lib/scan.d.ts +5 -5
- package/lib/scan.js +2 -2
- package/lib/session.d.ts +2 -2
- package/lib/session.js +4 -4
- package/package.json +1 -1
- package/sys/ctr.d.ts +1 -1
- package/www/example/ctr/test.js +14 -11
package/lib/kv.js
CHANGED
|
@@ -1,708 +1,69 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Project: Kebab, User: JianSuoQiYue
|
|
3
3
|
* Date: 2019-5-30 19:25:22
|
|
4
|
-
* Last: 2020-3-28 18:54:04, 2022-09-12 23:24:45, 2022-09-22 01:06:22, 2024-2-21 13:32:56, 2024-8-21 16:59:57
|
|
4
|
+
* Last: 2020-3-28 18:54:04, 2022-09-12 23:24:45, 2022-09-22 01:06:22, 2024-2-21 13:32:56, 2024-8-21 16:59:57, 2025-11-6 14:56:45
|
|
5
5
|
*/
|
|
6
|
-
// --- Pool 是使用时必须要一个用户创建一份的,Connection 是池子里获取的 ---
|
|
7
|
-
// --- 为啥 Pool 要独立,因为有些配置项目不能存在 Connection 是用户单独使用的,例如 pre ---
|
|
8
6
|
// --- 第三方 ---
|
|
9
7
|
import * as redis from '@litert/redis';
|
|
10
|
-
|
|
8
|
+
// --- 库和定义 ---
|
|
11
9
|
import * as lText from '#kebab/lib/text.js';
|
|
12
10
|
import * as lCore from '#kebab/lib/core.js';
|
|
13
|
-
/** --- 连接列表(同一个 host、port、index
|
|
11
|
+
/** --- 连接列表(同一个 host、port、index 只有一个连接) --- */
|
|
14
12
|
const connections = [];
|
|
15
|
-
|
|
16
|
-
* --- 计划任务 10 秒一次,关闭超过 30 秒不活动的连接 ---
|
|
17
|
-
*/
|
|
18
|
-
async function checkConnection() {
|
|
19
|
-
const now = lTime.stamp();
|
|
20
|
-
for (let i = 0; i < connections.length; ++i) {
|
|
21
|
-
const connection = connections[i];
|
|
22
|
-
if (connection.isLost()) {
|
|
23
|
-
// --- 连接已经丢失,移除 ---
|
|
24
|
-
await connection.end();
|
|
25
|
-
connections.splice(i, 1);
|
|
26
|
-
--i;
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
if (connection.isUsing()) {
|
|
30
|
-
// --- 连接正在被使用,看看是否使用超过 30 秒,超过则不是正常状态 ---
|
|
31
|
-
if (connection.getLast() <= now - 30) {
|
|
32
|
-
// --- 30 秒之前开始的 ---
|
|
33
|
-
const msg = `[KV][checkConnection] There is a transactional connection[${i}] that is not closed.`;
|
|
34
|
-
lCore.display(msg);
|
|
35
|
-
lCore.log({}, msg, '-error');
|
|
36
|
-
await connection.end();
|
|
37
|
-
connections.splice(i, 1);
|
|
38
|
-
--i;
|
|
39
|
-
}
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
if (connection.getLast() <= now - 30) {
|
|
43
|
-
// --- 超 30 秒未被使用,则关闭 ---
|
|
44
|
-
await connection.end();
|
|
45
|
-
connections.splice(i, 1);
|
|
46
|
-
--i;
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
// --- 30 秒内使用过,看看连接是否正常 ---
|
|
50
|
-
if (await connection.ping(false)) {
|
|
51
|
-
// --- 正常 ---
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
// --- 连接有问题,直接关闭 ---
|
|
55
|
-
await connection.end();
|
|
56
|
-
connections.splice(i, 1);
|
|
57
|
-
--i;
|
|
58
|
-
}
|
|
59
|
-
setTimeout(function () {
|
|
60
|
-
checkConnection().catch(() => { });
|
|
61
|
-
}, 10_000);
|
|
62
|
-
}
|
|
63
|
-
setTimeout(function () {
|
|
64
|
-
checkConnection().catch(() => { });
|
|
65
|
-
}, 10_000);
|
|
66
|
-
export class Pool {
|
|
13
|
+
export class Kv {
|
|
67
14
|
constructor(ctr, etc) {
|
|
68
15
|
const configKv = ctr.getPrototype('_config').kv;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* --- 设定一个值 ---
|
|
80
|
-
* @param key
|
|
81
|
-
* @param val
|
|
82
|
-
* @param ttl 秒,0 为不限制
|
|
83
|
-
* @param mod 设置模式: 空,nx(key不存在才建立),xx(key存在才修改)
|
|
84
|
-
*/
|
|
85
|
-
async set(key, val, ttl = 0, mod = '') {
|
|
86
|
-
const conn = await this._getConnection();
|
|
87
|
-
if (!conn) {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
const r = await conn.set(key, val, ttl, mod, this._etc);
|
|
91
|
-
conn.used();
|
|
92
|
-
return r;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* --- 添加一个值,存在则不变 ---
|
|
96
|
-
* @param key
|
|
97
|
-
* @param val
|
|
98
|
-
* @param ttl 秒,0 为不限制
|
|
99
|
-
*/
|
|
100
|
-
async add(key, val, ttl = 0) {
|
|
101
|
-
const conn = await this._getConnection();
|
|
102
|
-
if (!conn) {
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
const r = await conn.add(key, val, ttl, this._etc);
|
|
106
|
-
conn.used();
|
|
107
|
-
return r;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* --- 替换一个存在的值 ---
|
|
111
|
-
* @param key
|
|
112
|
-
* @param val
|
|
113
|
-
* @param ttl 秒,0 为不限制
|
|
114
|
-
*/
|
|
115
|
-
async replace(key, val, ttl = 0) {
|
|
116
|
-
const conn = await this._getConnection();
|
|
117
|
-
if (!conn) {
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
const r = await conn.replace(key, val, ttl, this._etc);
|
|
121
|
-
conn.used();
|
|
122
|
-
return r;
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* --- 向已存在的值后追加数据 ---
|
|
126
|
-
* @param key
|
|
127
|
-
* @param val
|
|
128
|
-
*/
|
|
129
|
-
async append(key, val) {
|
|
130
|
-
const conn = await this._getConnection();
|
|
131
|
-
if (!conn) {
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
const r = await conn.append(key, val, this._etc);
|
|
135
|
-
conn.used();
|
|
136
|
-
return r;
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* --- 向已存在的值之前追加数据 ---
|
|
140
|
-
* @param key
|
|
141
|
-
* @param val
|
|
142
|
-
*/
|
|
143
|
-
async prepend(key, val) {
|
|
144
|
-
const conn = await this._getConnection();
|
|
145
|
-
if (!conn) {
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
const r = await conn.prepend(key, val, this._etc);
|
|
149
|
-
conn.used();
|
|
150
|
-
return r;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* --- 检测 key 是否存在 ---
|
|
154
|
-
* @param keys
|
|
155
|
-
*/
|
|
156
|
-
async exists(keys) {
|
|
157
|
-
const conn = await this._getConnection();
|
|
158
|
-
if (!conn) {
|
|
159
|
-
return 0;
|
|
160
|
-
}
|
|
161
|
-
const r = await conn.exists(keys, this._etc);
|
|
162
|
-
conn.used();
|
|
163
|
-
return r;
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* --- 获取字符串 ---
|
|
167
|
-
* @param key
|
|
168
|
-
*/
|
|
169
|
-
async get(key) {
|
|
170
|
-
const conn = await this._getConnection();
|
|
171
|
-
if (!conn) {
|
|
172
|
-
return null;
|
|
173
|
-
}
|
|
174
|
-
const r = await conn.get(key, this._etc);
|
|
175
|
-
conn.used();
|
|
176
|
-
return r;
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* --- 获取相应的剩余有效期秒数 ---
|
|
180
|
-
* @param key
|
|
181
|
-
*/
|
|
182
|
-
async ttl(key) {
|
|
183
|
-
const conn = await this._getConnection();
|
|
184
|
-
if (!conn) {
|
|
185
|
-
return null;
|
|
186
|
-
}
|
|
187
|
-
const r = await conn.ttl(key, this._etc);
|
|
188
|
-
conn.used();
|
|
189
|
-
return r;
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* --- 获取相应的剩余有效期毫秒数 ---
|
|
193
|
-
* @param key
|
|
194
|
-
*/
|
|
195
|
-
async pttl(key) {
|
|
196
|
-
const conn = await this._getConnection();
|
|
197
|
-
if (!conn) {
|
|
198
|
-
return null;
|
|
199
|
-
}
|
|
200
|
-
const r = await conn.pttl(key, this._etc);
|
|
201
|
-
conn.used();
|
|
202
|
-
return r;
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* --- 批量获取值 ---
|
|
206
|
-
* @param keys key 序列
|
|
207
|
-
*/
|
|
208
|
-
async mSet(rows) {
|
|
209
|
-
const conn = await this._getConnection();
|
|
210
|
-
if (!conn) {
|
|
211
|
-
return false;
|
|
16
|
+
const host = etc?.host ?? configKv.host;
|
|
17
|
+
const port = etc?.port ?? configKv.port;
|
|
18
|
+
this._index = etc?.index ?? configKv.index;
|
|
19
|
+
this._pre = etc?.pre ?? configKv.pre;
|
|
20
|
+
const item = connections.find(item => (item.host === host) && (item.port === port) && (item.index === this._index));
|
|
21
|
+
if (item) {
|
|
22
|
+
this._new = false;
|
|
23
|
+
this._link = item.link;
|
|
24
|
+
return;
|
|
212
25
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
26
|
+
this._new = true;
|
|
27
|
+
this._link = redis.createCommandClient({
|
|
28
|
+
'host': host,
|
|
29
|
+
'port': port,
|
|
30
|
+
});
|
|
31
|
+
this._link.on('error', err => {
|
|
32
|
+
lCore.debug('[KV][constructor][error]', err);
|
|
33
|
+
}).on('end', () => {
|
|
34
|
+
// --- 连接断开,不过没关系,执行命令时会自动重连 ---
|
|
35
|
+
}).on('close', () => {
|
|
36
|
+
// --- 连接断开,不过没关系,执行命令时会自动重连 ---
|
|
37
|
+
});
|
|
38
|
+
connections.push({
|
|
39
|
+
'host': host,
|
|
40
|
+
'port': port,
|
|
41
|
+
'index': this._index,
|
|
42
|
+
'link': this._link,
|
|
43
|
+
});
|
|
216
44
|
}
|
|
217
|
-
/**
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
if (conn) {
|
|
224
|
-
const r = await conn.mGet(keys, this._etc);
|
|
225
|
-
conn.used();
|
|
226
|
-
return r;
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
const rtn = {};
|
|
230
|
-
for (const key of keys) {
|
|
231
|
-
rtn[key] = null;
|
|
45
|
+
/** --- 初始化连接 --- */
|
|
46
|
+
async init(ctr, etc) {
|
|
47
|
+
try {
|
|
48
|
+
if (!this._new) {
|
|
49
|
+
// --- 不是新连接,不需要初始化 ---
|
|
50
|
+
return true;
|
|
232
51
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
* @returns false 表示系统错误, null 表示不存在, 其他值为 json 对象
|
|
240
|
-
*/
|
|
241
|
-
async getJson(key) {
|
|
242
|
-
const conn = await this._getConnection();
|
|
243
|
-
if (!conn) {
|
|
244
|
-
return false;
|
|
245
|
-
}
|
|
246
|
-
const r = await conn.getJson(key, this._etc);
|
|
247
|
-
conn.used();
|
|
248
|
-
return r;
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* --- 删除已存在的值 ---
|
|
252
|
-
* @param keys
|
|
253
|
-
*/
|
|
254
|
-
async del(keys) {
|
|
255
|
-
const conn = await this._getConnection();
|
|
256
|
-
if (!conn) {
|
|
257
|
-
return false;
|
|
258
|
-
}
|
|
259
|
-
const r = await conn.del(keys, this._etc);
|
|
260
|
-
conn.used();
|
|
261
|
-
return r;
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* --- 自增 ---
|
|
265
|
-
* @param key
|
|
266
|
-
* @param num 整数或浮点正数
|
|
267
|
-
*/
|
|
268
|
-
async incr(key, num = 1) {
|
|
269
|
-
const conn = await this._getConnection();
|
|
270
|
-
if (!conn) {
|
|
271
|
-
return false;
|
|
272
|
-
}
|
|
273
|
-
const r = await conn.incr(key, num, this._etc);
|
|
274
|
-
conn.used();
|
|
275
|
-
return r;
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* --- 自减 ---
|
|
279
|
-
* @param key
|
|
280
|
-
* @param num 整数或浮点正数
|
|
281
|
-
*/
|
|
282
|
-
async decr(key, num = 1) {
|
|
283
|
-
const conn = await this._getConnection();
|
|
284
|
-
if (!conn) {
|
|
285
|
-
return false;
|
|
286
|
-
}
|
|
287
|
-
const r = await conn.decr(key, num, this._etc);
|
|
288
|
-
conn.used();
|
|
289
|
-
return r;
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* --- 仅修改过期时间不修改值 ---
|
|
293
|
-
* @param key
|
|
294
|
-
* @param ttl
|
|
295
|
-
*/
|
|
296
|
-
async expire(key, ttl) {
|
|
297
|
-
const conn = await this._getConnection();
|
|
298
|
-
if (!conn) {
|
|
299
|
-
return false;
|
|
300
|
-
}
|
|
301
|
-
const r = await conn.expire(key, ttl, this._etc);
|
|
302
|
-
conn.used();
|
|
303
|
-
return r;
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* --- 获取服务器上的所有 key 列表 ---
|
|
307
|
-
* @param pattern
|
|
308
|
-
*/
|
|
309
|
-
async keys(pattern) {
|
|
310
|
-
const conn = await this._getConnection();
|
|
311
|
-
if (!conn) {
|
|
312
|
-
return false;
|
|
313
|
-
}
|
|
314
|
-
const r = await conn.keys(pattern, this._etc);
|
|
315
|
-
conn.used();
|
|
316
|
-
return r;
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* --- 根据条件获取服务器上的 keys ---
|
|
320
|
-
* @param cursor
|
|
321
|
-
* @param pattern 例如 *
|
|
322
|
-
* @param count 获取的条数
|
|
323
|
-
*/
|
|
324
|
-
async scan(cursor = 0, pattern = '*', count = 10) {
|
|
325
|
-
const conn = await this._getConnection();
|
|
326
|
-
if (!conn) {
|
|
327
|
-
return false;
|
|
328
|
-
}
|
|
329
|
-
const r = await conn.scan(cursor, pattern, count, this._etc);
|
|
330
|
-
conn.used();
|
|
331
|
-
return r;
|
|
332
|
-
}
|
|
333
|
-
/**
|
|
334
|
-
* --- 清除当前所选数据库的所有内容 ---
|
|
335
|
-
*/
|
|
336
|
-
async flushDb() {
|
|
337
|
-
const conn = await this._getConnection();
|
|
338
|
-
if (!conn) {
|
|
339
|
-
return false;
|
|
340
|
-
}
|
|
341
|
-
const r = await conn.flushDb();
|
|
342
|
-
conn.used();
|
|
343
|
-
return r;
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* --- 发送 ping ---
|
|
347
|
-
*/
|
|
348
|
-
async ping() {
|
|
349
|
-
const conn = await this._getConnection();
|
|
350
|
-
if (!conn) {
|
|
351
|
-
return false;
|
|
352
|
-
}
|
|
353
|
-
const r = await conn.ping();
|
|
354
|
-
conn.used();
|
|
355
|
-
return r;
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* --- 设置哈希表值 ---
|
|
359
|
-
* @param key key 名
|
|
360
|
-
* @param field 字段名
|
|
361
|
-
* @param val 值
|
|
362
|
-
* @param mod 空,nx(key不存在才建立)
|
|
363
|
-
*/
|
|
364
|
-
async hSet(key, field, val, mod = '') {
|
|
365
|
-
const conn = await this._getConnection();
|
|
366
|
-
if (!conn) {
|
|
367
|
-
return false;
|
|
368
|
-
}
|
|
369
|
-
const r = await conn.hSet(key, field, val, mod, this._etc);
|
|
370
|
-
conn.used();
|
|
371
|
-
return r;
|
|
372
|
-
}
|
|
373
|
-
/**
|
|
374
|
-
* --- 批量设置哈希值 ---
|
|
375
|
-
* @param key key 名
|
|
376
|
-
* @param rows key / val 数组
|
|
377
|
-
*/
|
|
378
|
-
async hMSet(key, rows) {
|
|
379
|
-
const conn = await this._getConnection();
|
|
380
|
-
if (!conn) {
|
|
381
|
-
return false;
|
|
382
|
-
}
|
|
383
|
-
const r = await conn.hMSet(key, rows, this._etc);
|
|
384
|
-
conn.used();
|
|
385
|
-
return r;
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* --- 获取哈希值 ---
|
|
389
|
-
* @param key
|
|
390
|
-
* @param field
|
|
391
|
-
*/
|
|
392
|
-
async hGet(key, field) {
|
|
393
|
-
const conn = await this._getConnection();
|
|
394
|
-
if (!conn) {
|
|
395
|
-
return null;
|
|
396
|
-
}
|
|
397
|
-
const r = await conn.hGet(key, field, this._etc);
|
|
398
|
-
conn.used();
|
|
399
|
-
return r;
|
|
400
|
-
}
|
|
401
|
-
/**
|
|
402
|
-
* --- 获取哈希 json 对象 ---
|
|
403
|
-
* @param key
|
|
404
|
-
* @param field
|
|
405
|
-
*/
|
|
406
|
-
async hGetJson(key, field) {
|
|
407
|
-
const conn = await this._getConnection();
|
|
408
|
-
if (!conn) {
|
|
409
|
-
return null;
|
|
410
|
-
}
|
|
411
|
-
const r = await conn.hGetJson(key, field, this._etc);
|
|
412
|
-
conn.used();
|
|
413
|
-
return r;
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* --- 批量获取哈希值 ---
|
|
417
|
-
* @param key
|
|
418
|
-
* @param fields
|
|
419
|
-
*/
|
|
420
|
-
async hMGet(key, fields) {
|
|
421
|
-
const conn = await this._getConnection();
|
|
422
|
-
if (conn) {
|
|
423
|
-
const r = await conn.hMGet(key, fields, this._etc);
|
|
424
|
-
conn.used();
|
|
425
|
-
return r;
|
|
52
|
+
const configKv = ctr.getPrototype('_config').kv;
|
|
53
|
+
const user = etc?.user ?? configKv.user;
|
|
54
|
+
const pwd = etc?.pwd ?? configKv.pwd;
|
|
55
|
+
await this._link.auth(pwd, user || undefined);
|
|
56
|
+
await this._link.select(this._index);
|
|
57
|
+
return true;
|
|
426
58
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
59
|
+
catch {
|
|
60
|
+
// --- 初始化失败,移除 ---
|
|
61
|
+
const item = connections.findIndex(item => item.link === this._link);
|
|
62
|
+
if (item !== -1) {
|
|
63
|
+
connections.splice(item, 1);
|
|
431
64
|
}
|
|
432
|
-
return rtn;
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
/**
|
|
436
|
-
* --- 批量获取哈希键值对 ---
|
|
437
|
-
* @param key
|
|
438
|
-
*/
|
|
439
|
-
async hGetAll(key) {
|
|
440
|
-
const conn = await this._getConnection();
|
|
441
|
-
if (!conn) {
|
|
442
|
-
return null;
|
|
443
|
-
}
|
|
444
|
-
const r = await conn.hGetAll(key, this._etc);
|
|
445
|
-
conn.used();
|
|
446
|
-
return r;
|
|
447
|
-
}
|
|
448
|
-
/**
|
|
449
|
-
* --- 删除哈希键 ---
|
|
450
|
-
* @param key
|
|
451
|
-
* @param fields 值序列
|
|
452
|
-
*/
|
|
453
|
-
async hDel(key, fields) {
|
|
454
|
-
const conn = await this._getConnection();
|
|
455
|
-
if (!conn) {
|
|
456
|
-
return 0;
|
|
457
|
-
}
|
|
458
|
-
const r = await conn.hDel(key, fields, this._etc);
|
|
459
|
-
conn.used();
|
|
460
|
-
return r;
|
|
461
|
-
}
|
|
462
|
-
/**
|
|
463
|
-
* --- 判断哈希字段是否存在 ---
|
|
464
|
-
* @param key
|
|
465
|
-
* @param field
|
|
466
|
-
*/
|
|
467
|
-
async hExists(key, field) {
|
|
468
|
-
const conn = await this._getConnection();
|
|
469
|
-
if (!conn) {
|
|
470
65
|
return false;
|
|
471
66
|
}
|
|
472
|
-
const r = await conn.hExists(key, field, this._etc);
|
|
473
|
-
conn.used();
|
|
474
|
-
return r;
|
|
475
|
-
}
|
|
476
|
-
/**
|
|
477
|
-
* --- 设置哈希自增自减 ---
|
|
478
|
-
* @param key key
|
|
479
|
-
* @param field 字段
|
|
480
|
-
* @param increment 正数或负数,整数或浮点
|
|
481
|
-
*/
|
|
482
|
-
async hIncr(key, field, increment) {
|
|
483
|
-
const conn = await this._getConnection();
|
|
484
|
-
if (!conn) {
|
|
485
|
-
return 0;
|
|
486
|
-
}
|
|
487
|
-
const r = await conn.hIncr(key, field, increment, this._etc);
|
|
488
|
-
conn.used();
|
|
489
|
-
return r;
|
|
490
|
-
}
|
|
491
|
-
/**
|
|
492
|
-
* --- 获取哈希所有字段 ---
|
|
493
|
-
* @param key
|
|
494
|
-
*/
|
|
495
|
-
async hKeys(key) {
|
|
496
|
-
const conn = await this._getConnection();
|
|
497
|
-
if (!conn) {
|
|
498
|
-
return [];
|
|
499
|
-
}
|
|
500
|
-
const r = await conn.hKeys(key, this._etc);
|
|
501
|
-
conn.used();
|
|
502
|
-
return r;
|
|
503
|
-
}
|
|
504
|
-
async lPush(key, values) {
|
|
505
|
-
const conn = await this._getConnection();
|
|
506
|
-
if (!conn) {
|
|
507
|
-
return 0;
|
|
508
|
-
}
|
|
509
|
-
const r = await conn.lPush(key, values, this._etc);
|
|
510
|
-
conn.used();
|
|
511
|
-
return r;
|
|
512
|
-
}
|
|
513
|
-
async rPush(key, values) {
|
|
514
|
-
const conn = await this._getConnection();
|
|
515
|
-
if (!conn) {
|
|
516
|
-
return 0;
|
|
517
|
-
}
|
|
518
|
-
const r = await conn.rPush(key, values, this._etc);
|
|
519
|
-
conn.used();
|
|
520
|
-
return r;
|
|
521
|
-
}
|
|
522
|
-
async bLMove(sourceKey, destKey, soo, deo, timeout) {
|
|
523
|
-
const conn = await this._getConnection();
|
|
524
|
-
if (!conn) {
|
|
525
|
-
return null;
|
|
526
|
-
}
|
|
527
|
-
const r = await conn.bLMove(sourceKey, destKey, soo, deo, timeout, this._etc);
|
|
528
|
-
conn.used();
|
|
529
|
-
return r;
|
|
530
|
-
}
|
|
531
|
-
async lPop(key) {
|
|
532
|
-
const conn = await this._getConnection();
|
|
533
|
-
if (!conn) {
|
|
534
|
-
return null;
|
|
535
|
-
}
|
|
536
|
-
const r = await conn.lPop(key, this._etc);
|
|
537
|
-
conn.used();
|
|
538
|
-
return r;
|
|
539
|
-
}
|
|
540
|
-
async rPop(key) {
|
|
541
|
-
const conn = await this._getConnection();
|
|
542
|
-
if (!conn) {
|
|
543
|
-
return null;
|
|
544
|
-
}
|
|
545
|
-
const r = await conn.rPop(key, this._etc);
|
|
546
|
-
conn.used();
|
|
547
|
-
return r;
|
|
548
|
-
}
|
|
549
|
-
async bRPop(key, timeout) {
|
|
550
|
-
const conn = await this._getConnection();
|
|
551
|
-
if (!conn) {
|
|
552
|
-
return {};
|
|
553
|
-
}
|
|
554
|
-
const r = await conn.bRPop(key, timeout, this._etc);
|
|
555
|
-
conn.used();
|
|
556
|
-
return r;
|
|
557
|
-
}
|
|
558
|
-
async lRange(key, start, stop) {
|
|
559
|
-
const conn = await this._getConnection();
|
|
560
|
-
if (!conn) {
|
|
561
|
-
return [];
|
|
562
|
-
}
|
|
563
|
-
const r = await conn.lRange(key, start, stop, this._etc);
|
|
564
|
-
conn.used();
|
|
565
|
-
return r;
|
|
566
|
-
}
|
|
567
|
-
async lLen(key) {
|
|
568
|
-
const conn = await this._getConnection();
|
|
569
|
-
if (!conn) {
|
|
570
|
-
return 0;
|
|
571
|
-
}
|
|
572
|
-
const r = await conn.lLen(key, this._etc);
|
|
573
|
-
conn.used();
|
|
574
|
-
return r;
|
|
575
|
-
}
|
|
576
|
-
/**
|
|
577
|
-
* --- 从连接池获取一个连接,会被自动设置为使用中,需要在执行命令后解除占用 ---
|
|
578
|
-
*/
|
|
579
|
-
async _getConnection() {
|
|
580
|
-
let conn;
|
|
581
|
-
for (const connection of connections) {
|
|
582
|
-
const etc = connection.getEtc();
|
|
583
|
-
if (connection.isLost() ||
|
|
584
|
-
connection.isUsing() ||
|
|
585
|
-
(etc.host !== this._etc.host) ||
|
|
586
|
-
(etc.port !== this._etc.port) ||
|
|
587
|
-
(etc.index !== this._etc.index)) {
|
|
588
|
-
// --- 配置项连接项不匹配 ---
|
|
589
|
-
continue;
|
|
590
|
-
}
|
|
591
|
-
connection.refreshLast();
|
|
592
|
-
connection.setUsing();
|
|
593
|
-
conn = connection;
|
|
594
|
-
break;
|
|
595
|
-
}
|
|
596
|
-
if (!conn) {
|
|
597
|
-
// --- 没有找到合适的连接,创建一个 ---
|
|
598
|
-
const link = redis.createCommandClient({
|
|
599
|
-
'host': this._etc.host,
|
|
600
|
-
'port': this._etc.port,
|
|
601
|
-
});
|
|
602
|
-
// --- 开始连接 ---
|
|
603
|
-
try {
|
|
604
|
-
await link.connect();
|
|
605
|
-
}
|
|
606
|
-
catch {
|
|
607
|
-
return null;
|
|
608
|
-
}
|
|
609
|
-
// --- 认证 ---
|
|
610
|
-
if (this._etc.user || this._etc.pwd) {
|
|
611
|
-
try {
|
|
612
|
-
await link.auth(this._etc.user + this._etc.pwd);
|
|
613
|
-
}
|
|
614
|
-
catch {
|
|
615
|
-
return null;
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
await link.select(this._etc.index);
|
|
619
|
-
conn = new Connection(this._etc, link);
|
|
620
|
-
conn.refreshLast();
|
|
621
|
-
conn.setUsing();
|
|
622
|
-
link.on('error', function (err) {
|
|
623
|
-
conn.setLost();
|
|
624
|
-
// console.log(`--- redis [${conn._etc.host}:${conn._etc.port}] error ---`);
|
|
625
|
-
lCore.debug('[KV][_getConnection][error]', err);
|
|
626
|
-
}).on('end', () => {
|
|
627
|
-
conn.setLost();
|
|
628
|
-
}).on('close', () => {
|
|
629
|
-
conn.setLost();
|
|
630
|
-
});
|
|
631
|
-
connections.push(conn);
|
|
632
|
-
}
|
|
633
|
-
return conn;
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
export class Connection {
|
|
637
|
-
constructor(etc, link) {
|
|
638
|
-
/** --- 本连接最后一次使用时间 --- */
|
|
639
|
-
this._last = 0;
|
|
640
|
-
/** --- 当前连接是否正在被独占使用 --- */
|
|
641
|
-
this._using = false;
|
|
642
|
-
/** --- 当发生断开,则需从连接池移除连接 --- */
|
|
643
|
-
this._lost = false;
|
|
644
|
-
this._etc = etc;
|
|
645
|
-
this._link = link;
|
|
646
|
-
this.refreshLast();
|
|
647
|
-
}
|
|
648
|
-
/**
|
|
649
|
-
* --- 获取连接 etc 信息 ---
|
|
650
|
-
*/
|
|
651
|
-
getEtc() {
|
|
652
|
-
return this._etc;
|
|
653
|
-
}
|
|
654
|
-
/**
|
|
655
|
-
* --- 获取最后一次获取连接的时间 ---
|
|
656
|
-
*/
|
|
657
|
-
getLast() {
|
|
658
|
-
return this._last;
|
|
659
|
-
}
|
|
660
|
-
/**
|
|
661
|
-
* --- 将本条连接设置为不可用 ---
|
|
662
|
-
*/
|
|
663
|
-
setLost() {
|
|
664
|
-
this._lost = true;
|
|
665
|
-
}
|
|
666
|
-
/**
|
|
667
|
-
* --- 是否已经丢失 ---
|
|
668
|
-
*/
|
|
669
|
-
isLost() {
|
|
670
|
-
return this._lost;
|
|
671
|
-
}
|
|
672
|
-
/**
|
|
673
|
-
* --- 将本条连接设置占用中 ---
|
|
674
|
-
*/
|
|
675
|
-
setUsing() {
|
|
676
|
-
this._using = true;
|
|
677
|
-
}
|
|
678
|
-
/**
|
|
679
|
-
* --- 获取当前状态是否正在被使用中 ---
|
|
680
|
-
*/
|
|
681
|
-
isUsing() {
|
|
682
|
-
return this._using;
|
|
683
|
-
}
|
|
684
|
-
/**
|
|
685
|
-
* --- 取消占用 ---
|
|
686
|
-
*/
|
|
687
|
-
used() {
|
|
688
|
-
this._using = false;
|
|
689
|
-
}
|
|
690
|
-
/**
|
|
691
|
-
* --- 设定最后使用时间 ---
|
|
692
|
-
*/
|
|
693
|
-
refreshLast() {
|
|
694
|
-
this._last = lTime.stamp();
|
|
695
|
-
}
|
|
696
|
-
/**
|
|
697
|
-
* --- 断开此连接,一般情况下不使用 ---
|
|
698
|
-
*/
|
|
699
|
-
async end() {
|
|
700
|
-
try {
|
|
701
|
-
await this._link.close();
|
|
702
|
-
}
|
|
703
|
-
catch {
|
|
704
|
-
return;
|
|
705
|
-
}
|
|
706
67
|
}
|
|
707
68
|
/**
|
|
708
69
|
* --- 设定一个值 ---
|
|
@@ -710,23 +71,21 @@ export class Connection {
|
|
|
710
71
|
* @param val
|
|
711
72
|
* @param ttl 秒,0 为不限制
|
|
712
73
|
* @param mod 设置模式: 空,nx(key不存在才建立),xx(key存在才修改)
|
|
713
|
-
* @param etc 配置项,主要用 etc.pre
|
|
714
74
|
*/
|
|
715
|
-
async set(key, val, ttl, mod
|
|
716
|
-
this.refreshLast();
|
|
75
|
+
async set(key, val, ttl = 0, mod = '') {
|
|
717
76
|
if (typeof val !== 'string') {
|
|
718
77
|
val = lText.stringifyJson(val);
|
|
719
78
|
}
|
|
720
79
|
try {
|
|
721
80
|
switch (mod) {
|
|
722
81
|
case '': {
|
|
723
|
-
return await this._link.set(
|
|
82
|
+
return await this._link.set(this._pre + key, val, ttl === 0 ? undefined : ttl);
|
|
724
83
|
}
|
|
725
84
|
case 'nx': {
|
|
726
|
-
return await this._link.setNX(
|
|
85
|
+
return await this._link.setNX(this._pre + key, val, ttl === 0 ? undefined : ttl);
|
|
727
86
|
}
|
|
728
87
|
case 'xx': {
|
|
729
|
-
return await this._link.replace(
|
|
88
|
+
return await this._link.replace(this._pre + key, val, ttl === 0 ? undefined : ttl);
|
|
730
89
|
}
|
|
731
90
|
}
|
|
732
91
|
}
|
|
@@ -739,10 +98,9 @@ export class Connection {
|
|
|
739
98
|
* @param key
|
|
740
99
|
* @param val
|
|
741
100
|
* @param ttl 秒,0 为不限制
|
|
742
|
-
* @param etc
|
|
743
101
|
*/
|
|
744
|
-
async add(key, val, ttl
|
|
745
|
-
return this.set(key, val, ttl, 'nx'
|
|
102
|
+
async add(key, val, ttl = 0) {
|
|
103
|
+
return this.set(key, val, ttl, 'nx');
|
|
746
104
|
}
|
|
747
105
|
/**
|
|
748
106
|
* --- 替换一个存在的值 ---
|
|
@@ -751,19 +109,17 @@ export class Connection {
|
|
|
751
109
|
* @param ttl 秒,0 为不限制
|
|
752
110
|
* @param etc
|
|
753
111
|
*/
|
|
754
|
-
async replace(key, val, ttl
|
|
755
|
-
return this.set(key, val, ttl, 'xx'
|
|
112
|
+
async replace(key, val, ttl = 0) {
|
|
113
|
+
return this.set(key, val, ttl, 'xx');
|
|
756
114
|
}
|
|
757
115
|
/**
|
|
758
116
|
* --- 向已存在的值后追加数据 ---
|
|
759
117
|
* @param key
|
|
760
118
|
* @param val
|
|
761
|
-
* @param etc
|
|
762
119
|
*/
|
|
763
|
-
async append(key, val
|
|
764
|
-
this.refreshLast();
|
|
120
|
+
async append(key, val) {
|
|
765
121
|
try {
|
|
766
|
-
return await this._link.append(
|
|
122
|
+
return await this._link.append(this._pre + key, val) > 0 ? true : false;
|
|
767
123
|
}
|
|
768
124
|
catch {
|
|
769
125
|
return false;
|
|
@@ -774,8 +130,7 @@ export class Connection {
|
|
|
774
130
|
* @param key
|
|
775
131
|
* @param val
|
|
776
132
|
*/
|
|
777
|
-
async prepend(key, val
|
|
778
|
-
this.refreshLast();
|
|
133
|
+
async prepend(key, val) {
|
|
779
134
|
try {
|
|
780
135
|
const script = `local val = redis.call('GET', KEYS[1])
|
|
781
136
|
if (val == false) then
|
|
@@ -787,11 +142,11 @@ if (r) then
|
|
|
787
142
|
else
|
|
788
143
|
return 0
|
|
789
144
|
end`;
|
|
790
|
-
let r = await this._link.evalSHA('ea360f3f6508a243824ecda6be15db56df217873', [
|
|
145
|
+
let r = await this._link.evalSHA('ea360f3f6508a243824ecda6be15db56df217873', [this._pre + key], [val]);
|
|
791
146
|
r = parseInt(r);
|
|
792
147
|
if (r <= 0) {
|
|
793
148
|
await this._link.scriptLoad(script);
|
|
794
|
-
r = this._link.evalSHA('ea360f3f6508a243824ecda6be15db56df217873', [
|
|
149
|
+
r = await this._link.evalSHA('ea360f3f6508a243824ecda6be15db56df217873', [this._pre + key], [val]);
|
|
795
150
|
r = parseInt(r);
|
|
796
151
|
}
|
|
797
152
|
return r > 0 ? true : false;
|
|
@@ -803,16 +158,14 @@ end`;
|
|
|
803
158
|
/**
|
|
804
159
|
* --- 检测 key 是否存在 ---
|
|
805
160
|
* @param keys 单个或序列
|
|
806
|
-
* @param etc
|
|
807
161
|
*/
|
|
808
|
-
async exists(keys
|
|
809
|
-
this.refreshLast();
|
|
162
|
+
async exists(keys) {
|
|
810
163
|
try {
|
|
811
164
|
if (typeof keys === 'string') {
|
|
812
165
|
keys = [keys];
|
|
813
166
|
}
|
|
814
167
|
for (let k = 0; k < keys.length; ++k) {
|
|
815
|
-
keys[k] =
|
|
168
|
+
keys[k] = this._pre + keys[k];
|
|
816
169
|
}
|
|
817
170
|
return await this._link.mExists(keys);
|
|
818
171
|
}
|
|
@@ -823,13 +176,11 @@ end`;
|
|
|
823
176
|
/**
|
|
824
177
|
* --- 获取字符串 ---
|
|
825
178
|
* @param key
|
|
826
|
-
* @param etc
|
|
827
179
|
* @returns 字符串 / false / null(即使存入时是 number,这个方法也只会返回字符串)
|
|
828
180
|
*/
|
|
829
|
-
async get(key
|
|
830
|
-
this.refreshLast();
|
|
181
|
+
async get(key) {
|
|
831
182
|
try {
|
|
832
|
-
return await this._link.get(
|
|
183
|
+
return await this._link.get(this._pre + key);
|
|
833
184
|
}
|
|
834
185
|
catch {
|
|
835
186
|
return false;
|
|
@@ -838,12 +189,10 @@ end`;
|
|
|
838
189
|
/**
|
|
839
190
|
* --- 获取相应的剩余有效期秒数 ---
|
|
840
191
|
* @param key
|
|
841
|
-
* @param etc
|
|
842
192
|
*/
|
|
843
|
-
async ttl(key
|
|
844
|
-
this.refreshLast();
|
|
193
|
+
async ttl(key) {
|
|
845
194
|
try {
|
|
846
|
-
return await this._link.ttl(
|
|
195
|
+
return await this._link.ttl(this._pre + key);
|
|
847
196
|
}
|
|
848
197
|
catch {
|
|
849
198
|
return null;
|
|
@@ -852,12 +201,10 @@ end`;
|
|
|
852
201
|
/**
|
|
853
202
|
* --- 获取相应的剩余有效期毫秒数 ---
|
|
854
203
|
* @param key
|
|
855
|
-
* @param etc
|
|
856
204
|
*/
|
|
857
|
-
async pttl(key
|
|
858
|
-
this.refreshLast();
|
|
205
|
+
async pttl(key) {
|
|
859
206
|
try {
|
|
860
|
-
return await this._link.pTTL(
|
|
207
|
+
return await this._link.pTTL(this._pre + key);
|
|
861
208
|
}
|
|
862
209
|
catch {
|
|
863
210
|
return null;
|
|
@@ -866,16 +213,14 @@ end`;
|
|
|
866
213
|
/**
|
|
867
214
|
* --- 批量获取值 ---
|
|
868
215
|
* @param keys key 序列
|
|
869
|
-
* @param etc 顺序数组
|
|
870
216
|
*/
|
|
871
|
-
async mGet(keys
|
|
872
|
-
this.refreshLast();
|
|
217
|
+
async mGet(keys) {
|
|
873
218
|
for (let k = 0; k < keys.length; ++k) {
|
|
874
|
-
keys[k] =
|
|
219
|
+
keys[k] = this._pre + keys[k];
|
|
875
220
|
}
|
|
876
221
|
const rtn = {};
|
|
877
222
|
try {
|
|
878
|
-
const pl =
|
|
223
|
+
const pl = this._pre.length;
|
|
879
224
|
const r = await this._link.mGet(keys);
|
|
880
225
|
if (pl === 0) {
|
|
881
226
|
return r;
|
|
@@ -897,12 +242,11 @@ end`;
|
|
|
897
242
|
* @param rows key / val 数组
|
|
898
243
|
* @param etc
|
|
899
244
|
*/
|
|
900
|
-
async mSet(rows
|
|
901
|
-
this.refreshLast();
|
|
245
|
+
async mSet(rows) {
|
|
902
246
|
try {
|
|
903
247
|
const rtn = {};
|
|
904
248
|
for (const key in rows) {
|
|
905
|
-
rtn[
|
|
249
|
+
rtn[this._pre + key] = rows[key];
|
|
906
250
|
}
|
|
907
251
|
await this._link.mSet(rtn);
|
|
908
252
|
return true;
|
|
@@ -914,10 +258,9 @@ end`;
|
|
|
914
258
|
/**
|
|
915
259
|
* --- 获取 json 对象 ---
|
|
916
260
|
* @param key
|
|
917
|
-
* @param etc
|
|
918
261
|
*/
|
|
919
|
-
async getJson(key
|
|
920
|
-
const v = await this.get(key
|
|
262
|
+
async getJson(key) {
|
|
263
|
+
const v = await this.get(key);
|
|
921
264
|
if (v === null || v === false) {
|
|
922
265
|
return v;
|
|
923
266
|
}
|
|
@@ -927,15 +270,13 @@ end`;
|
|
|
927
270
|
/**
|
|
928
271
|
* --- 删除已存在的值 ---
|
|
929
272
|
* @param keys
|
|
930
|
-
* @param etc
|
|
931
273
|
*/
|
|
932
|
-
async del(keys
|
|
933
|
-
this.refreshLast();
|
|
274
|
+
async del(keys) {
|
|
934
275
|
if (typeof keys === 'string') {
|
|
935
276
|
keys = [keys];
|
|
936
277
|
}
|
|
937
278
|
for (let k = 0; k < keys.length; ++k) {
|
|
938
|
-
keys[k] =
|
|
279
|
+
keys[k] = this._pre + keys[k];
|
|
939
280
|
}
|
|
940
281
|
try {
|
|
941
282
|
return await this._link.del(keys) > 0 ? true : false;
|
|
@@ -948,21 +289,19 @@ end`;
|
|
|
948
289
|
* --- 自增 ---
|
|
949
290
|
* @param key
|
|
950
291
|
* @param num 整数或浮点正数
|
|
951
|
-
* @param etc
|
|
952
292
|
*/
|
|
953
|
-
async incr(key, num
|
|
954
|
-
this.refreshLast();
|
|
293
|
+
async incr(key, num = 1) {
|
|
955
294
|
try {
|
|
956
295
|
if (Number.isInteger(num)) {
|
|
957
296
|
if (num === 1) {
|
|
958
|
-
return await this._link.incr(
|
|
297
|
+
return await this._link.incr(this._pre + key);
|
|
959
298
|
}
|
|
960
299
|
else {
|
|
961
|
-
return await this._link.incr(
|
|
300
|
+
return await this._link.incr(this._pre + key, num);
|
|
962
301
|
}
|
|
963
302
|
}
|
|
964
303
|
else {
|
|
965
|
-
return await this._link.incrByFloat(
|
|
304
|
+
return await this._link.incrByFloat(this._pre + key, num);
|
|
966
305
|
}
|
|
967
306
|
}
|
|
968
307
|
catch {
|
|
@@ -973,21 +312,19 @@ end`;
|
|
|
973
312
|
* --- 自减 ---
|
|
974
313
|
* @param key
|
|
975
314
|
* @param num 整数或浮点正数
|
|
976
|
-
* @param etc
|
|
977
315
|
*/
|
|
978
|
-
async decr(key, num
|
|
979
|
-
this.refreshLast();
|
|
316
|
+
async decr(key, num = 1) {
|
|
980
317
|
try {
|
|
981
318
|
if (Number.isInteger(num)) {
|
|
982
319
|
if (num === 1) {
|
|
983
|
-
return await this._link.decr(
|
|
320
|
+
return await this._link.decr(this._pre + key);
|
|
984
321
|
}
|
|
985
322
|
else {
|
|
986
|
-
return await this._link.decr(
|
|
323
|
+
return await this._link.decr(this._pre + key, num);
|
|
987
324
|
}
|
|
988
325
|
}
|
|
989
326
|
else {
|
|
990
|
-
return await this._link.incrByFloat(
|
|
327
|
+
return await this._link.incrByFloat(this._pre + key, -num);
|
|
991
328
|
}
|
|
992
329
|
}
|
|
993
330
|
catch {
|
|
@@ -998,12 +335,10 @@ end`;
|
|
|
998
335
|
* --- 仅修改过期时间不修改值 ---
|
|
999
336
|
* @param key
|
|
1000
337
|
* @param ttl
|
|
1001
|
-
* @param etc
|
|
1002
338
|
*/
|
|
1003
|
-
async expire(key, ttl
|
|
1004
|
-
this.refreshLast();
|
|
339
|
+
async expire(key, ttl) {
|
|
1005
340
|
try {
|
|
1006
|
-
return await this._link.expire(
|
|
341
|
+
return await this._link.expire(this._pre + key, ttl);
|
|
1007
342
|
}
|
|
1008
343
|
catch {
|
|
1009
344
|
return false;
|
|
@@ -1013,11 +348,10 @@ end`;
|
|
|
1013
348
|
* --- 获取服务器上的所有 key 列表 ---
|
|
1014
349
|
* @param pattern
|
|
1015
350
|
*/
|
|
1016
|
-
async keys(pattern
|
|
1017
|
-
this.refreshLast();
|
|
351
|
+
async keys(pattern) {
|
|
1018
352
|
try {
|
|
1019
|
-
const r = await this._link.keys(
|
|
1020
|
-
const pl =
|
|
353
|
+
const r = await this._link.keys(this._pre + pattern);
|
|
354
|
+
const pl = this._pre.length;
|
|
1021
355
|
if (pl > 0) {
|
|
1022
356
|
for (let k = 0; k < r.length; ++k) {
|
|
1023
357
|
r[k] = r[k].slice(pl);
|
|
@@ -1034,14 +368,12 @@ end`;
|
|
|
1034
368
|
* @param cursor
|
|
1035
369
|
* @param pattern 例如 *
|
|
1036
370
|
* @param count 获取的条数
|
|
1037
|
-
* @param etc
|
|
1038
371
|
*/
|
|
1039
|
-
async scan(cursor, pattern, count
|
|
1040
|
-
this.refreshLast();
|
|
372
|
+
async scan(cursor = 0, pattern = '*', count = 10) {
|
|
1041
373
|
try {
|
|
1042
|
-
const r = await this._link.scan(cursor,
|
|
374
|
+
const r = await this._link.scan(cursor, this._pre + pattern, count);
|
|
1043
375
|
for (let i = 0; i < r.items.length; ++i) {
|
|
1044
|
-
r.items[i] = r.items[i].slice(this.
|
|
376
|
+
r.items[i] = r.items[i].slice(this._pre.length);
|
|
1045
377
|
}
|
|
1046
378
|
return r;
|
|
1047
379
|
}
|
|
@@ -1053,7 +385,6 @@ end`;
|
|
|
1053
385
|
* --- 清除当前所选数据库的所有内容 ---
|
|
1054
386
|
*/
|
|
1055
387
|
async flushDb() {
|
|
1056
|
-
this.refreshLast();
|
|
1057
388
|
try {
|
|
1058
389
|
await this._link.flushDb();
|
|
1059
390
|
return true;
|
|
@@ -1066,10 +397,7 @@ end`;
|
|
|
1066
397
|
* --- 发送 ping ---
|
|
1067
398
|
* @param last 是否刷新最后使用时间(默认刷新)
|
|
1068
399
|
*/
|
|
1069
|
-
async ping(
|
|
1070
|
-
if (last) {
|
|
1071
|
-
this.refreshLast();
|
|
1072
|
-
}
|
|
400
|
+
async ping() {
|
|
1073
401
|
try {
|
|
1074
402
|
return (await this._link.ping()) === 'PONG' ? 'PONG' : false;
|
|
1075
403
|
}
|
|
@@ -1083,19 +411,17 @@ end`;
|
|
|
1083
411
|
* @param field 字段名
|
|
1084
412
|
* @param val 值
|
|
1085
413
|
* @param mod 空,nx(key不存在才建立)
|
|
1086
|
-
* @param etc
|
|
1087
414
|
*/
|
|
1088
|
-
async hSet(key, field, val, mod
|
|
1089
|
-
this.refreshLast();
|
|
415
|
+
async hSet(key, field, val, mod = '') {
|
|
1090
416
|
try {
|
|
1091
417
|
if (typeof val !== 'string') {
|
|
1092
418
|
val = lText.stringifyJson(val);
|
|
1093
419
|
}
|
|
1094
420
|
if (mod === 'nx') {
|
|
1095
|
-
return await this._link.hSetNX(
|
|
421
|
+
return await this._link.hSetNX(this._pre + key, field, val);
|
|
1096
422
|
}
|
|
1097
423
|
else {
|
|
1098
|
-
return await this._link.hSet(
|
|
424
|
+
return await this._link.hSet(this._pre + key, field, val);
|
|
1099
425
|
}
|
|
1100
426
|
}
|
|
1101
427
|
catch {
|
|
@@ -1106,10 +432,8 @@ end`;
|
|
|
1106
432
|
* --- 批量设置哈希值 ---
|
|
1107
433
|
* @param key key 名
|
|
1108
434
|
* @param rows key / val 数组
|
|
1109
|
-
* @param etc
|
|
1110
435
|
*/
|
|
1111
|
-
async hMSet(key, rows
|
|
1112
|
-
this.refreshLast();
|
|
436
|
+
async hMSet(key, rows) {
|
|
1113
437
|
try {
|
|
1114
438
|
for (const i in rows) {
|
|
1115
439
|
const val = rows[i];
|
|
@@ -1117,7 +441,7 @@ end`;
|
|
|
1117
441
|
rows[i] = lText.stringifyJson(val);
|
|
1118
442
|
}
|
|
1119
443
|
}
|
|
1120
|
-
await this._link.hMSet(
|
|
444
|
+
await this._link.hMSet(this._pre + key, rows);
|
|
1121
445
|
return true;
|
|
1122
446
|
}
|
|
1123
447
|
catch {
|
|
@@ -1128,12 +452,10 @@ end`;
|
|
|
1128
452
|
* --- 获取哈希值 ---
|
|
1129
453
|
* @param key
|
|
1130
454
|
* @param field
|
|
1131
|
-
* @param etc
|
|
1132
455
|
*/
|
|
1133
|
-
async hGet(key, field
|
|
1134
|
-
this.refreshLast();
|
|
456
|
+
async hGet(key, field) {
|
|
1135
457
|
try {
|
|
1136
|
-
return await this._link.hGet(
|
|
458
|
+
return await this._link.hGet(this._pre + key, field);
|
|
1137
459
|
}
|
|
1138
460
|
catch {
|
|
1139
461
|
return null;
|
|
@@ -1143,10 +465,9 @@ end`;
|
|
|
1143
465
|
* --- 获取哈希 json 对象 ---
|
|
1144
466
|
* @param key
|
|
1145
467
|
* @param field
|
|
1146
|
-
* @param etc
|
|
1147
468
|
*/
|
|
1148
|
-
async hGetJson(key, field
|
|
1149
|
-
const v = await this.hGet(key, field
|
|
469
|
+
async hGetJson(key, field) {
|
|
470
|
+
const v = await this.hGet(key, field);
|
|
1150
471
|
if (v === null) {
|
|
1151
472
|
return null;
|
|
1152
473
|
}
|
|
@@ -1157,12 +478,10 @@ end`;
|
|
|
1157
478
|
* --- 批量获取哈希值 ---
|
|
1158
479
|
* @param key
|
|
1159
480
|
* @param fields
|
|
1160
|
-
* @param etc
|
|
1161
481
|
*/
|
|
1162
|
-
async hMGet(key, fields
|
|
1163
|
-
this.refreshLast();
|
|
482
|
+
async hMGet(key, fields) {
|
|
1164
483
|
try {
|
|
1165
|
-
return await this._link.hMGet(
|
|
484
|
+
return await this._link.hMGet(this._pre + key, fields);
|
|
1166
485
|
}
|
|
1167
486
|
catch {
|
|
1168
487
|
const rtn = {};
|
|
@@ -1175,12 +494,10 @@ end`;
|
|
|
1175
494
|
/**
|
|
1176
495
|
* --- 批量获取哈希键值对 ---
|
|
1177
496
|
* @param key
|
|
1178
|
-
* @param etc
|
|
1179
497
|
*/
|
|
1180
|
-
async hGetAll(key
|
|
1181
|
-
this.refreshLast();
|
|
498
|
+
async hGetAll(key) {
|
|
1182
499
|
try {
|
|
1183
|
-
return await this._link.hGetAll(
|
|
500
|
+
return await this._link.hGetAll(this._pre + key);
|
|
1184
501
|
}
|
|
1185
502
|
catch {
|
|
1186
503
|
return null;
|
|
@@ -1190,12 +507,10 @@ end`;
|
|
|
1190
507
|
* --- 删除哈希键 ---
|
|
1191
508
|
* @param key
|
|
1192
509
|
* @param fields 值序列
|
|
1193
|
-
* @param etc
|
|
1194
510
|
*/
|
|
1195
|
-
async hDel(key, fields
|
|
1196
|
-
this.refreshLast();
|
|
511
|
+
async hDel(key, fields) {
|
|
1197
512
|
try {
|
|
1198
|
-
return await this._link.hDel(
|
|
513
|
+
return await this._link.hDel(this._pre + key, fields);
|
|
1199
514
|
}
|
|
1200
515
|
catch {
|
|
1201
516
|
return 0;
|
|
@@ -1205,12 +520,10 @@ end`;
|
|
|
1205
520
|
* --- 判断哈希字段是否存在 ---
|
|
1206
521
|
* @param key
|
|
1207
522
|
* @param field
|
|
1208
|
-
* @param etc
|
|
1209
523
|
*/
|
|
1210
|
-
async hExists(key, field
|
|
1211
|
-
this.refreshLast();
|
|
524
|
+
async hExists(key, field) {
|
|
1212
525
|
try {
|
|
1213
|
-
return await this._link.hExists(
|
|
526
|
+
return await this._link.hExists(this._pre + key, field);
|
|
1214
527
|
}
|
|
1215
528
|
catch {
|
|
1216
529
|
return false;
|
|
@@ -1221,16 +534,14 @@ end`;
|
|
|
1221
534
|
* @param key key
|
|
1222
535
|
* @param field 字段
|
|
1223
536
|
* @param increment 正数或负数,整数或浮点
|
|
1224
|
-
* @param etc
|
|
1225
537
|
*/
|
|
1226
|
-
async hIncr(key, field, increment
|
|
1227
|
-
this.refreshLast();
|
|
538
|
+
async hIncr(key, field, increment) {
|
|
1228
539
|
try {
|
|
1229
540
|
if (Number.isInteger(increment)) {
|
|
1230
|
-
return await this._link.hIncr(
|
|
541
|
+
return await this._link.hIncr(this._pre + key, field, increment);
|
|
1231
542
|
}
|
|
1232
543
|
else {
|
|
1233
|
-
return await this._link.hIncrByFloat(
|
|
544
|
+
return await this._link.hIncrByFloat(this._pre + key, field, increment);
|
|
1234
545
|
}
|
|
1235
546
|
}
|
|
1236
547
|
catch {
|
|
@@ -1240,87 +551,77 @@ end`;
|
|
|
1240
551
|
/**
|
|
1241
552
|
* --- 获取哈希所有字段 ---
|
|
1242
553
|
* @param key
|
|
1243
|
-
* @param etc
|
|
1244
554
|
*/
|
|
1245
|
-
async hKeys(key
|
|
1246
|
-
this.refreshLast();
|
|
555
|
+
async hKeys(key) {
|
|
1247
556
|
try {
|
|
1248
|
-
return await this._link.hKeys(
|
|
557
|
+
return await this._link.hKeys(this._pre + key);
|
|
1249
558
|
}
|
|
1250
559
|
catch {
|
|
1251
560
|
return [];
|
|
1252
561
|
}
|
|
1253
562
|
}
|
|
1254
|
-
async lPush(key, values
|
|
1255
|
-
this.refreshLast();
|
|
563
|
+
async lPush(key, values) {
|
|
1256
564
|
try {
|
|
1257
|
-
return await this._link.lPush(
|
|
565
|
+
return await this._link.lPush(this._pre + key, values);
|
|
1258
566
|
}
|
|
1259
567
|
catch {
|
|
1260
568
|
return 0;
|
|
1261
569
|
}
|
|
1262
570
|
}
|
|
1263
|
-
async rPush(key, values
|
|
1264
|
-
this.refreshLast();
|
|
571
|
+
async rPush(key, values) {
|
|
1265
572
|
try {
|
|
1266
|
-
return await this._link.rPush(
|
|
573
|
+
return await this._link.rPush(this._pre + key, values);
|
|
1267
574
|
}
|
|
1268
575
|
catch {
|
|
1269
576
|
return 0;
|
|
1270
577
|
}
|
|
1271
578
|
}
|
|
1272
|
-
async bLMove(sourceKey, destKey, soo, deo, timeout
|
|
1273
|
-
this.refreshLast();
|
|
579
|
+
async bLMove(sourceKey, destKey, soo, deo, timeout) {
|
|
1274
580
|
try {
|
|
1275
|
-
return await this._link.bLMove(
|
|
581
|
+
return await this._link.bLMove(this._pre + sourceKey, this._pre + destKey, soo, deo, timeout);
|
|
1276
582
|
}
|
|
1277
583
|
catch {
|
|
1278
584
|
return null;
|
|
1279
585
|
}
|
|
1280
586
|
}
|
|
1281
|
-
async lPop(key
|
|
1282
|
-
this.refreshLast();
|
|
587
|
+
async lPop(key) {
|
|
1283
588
|
try {
|
|
1284
|
-
return await this._link.lPop(
|
|
589
|
+
return await this._link.lPop(this._pre + key);
|
|
1285
590
|
}
|
|
1286
591
|
catch {
|
|
1287
592
|
return null;
|
|
1288
593
|
}
|
|
1289
594
|
}
|
|
1290
|
-
async rPop(key
|
|
1291
|
-
this.refreshLast();
|
|
595
|
+
async rPop(key) {
|
|
1292
596
|
try {
|
|
1293
|
-
return await this._link.rPop(
|
|
597
|
+
return await this._link.rPop(this._pre + key);
|
|
1294
598
|
}
|
|
1295
599
|
catch {
|
|
1296
600
|
return null;
|
|
1297
601
|
}
|
|
1298
602
|
}
|
|
1299
|
-
async bRPop(key, timeout
|
|
1300
|
-
this.refreshLast();
|
|
603
|
+
async bRPop(key, timeout) {
|
|
1301
604
|
try {
|
|
1302
605
|
if (typeof key === 'string') {
|
|
1303
606
|
key = [key];
|
|
1304
607
|
}
|
|
1305
|
-
return await this._link.bRPop(key.map(item =>
|
|
608
|
+
return await this._link.bRPop(key.map(item => this._pre + item), timeout);
|
|
1306
609
|
}
|
|
1307
610
|
catch {
|
|
1308
611
|
return {};
|
|
1309
612
|
}
|
|
1310
613
|
}
|
|
1311
|
-
async lRange(key, start, stop
|
|
1312
|
-
this.refreshLast();
|
|
614
|
+
async lRange(key, start, stop) {
|
|
1313
615
|
try {
|
|
1314
|
-
return await this._link.lRange(
|
|
616
|
+
return await this._link.lRange(this._pre + key, start, stop);
|
|
1315
617
|
}
|
|
1316
618
|
catch {
|
|
1317
619
|
return [];
|
|
1318
620
|
}
|
|
1319
621
|
}
|
|
1320
|
-
async lLen(key
|
|
1321
|
-
this.refreshLast();
|
|
622
|
+
async lLen(key) {
|
|
1322
623
|
try {
|
|
1323
|
-
return await this._link.lLen(
|
|
624
|
+
return await this._link.lLen(this._pre + key);
|
|
1324
625
|
}
|
|
1325
626
|
catch {
|
|
1326
627
|
return 0;
|
|
@@ -1328,30 +629,12 @@ end`;
|
|
|
1328
629
|
}
|
|
1329
630
|
}
|
|
1330
631
|
/**
|
|
1331
|
-
* --- 获取 Kv
|
|
632
|
+
* --- 获取 Kv 对象 ---
|
|
1332
633
|
* @param etc 配置信息可留空
|
|
1333
634
|
*/
|
|
1334
|
-
export function get(ctr, etc) {
|
|
635
|
+
export async function get(ctr, etc) {
|
|
1335
636
|
etc ??= ctr.getPrototype('_config').kv;
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
* --- 获取当前连接池中所有连接的信息 ---
|
|
1340
|
-
*/
|
|
1341
|
-
export function getConnectionList() {
|
|
1342
|
-
const list = [];
|
|
1343
|
-
for (let i = 0; i < connections.length; ++i) {
|
|
1344
|
-
const connection = connections[i];
|
|
1345
|
-
const etc = connection.getEtc();
|
|
1346
|
-
list.push({
|
|
1347
|
-
'id': i,
|
|
1348
|
-
'last': connection.getLast(),
|
|
1349
|
-
'host': etc.host,
|
|
1350
|
-
'port': etc.port,
|
|
1351
|
-
'index': etc.index,
|
|
1352
|
-
'lost': connection.isLost(),
|
|
1353
|
-
'using': connection.isUsing()
|
|
1354
|
-
});
|
|
1355
|
-
}
|
|
1356
|
-
return list;
|
|
637
|
+
const kv = new Kv(ctr, etc);
|
|
638
|
+
const r = await kv.init(ctr, etc);
|
|
639
|
+
return r ? kv : false;
|
|
1357
640
|
}
|