mm_cachebase 1.4.6 → 1.5.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/LICENSE +21 -0
- package/README.md +225 -709
- package/compatibility_table.md +63 -0
- package/index.js +503 -1418
- package/package.json +41 -35
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require('mm_logs');
|
|
2
2
|
const EventEmitter = require('events');
|
|
3
3
|
|
|
4
|
-
//
|
|
4
|
+
// 符合Redis API的CacheBase类
|
|
5
5
|
class CacheBase extends EventEmitter {
|
|
6
6
|
constructor() {
|
|
7
7
|
super();
|
|
@@ -24,7 +24,7 @@ class CacheBase extends EventEmitter {
|
|
|
24
24
|
|
|
25
25
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
26
26
|
if (beforeEventData.cancel) {
|
|
27
|
-
resolve(
|
|
27
|
+
resolve(0);
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -40,9 +40,9 @@ class CacheBase extends EventEmitter {
|
|
|
40
40
|
this.emit('set_after', {
|
|
41
41
|
key,
|
|
42
42
|
value,
|
|
43
|
-
result:
|
|
43
|
+
result: 'OK'
|
|
44
44
|
});
|
|
45
|
-
resolve(
|
|
45
|
+
resolve('OK');
|
|
46
46
|
} catch (error) {
|
|
47
47
|
// 触发错误事件
|
|
48
48
|
this.emit('set_error', {
|
|
@@ -146,7 +146,156 @@ class CacheBase extends EventEmitter {
|
|
|
146
146
|
});
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
//
|
|
149
|
+
// Redis兼容的getset方法
|
|
150
|
+
async getset(key, value) {
|
|
151
|
+
return new Promise((resolve) => {
|
|
152
|
+
try {
|
|
153
|
+
// 触发前置事件
|
|
154
|
+
const beforeEventData = {
|
|
155
|
+
key,
|
|
156
|
+
value,
|
|
157
|
+
cancel: false
|
|
158
|
+
};
|
|
159
|
+
this.emit('getset_before', beforeEventData);
|
|
160
|
+
|
|
161
|
+
// 如果事件处理器设置了cancel为true,则取消操作
|
|
162
|
+
if (beforeEventData.cancel) {
|
|
163
|
+
resolve(null);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// 获取旧值
|
|
168
|
+
const obj = this.data[key];
|
|
169
|
+
const oldValue = obj ? obj.value : null;
|
|
170
|
+
|
|
171
|
+
// 设置新值
|
|
172
|
+
this.data[key] = { value, expire: 0 };
|
|
173
|
+
|
|
174
|
+
// 如果键不存在于列表中,添加到列表
|
|
175
|
+
if (!this.list.includes(key)) {
|
|
176
|
+
this.list.push(key);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// 触发后置事件
|
|
180
|
+
this.emit('getset_after', {
|
|
181
|
+
key,
|
|
182
|
+
value,
|
|
183
|
+
result: oldValue
|
|
184
|
+
});
|
|
185
|
+
resolve(oldValue);
|
|
186
|
+
} catch (error) {
|
|
187
|
+
// 触发错误事件
|
|
188
|
+
this.emit('getset_error', {
|
|
189
|
+
key,
|
|
190
|
+
value,
|
|
191
|
+
error
|
|
192
|
+
});
|
|
193
|
+
$.log.error('[cachebase] getset操作失败:', error);
|
|
194
|
+
resolve(null);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Redis兼容的append方法
|
|
200
|
+
async append(key, value) {
|
|
201
|
+
return new Promise((resolve) => {
|
|
202
|
+
try {
|
|
203
|
+
// 触发前置事件
|
|
204
|
+
const beforeEventData = {
|
|
205
|
+
key,
|
|
206
|
+
value,
|
|
207
|
+
cancel: false
|
|
208
|
+
};
|
|
209
|
+
this.emit('append_before', beforeEventData);
|
|
210
|
+
|
|
211
|
+
// 如果事件处理器设置了cancel为true,则取消操作
|
|
212
|
+
if (beforeEventData.cancel) {
|
|
213
|
+
resolve(0);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// 获取当前值或默认为空字符串
|
|
218
|
+
const obj = this.data[key];
|
|
219
|
+
let currentValue = '';
|
|
220
|
+
if (obj) {
|
|
221
|
+
currentValue = String(obj.value);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// 执行字符串拼接
|
|
225
|
+
const newValue = currentValue + String(value);
|
|
226
|
+
const result = newValue.length;
|
|
227
|
+
|
|
228
|
+
// 保存结果
|
|
229
|
+
this.data[key] = { value: newValue, expire: 0 };
|
|
230
|
+
|
|
231
|
+
// 如果键不存在于列表中,添加到列表
|
|
232
|
+
if (!this.list.includes(key)) {
|
|
233
|
+
this.list.push(key);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// 触发后置事件
|
|
237
|
+
this.emit('append_after', {
|
|
238
|
+
key,
|
|
239
|
+
value,
|
|
240
|
+
result
|
|
241
|
+
});
|
|
242
|
+
resolve(result);
|
|
243
|
+
} catch (error) {
|
|
244
|
+
// 触发错误事件
|
|
245
|
+
this.emit('append_error', {
|
|
246
|
+
key,
|
|
247
|
+
value,
|
|
248
|
+
error
|
|
249
|
+
});
|
|
250
|
+
$.log.error('[cachebase] append操作失败:', error);
|
|
251
|
+
resolve(0);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Redis兼容的strlen方法
|
|
257
|
+
async strlen(key) {
|
|
258
|
+
return new Promise((resolve) => {
|
|
259
|
+
try {
|
|
260
|
+
// 触发前置事件
|
|
261
|
+
const beforeEventData = {
|
|
262
|
+
key,
|
|
263
|
+
cancel: false
|
|
264
|
+
};
|
|
265
|
+
this.emit('strlen_before', beforeEventData);
|
|
266
|
+
|
|
267
|
+
// 如果事件处理器设置了cancel为true,则取消操作
|
|
268
|
+
if (beforeEventData.cancel) {
|
|
269
|
+
resolve(0);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// 执行实际操作
|
|
274
|
+
const obj = this.data[key];
|
|
275
|
+
let result = 0;
|
|
276
|
+
if (obj) {
|
|
277
|
+
result = String(obj.value).length;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// 触发后置事件
|
|
281
|
+
this.emit('strlen_after', {
|
|
282
|
+
key,
|
|
283
|
+
result
|
|
284
|
+
});
|
|
285
|
+
resolve(result);
|
|
286
|
+
} catch (error) {
|
|
287
|
+
// 触发错误事件
|
|
288
|
+
this.emit('strlen_error', {
|
|
289
|
+
key,
|
|
290
|
+
error
|
|
291
|
+
});
|
|
292
|
+
$.log.error('[cachebase] strlen操作失败:', error);
|
|
293
|
+
resolve(0);
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// 哈希表设置方法 - 模拟实现
|
|
150
299
|
async hset(key, field, value) {
|
|
151
300
|
return new Promise((resolve) => {
|
|
152
301
|
try {
|
|
@@ -201,129 +350,104 @@ class CacheBase extends EventEmitter {
|
|
|
201
350
|
});
|
|
202
351
|
}
|
|
203
352
|
|
|
204
|
-
//
|
|
205
|
-
async
|
|
353
|
+
// 哈希表获取字段值方法 - 模拟实现
|
|
354
|
+
async hget(key, field) {
|
|
206
355
|
return new Promise((resolve) => {
|
|
207
356
|
try {
|
|
208
|
-
//
|
|
357
|
+
// 触发前置事件
|
|
209
358
|
const beforeEventData = {
|
|
210
359
|
key,
|
|
211
|
-
value: {
|
|
360
|
+
value: { field },
|
|
212
361
|
cancel: false
|
|
213
362
|
};
|
|
214
|
-
this.emit('
|
|
363
|
+
this.emit('hget_before', beforeEventData);
|
|
215
364
|
|
|
216
365
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
217
366
|
if (beforeEventData.cancel) {
|
|
218
|
-
resolve(
|
|
367
|
+
resolve(null);
|
|
219
368
|
return;
|
|
220
369
|
}
|
|
221
370
|
|
|
222
|
-
//
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
this.list.push(key);
|
|
228
|
-
}
|
|
229
|
-
} else if (!Array.isArray(this.data[key].value)) {
|
|
230
|
-
this.data[key].value = [];
|
|
371
|
+
// 执行实际操作
|
|
372
|
+
const obj = this.data[key];
|
|
373
|
+
let result = null;
|
|
374
|
+
if (obj && typeof obj.value === 'object' && field in obj.value) {
|
|
375
|
+
result = obj.value[field];
|
|
231
376
|
}
|
|
232
377
|
|
|
233
|
-
// 将值添加到列表头部
|
|
234
|
-
this.data[key].value.unshift(...values);
|
|
235
|
-
|
|
236
378
|
// 触发后置事件
|
|
237
|
-
this.emit('
|
|
379
|
+
this.emit('hget_after', {
|
|
238
380
|
key,
|
|
239
|
-
value: {
|
|
240
|
-
result
|
|
381
|
+
value: { field },
|
|
382
|
+
result
|
|
241
383
|
});
|
|
242
|
-
resolve(
|
|
384
|
+
resolve(result);
|
|
243
385
|
} catch (error) {
|
|
244
386
|
// 触发错误事件
|
|
245
|
-
this.emit('
|
|
387
|
+
this.emit('hget_error', {
|
|
246
388
|
key,
|
|
247
|
-
value: {
|
|
389
|
+
value: { field },
|
|
248
390
|
error
|
|
249
391
|
});
|
|
250
|
-
$.log.error('[cachebase]
|
|
251
|
-
resolve(
|
|
392
|
+
$.log.error('[cachebase] hget操作失败:', error);
|
|
393
|
+
resolve(null);
|
|
252
394
|
}
|
|
253
395
|
});
|
|
254
396
|
}
|
|
255
397
|
|
|
256
|
-
//
|
|
257
|
-
async
|
|
398
|
+
// 哈希表获取所有字段和值方法 - 模拟实现
|
|
399
|
+
async hgetall(key) {
|
|
258
400
|
return new Promise((resolve) => {
|
|
259
401
|
try {
|
|
260
|
-
//
|
|
402
|
+
// 触发前置事件
|
|
261
403
|
const beforeEventData = {
|
|
262
404
|
key,
|
|
263
|
-
value: { members },
|
|
264
405
|
cancel: false
|
|
265
406
|
};
|
|
266
|
-
this.emit('
|
|
407
|
+
this.emit('hgetall_before', beforeEventData);
|
|
267
408
|
|
|
268
409
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
269
410
|
if (beforeEventData.cancel) {
|
|
270
|
-
resolve(
|
|
411
|
+
resolve({});
|
|
271
412
|
return;
|
|
272
413
|
}
|
|
273
414
|
|
|
274
|
-
//
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
this.list.push(key);
|
|
280
|
-
}
|
|
281
|
-
} else if (!(this.data[key].value instanceof Set)) {
|
|
282
|
-
this.data[key].value = new Set();
|
|
415
|
+
// 执行实际操作
|
|
416
|
+
const obj = this.data[key];
|
|
417
|
+
let result = {};
|
|
418
|
+
if (obj && typeof obj.value === 'object') {
|
|
419
|
+
result = {...obj.value};
|
|
283
420
|
}
|
|
284
421
|
|
|
285
|
-
// 记录添加前的大小
|
|
286
|
-
const beforeSize = this.data[key].value.size;
|
|
287
|
-
|
|
288
|
-
// 添加成员
|
|
289
|
-
members.forEach(member => {
|
|
290
|
-
this.data[key].value.add(member);
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
// 计算新增的成员数
|
|
294
|
-
const addedCount = this.data[key].value.size - beforeSize;
|
|
295
|
-
|
|
296
422
|
// 触发后置事件
|
|
297
|
-
this.emit('
|
|
423
|
+
this.emit('hgetall_after', {
|
|
298
424
|
key,
|
|
299
|
-
|
|
300
|
-
result: addedCount
|
|
425
|
+
result
|
|
301
426
|
});
|
|
302
|
-
resolve(
|
|
427
|
+
resolve(result);
|
|
303
428
|
} catch (error) {
|
|
304
429
|
// 触发错误事件
|
|
305
|
-
this.emit('
|
|
430
|
+
this.emit('hgetall_error', {
|
|
306
431
|
key,
|
|
307
|
-
value: { members },
|
|
308
432
|
error
|
|
309
433
|
});
|
|
310
|
-
$.log.error('[cachebase]
|
|
311
|
-
resolve(
|
|
434
|
+
$.log.error('[cachebase] hgetall操作失败:', error);
|
|
435
|
+
resolve({});
|
|
312
436
|
}
|
|
313
437
|
});
|
|
314
438
|
}
|
|
315
439
|
|
|
316
|
-
//
|
|
317
|
-
async
|
|
440
|
+
// 哈希表删除字段方法 - 模拟实现
|
|
441
|
+
async hdel(key, field) {
|
|
318
442
|
return new Promise((resolve) => {
|
|
319
443
|
try {
|
|
320
|
-
//
|
|
444
|
+
// 触发前置事件
|
|
321
445
|
const beforeEventData = {
|
|
322
446
|
key,
|
|
323
|
-
value: {
|
|
447
|
+
value: { field },
|
|
324
448
|
cancel: false
|
|
325
449
|
};
|
|
326
|
-
this.emit('
|
|
450
|
+
this.emit('hdel_before', beforeEventData);
|
|
327
451
|
|
|
328
452
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
329
453
|
if (beforeEventData.cancel) {
|
|
@@ -331,59 +455,43 @@ class CacheBase extends EventEmitter {
|
|
|
331
455
|
return;
|
|
332
456
|
}
|
|
333
457
|
|
|
334
|
-
//
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
// 处理参数并添加成员
|
|
348
|
-
for (let i = 0; i < args.length; i += 2) {
|
|
349
|
-
const score = parseFloat(args[i]);
|
|
350
|
-
const member = args[i + 1];
|
|
351
|
-
|
|
352
|
-
// 如果成员不存在,则计数增加
|
|
353
|
-
if (!this.data[key].value.members.hasOwnProperty(member)) {
|
|
354
|
-
addedCount++;
|
|
458
|
+
// 执行实际操作
|
|
459
|
+
let result = 0;
|
|
460
|
+
const obj = this.data[key];
|
|
461
|
+
if (obj && typeof obj.value === 'object' && field in obj.value) {
|
|
462
|
+
delete obj.value[field];
|
|
463
|
+
// 如果哈希表变空了,删除整个键
|
|
464
|
+
if (Object.keys(obj.value).length === 0) {
|
|
465
|
+
delete this.data[key];
|
|
466
|
+
const index = this.list.indexOf(key);
|
|
467
|
+
if (index > -1) {
|
|
468
|
+
this.list.splice(index, 1);
|
|
469
|
+
}
|
|
355
470
|
}
|
|
356
|
-
|
|
357
|
-
// 设置成员分数
|
|
358
|
-
this.data[key].value.members[member] = score;
|
|
471
|
+
result = 1;
|
|
359
472
|
}
|
|
360
473
|
|
|
361
|
-
// 更新排序
|
|
362
|
-
this.data[key].value.sorted = Object.entries(this.data[key].value.members)
|
|
363
|
-
.sort((a, b) => a[1] - b[1])
|
|
364
|
-
.map(entry => entry[0]);
|
|
365
|
-
|
|
366
474
|
// 触发后置事件
|
|
367
|
-
this.emit('
|
|
475
|
+
this.emit('hdel_after', {
|
|
368
476
|
key,
|
|
369
|
-
value: {
|
|
370
|
-
result
|
|
477
|
+
value: { field },
|
|
478
|
+
result
|
|
371
479
|
});
|
|
372
|
-
resolve(
|
|
480
|
+
resolve(result);
|
|
373
481
|
} catch (error) {
|
|
374
482
|
// 触发错误事件
|
|
375
|
-
this.emit('
|
|
483
|
+
this.emit('hdel_error', {
|
|
376
484
|
key,
|
|
377
|
-
value: {
|
|
485
|
+
value: { field },
|
|
378
486
|
error
|
|
379
487
|
});
|
|
380
|
-
$.log.error('[cachebase]
|
|
488
|
+
$.log.error('[cachebase] hdel操作失败:', error);
|
|
381
489
|
resolve(0);
|
|
382
490
|
}
|
|
383
491
|
});
|
|
384
492
|
}
|
|
385
493
|
|
|
386
|
-
// 修复的mset方法
|
|
494
|
+
// 修复的mset方法 - Redis兼容格式
|
|
387
495
|
async mset(...args) {
|
|
388
496
|
return new Promise((resolve) => {
|
|
389
497
|
try {
|
|
@@ -396,13 +504,13 @@ class CacheBase extends EventEmitter {
|
|
|
396
504
|
|
|
397
505
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
398
506
|
if (beforeEventData.cancel) {
|
|
399
|
-
resolve(
|
|
507
|
+
resolve(null);
|
|
400
508
|
return;
|
|
401
509
|
}
|
|
402
510
|
|
|
403
511
|
// 参数校验
|
|
404
512
|
if (args.length % 2 !== 0) {
|
|
405
|
-
$.log.error('[cachebase]
|
|
513
|
+
$.log.error('[cachebase] mset参数数量不正确');
|
|
406
514
|
resolve('ERR');
|
|
407
515
|
return;
|
|
408
516
|
}
|
|
@@ -436,71 +544,57 @@ class CacheBase extends EventEmitter {
|
|
|
436
544
|
});
|
|
437
545
|
}
|
|
438
546
|
|
|
439
|
-
//
|
|
440
|
-
async
|
|
547
|
+
// 修复的mget方法 - 返回数组格式,与Redis保持一致
|
|
548
|
+
async mget(...keys) {
|
|
441
549
|
return new Promise((resolve) => {
|
|
442
550
|
try {
|
|
443
|
-
//
|
|
551
|
+
// 触发前置事件
|
|
444
552
|
const beforeEventData = {
|
|
445
|
-
|
|
446
|
-
value: parseFloat(value),
|
|
553
|
+
value: { keys },
|
|
447
554
|
cancel: false
|
|
448
555
|
};
|
|
449
|
-
this.emit('
|
|
556
|
+
this.emit('mget_before', beforeEventData);
|
|
450
557
|
|
|
451
558
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
452
559
|
if (beforeEventData.cancel) {
|
|
453
|
-
resolve(
|
|
560
|
+
resolve([]);
|
|
454
561
|
return;
|
|
455
562
|
}
|
|
456
563
|
|
|
457
|
-
//
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
// 执行加法
|
|
464
|
-
const result = currentValue + parseFloat(value);
|
|
465
|
-
|
|
466
|
-
// 保存结果
|
|
467
|
-
this.data[key] = { value: result, expire: 0 };
|
|
468
|
-
// 添加到列表
|
|
469
|
-
if (!this.list.includes(key)) {
|
|
470
|
-
this.list.push(key);
|
|
471
|
-
}
|
|
564
|
+
// 执行实际操作 - 返回数组格式,与Redis保持一致
|
|
565
|
+
const result = keys.map(key => {
|
|
566
|
+
const obj = this.data[key];
|
|
567
|
+
return obj ? obj.value : null;
|
|
568
|
+
});
|
|
472
569
|
|
|
473
570
|
// 触发后置事件
|
|
474
|
-
this.emit('
|
|
475
|
-
|
|
476
|
-
value: parseFloat(value),
|
|
571
|
+
this.emit('mget_after', {
|
|
572
|
+
value: { keys },
|
|
477
573
|
result
|
|
478
574
|
});
|
|
479
575
|
resolve(result);
|
|
480
576
|
} catch (error) {
|
|
481
577
|
// 触发错误事件
|
|
482
|
-
this.emit('
|
|
483
|
-
|
|
484
|
-
value: parseFloat(value),
|
|
578
|
+
this.emit('mget_error', {
|
|
579
|
+
value: { keys },
|
|
485
580
|
error
|
|
486
581
|
});
|
|
487
|
-
$.log.error('[cachebase]
|
|
488
|
-
resolve(
|
|
582
|
+
$.log.error('[cachebase] mget操作失败:', error);
|
|
583
|
+
resolve([]);
|
|
489
584
|
}
|
|
490
585
|
});
|
|
491
586
|
}
|
|
492
587
|
|
|
493
|
-
//
|
|
494
|
-
async
|
|
588
|
+
// Redis兼容的exists方法,支持多个键
|
|
589
|
+
async exists(...keys) {
|
|
495
590
|
return new Promise((resolve) => {
|
|
496
591
|
try {
|
|
497
|
-
//
|
|
592
|
+
// 触发前置事件
|
|
498
593
|
const beforeEventData = {
|
|
499
|
-
|
|
500
|
-
value: String(value),
|
|
594
|
+
value: { keys },
|
|
501
595
|
cancel: false
|
|
502
596
|
};
|
|
503
|
-
this.emit('
|
|
597
|
+
this.emit('exists_before', beforeEventData);
|
|
504
598
|
|
|
505
599
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
506
600
|
if (beforeEventData.cancel) {
|
|
@@ -508,1118 +602,139 @@ class CacheBase extends EventEmitter {
|
|
|
508
602
|
return;
|
|
509
603
|
}
|
|
510
604
|
|
|
511
|
-
//
|
|
512
|
-
|
|
513
|
-
if (this.data[key] && typeof this.data[key].value === 'string') {
|
|
514
|
-
currentValue = this.data[key].value;
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
// 执行字符串拼接
|
|
518
|
-
const result = currentValue + value;
|
|
519
|
-
|
|
520
|
-
// 保存结果
|
|
521
|
-
this.data[key] = { value: result, expire: 0 };
|
|
522
|
-
// 添加到列表
|
|
523
|
-
if (!this.list.includes(key)) {
|
|
524
|
-
this.list.push(key);
|
|
525
|
-
}
|
|
605
|
+
// 执行实际操作
|
|
606
|
+
const result = keys.filter(key => key in this.data).length;
|
|
526
607
|
|
|
527
608
|
// 触发后置事件
|
|
528
|
-
this.emit('
|
|
529
|
-
|
|
530
|
-
value: String(value),
|
|
609
|
+
this.emit('exists_after', {
|
|
610
|
+
value: { keys },
|
|
531
611
|
result
|
|
532
612
|
});
|
|
533
613
|
resolve(result);
|
|
534
614
|
} catch (error) {
|
|
535
615
|
// 触发错误事件
|
|
536
|
-
this.emit('
|
|
537
|
-
|
|
538
|
-
value: String(value),
|
|
616
|
+
this.emit('exists_error', {
|
|
617
|
+
value: { keys },
|
|
539
618
|
error
|
|
540
619
|
});
|
|
541
|
-
$.log.error('[cachebase]
|
|
620
|
+
$.log.error('[cachebase] exists操作失败:', error);
|
|
542
621
|
resolve(0);
|
|
543
622
|
}
|
|
544
623
|
});
|
|
545
624
|
}
|
|
546
625
|
|
|
547
|
-
//
|
|
548
|
-
async
|
|
626
|
+
// 查询/设置过期时间方法,包含事件触发
|
|
627
|
+
async ttl(key) {
|
|
549
628
|
return new Promise((resolve) => {
|
|
550
629
|
try {
|
|
551
|
-
//
|
|
630
|
+
// 触发前置事件
|
|
552
631
|
const beforeEventData = {
|
|
553
|
-
key,
|
|
554
|
-
value: parseInt(value, 10),
|
|
632
|
+
key,
|
|
555
633
|
cancel: false
|
|
556
634
|
};
|
|
557
|
-
this.emit('
|
|
635
|
+
this.emit('ttl_before', beforeEventData);
|
|
558
636
|
|
|
559
637
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
560
638
|
if (beforeEventData.cancel) {
|
|
561
|
-
resolve(
|
|
562
|
-
return;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
// 获取当前值或默认为0
|
|
566
|
-
let currentValue = 0;
|
|
567
|
-
if (this.data[key] && typeof this.data[key].value === 'number') {
|
|
568
|
-
currentValue = this.data[key].value;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// 执行整数加法
|
|
572
|
-
const result = currentValue + parseInt(value, 10);
|
|
573
|
-
|
|
574
|
-
// 保存结果
|
|
575
|
-
this.data[key] = { value: result, expire: 0 };
|
|
576
|
-
// 添加到列表
|
|
577
|
-
if (!this.list.includes(key)) {
|
|
578
|
-
this.list.push(key);
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
// 触发后置事件
|
|
582
|
-
this.emit('add_after', {
|
|
583
|
-
key,
|
|
584
|
-
value: parseInt(value, 10),
|
|
585
|
-
result
|
|
586
|
-
});
|
|
587
|
-
resolve(result);
|
|
588
|
-
} catch (error) {
|
|
589
|
-
// 触发错误事件
|
|
590
|
-
this.emit('add_error', {
|
|
591
|
-
key,
|
|
592
|
-
value: parseInt(value, 10),
|
|
593
|
-
error
|
|
594
|
-
});
|
|
595
|
-
$.log.error('[cachebase] add操作失败:', error);
|
|
596
|
-
resolve(0);
|
|
597
|
-
}
|
|
598
|
-
});
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// 列表设置方法 - 修改为兼容test.js
|
|
602
|
-
async list_set(key, value) {
|
|
603
|
-
return new Promise((resolve) => {
|
|
604
|
-
try {
|
|
605
|
-
// 触发前置事件
|
|
606
|
-
const beforeEventData = {
|
|
607
|
-
key,
|
|
608
|
-
value,
|
|
609
|
-
cancel: false
|
|
610
|
-
};
|
|
611
|
-
this.emit('list_set_before', beforeEventData);
|
|
612
|
-
|
|
613
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
614
|
-
if (beforeEventData.cancel) {
|
|
615
|
-
resolve(0);
|
|
616
|
-
return;
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
// 确保值是数组
|
|
620
|
-
if (!Array.isArray(value)) {
|
|
621
|
-
this.emit('list_set_error', {
|
|
622
|
-
key,
|
|
623
|
-
value,
|
|
624
|
-
error: new Error('值必须是数组')
|
|
625
|
-
});
|
|
626
|
-
resolve(0);
|
|
627
|
-
return;
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
// 设置数组
|
|
631
|
-
this.data[key] = { value, expire: 0 };
|
|
632
|
-
// 添加到列表
|
|
633
|
-
if (!this.list.includes(key)) {
|
|
634
|
-
this.list.push(key);
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
// 触发后置事件
|
|
638
|
-
this.emit('list_set_after', {
|
|
639
|
-
key,
|
|
640
|
-
value,
|
|
641
|
-
result: 1
|
|
642
|
-
});
|
|
643
|
-
resolve(1);
|
|
644
|
-
} catch (error) {
|
|
645
|
-
// 触发错误事件
|
|
646
|
-
this.emit('list_set_error', {
|
|
647
|
-
key,
|
|
648
|
-
value,
|
|
649
|
-
error
|
|
650
|
-
});
|
|
651
|
-
$.log.error('[cachebase] list_set操作失败:', error);
|
|
652
|
-
resolve(0);
|
|
653
|
-
}
|
|
654
|
-
});
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
// 列表添加元素方法
|
|
658
|
-
async list_add(key, value) {
|
|
659
|
-
return new Promise((resolve) => {
|
|
660
|
-
try {
|
|
661
|
-
// 触发前置事件
|
|
662
|
-
const beforeEventData = {
|
|
663
|
-
key,
|
|
664
|
-
value,
|
|
665
|
-
cancel: false
|
|
666
|
-
};
|
|
667
|
-
this.emit('list_add_before', beforeEventData);
|
|
668
|
-
|
|
669
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
670
|
-
if (beforeEventData.cancel) {
|
|
671
|
-
resolve(0);
|
|
672
|
-
return;
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
// 确保列表存在
|
|
676
|
-
if (!this.data[key]) {
|
|
677
|
-
this.data[key] = { value: [], expire: 0 };
|
|
678
|
-
// 添加到列表
|
|
679
|
-
if (!this.list.includes(key)) {
|
|
680
|
-
this.list.push(key);
|
|
681
|
-
}
|
|
682
|
-
} else if (!Array.isArray(this.data[key].value)) {
|
|
683
|
-
this.data[key].value = [];
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
// 添加元素到列表末尾
|
|
687
|
-
this.data[key].value.push(value);
|
|
688
|
-
|
|
689
|
-
// 触发后置事件
|
|
690
|
-
this.emit('list_add_after', {
|
|
691
|
-
key,
|
|
692
|
-
value,
|
|
693
|
-
result: this.data[key].value.length
|
|
694
|
-
});
|
|
695
|
-
resolve(this.data[key].value.length);
|
|
696
|
-
} catch (error) {
|
|
697
|
-
// 触发错误事件
|
|
698
|
-
this.emit('list_add_error', {
|
|
699
|
-
key,
|
|
700
|
-
value,
|
|
701
|
-
error
|
|
702
|
-
});
|
|
703
|
-
$.log.error('[cachebase] list_add操作失败:', error);
|
|
704
|
-
resolve(0);
|
|
705
|
-
}
|
|
706
|
-
});
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
// 列表清空方法
|
|
710
|
-
async list_clear(key, newValue) {
|
|
711
|
-
return new Promise((resolve) => {
|
|
712
|
-
try {
|
|
713
|
-
// 触发前置事件
|
|
714
|
-
const beforeEventData = {
|
|
715
|
-
key,
|
|
716
|
-
cancel: false
|
|
717
|
-
};
|
|
718
|
-
this.emit('list_clear_before', beforeEventData);
|
|
719
|
-
|
|
720
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
721
|
-
if (beforeEventData.cancel) {
|
|
722
|
-
resolve(0);
|
|
723
|
-
return;
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
// 检查键是否存在且值为数组
|
|
727
|
-
if (this.data[key] && Array.isArray(this.data[key].value)) {
|
|
728
|
-
// 如果提供了新值且是数组,则替换
|
|
729
|
-
if (newValue && Array.isArray(newValue)) {
|
|
730
|
-
this.data[key].value = newValue;
|
|
731
|
-
} else {
|
|
732
|
-
// 否则清空数组
|
|
733
|
-
this.data[key].value = [];
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
// 触发后置事件
|
|
737
|
-
this.emit('list_clear_after', {
|
|
738
|
-
key,
|
|
739
|
-
result: 1
|
|
740
|
-
});
|
|
741
|
-
resolve(1);
|
|
742
|
-
} else {
|
|
743
|
-
// 键不存在或值不是数组,如果提供了新值,则设置
|
|
744
|
-
if (newValue && Array.isArray(newValue)) {
|
|
745
|
-
this.data[key] = { value: newValue, expire: 0 };
|
|
746
|
-
// 添加到列表
|
|
747
|
-
if (!this.list.includes(key)) {
|
|
748
|
-
this.list.push(key);
|
|
749
|
-
}
|
|
750
|
-
this.emit('list_clear_after', {
|
|
751
|
-
key,
|
|
752
|
-
result: 1
|
|
753
|
-
});
|
|
754
|
-
resolve(1);
|
|
755
|
-
} else {
|
|
756
|
-
this.emit('list_clear_after', {
|
|
757
|
-
key,
|
|
758
|
-
result: 0
|
|
759
|
-
});
|
|
760
|
-
resolve(0);
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
} catch (error) {
|
|
764
|
-
// 触发错误事件
|
|
765
|
-
this.emit('list_clear_error', {
|
|
766
|
-
key,
|
|
767
|
-
error
|
|
768
|
-
});
|
|
769
|
-
$.log.error('[cachebase] list_clear操作失败:', error);
|
|
770
|
-
resolve(0);
|
|
771
|
-
}
|
|
772
|
-
});
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
// 仅当键不存在时设置值方法
|
|
776
|
-
async setnx(key, value) {
|
|
777
|
-
return new Promise((resolve) => {
|
|
778
|
-
try {
|
|
779
|
-
// 触发前置事件
|
|
780
|
-
const beforeEventData = {
|
|
781
|
-
key,
|
|
782
|
-
value,
|
|
783
|
-
cancel: false
|
|
784
|
-
};
|
|
785
|
-
this.emit('setnx_before', beforeEventData);
|
|
786
|
-
|
|
787
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
788
|
-
if (beforeEventData.cancel) {
|
|
789
|
-
resolve(0);
|
|
790
|
-
return;
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
// 检查键是否不存在
|
|
794
|
-
if (!this.data.hasOwnProperty(key)) {
|
|
795
|
-
// 设置值
|
|
796
|
-
this.data[key] = { value, expire: 0 };
|
|
797
|
-
// 添加到列表
|
|
798
|
-
if (!this.list.includes(key)) {
|
|
799
|
-
this.list.push(key);
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
// 触发后置事件
|
|
803
|
-
this.emit('setnx_after', {
|
|
804
|
-
key,
|
|
805
|
-
value,
|
|
806
|
-
result: 1
|
|
807
|
-
});
|
|
808
|
-
resolve(1);
|
|
809
|
-
} else {
|
|
810
|
-
// 键已存在
|
|
811
|
-
this.emit('setnx_after', {
|
|
812
|
-
key,
|
|
813
|
-
value,
|
|
814
|
-
result: 0
|
|
815
|
-
});
|
|
816
|
-
resolve(0);
|
|
817
|
-
}
|
|
818
|
-
} catch (error) {
|
|
819
|
-
// 触发错误事件
|
|
820
|
-
this.emit('setnx_error', {
|
|
821
|
-
key,
|
|
822
|
-
value,
|
|
823
|
-
error
|
|
824
|
-
});
|
|
825
|
-
$.log.error('[cachebase] setnx操作失败:', error);
|
|
826
|
-
resolve(0);
|
|
827
|
-
}
|
|
828
|
-
});
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
// 设置带过期时间的键值对方法
|
|
832
|
-
async setex(key, seconds, value) {
|
|
833
|
-
return new Promise((resolve) => {
|
|
834
|
-
try {
|
|
835
|
-
// 触发前置事件,使用ttl替代seconds
|
|
836
|
-
const beforeEventData = {
|
|
837
|
-
key,
|
|
838
|
-
value,
|
|
839
|
-
ttl: parseInt(seconds, 10),
|
|
840
|
-
cancel: false
|
|
841
|
-
};
|
|
842
|
-
this.emit('setex_before', beforeEventData);
|
|
843
|
-
|
|
844
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
845
|
-
if (beforeEventData.cancel) {
|
|
846
|
-
resolve(0);
|
|
847
|
-
return;
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
// 计算过期时间
|
|
851
|
-
const expireTime = Date.now() + (parseInt(seconds, 10) * 1000);
|
|
852
|
-
|
|
853
|
-
// 设置值和过期时间
|
|
854
|
-
this.data[key] = { value, expire: expireTime };
|
|
855
|
-
// 添加到列表
|
|
856
|
-
if (!this.list.includes(key)) {
|
|
857
|
-
this.list.push(key);
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
// 触发后置事件,使用ttl替代seconds
|
|
861
|
-
this.emit('setex_after', {
|
|
862
|
-
key,
|
|
863
|
-
value,
|
|
864
|
-
ttl: parseInt(seconds, 10),
|
|
865
|
-
result: "OK"
|
|
866
|
-
});
|
|
867
|
-
resolve("OK");
|
|
868
|
-
} catch (error) {
|
|
869
|
-
// 触发错误事件,使用ttl替代seconds
|
|
870
|
-
this.emit('setex_error', {
|
|
871
|
-
key,
|
|
872
|
-
value,
|
|
873
|
-
ttl: parseInt(seconds, 10),
|
|
874
|
-
error
|
|
875
|
-
});
|
|
876
|
-
$.log.error('[cachebase] setex操作失败:', error);
|
|
877
|
-
resolve(0);
|
|
878
|
-
}
|
|
879
|
-
});
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
// 修复的setrange方法
|
|
883
|
-
async setrange(key, index, value) {
|
|
884
|
-
return new Promise((resolve) => {
|
|
885
|
-
try {
|
|
886
|
-
// 触发前置事件,将index和value作为value的一部分
|
|
887
|
-
const beforeEventData = {
|
|
888
|
-
key,
|
|
889
|
-
value: { index, value },
|
|
890
|
-
cancel: false
|
|
891
|
-
};
|
|
892
|
-
this.emit('setrange_before', beforeEventData);
|
|
893
|
-
|
|
894
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
895
|
-
if (beforeEventData.cancel) {
|
|
896
|
-
resolve('ERR');
|
|
897
|
-
return;
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
const obj = this.data[key];
|
|
901
|
-
if (obj) {
|
|
902
|
-
// 确保值为字符串类型
|
|
903
|
-
let val = String(obj.value || '');
|
|
904
|
-
index = Math.max(0, parseInt(index) || 0);
|
|
905
|
-
|
|
906
|
-
// 处理index超出字符串长度的情况
|
|
907
|
-
if (index > val.length) {
|
|
908
|
-
// 填充空白字符
|
|
909
|
-
val = val.padEnd(index, '');
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
const start = val.substring(0, index);
|
|
913
|
-
const end = val.substring(index, val.length);
|
|
914
|
-
obj.value = start + value + end;
|
|
915
|
-
|
|
916
|
-
// 触发后置事件
|
|
917
|
-
this.emit('setrange_after', {
|
|
918
|
-
key,
|
|
919
|
-
value: { index, value },
|
|
920
|
-
result: obj.value.length
|
|
921
|
-
});
|
|
922
|
-
resolve(obj.value.length);
|
|
923
|
-
} else {
|
|
924
|
-
resolve('ERR');
|
|
925
|
-
}
|
|
926
|
-
} catch (error) {
|
|
927
|
-
// 触发错误事件
|
|
928
|
-
this.emit('setrange_error', {
|
|
929
|
-
key,
|
|
930
|
-
value: { index, value },
|
|
931
|
-
error
|
|
932
|
-
});
|
|
933
|
-
$.log.error('[cachebase] setrange操作失败:', error);
|
|
934
|
-
resolve('ERR');
|
|
935
|
-
}
|
|
936
|
-
});
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
// 新增:列表获取方法,包含事件触发
|
|
940
|
-
async list_get(key, start = 0, end = -1) {
|
|
941
|
-
return new Promise((resolve) => {
|
|
942
|
-
try {
|
|
943
|
-
// 触发前置事件
|
|
944
|
-
const beforeEventData = {
|
|
945
|
-
key,
|
|
946
|
-
value: { start, end },
|
|
947
|
-
cancel: false
|
|
948
|
-
};
|
|
949
|
-
this.emit('list_get_before', beforeEventData);
|
|
950
|
-
|
|
951
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
952
|
-
if (beforeEventData.cancel) {
|
|
953
|
-
resolve([]);
|
|
954
|
-
return;
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
// 执行实际操作
|
|
958
|
-
const obj = this.data[key];
|
|
959
|
-
let result = [];
|
|
960
|
-
if (obj && Array.isArray(obj.value)) {
|
|
961
|
-
if (end === -1) {
|
|
962
|
-
result = obj.value.slice(start);
|
|
963
|
-
} else {
|
|
964
|
-
result = obj.value.slice(start, end + 1);
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
// 触发后置事件
|
|
969
|
-
this.emit('list_get_after', {
|
|
970
|
-
key,
|
|
971
|
-
value: { start, end },
|
|
972
|
-
result
|
|
973
|
-
});
|
|
974
|
-
resolve(result);
|
|
975
|
-
} catch (error) {
|
|
976
|
-
// 触发错误事件
|
|
977
|
-
this.emit('list_get_error', {
|
|
978
|
-
key,
|
|
979
|
-
value: { start, end },
|
|
980
|
-
error
|
|
981
|
-
});
|
|
982
|
-
$.log.error('[cachebase] list_get操作失败:', error);
|
|
983
|
-
resolve([]);
|
|
984
|
-
}
|
|
985
|
-
});
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
// 新增:字符串范围获取方法,包含事件触发
|
|
989
|
-
async getrange(key, start, end) {
|
|
990
|
-
return new Promise((resolve) => {
|
|
991
|
-
try {
|
|
992
|
-
// 触发前置事件
|
|
993
|
-
const beforeEventData = {
|
|
994
|
-
key,
|
|
995
|
-
value: { start, end },
|
|
996
|
-
cancel: false
|
|
997
|
-
};
|
|
998
|
-
this.emit('getrange_before', beforeEventData);
|
|
999
|
-
|
|
1000
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1001
|
-
if (beforeEventData.cancel) {
|
|
1002
|
-
resolve('');
|
|
1003
|
-
return;
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
// 执行实际操作
|
|
1007
|
-
const obj = this.data[key];
|
|
1008
|
-
let result = '';
|
|
1009
|
-
if (obj && typeof obj.value === 'string') {
|
|
1010
|
-
// 处理负数索引
|
|
1011
|
-
if (start < 0) start = Math.max(0, obj.value.length + start);
|
|
1012
|
-
if (end < 0) end = Math.max(0, obj.value.length + end);
|
|
1013
|
-
|
|
1014
|
-
// 确保索引在有效范围内
|
|
1015
|
-
start = Math.max(0, start);
|
|
1016
|
-
end = Math.min(obj.value.length - 1, end);
|
|
1017
|
-
|
|
1018
|
-
if (start <= end) {
|
|
1019
|
-
result = obj.value.substring(start, end + 1);
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
// 触发后置事件
|
|
1024
|
-
this.emit('getrange_after', {
|
|
1025
|
-
key,
|
|
1026
|
-
value: { start, end },
|
|
1027
|
-
result
|
|
1028
|
-
});
|
|
1029
|
-
resolve(result);
|
|
1030
|
-
} catch (error) {
|
|
1031
|
-
// 触发错误事件
|
|
1032
|
-
this.emit('getrange_error', {
|
|
1033
|
-
key,
|
|
1034
|
-
value: { start, end },
|
|
1035
|
-
error
|
|
1036
|
-
});
|
|
1037
|
-
$.log.error('[cachebase] getrange操作失败:', error);
|
|
1038
|
-
resolve('');
|
|
1039
|
-
}
|
|
1040
|
-
});
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
// 新增:列表包含检查方法,包含事件触发
|
|
1044
|
-
async list_has(key, value) {
|
|
1045
|
-
return new Promise((resolve) => {
|
|
1046
|
-
try {
|
|
1047
|
-
// 触发前置事件
|
|
1048
|
-
const beforeEventData = {
|
|
1049
|
-
key,
|
|
1050
|
-
value,
|
|
1051
|
-
cancel: false
|
|
1052
|
-
};
|
|
1053
|
-
this.emit('list_has_before', beforeEventData);
|
|
1054
|
-
|
|
1055
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1056
|
-
if (beforeEventData.cancel) {
|
|
1057
|
-
resolve(0);
|
|
1058
|
-
return;
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
// 执行实际操作
|
|
1062
|
-
const obj = this.data[key];
|
|
1063
|
-
let result = 0;
|
|
1064
|
-
if (obj && Array.isArray(obj.value)) {
|
|
1065
|
-
result = obj.value.includes(value) ? 1 : 0;
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
// 触发后置事件
|
|
1069
|
-
this.emit('list_has_after', {
|
|
1070
|
-
key,
|
|
1071
|
-
value,
|
|
1072
|
-
result
|
|
1073
|
-
});
|
|
1074
|
-
resolve(result);
|
|
1075
|
-
} catch (error) {
|
|
1076
|
-
// 触发错误事件
|
|
1077
|
-
this.emit('list_has_error', {
|
|
1078
|
-
key,
|
|
1079
|
-
value,
|
|
1080
|
-
error
|
|
1081
|
-
});
|
|
1082
|
-
$.log.error('[cachebase] list_has操作失败:', error);
|
|
1083
|
-
resolve(0);
|
|
1084
|
-
}
|
|
1085
|
-
});
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
// 检查键是否存在方法,包含事件触发
|
|
1089
|
-
async exists(key) {
|
|
1090
|
-
return new Promise((resolve) => {
|
|
1091
|
-
try {
|
|
1092
|
-
// 触发前置事件
|
|
1093
|
-
const beforeEventData = {
|
|
1094
|
-
key,
|
|
1095
|
-
cancel: false
|
|
1096
|
-
};
|
|
1097
|
-
this.emit('exists_before', beforeEventData);
|
|
1098
|
-
|
|
1099
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1100
|
-
if (beforeEventData.cancel) {
|
|
1101
|
-
resolve(0);
|
|
1102
|
-
return;
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
// 执行实际操作
|
|
1106
|
-
const result = key in this.data ? 1 : 0;
|
|
1107
|
-
|
|
1108
|
-
// 触发后置事件
|
|
1109
|
-
this.emit('exists_after', {
|
|
1110
|
-
key,
|
|
1111
|
-
result
|
|
1112
|
-
});
|
|
1113
|
-
resolve(result);
|
|
1114
|
-
} catch (error) {
|
|
1115
|
-
// 触发错误事件
|
|
1116
|
-
this.emit('exists_error', {
|
|
1117
|
-
key,
|
|
1118
|
-
error
|
|
1119
|
-
});
|
|
1120
|
-
$.log.error('[cachebase] exists操作失败:', error);
|
|
1121
|
-
resolve(0);
|
|
1122
|
-
}
|
|
1123
|
-
});
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
|
-
// 检查键是否存在的别名方法,包含事件触发
|
|
1127
|
-
async has(key) {
|
|
1128
|
-
return new Promise((resolve) => {
|
|
1129
|
-
try {
|
|
1130
|
-
// 触发前置事件
|
|
1131
|
-
const beforeEventData = {
|
|
1132
|
-
key,
|
|
1133
|
-
cancel: false
|
|
1134
|
-
};
|
|
1135
|
-
this.emit('has_before', beforeEventData);
|
|
1136
|
-
|
|
1137
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1138
|
-
if (beforeEventData.cancel) {
|
|
1139
|
-
resolve(0);
|
|
1140
|
-
return;
|
|
1141
|
-
}
|
|
1142
|
-
|
|
1143
|
-
// 执行实际操作
|
|
1144
|
-
const result = key in this.data ? 1 : 0;
|
|
1145
|
-
|
|
1146
|
-
// 触发后置事件
|
|
1147
|
-
this.emit('has_after', {
|
|
1148
|
-
key,
|
|
1149
|
-
result
|
|
1150
|
-
});
|
|
1151
|
-
resolve(result);
|
|
1152
|
-
} catch (error) {
|
|
1153
|
-
// 触发错误事件
|
|
1154
|
-
this.emit('has_error', {
|
|
1155
|
-
key,
|
|
1156
|
-
error
|
|
1157
|
-
});
|
|
1158
|
-
$.log.error('[cachebase] has操作失败:', error);
|
|
1159
|
-
resolve(0);
|
|
1160
|
-
}
|
|
1161
|
-
});
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
|
-
// 查询/设置过期时间方法,包含事件触发
|
|
1165
|
-
async ttl(key, maxAge) {
|
|
1166
|
-
return new Promise((resolve) => {
|
|
1167
|
-
try {
|
|
1168
|
-
// 触发前置事件
|
|
1169
|
-
const beforeEventData = {
|
|
1170
|
-
key,
|
|
1171
|
-
value: maxAge !== undefined ? { ttl: maxAge } : undefined,
|
|
1172
|
-
cancel: false
|
|
1173
|
-
};
|
|
1174
|
-
this.emit('ttl_before', beforeEventData);
|
|
1175
|
-
|
|
1176
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1177
|
-
if (beforeEventData.cancel) {
|
|
1178
|
-
resolve(maxAge !== undefined ? 0 : -2);
|
|
1179
|
-
return;
|
|
1180
|
-
}
|
|
1181
|
-
|
|
1182
|
-
// 执行实际操作
|
|
1183
|
-
const obj = this.data[key];
|
|
1184
|
-
let result;
|
|
1185
|
-
|
|
1186
|
-
if (!obj) {
|
|
1187
|
-
result = -2; // 键不存在
|
|
1188
|
-
} else if (maxAge !== undefined) {
|
|
1189
|
-
// 设置过期时间
|
|
1190
|
-
if (maxAge === -1) {
|
|
1191
|
-
obj.expire = 0; // 永不过期
|
|
1192
|
-
} else {
|
|
1193
|
-
obj.expire = Date.now() + (parseInt(maxAge, 10) * 1000);
|
|
1194
|
-
}
|
|
1195
|
-
result = 1;
|
|
1196
|
-
} else {
|
|
1197
|
-
// 查询过期时间
|
|
1198
|
-
if (obj.expire === 0) {
|
|
1199
|
-
result = -1; // 永不过期
|
|
1200
|
-
} else {
|
|
1201
|
-
const remaining = Math.floor((obj.expire - Date.now()) / 1000);
|
|
1202
|
-
result = remaining > 0 ? remaining : -2; // -2表示已过期
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
|
-
// 触发后置事件
|
|
1207
|
-
this.emit('ttl_after', {
|
|
1208
|
-
key,
|
|
1209
|
-
value: maxAge !== undefined ? { ttl: maxAge } : undefined,
|
|
1210
|
-
result
|
|
1211
|
-
});
|
|
1212
|
-
resolve(result);
|
|
1213
|
-
} catch (error) {
|
|
1214
|
-
// 触发错误事件
|
|
1215
|
-
this.emit('ttl_error', {
|
|
1216
|
-
key,
|
|
1217
|
-
value: maxAge !== undefined ? { ttl: maxAge } : undefined,
|
|
1218
|
-
error
|
|
1219
|
-
});
|
|
1220
|
-
$.log.error('[cachebase] ttl操作失败:', error);
|
|
1221
|
-
resolve(-2);
|
|
1222
|
-
}
|
|
1223
|
-
});
|
|
1224
|
-
}
|
|
1225
|
-
|
|
1226
|
-
// 获取所有匹配键方法,包含事件触发
|
|
1227
|
-
async keys(pattern) {
|
|
1228
|
-
return new Promise((resolve) => {
|
|
1229
|
-
try {
|
|
1230
|
-
// 触发前置事件
|
|
1231
|
-
const beforeEventData = {
|
|
1232
|
-
value: { pattern },
|
|
1233
|
-
cancel: false
|
|
1234
|
-
};
|
|
1235
|
-
this.emit('keys_before', beforeEventData);
|
|
1236
|
-
|
|
1237
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1238
|
-
if (beforeEventData.cancel) {
|
|
1239
|
-
resolve([]);
|
|
1240
|
-
return;
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
// 执行实际操作
|
|
1244
|
-
let result;
|
|
1245
|
-
if (!pattern || pattern === '*') {
|
|
1246
|
-
result = [...this.list];
|
|
1247
|
-
} else {
|
|
1248
|
-
// 转换模式为正则表达式
|
|
1249
|
-
const regexPattern = pattern
|
|
1250
|
-
.replace(/\./g, '\\.')
|
|
1251
|
-
.replace(/\*/g, '.*')
|
|
1252
|
-
.replace(/\?/g, '.');
|
|
1253
|
-
const regex = new RegExp(`^${regexPattern}$`);
|
|
1254
|
-
|
|
1255
|
-
// 过滤匹配的键
|
|
1256
|
-
result = this.list.filter(key => regex.test(key));
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
// 触发后置事件
|
|
1260
|
-
this.emit('keys_after', {
|
|
1261
|
-
value: { pattern },
|
|
1262
|
-
result
|
|
1263
|
-
});
|
|
1264
|
-
resolve(result);
|
|
1265
|
-
} catch (error) {
|
|
1266
|
-
// 触发错误事件
|
|
1267
|
-
this.emit('keys_error', {
|
|
1268
|
-
value: { pattern },
|
|
1269
|
-
error
|
|
1270
|
-
});
|
|
1271
|
-
$.log.error('[cachebase] keys操作失败:', error);
|
|
1272
|
-
resolve([]);
|
|
1273
|
-
}
|
|
1274
|
-
});
|
|
1275
|
-
}
|
|
1276
|
-
|
|
1277
|
-
// 清空缓存方法,包含事件触发
|
|
1278
|
-
async clear(pattern) {
|
|
1279
|
-
return new Promise((resolve) => {
|
|
1280
|
-
try {
|
|
1281
|
-
// 触发前置事件
|
|
1282
|
-
const beforeEventData = {
|
|
1283
|
-
value: { pattern },
|
|
1284
|
-
cancel: false
|
|
1285
|
-
};
|
|
1286
|
-
this.emit('clear_before', beforeEventData);
|
|
1287
|
-
|
|
1288
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1289
|
-
if (beforeEventData.cancel) {
|
|
1290
|
-
resolve(0);
|
|
1291
|
-
return;
|
|
1292
|
-
}
|
|
1293
|
-
|
|
1294
|
-
// 执行实际操作
|
|
1295
|
-
let keysToDelete;
|
|
1296
|
-
|
|
1297
|
-
if (!pattern || pattern === '*') {
|
|
1298
|
-
keysToDelete = [...this.list];
|
|
1299
|
-
} else {
|
|
1300
|
-
// 转换模式为正则表达式
|
|
1301
|
-
const regexPattern = pattern
|
|
1302
|
-
.replace(/\./g, '\\.')
|
|
1303
|
-
.replace(/\*/g, '.*')
|
|
1304
|
-
.replace(/\?/g, '.');
|
|
1305
|
-
const regex = new RegExp(`^${regexPattern}$`);
|
|
1306
|
-
|
|
1307
|
-
keysToDelete = this.list.filter(key => regex.test(key));
|
|
1308
|
-
}
|
|
1309
|
-
|
|
1310
|
-
// 删除匹配的键
|
|
1311
|
-
keysToDelete.forEach(key => {
|
|
1312
|
-
delete this.data[key];
|
|
1313
|
-
const index = this.list.indexOf(key);
|
|
1314
|
-
if (index > -1) {
|
|
1315
|
-
this.list.splice(index, 1);
|
|
1316
|
-
}
|
|
1317
|
-
});
|
|
1318
|
-
|
|
1319
|
-
// 触发后置事件
|
|
1320
|
-
this.emit('clear_after', {
|
|
1321
|
-
value: { pattern },
|
|
1322
|
-
result: keysToDelete.length
|
|
1323
|
-
});
|
|
1324
|
-
resolve(keysToDelete.length);
|
|
1325
|
-
} catch (error) {
|
|
1326
|
-
// 触发错误事件
|
|
1327
|
-
this.emit('clear_error', {
|
|
1328
|
-
value: { pattern },
|
|
1329
|
-
error
|
|
1330
|
-
});
|
|
1331
|
-
$.log.error('[cachebase] clear操作失败:', error);
|
|
1332
|
-
resolve(0);
|
|
1333
|
-
}
|
|
1334
|
-
});
|
|
1335
|
-
}
|
|
1336
|
-
|
|
1337
|
-
// 哈希表获取字段值方法,包含事件触发
|
|
1338
|
-
async hget(key, field) {
|
|
1339
|
-
return new Promise((resolve) => {
|
|
1340
|
-
try {
|
|
1341
|
-
// 触发前置事件
|
|
1342
|
-
const beforeEventData = {
|
|
1343
|
-
key,
|
|
1344
|
-
value: { field },
|
|
1345
|
-
cancel: false
|
|
1346
|
-
};
|
|
1347
|
-
this.emit('hget_before', beforeEventData);
|
|
1348
|
-
|
|
1349
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1350
|
-
if (beforeEventData.cancel) {
|
|
1351
|
-
resolve(null);
|
|
1352
|
-
return;
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
|
-
// 执行实际操作
|
|
1356
|
-
const obj = this.data[key];
|
|
1357
|
-
let result = null;
|
|
1358
|
-
if (obj && typeof obj.value === 'object' && field in obj.value) {
|
|
1359
|
-
result = obj.value[field];
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
// 触发后置事件
|
|
1363
|
-
this.emit('hget_after', {
|
|
1364
|
-
key,
|
|
1365
|
-
value: { field },
|
|
1366
|
-
result
|
|
1367
|
-
});
|
|
1368
|
-
resolve(result);
|
|
1369
|
-
} catch (error) {
|
|
1370
|
-
// 触发错误事件
|
|
1371
|
-
this.emit('hget_error', {
|
|
1372
|
-
key,
|
|
1373
|
-
value: { field },
|
|
1374
|
-
error
|
|
1375
|
-
});
|
|
1376
|
-
$.log.error('[cachebase] hget操作失败:', error);
|
|
1377
|
-
resolve(null);
|
|
1378
|
-
}
|
|
1379
|
-
});
|
|
1380
|
-
}
|
|
1381
|
-
|
|
1382
|
-
// 哈希表获取所有字段和值方法,包含事件触发
|
|
1383
|
-
async hgetall(key) {
|
|
1384
|
-
return new Promise((resolve) => {
|
|
1385
|
-
try {
|
|
1386
|
-
// 触发前置事件
|
|
1387
|
-
const beforeEventData = {
|
|
1388
|
-
key,
|
|
1389
|
-
cancel: false
|
|
1390
|
-
};
|
|
1391
|
-
this.emit('hgetall_before', beforeEventData);
|
|
1392
|
-
|
|
1393
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1394
|
-
if (beforeEventData.cancel) {
|
|
1395
|
-
resolve({});
|
|
1396
|
-
return;
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
// 执行实际操作
|
|
1400
|
-
const obj = this.data[key];
|
|
1401
|
-
let result = {};
|
|
1402
|
-
if (obj && typeof obj.value === 'object') {
|
|
1403
|
-
result = {...obj.value};
|
|
1404
|
-
}
|
|
1405
|
-
|
|
1406
|
-
// 触发后置事件
|
|
1407
|
-
this.emit('hgetall_after', {
|
|
1408
|
-
key,
|
|
1409
|
-
result
|
|
1410
|
-
});
|
|
1411
|
-
resolve(result);
|
|
1412
|
-
} catch (error) {
|
|
1413
|
-
// 触发错误事件
|
|
1414
|
-
this.emit('hgetall_error', {
|
|
1415
|
-
key,
|
|
1416
|
-
error
|
|
1417
|
-
});
|
|
1418
|
-
$.log.error('[cachebase] hgetall操作失败:', error);
|
|
1419
|
-
resolve({});
|
|
1420
|
-
}
|
|
1421
|
-
});
|
|
1422
|
-
}
|
|
1423
|
-
|
|
1424
|
-
// 哈希表删除字段方法,包含事件触发
|
|
1425
|
-
async hdel(key, field) {
|
|
1426
|
-
return new Promise((resolve) => {
|
|
1427
|
-
try {
|
|
1428
|
-
// 触发前置事件
|
|
1429
|
-
const beforeEventData = {
|
|
1430
|
-
key,
|
|
1431
|
-
value: { field },
|
|
1432
|
-
cancel: false
|
|
1433
|
-
};
|
|
1434
|
-
this.emit('hdel_before', beforeEventData);
|
|
1435
|
-
|
|
1436
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1437
|
-
if (beforeEventData.cancel) {
|
|
1438
|
-
resolve(0);
|
|
1439
|
-
return;
|
|
1440
|
-
}
|
|
1441
|
-
|
|
1442
|
-
// 执行实际操作
|
|
1443
|
-
let result = 0;
|
|
1444
|
-
const obj = this.data[key];
|
|
1445
|
-
if (obj && typeof obj.value === 'object' && field in obj.value) {
|
|
1446
|
-
delete obj.value[field];
|
|
1447
|
-
// 如果哈希表变空了,删除整个键
|
|
1448
|
-
if (Object.keys(obj.value).length === 0) {
|
|
1449
|
-
delete this.data[key];
|
|
1450
|
-
const index = this.list.indexOf(key);
|
|
1451
|
-
if (index > -1) {
|
|
1452
|
-
this.list.splice(index, 1);
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
result = 1;
|
|
1456
|
-
}
|
|
1457
|
-
|
|
1458
|
-
// 触发后置事件
|
|
1459
|
-
this.emit('hdel_after', {
|
|
1460
|
-
key,
|
|
1461
|
-
value: { field },
|
|
1462
|
-
result
|
|
1463
|
-
});
|
|
1464
|
-
resolve(result);
|
|
1465
|
-
} catch (error) {
|
|
1466
|
-
// 触发错误事件
|
|
1467
|
-
this.emit('hdel_error', {
|
|
1468
|
-
key,
|
|
1469
|
-
value: { field },
|
|
1470
|
-
error
|
|
1471
|
-
});
|
|
1472
|
-
$.log.error('[cachebase] hdel操作失败:', error);
|
|
1473
|
-
resolve(0);
|
|
1474
|
-
}
|
|
1475
|
-
});
|
|
1476
|
-
}
|
|
1477
|
-
|
|
1478
|
-
// 哈希表获取所有字段名方法,包含事件触发
|
|
1479
|
-
async hkeys(key) {
|
|
1480
|
-
return new Promise((resolve) => {
|
|
1481
|
-
try {
|
|
1482
|
-
// 触发前置事件
|
|
1483
|
-
const beforeEventData = {
|
|
1484
|
-
key,
|
|
1485
|
-
cancel: false
|
|
1486
|
-
};
|
|
1487
|
-
this.emit('hkeys_before', beforeEventData);
|
|
1488
|
-
|
|
1489
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1490
|
-
if (beforeEventData.cancel) {
|
|
1491
|
-
resolve([]);
|
|
1492
|
-
return;
|
|
1493
|
-
}
|
|
1494
|
-
|
|
1495
|
-
// 执行实际操作
|
|
1496
|
-
let result = [];
|
|
1497
|
-
const obj = this.data[key];
|
|
1498
|
-
if (obj && typeof obj.value === 'object') {
|
|
1499
|
-
result = Object.keys(obj.value);
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
|
-
// 触发后置事件
|
|
1503
|
-
this.emit('hkeys_after', {
|
|
1504
|
-
key,
|
|
1505
|
-
result
|
|
1506
|
-
});
|
|
1507
|
-
resolve(result);
|
|
1508
|
-
} catch (error) {
|
|
1509
|
-
// 触发错误事件
|
|
1510
|
-
this.emit('hkeys_error', {
|
|
1511
|
-
key,
|
|
1512
|
-
error
|
|
1513
|
-
});
|
|
1514
|
-
$.log.error('[cachebase] hkeys操作失败:', error);
|
|
1515
|
-
resolve([]);
|
|
1516
|
-
}
|
|
1517
|
-
});
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
|
-
// 哈希表获取所有字段值方法,包含事件触发
|
|
1521
|
-
async hvals(key) {
|
|
1522
|
-
return new Promise((resolve) => {
|
|
1523
|
-
try {
|
|
1524
|
-
// 触发前置事件
|
|
1525
|
-
const beforeEventData = {
|
|
1526
|
-
key,
|
|
1527
|
-
cancel: false
|
|
1528
|
-
};
|
|
1529
|
-
this.emit('hvals_before', beforeEventData);
|
|
1530
|
-
|
|
1531
|
-
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1532
|
-
if (beforeEventData.cancel) {
|
|
1533
|
-
resolve([]);
|
|
639
|
+
resolve(-2);
|
|
1534
640
|
return;
|
|
1535
641
|
}
|
|
1536
642
|
|
|
1537
643
|
// 执行实际操作
|
|
1538
|
-
let result = [];
|
|
1539
644
|
const obj = this.data[key];
|
|
1540
|
-
|
|
1541
|
-
|
|
645
|
+
let result;
|
|
646
|
+
|
|
647
|
+
if (!obj) {
|
|
648
|
+
result = -2; // 键不存在
|
|
649
|
+
} else {
|
|
650
|
+
// 查询过期时间
|
|
651
|
+
if (obj.expire === 0) {
|
|
652
|
+
result = -1; // 永不过期
|
|
653
|
+
} else {
|
|
654
|
+
const remaining = Math.floor((obj.expire - Date.now()) / 1000);
|
|
655
|
+
result = remaining > 0 ? remaining : -2; // -2表示已过期
|
|
656
|
+
}
|
|
1542
657
|
}
|
|
1543
658
|
|
|
1544
659
|
// 触发后置事件
|
|
1545
|
-
this.emit('
|
|
1546
|
-
key,
|
|
660
|
+
this.emit('ttl_after', {
|
|
661
|
+
key,
|
|
1547
662
|
result
|
|
1548
663
|
});
|
|
1549
664
|
resolve(result);
|
|
1550
665
|
} catch (error) {
|
|
1551
666
|
// 触发错误事件
|
|
1552
|
-
this.emit('
|
|
1553
|
-
key,
|
|
667
|
+
this.emit('ttl_error', {
|
|
668
|
+
key,
|
|
1554
669
|
error
|
|
1555
670
|
});
|
|
1556
|
-
$.log.error('[cachebase]
|
|
1557
|
-
resolve(
|
|
671
|
+
$.log.error('[cachebase] ttl操作失败:', error);
|
|
672
|
+
resolve(-2);
|
|
1558
673
|
}
|
|
1559
674
|
});
|
|
1560
675
|
}
|
|
1561
676
|
|
|
1562
|
-
//
|
|
1563
|
-
async
|
|
677
|
+
// Redis兼容的expire方法
|
|
678
|
+
async expire(key, seconds) {
|
|
1564
679
|
return new Promise((resolve) => {
|
|
1565
680
|
try {
|
|
1566
681
|
// 触发前置事件
|
|
1567
682
|
const beforeEventData = {
|
|
1568
|
-
key,
|
|
683
|
+
key,
|
|
684
|
+
value: { seconds },
|
|
1569
685
|
cancel: false
|
|
1570
686
|
};
|
|
1571
|
-
this.emit('
|
|
687
|
+
this.emit('expire_before', beforeEventData);
|
|
1572
688
|
|
|
1573
689
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1574
690
|
if (beforeEventData.cancel) {
|
|
1575
|
-
resolve(
|
|
691
|
+
resolve(0);
|
|
1576
692
|
return;
|
|
1577
693
|
}
|
|
1578
694
|
|
|
1579
695
|
// 执行实际操作
|
|
1580
696
|
const obj = this.data[key];
|
|
1581
|
-
let result =
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
if (index > -1) {
|
|
1589
|
-
this.list.splice(index, 1);
|
|
1590
|
-
}
|
|
697
|
+
let result = 0;
|
|
698
|
+
|
|
699
|
+
if (obj) {
|
|
700
|
+
if (seconds === 0) {
|
|
701
|
+
obj.expire = 0; // 永不过期
|
|
702
|
+
} else {
|
|
703
|
+
obj.expire = Date.now() + (parseInt(seconds, 10) * 1000);
|
|
1591
704
|
}
|
|
705
|
+
result = 1;
|
|
1592
706
|
}
|
|
1593
707
|
|
|
1594
708
|
// 触发后置事件
|
|
1595
|
-
this.emit('
|
|
1596
|
-
key,
|
|
709
|
+
this.emit('expire_after', {
|
|
710
|
+
key,
|
|
711
|
+
value: { seconds },
|
|
1597
712
|
result
|
|
1598
713
|
});
|
|
1599
714
|
resolve(result);
|
|
1600
715
|
} catch (error) {
|
|
1601
716
|
// 触发错误事件
|
|
1602
|
-
this.emit('
|
|
1603
|
-
key,
|
|
717
|
+
this.emit('expire_error', {
|
|
718
|
+
key,
|
|
719
|
+
value: { seconds },
|
|
1604
720
|
error
|
|
1605
721
|
});
|
|
1606
|
-
$.log.error('[cachebase]
|
|
1607
|
-
resolve(
|
|
722
|
+
$.log.error('[cachebase] expire操作失败:', error);
|
|
723
|
+
resolve(0);
|
|
1608
724
|
}
|
|
1609
725
|
});
|
|
1610
726
|
}
|
|
1611
727
|
|
|
1612
|
-
//
|
|
1613
|
-
async
|
|
728
|
+
// Redis兼容的persist方法
|
|
729
|
+
async persist(key) {
|
|
1614
730
|
return new Promise((resolve) => {
|
|
1615
731
|
try {
|
|
1616
732
|
// 触发前置事件
|
|
1617
733
|
const beforeEventData = {
|
|
1618
|
-
key,
|
|
1619
|
-
value: { values },
|
|
734
|
+
key,
|
|
1620
735
|
cancel: false
|
|
1621
736
|
};
|
|
1622
|
-
this.emit('
|
|
737
|
+
this.emit('persist_before', beforeEventData);
|
|
1623
738
|
|
|
1624
739
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1625
740
|
if (beforeEventData.cancel) {
|
|
@@ -1627,100 +742,93 @@ class CacheBase extends EventEmitter {
|
|
|
1627
742
|
return;
|
|
1628
743
|
}
|
|
1629
744
|
|
|
1630
|
-
//
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
} else if (!Array.isArray(this.data[key].value)) {
|
|
1638
|
-
this.data[key].value = [];
|
|
745
|
+
// 执行实际操作
|
|
746
|
+
const obj = this.data[key];
|
|
747
|
+
let result = 0;
|
|
748
|
+
|
|
749
|
+
if (obj && obj.expire !== 0) {
|
|
750
|
+
obj.expire = 0; // 移除过期时间
|
|
751
|
+
result = 1;
|
|
1639
752
|
}
|
|
1640
753
|
|
|
1641
|
-
// 将值添加到列表尾部
|
|
1642
|
-
this.data[key].value.push(...values);
|
|
1643
|
-
|
|
1644
754
|
// 触发后置事件
|
|
1645
|
-
this.emit('
|
|
1646
|
-
key,
|
|
1647
|
-
|
|
1648
|
-
result: this.data[key].value.length
|
|
755
|
+
this.emit('persist_after', {
|
|
756
|
+
key,
|
|
757
|
+
result
|
|
1649
758
|
});
|
|
1650
|
-
resolve(
|
|
759
|
+
resolve(result);
|
|
1651
760
|
} catch (error) {
|
|
1652
761
|
// 触发错误事件
|
|
1653
|
-
this.emit('
|
|
1654
|
-
key,
|
|
1655
|
-
value: { values },
|
|
762
|
+
this.emit('persist_error', {
|
|
763
|
+
key,
|
|
1656
764
|
error
|
|
1657
765
|
});
|
|
1658
|
-
$.log.error('[cachebase]
|
|
766
|
+
$.log.error('[cachebase] persist操作失败:', error);
|
|
1659
767
|
resolve(0);
|
|
1660
768
|
}
|
|
1661
769
|
});
|
|
1662
770
|
}
|
|
1663
771
|
|
|
1664
|
-
//
|
|
1665
|
-
async
|
|
772
|
+
// 获取所有匹配键方法,包含事件触发
|
|
773
|
+
async keys(pattern) {
|
|
1666
774
|
return new Promise((resolve) => {
|
|
1667
775
|
try {
|
|
1668
776
|
// 触发前置事件
|
|
1669
777
|
const beforeEventData = {
|
|
1670
|
-
|
|
778
|
+
value: { pattern },
|
|
1671
779
|
cancel: false
|
|
1672
780
|
};
|
|
1673
|
-
this.emit('
|
|
781
|
+
this.emit('keys_before', beforeEventData);
|
|
1674
782
|
|
|
1675
783
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1676
784
|
if (beforeEventData.cancel) {
|
|
1677
|
-
resolve(
|
|
785
|
+
resolve([]);
|
|
1678
786
|
return;
|
|
1679
787
|
}
|
|
1680
788
|
|
|
1681
789
|
// 执行实际操作
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
//
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
790
|
+
let result;
|
|
791
|
+
if (!pattern || pattern === '*') {
|
|
792
|
+
result = [...this.list];
|
|
793
|
+
} else {
|
|
794
|
+
// 转换模式为正则表达式
|
|
795
|
+
const regexPattern = pattern
|
|
796
|
+
.replace(/\./g, '\\.')
|
|
797
|
+
.replace(/\*/g, '.*')
|
|
798
|
+
.replace(/\?/g, '.');
|
|
799
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
800
|
+
|
|
801
|
+
// 过滤匹配的键
|
|
802
|
+
result = this.list.filter(key => regex.test(key));
|
|
1694
803
|
}
|
|
1695
804
|
|
|
1696
805
|
// 触发后置事件
|
|
1697
|
-
this.emit('
|
|
1698
|
-
|
|
806
|
+
this.emit('keys_after', {
|
|
807
|
+
value: { pattern },
|
|
1699
808
|
result
|
|
1700
809
|
});
|
|
1701
810
|
resolve(result);
|
|
1702
811
|
} catch (error) {
|
|
1703
812
|
// 触发错误事件
|
|
1704
|
-
this.emit('
|
|
1705
|
-
|
|
813
|
+
this.emit('keys_error', {
|
|
814
|
+
value: { pattern },
|
|
1706
815
|
error
|
|
1707
816
|
});
|
|
1708
|
-
$.log.error('[cachebase]
|
|
1709
|
-
resolve(
|
|
817
|
+
$.log.error('[cachebase] keys操作失败:', error);
|
|
818
|
+
resolve([]);
|
|
1710
819
|
}
|
|
1711
820
|
});
|
|
1712
821
|
}
|
|
1713
822
|
|
|
1714
|
-
//
|
|
1715
|
-
async
|
|
823
|
+
// Redis兼容的dbsize方法
|
|
824
|
+
async dbsize() {
|
|
1716
825
|
return new Promise((resolve) => {
|
|
1717
826
|
try {
|
|
1718
827
|
// 触发前置事件
|
|
1719
828
|
const beforeEventData = {
|
|
1720
|
-
key,
|
|
1721
829
|
cancel: false
|
|
1722
830
|
};
|
|
1723
|
-
this.emit('
|
|
831
|
+
this.emit('dbsize_before', beforeEventData);
|
|
1724
832
|
|
|
1725
833
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1726
834
|
if (beforeEventData.cancel) {
|
|
@@ -1729,141 +837,123 @@ class CacheBase extends EventEmitter {
|
|
|
1729
837
|
}
|
|
1730
838
|
|
|
1731
839
|
// 执行实际操作
|
|
1732
|
-
|
|
1733
|
-
const obj = this.data[key];
|
|
1734
|
-
if (obj && Array.isArray(obj.value)) {
|
|
1735
|
-
result = obj.value.length;
|
|
1736
|
-
}
|
|
840
|
+
const result = this.list.length;
|
|
1737
841
|
|
|
1738
842
|
// 触发后置事件
|
|
1739
|
-
this.emit('
|
|
1740
|
-
key,
|
|
843
|
+
this.emit('dbsize_after', {
|
|
1741
844
|
result
|
|
1742
845
|
});
|
|
1743
846
|
resolve(result);
|
|
1744
847
|
} catch (error) {
|
|
1745
848
|
// 触发错误事件
|
|
1746
|
-
this.emit('
|
|
1747
|
-
key,
|
|
849
|
+
this.emit('dbsize_error', {
|
|
1748
850
|
error
|
|
1749
851
|
});
|
|
1750
|
-
$.log.error('[cachebase]
|
|
852
|
+
$.log.error('[cachebase] dbsize操作失败:', error);
|
|
1751
853
|
resolve(0);
|
|
1752
854
|
}
|
|
1753
855
|
});
|
|
1754
856
|
}
|
|
1755
857
|
|
|
1756
|
-
//
|
|
1757
|
-
async
|
|
858
|
+
// Redis兼容的flushdb方法
|
|
859
|
+
async flushdb() {
|
|
1758
860
|
return new Promise((resolve) => {
|
|
1759
861
|
try {
|
|
1760
862
|
// 触发前置事件
|
|
1761
863
|
const beforeEventData = {
|
|
1762
|
-
key,
|
|
1763
|
-
value,
|
|
1764
864
|
cancel: false
|
|
1765
865
|
};
|
|
1766
|
-
this.emit('
|
|
866
|
+
this.emit('flushdb_before', beforeEventData);
|
|
1767
867
|
|
|
1768
868
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1769
869
|
if (beforeEventData.cancel) {
|
|
1770
|
-
resolve(
|
|
870
|
+
resolve(null);
|
|
1771
871
|
return;
|
|
1772
872
|
}
|
|
1773
873
|
|
|
1774
874
|
// 执行实际操作
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
if (obj.value.members.hasOwnProperty(value)) {
|
|
1779
|
-
delete obj.value.members[value];
|
|
1780
|
-
// 更新有序数组
|
|
1781
|
-
obj.value.sorted = Object.keys(obj.value.members);
|
|
1782
|
-
result = 1;
|
|
1783
|
-
// 如果集合变空了,删除整个键
|
|
1784
|
-
if (Object.keys(obj.value.members).length === 0) {
|
|
1785
|
-
delete this.data[key];
|
|
1786
|
-
const index = this.list.indexOf(key);
|
|
1787
|
-
if (index > -1) {
|
|
1788
|
-
this.list.splice(index, 1);
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
}
|
|
1792
|
-
}
|
|
875
|
+
this.data = {};
|
|
876
|
+
this.list = [];
|
|
877
|
+
this.dict = this.data; // 同步dict引用
|
|
1793
878
|
|
|
1794
879
|
// 触发后置事件
|
|
1795
|
-
this.emit('
|
|
1796
|
-
|
|
1797
|
-
value,
|
|
1798
|
-
result
|
|
880
|
+
this.emit('flushdb_after', {
|
|
881
|
+
result: 'OK'
|
|
1799
882
|
});
|
|
1800
|
-
resolve(
|
|
883
|
+
resolve('OK');
|
|
1801
884
|
} catch (error) {
|
|
1802
885
|
// 触发错误事件
|
|
1803
|
-
this.emit('
|
|
1804
|
-
key,
|
|
1805
|
-
value,
|
|
886
|
+
this.emit('flushdb_error', {
|
|
1806
887
|
error
|
|
1807
888
|
});
|
|
1808
|
-
$.log.error('[cachebase]
|
|
1809
|
-
resolve(
|
|
889
|
+
$.log.error('[cachebase] flushdb操作失败:', error);
|
|
890
|
+
resolve(null);
|
|
1810
891
|
}
|
|
1811
892
|
});
|
|
1812
893
|
}
|
|
1813
894
|
|
|
1814
|
-
//
|
|
1815
|
-
async
|
|
895
|
+
// Redis兼容的incr方法
|
|
896
|
+
async incr(key) {
|
|
1816
897
|
return new Promise((resolve) => {
|
|
1817
898
|
try {
|
|
1818
899
|
// 触发前置事件
|
|
1819
900
|
const beforeEventData = {
|
|
1820
|
-
key,
|
|
901
|
+
key,
|
|
1821
902
|
cancel: false
|
|
1822
903
|
};
|
|
1823
|
-
this.emit('
|
|
904
|
+
this.emit('incr_before', beforeEventData);
|
|
1824
905
|
|
|
1825
906
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1826
907
|
if (beforeEventData.cancel) {
|
|
1827
|
-
resolve(
|
|
908
|
+
resolve(0);
|
|
1828
909
|
return;
|
|
1829
910
|
}
|
|
1830
911
|
|
|
1831
|
-
//
|
|
1832
|
-
let
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
912
|
+
// 获取当前值或默认为0
|
|
913
|
+
let currentValue = 0;
|
|
914
|
+
if (this.data[key] && !isNaN(this.data[key].value)) {
|
|
915
|
+
currentValue = parseInt(this.data[key].value, 10);
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// 执行递增
|
|
919
|
+
const result = currentValue + 1;
|
|
920
|
+
|
|
921
|
+
// 保存结果
|
|
922
|
+
this.data[key] = { value: result, expire: 0 };
|
|
923
|
+
|
|
924
|
+
// 如果键不存在于列表中,添加到列表
|
|
925
|
+
if (!this.list.includes(key)) {
|
|
926
|
+
this.list.push(key);
|
|
1836
927
|
}
|
|
1837
928
|
|
|
1838
929
|
// 触发后置事件
|
|
1839
|
-
this.emit('
|
|
1840
|
-
key,
|
|
930
|
+
this.emit('incr_after', {
|
|
931
|
+
key,
|
|
1841
932
|
result
|
|
1842
933
|
});
|
|
1843
934
|
resolve(result);
|
|
1844
935
|
} catch (error) {
|
|
1845
936
|
// 触发错误事件
|
|
1846
|
-
this.emit('
|
|
1847
|
-
key,
|
|
937
|
+
this.emit('incr_error', {
|
|
938
|
+
key,
|
|
1848
939
|
error
|
|
1849
940
|
});
|
|
1850
|
-
$.log.error('[cachebase]
|
|
1851
|
-
resolve(
|
|
941
|
+
$.log.error('[cachebase] incr操作失败:', error);
|
|
942
|
+
resolve(0);
|
|
1852
943
|
}
|
|
1853
944
|
});
|
|
1854
945
|
}
|
|
1855
946
|
|
|
1856
|
-
//
|
|
1857
|
-
async
|
|
947
|
+
// Redis兼容的decr方法
|
|
948
|
+
async decr(key) {
|
|
1858
949
|
return new Promise((resolve) => {
|
|
1859
950
|
try {
|
|
1860
951
|
// 触发前置事件
|
|
1861
952
|
const beforeEventData = {
|
|
1862
|
-
key,
|
|
1863
|
-
value,
|
|
953
|
+
key,
|
|
1864
954
|
cancel: false
|
|
1865
955
|
};
|
|
1866
|
-
this.emit('
|
|
956
|
+
this.emit('decr_before', beforeEventData);
|
|
1867
957
|
|
|
1868
958
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1869
959
|
if (beforeEventData.cancel) {
|
|
@@ -1871,43 +961,52 @@ class CacheBase extends EventEmitter {
|
|
|
1871
961
|
return;
|
|
1872
962
|
}
|
|
1873
963
|
|
|
1874
|
-
//
|
|
1875
|
-
let
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
964
|
+
// 获取当前值或默认为0
|
|
965
|
+
let currentValue = 0;
|
|
966
|
+
if (this.data[key] && !isNaN(this.data[key].value)) {
|
|
967
|
+
currentValue = parseInt(this.data[key].value, 10);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// 执行递减
|
|
971
|
+
const result = currentValue - 1;
|
|
972
|
+
|
|
973
|
+
// 保存结果
|
|
974
|
+
this.data[key] = { value: result, expire: 0 };
|
|
975
|
+
|
|
976
|
+
// 如果键不存在于列表中,添加到列表
|
|
977
|
+
if (!this.list.includes(key)) {
|
|
978
|
+
this.list.push(key);
|
|
1879
979
|
}
|
|
1880
980
|
|
|
1881
981
|
// 触发后置事件
|
|
1882
|
-
this.emit('
|
|
1883
|
-
key,
|
|
1884
|
-
value,
|
|
982
|
+
this.emit('decr_after', {
|
|
983
|
+
key,
|
|
1885
984
|
result
|
|
1886
985
|
});
|
|
1887
986
|
resolve(result);
|
|
1888
987
|
} catch (error) {
|
|
1889
988
|
// 触发错误事件
|
|
1890
|
-
this.emit('
|
|
1891
|
-
key,
|
|
1892
|
-
value,
|
|
989
|
+
this.emit('decr_error', {
|
|
990
|
+
key,
|
|
1893
991
|
error
|
|
1894
992
|
});
|
|
1895
|
-
$.log.error('[cachebase]
|
|
993
|
+
$.log.error('[cachebase] decr操作失败:', error);
|
|
1896
994
|
resolve(0);
|
|
1897
995
|
}
|
|
1898
996
|
});
|
|
1899
997
|
}
|
|
1900
998
|
|
|
1901
|
-
//
|
|
1902
|
-
async
|
|
999
|
+
// Redis兼容的incrby方法
|
|
1000
|
+
async incrby(key, increment) {
|
|
1903
1001
|
return new Promise((resolve) => {
|
|
1904
1002
|
try {
|
|
1905
1003
|
// 触发前置事件
|
|
1906
1004
|
const beforeEventData = {
|
|
1907
|
-
key,
|
|
1005
|
+
key,
|
|
1006
|
+
value: { increment },
|
|
1908
1007
|
cancel: false
|
|
1909
1008
|
};
|
|
1910
|
-
this.emit('
|
|
1009
|
+
this.emit('incrby_before', beforeEventData);
|
|
1911
1010
|
|
|
1912
1011
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1913
1012
|
if (beforeEventData.cancel) {
|
|
@@ -1915,96 +1014,109 @@ class CacheBase extends EventEmitter {
|
|
|
1915
1014
|
return;
|
|
1916
1015
|
}
|
|
1917
1016
|
|
|
1918
|
-
//
|
|
1919
|
-
let
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1017
|
+
// 获取当前值或默认为0
|
|
1018
|
+
let currentValue = 0;
|
|
1019
|
+
if (this.data[key] && !isNaN(this.data[key].value)) {
|
|
1020
|
+
currentValue = parseInt(this.data[key].value, 10);
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
// 执行递增
|
|
1024
|
+
const result = currentValue + parseInt(increment, 10);
|
|
1025
|
+
|
|
1026
|
+
// 保存结果
|
|
1027
|
+
this.data[key] = { value: result, expire: 0 };
|
|
1028
|
+
|
|
1029
|
+
// 如果键不存在于列表中,添加到列表
|
|
1030
|
+
if (!this.list.includes(key)) {
|
|
1031
|
+
this.list.push(key);
|
|
1923
1032
|
}
|
|
1924
1033
|
|
|
1925
1034
|
// 触发后置事件
|
|
1926
|
-
this.emit('
|
|
1927
|
-
key,
|
|
1035
|
+
this.emit('incrby_after', {
|
|
1036
|
+
key,
|
|
1037
|
+
value: { increment },
|
|
1928
1038
|
result
|
|
1929
1039
|
});
|
|
1930
1040
|
resolve(result);
|
|
1931
1041
|
} catch (error) {
|
|
1932
1042
|
// 触发错误事件
|
|
1933
|
-
this.emit('
|
|
1934
|
-
key,
|
|
1043
|
+
this.emit('incrby_error', {
|
|
1044
|
+
key,
|
|
1045
|
+
value: { increment },
|
|
1935
1046
|
error
|
|
1936
1047
|
});
|
|
1937
|
-
$.log.error('[cachebase]
|
|
1048
|
+
$.log.error('[cachebase] incrby操作失败:', error);
|
|
1938
1049
|
resolve(0);
|
|
1939
1050
|
}
|
|
1940
1051
|
});
|
|
1941
1052
|
}
|
|
1942
1053
|
|
|
1943
|
-
//
|
|
1944
|
-
async
|
|
1054
|
+
// Redis兼容的decrby方法
|
|
1055
|
+
async decrby(key, decrement) {
|
|
1945
1056
|
return new Promise((resolve) => {
|
|
1946
1057
|
try {
|
|
1947
1058
|
// 触发前置事件
|
|
1948
1059
|
const beforeEventData = {
|
|
1949
|
-
key,
|
|
1950
|
-
value: {
|
|
1060
|
+
key,
|
|
1061
|
+
value: { decrement },
|
|
1951
1062
|
cancel: false
|
|
1952
1063
|
};
|
|
1953
|
-
this.emit('
|
|
1064
|
+
this.emit('decrby_before', beforeEventData);
|
|
1954
1065
|
|
|
1955
1066
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
1956
1067
|
if (beforeEventData.cancel) {
|
|
1957
|
-
resolve(
|
|
1068
|
+
resolve(0);
|
|
1958
1069
|
return;
|
|
1959
1070
|
}
|
|
1960
1071
|
|
|
1961
|
-
//
|
|
1962
|
-
let
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1072
|
+
// 获取当前值或默认为0
|
|
1073
|
+
let currentValue = 0;
|
|
1074
|
+
if (this.data[key] && !isNaN(this.data[key].value)) {
|
|
1075
|
+
currentValue = parseInt(this.data[key].value, 10);
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
// 执行递减
|
|
1079
|
+
const result = currentValue - parseInt(decrement, 10);
|
|
1080
|
+
|
|
1081
|
+
// 保存结果
|
|
1082
|
+
this.data[key] = { value: result, expire: 0 };
|
|
1083
|
+
|
|
1084
|
+
// 如果键不存在于列表中,添加到列表
|
|
1085
|
+
if (!this.list.includes(key)) {
|
|
1086
|
+
this.list.push(key);
|
|
1975
1087
|
}
|
|
1976
1088
|
|
|
1977
1089
|
// 触发后置事件
|
|
1978
|
-
this.emit('
|
|
1979
|
-
key,
|
|
1980
|
-
value: {
|
|
1090
|
+
this.emit('decrby_after', {
|
|
1091
|
+
key,
|
|
1092
|
+
value: { decrement },
|
|
1981
1093
|
result
|
|
1982
1094
|
});
|
|
1983
1095
|
resolve(result);
|
|
1984
1096
|
} catch (error) {
|
|
1985
1097
|
// 触发错误事件
|
|
1986
|
-
this.emit('
|
|
1987
|
-
key,
|
|
1988
|
-
value: {
|
|
1098
|
+
this.emit('decrby_error', {
|
|
1099
|
+
key,
|
|
1100
|
+
value: { decrement },
|
|
1989
1101
|
error
|
|
1990
1102
|
});
|
|
1991
|
-
$.log.error('[cachebase]
|
|
1992
|
-
resolve(
|
|
1103
|
+
$.log.error('[cachebase] decrby操作失败:', error);
|
|
1104
|
+
resolve(0);
|
|
1993
1105
|
}
|
|
1994
1106
|
});
|
|
1995
1107
|
}
|
|
1996
1108
|
|
|
1997
|
-
//
|
|
1998
|
-
async
|
|
1109
|
+
// Redis兼容的incrbyfloat方法
|
|
1110
|
+
async incrbyfloat(key, increment) {
|
|
1999
1111
|
return new Promise((resolve) => {
|
|
2000
1112
|
try {
|
|
2001
1113
|
// 触发前置事件
|
|
2002
1114
|
const beforeEventData = {
|
|
2003
|
-
key,
|
|
2004
|
-
value: {
|
|
1115
|
+
key,
|
|
1116
|
+
value: { increment },
|
|
2005
1117
|
cancel: false
|
|
2006
1118
|
};
|
|
2007
|
-
this.emit('
|
|
1119
|
+
this.emit('incrbyfloat_before', beforeEventData);
|
|
2008
1120
|
|
|
2009
1121
|
// 如果事件处理器设置了cancel为true,则取消操作
|
|
2010
1122
|
if (beforeEventData.cancel) {
|
|
@@ -2012,89 +1124,62 @@ class CacheBase extends EventEmitter {
|
|
|
2012
1124
|
return;
|
|
2013
1125
|
}
|
|
2014
1126
|
|
|
2015
|
-
//
|
|
2016
|
-
let
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
this.list.splice(index, 1);
|
|
2031
|
-
}
|
|
2032
|
-
}
|
|
1127
|
+
// 获取当前值或默认为0
|
|
1128
|
+
let currentValue = 0;
|
|
1129
|
+
if (this.data[key] && !isNaN(this.data[key].value)) {
|
|
1130
|
+
currentValue = parseFloat(this.data[key].value);
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
// 执行浮点递增
|
|
1134
|
+
const result = currentValue + parseFloat(increment);
|
|
1135
|
+
|
|
1136
|
+
// 保存结果
|
|
1137
|
+
this.data[key] = { value: result, expire: 0 };
|
|
1138
|
+
|
|
1139
|
+
// 如果键不存在于列表中,添加到列表
|
|
1140
|
+
if (!this.list.includes(key)) {
|
|
1141
|
+
this.list.push(key);
|
|
2033
1142
|
}
|
|
2034
1143
|
|
|
2035
1144
|
// 触发后置事件
|
|
2036
|
-
this.emit('
|
|
2037
|
-
key,
|
|
2038
|
-
value: {
|
|
1145
|
+
this.emit('incrbyfloat_after', {
|
|
1146
|
+
key,
|
|
1147
|
+
value: { increment },
|
|
2039
1148
|
result
|
|
2040
1149
|
});
|
|
2041
1150
|
resolve(result);
|
|
2042
1151
|
} catch (error) {
|
|
2043
1152
|
// 触发错误事件
|
|
2044
|
-
this.emit('
|
|
2045
|
-
key,
|
|
2046
|
-
value: {
|
|
1153
|
+
this.emit('incrbyfloat_error', {
|
|
1154
|
+
key,
|
|
1155
|
+
value: { increment },
|
|
2047
1156
|
error
|
|
2048
1157
|
});
|
|
2049
|
-
$.log.error('[cachebase]
|
|
1158
|
+
$.log.error('[cachebase] incrbyfloat操作失败:', error);
|
|
2050
1159
|
resolve(0);
|
|
2051
1160
|
}
|
|
2052
1161
|
});
|
|
2053
1162
|
}
|
|
2054
1163
|
|
|
2055
|
-
//
|
|
2056
|
-
async
|
|
2057
|
-
return
|
|
2058
|
-
|
|
2059
|
-
// 触发前置事件
|
|
2060
|
-
const beforeEventData = {
|
|
2061
|
-
key,
|
|
2062
|
-
value: { member },
|
|
2063
|
-
cancel: false
|
|
2064
|
-
};
|
|
2065
|
-
this.emit('zscore_before', beforeEventData);
|
|
1164
|
+
// 保持兼容性的方法
|
|
1165
|
+
async has(key) {
|
|
1166
|
+
return this.exists(key);
|
|
1167
|
+
}
|
|
2066
1168
|
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
return;
|
|
2071
|
-
}
|
|
1169
|
+
async clear(pattern) {
|
|
1170
|
+
return this.flushdb();
|
|
1171
|
+
}
|
|
2072
1172
|
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
if (obj && obj.value && obj.value.members && obj.value.members.hasOwnProperty(member)) {
|
|
2077
|
-
result = obj.value.members[member];
|
|
2078
|
-
}
|
|
1173
|
+
async add(key, value) {
|
|
1174
|
+
return this.incrby(key, value);
|
|
1175
|
+
}
|
|
2079
1176
|
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
resolve(result);
|
|
2087
|
-
} catch (error) {
|
|
2088
|
-
// 触发错误事件
|
|
2089
|
-
this.emit('zscore_error', {
|
|
2090
|
-
key,
|
|
2091
|
-
value: { member },
|
|
2092
|
-
error
|
|
2093
|
-
});
|
|
2094
|
-
$.log.error('[cachebase] zscore操作失败:', error);
|
|
2095
|
-
resolve(null);
|
|
2096
|
-
}
|
|
2097
|
-
});
|
|
1177
|
+
async addFloat(key, value) {
|
|
1178
|
+
return this.incrbyfloat(key, value);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
async addStr(key, value) {
|
|
1182
|
+
return this.append(key, value);
|
|
2098
1183
|
}
|
|
2099
1184
|
|
|
2100
1185
|
// 资源销毁方法,包含事件触发
|