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/README.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # mm_cachebase
2
2
 
3
- 一个轻量级的本地缓存类库,提供了丰富的缓存操作接口,支持过期时间设置、数组操作、哈希表、集合、有序集合等功能,以及完整的事件通知系统。
3
+ 一个轻量级的本地缓存类库,提供了与Redis兼容的缓存操作接口,支持过期时间设置、哈希表操作、数值操作、字符串操作等功能,以及完整的事件通知系统。
4
+
5
+ ## 特点
6
+
7
+ - **Redis兼容API**:实现了与npm redis模块相似的接口,便于无缝切换
8
+ - **轻量级设计**:纯JavaScript实现,无外部依赖
9
+ - **完整的事件系统**:支持前置/后置/错误事件,便于日志记录和访问控制
10
+ - **过期时间管理**:支持设置和查询键的过期时间
11
+ - **丰富的数据类型支持**:支持字符串、哈希表等Redis常见数据类型
4
12
 
5
13
  ## 安装
6
14
 
@@ -38,9 +46,7 @@ async function example() {
38
46
  const cache = new CacheBase();
39
47
  ```
40
48
 
41
- 创建一个新的缓存实例。缓存实例包含以下属性:
42
- - `list`: 存储缓存数据的数组
43
- - `func`: 到期通知函数(可选)
49
+ 创建一个新的缓存实例。缓存实例基于EventEmitter,支持完整的事件系统。
44
50
 
45
51
  ### 基本操作
46
52
 
@@ -51,14 +57,14 @@ await cache.set(key, value, maxAge)
51
57
  - `key`: 缓存键名
52
58
  - `value`: 缓存的值
53
59
  - `maxAge`: 过期时间(秒),-1表示永不过期
54
- - 返回: 设置的值
60
+ - 返回: 'OK'
55
61
 
56
62
  #### 获取缓存
57
63
  ```javascript
58
64
  await cache.get(key)
59
65
  ```
60
66
  - `key`: 缓存键名
61
- - 返回: 缓存值,不存在则返回undefined
67
+ - 返回: 缓存值,不存在则返回null
62
68
 
63
69
  #### 删除缓存
64
70
  ```javascript
@@ -67,239 +73,138 @@ await cache.del(key)
67
73
  - `key`: 缓存键名
68
74
  - 返回: 成功返回1,失败返回0
69
75
 
70
- #### 添加缓存
76
+ #### 设置并获取旧值
71
77
  ```javascript
72
- await cache.add(key, value, maxAge)
78
+ await cache.getset(key, value, maxAge)
73
79
  ```
74
- - 只在键不存在时添加缓存
75
- - 返回: 添加成功返回值,已存在返回0
80
+ - 先获取旧值,然后设置新值
81
+ - 返回: 旧值,不存在则返回null
76
82
 
77
- #### 判断键是否存在
83
+ #### 批量设置缓存
78
84
  ```javascript
79
- await cache.has(key)
85
+ await cache.mset(keys, values, maxAge)
80
86
  ```
81
- - 返回: 存在返回1,不存在返回0
82
-
83
- ### 过期时间操作
84
-
85
- #### 设置/查询过期时间
86
- ```javascript
87
- await cache.ttl(key, maxAge)
88
- ```
89
- - `maxAge`: 不传则查询剩余时间,传入则设置新的过期时间
90
- - 返回: 查询时返回剩余秒数,设置时返回1
91
-
92
- ### 数值操作
93
-
94
- #### 增加整数
95
- ```javascript
96
- await cache.addInt(key, num)
97
- ```
98
- - `num`: 要增加的数值,可以为负数
99
- - 返回: 计算后的结果
87
+ - `keys`: 键名数组
88
+ - `values`: 值数组
89
+ - 返回: 'OK'
100
90
 
101
- #### 增加浮点数
91
+ #### 批量获取缓存
102
92
  ```javascript
103
- await cache.addFloat(key, num)
93
+ await cache.mget(...keys)
104
94
  ```
105
- - 用法同addInt,支持浮点数
106
-
107
- ### 字符串操作
95
+ - `keys`: 一个或多个键名
96
+ - 返回: 值数组
108
97
 
109
- #### 追加字符串
98
+ #### 判断键是否存在
110
99
  ```javascript
111
- await cache.addStr(key, str)
100
+ await cache.exists(...keys)
112
101
  ```
113
- - 在已有字符串后追加新字符串
114
- - 返回: 追加后的完整字符串
102
+ - `keys`: 一个或多个键名
103
+ - 返回: 存在的键数量
115
104
 
116
- #### 获取子字符串
117
- ```javascript
118
- await cache.getrange(key, start, end)
119
- ```
120
- - 获取缓存字符串的指定范围
121
- - 返回: 截取的字符串
105
+ ### 过期时间操作
122
106
 
123
- #### 替换字符串
107
+ #### 设置过期时间
124
108
  ```javascript
125
- await cache.setrange(key, index, value)
109
+ await cache.expire(key, maxAge)
126
110
  ```
127
- - 从指定位置替换字符串
128
-
129
- ### 哈希表操作
130
-
131
- #### 设置哈希表字段
132
- ```javascript
133
- await cache.hset(key, field, value)
134
- ```
135
- - `key`: 哈希表的键名
136
- - `field`: 字段名
137
- - `value`: 字段值
111
+ - `maxAge`: 过期时间(秒)
138
112
  - 返回: 成功返回1,失败返回0
139
113
 
140
- #### 获取哈希表字段
114
+ #### 查询剩余过期时间
141
115
  ```javascript
142
- await cache.hget(key, field)
116
+ await cache.ttl(key)
143
117
  ```
144
- - 返回: 字段值,不存在则返回null
118
+ - 返回: 剩余秒数,不存在或永不过期返回-1
145
119
 
146
- #### 删除哈希表字段
120
+ #### 移除过期时间
147
121
  ```javascript
148
- await cache.hdel(key, field)
122
+ await cache.persist(key)
149
123
  ```
150
124
  - 返回: 成功返回1,失败返回0
151
125
 
152
- #### 获取哈希表所有键名
153
- ```javascript
154
- await cache.hkeys(key)
155
- ```
156
- - 返回: 键名数组
157
-
158
- #### 获取哈希表所有值
159
- ```javascript
160
- await cache.hvals(key)
161
- ```
162
- - 返回: 值数组
163
-
164
- ### 列表操作
165
-
166
- #### 设置列表
167
- ```javascript
168
- await cache.list_set(key, value, maxAge)
169
- ```
170
- - 设置一个数组类型的缓存
171
-
172
- #### 添加列表元素
173
- ```javascript
174
- await cache.list_add(key, value)
175
- ```
176
- - 向数组末尾添加元素
177
- - 返回: 成功返回1,失败返回-1
178
-
179
- #### 从左侧推入元素
180
- ```javascript
181
- await cache.lpush(key, ...values)
182
- ```
183
- - 从列表左侧添加一个或多个元素
184
- - 返回: 操作后的列表长度
185
-
186
- #### 从左侧弹出元素
187
- ```javascript
188
- await cache.lpop(key)
189
- ```
190
- - 从列表左侧移除并返回一个元素
191
- - 返回: 弹出的元素,列表为空返回null
192
-
193
- #### 从右侧推入元素
194
- ```javascript
195
- await cache.rpush(key, ...values)
196
- ```
197
- - 从列表右侧添加一个或多个元素
198
- - 返回: 操作后的列表长度
199
-
200
- #### 从右侧弹出元素
201
- ```javascript
202
- await cache.rpop(key)
203
- ```
204
- - 从列表右侧移除并返回一个元素
205
- - 返回: 弹出的元素,列表为空返回null
206
-
207
- #### 获取列表长度
208
- ```javascript
209
- await cache.llen(key)
210
- ```
211
- - 返回: 列表长度,键不存在返回0
126
+ ### 数值操作
212
127
 
213
- #### 判断数组元素是否存在
128
+ #### 增加整数
214
129
  ```javascript
215
- await cache.list_has(key, value)
130
+ await cache.incr(key)
216
131
  ```
217
- - 检查数组中是否包含指定元素
132
+ - 将键的值加1
133
+ - 返回: 增加后的值
218
134
 
219
- #### 获取数组片段
135
+ #### 增加指定整数
220
136
  ```javascript
221
- await cache.list_get(key, start, end)
137
+ await cache.incrby(key, increment)
222
138
  ```
223
- - 获取数组的指定范围元素
139
+ - `increment`: 要增加的整数
140
+ - 返回: 增加后的值
224
141
 
225
- #### 清空/重置数组
142
+ #### 减少整数
226
143
  ```javascript
227
- await cache.list_clear(key, value)
144
+ await cache.decr(key)
228
145
  ```
229
- - 清空数组或用新数组替换
230
-
231
- ### 集合操作
146
+ - 将键的值减1
147
+ - 返回: 减少后的值
232
148
 
233
- #### 添加集合成员
149
+ #### 减少指定整数
234
150
  ```javascript
235
- await cache.sadd(key, member)
151
+ await cache.decrby(key, decrement)
236
152
  ```
237
- - 向集合添加一个成员
238
- - 返回: 成功返回1,成员已存在返回0
153
+ - `decrement`: 要减少的整数
154
+ - 返回: 减少后的值
239
155
 
240
- #### 删除集合成员
156
+ #### 增加浮点数
241
157
  ```javascript
242
- await cache.srem(key, member)
158
+ await cache.incrbyfloat(key, increment)
243
159
  ```
244
- - 从集合移除一个成员
245
- - 返回: 成功返回1,成员不存在返回0
160
+ - `increment`: 要增加的浮点数
161
+ - 返回: 增加后的值
246
162
 
247
- #### 获取集合所有成员
248
- ```javascript
249
- await cache.smembers(key)
250
- ```
251
- - 返回: 成员数组,键不存在返回空数组
163
+ ### 字符串操作
252
164
 
253
- #### 判断成员是否存在
165
+ #### 追加字符串
254
166
  ```javascript
255
- await cache.sismember(key, member)
167
+ await cache.append(key, value)
256
168
  ```
257
- - 返回: 存在返回1,不存在返回0
169
+ - 在已有字符串后追加新字符串
170
+ - 返回: 追加后的字符串长度
258
171
 
259
- #### 获取集合大小
172
+ #### 获取字符串长度
260
173
  ```javascript
261
- await cache.scard(key)
174
+ await cache.strlen(key)
262
175
  ```
263
- - 返回: 集合大小,键不存在返回0
176
+ - 返回: 字符串长度
264
177
 
265
- ### 有序集合操作
178
+ ### 哈希表操作
266
179
 
267
- #### 添加有序集合成员
180
+ #### 设置哈希表字段
268
181
  ```javascript
269
- await cache.zadd(key, score, member)
182
+ await cache.hset(key, field, value)
270
183
  ```
271
- - 向有序集合添加一个成员
272
- - 返回: 成功返回1,成员已存在返回0
184
+ - `key`: 哈希表的键名
185
+ - `field`: 字段名
186
+ - `value`: 字段值
187
+ - 返回: 成功返回1,失败返回0
273
188
 
274
- #### 获取有序集合范围
189
+ #### 获取哈希表字段
275
190
  ```javascript
276
- await cache.zrange(key, start, stop, withScores)
191
+ await cache.hget(key, field)
277
192
  ```
278
- - `start`/`stop`: 范围索引
279
- - `withScores`: 是否返回分数
280
- - 返回: 成员数组或[成员, 分数]数组
193
+ - 返回: 字段值,不存在则返回null
281
194
 
282
- #### 删除有序集合成员
195
+ #### 获取哈希表所有字段和值
283
196
  ```javascript
284
- await cache.zrem(key, member)
197
+ await cache.hgetall(key)
285
198
  ```
286
- - 从有序集合移除一个成员
287
- - 返回: 成功返回1,成员不存在返回0
199
+ - 返回: 包含所有字段和值的对象
288
200
 
289
- #### 获取成员分数
201
+ #### 删除哈希表字段
290
202
  ```javascript
291
- await cache.zscore(key, member)
203
+ await cache.hdel(key, field)
292
204
  ```
293
- - 返回: 成员分数,成员不存在返回null
205
+ - 返回: 成功返回1,失败返回0
294
206
 
295
- ### 其他操作
296
-
297
- #### 排序
298
- ```javascript
299
- await cache.sort(key, way, obj_key)
300
- ```
301
- - `way`: 'asc'升序或'desc'降序
302
- - `obj_key`: 如果数组元素是对象,指定排序的键
207
+ ### 键操作
303
208
 
304
209
  #### 获取所有键名
305
210
  ```javascript
@@ -308,12 +213,18 @@ await cache.keys(pattern)
308
213
  - `pattern`: 支持*通配符的匹配模式
309
214
  - 返回: 匹配的键名数组
310
215
 
216
+ #### 获取键数量
217
+ ```javascript
218
+ await cache.dbsize()
219
+ ```
220
+ - 返回: 缓存中的键数量
221
+
311
222
  #### 清空缓存
312
223
  ```javascript
313
- await cache.clear(pattern)
224
+ await cache.flushdb()
314
225
  ```
315
- - `pattern`: 可选,支持*通配符,清空匹配的键
316
- - 不传则清空所有缓存
226
+ - 清空所有缓存
227
+ - 返回: 'OK'
317
228
 
318
229
  #### 销毁缓存实例
319
230
  ```javascript
@@ -321,207 +232,38 @@ await cache.dispose()
321
232
  ```
322
233
  - 清理所有资源,移除所有监听器
323
234
 
324
- ## 使用示例
325
-
326
- ### 基本缓存操作
327
- ```javascript
328
- const cache = new CacheBase();
329
-
330
- async function example() {
331
- // 设置缓存
332
- await cache.set("user", "张三", 60); // 60秒后过期
333
-
334
- // 获取缓存
335
- const user = await cache.get("user");
336
- console.log(user); // 输出: 张三
337
-
338
- // 检查是否存在
339
- const exists = await cache.has("user");
340
- console.log(exists); // 输出: 1
341
-
342
- // 删除缓存
343
- await cache.del("user");
344
- }
345
- ```
346
-
347
- ### 哈希表操作示例
348
- ```javascript
349
- async function hashExample() {
350
- // 设置哈希表字段
351
- await cache.hset("user:123", "name", "张三");
352
- await cache.hset("user:123", "age", 30);
353
- await cache.hset("user:123", "email", "zhangsan@example.com");
354
-
355
- // 获取哈希表字段
356
- const name = await cache.hget("user:123", "name");
357
- console.log(name); // 输出: 张三
358
-
359
- // 获取所有键名
360
- const keys = await cache.hkeys("user:123");
361
- console.log(keys); // 输出: ["name", "age", "email"]
362
-
363
- // 获取所有值
364
- const values = await cache.hvals("user:123");
365
- console.log(values); // 输出: ["张三", 30, "zhangsan@example.com"]
366
-
367
- // 删除字段
368
- await cache.hdel("user:123", "email");
369
- }
370
- ```
235
+ ### 兼容方法(保持向后兼容)
371
236
 
372
- ### 列表操作示例
237
+ #### 添加缓存(仅当键不存在时)
373
238
  ```javascript
374
- async function listExample() {
375
- // 设置列表
376
- await cache.list_set("tasks", ["任务1", "任务2"], 300);
377
-
378
- // 添加元素到末尾
379
- await cache.list_add("tasks", "任务3");
380
-
381
- // 从左侧推入元素
382
- await cache.lpush("tasks", "任务0");
383
-
384
- // 从右侧推入元素
385
- await cache.rpush("tasks", "任务4");
386
-
387
- // 从左侧弹出元素
388
- const task0 = await cache.lpop("tasks");
389
- console.log("弹出任务:", task0); // 输出: 任务0
390
-
391
- // 从右侧弹出元素
392
- const task4 = await cache.rpop("tasks");
393
- console.log("弹出任务:", task4); // 输出: 任务4
394
-
395
- // 获取列表长度
396
- const length = await cache.llen("tasks");
397
- console.log("任务数量:", length); // 输出: 3
398
-
399
- // 获取列表
400
- const tasks = await cache.list_get("tasks");
401
- console.log("任务列表:", tasks); // 输出: ["任务1", "任务2", "任务3"]
402
-
403
- // 排序
404
- await cache.sort("tasks", "asc");
405
- }
239
+ await cache.add(key, value, maxAge)
406
240
  ```
241
+ - 返回: 添加成功返回值,已存在返回0
407
242
 
408
- ### 集合操作示例
243
+ #### 检查键是否存在
409
244
  ```javascript
410
- async function setExample() {
411
- // 添加集合成员
412
- await cache.sadd("users", "张三");
413
- await cache.sadd("users", "李四");
414
- await cache.sadd("users", "王五");
415
-
416
- // 尝试添加重复成员
417
- const result = await cache.sadd("users", "张三");
418
- console.log("添加重复成员结果:", result); // 输出: 0
419
-
420
- // 判断成员是否存在
421
- const exists = await cache.sismember("users", "张三");
422
- console.log("张三是否在用户集合中:", exists); // 输出: 1
423
-
424
- // 获取集合所有成员
425
- const members = await cache.smembers("users");
426
- console.log("用户集合:", members); // 输出: ["张三", "李四", "王五"]
427
-
428
- // 获取集合大小
429
- const size = await cache.scard("users");
430
- console.log("集合大小:", size); // 输出: 3
431
-
432
- // 删除成员
433
- await cache.srem("users", "李四");
434
- }
245
+ await cache.has(key)
435
246
  ```
247
+ - 返回: 存在返回1,不存在返回0
436
248
 
437
- ### 有序集合操作示例
249
+ #### 增加浮点数(兼容方法)
438
250
  ```javascript
439
- async function sortedSetExample() {
440
- // 添加有序集合成员
441
- await cache.zadd("scores", 95, "张三");
442
- await cache.zadd("scores", 88, "李四");
443
- await cache.zadd("scores", 92, "王五");
444
-
445
- // 获取有序集合范围(升序)
446
- const ascendingScores = await cache.zrange("scores", 0, -1, true);
447
- console.log("分数排序(升序):", ascendingScores);
448
- // 输出: ["李四", 88, "王五", 92, "张三", 95]
449
-
450
- // 获取指定成员分数
451
- const zhangScore = await cache.zscore("scores", "张三");
452
- console.log("张三的分数:", zhangScore); // 输出: 95
453
-
454
- // 删除成员
455
- await cache.zrem("scores", "李四");
456
-
457
- // 再次获取有序集合
458
- const remainingScores = await cache.zrange("scores", 0, -1);
459
- console.log("剩余成员:", remainingScores); // 输出: ["王五", "张三"]
460
- }
251
+ await cache.addFloat(key, num)
461
252
  ```
253
+ - `num`: 要增加的浮点数
254
+ - 返回: 计算后的结果
462
255
 
463
- ### 过期时间管理
256
+ #### 追加字符串(兼容方法)
464
257
  ```javascript
465
- async function ttlExample() {
466
- // 设置缓存
467
- await cache.set("token", "abc123", 30);
468
-
469
- // 查询剩余时间
470
- const ttl = await cache.ttl("token");
471
- console.log(`剩余${ttl}秒`);
472
-
473
- // 延长过期时间
474
- await cache.ttl("token", 60);
475
-
476
- // 设置永不过期
477
- await cache.ttl("token", -1);
478
- }
258
+ await cache.addStr(key, str)
479
259
  ```
260
+ - 返回: 追加后的完整字符串
480
261
 
481
- ### 批量操作
262
+ #### 清空匹配缓存(兼容方法)
482
263
  ```javascript
483
- async function batchExample() {
484
- // 获取所有以user开头的键
485
- const keys = await cache.keys("user*");
486
-
487
- // 清空所有以temp开头的缓存
488
- await cache.clear("temp*");
489
-
490
- // 清空所有缓存
491
- await cache.clear();
492
- }
493
-
494
- ### 事件系统使用示例
495
- ```javascript
496
- async function eventExample() {
497
- // 设置操作的前置事件
498
- cache.on('set_before', (data) => {
499
- console.log(`即将设置键: ${data.key}`);
500
-
501
- // 示例:进行数据验证
502
- if (typeof data.value === 'string' && data.value.length > 100) {
503
- console.log('值长度过长,取消设置');
504
- data.cancel = true; // 取消操作
505
- }
506
- });
507
-
508
- // 获取操作的后置事件
509
- cache.on('get_after', (data) => {
510
- console.log(`获取键 ${data.key} 的结果: ${data.result}`);
511
- });
512
-
513
- // 尝试设置缓存
514
- await cache.set("test", "这是一个测试值");
515
-
516
- // 获取缓存
517
- const value = await cache.get("test");
518
-
519
- // 错误事件监听
520
- cache.on('get_error', (data) => {
521
- console.error(`获取键 ${data.key} 时出错: ${data.error.message}`);
522
- });
523
- }
264
+ await cache.clear(pattern)
524
265
  ```
266
+ - `pattern`: 可选,支持*通配符
525
267
 
526
268
  ## 事件系统
527
269
 
@@ -553,385 +295,159 @@ cache.off('event_name', callback);
553
295
 
554
296
  ### 支持的事件类型
555
297
 
556
- 每个缓存操作都有对应的前置事件(`_before`)、后置事件(`_after`)和错误事件(`_error`)。以下是主要支持的事件类型:
298
+ 每个缓存操作都有对应的前置事件(`_before`)、后置事件(`_after`)和错误事件(`_error`)。
557
299
 
558
300
  #### 基本操作事件
559
301
  - `set_before`, `set_after`, `set_error`
560
302
  - `get_before`, `get_after`, `get_error`
561
303
  - `del_before`, `del_after`, `del_error`
562
304
  - `exists_before`, `exists_after`, `exists_error`
563
- - `dispose_before`, `dispose_after`, `dispose_error`
305
+ - `mset_before`, `mset_after`, `mset_error`
306
+ - `mget_before`, `mget_after`, `mget_error`
307
+
308
+ #### 过期时间操作事件
309
+ - `expire_before`, `expire_after`, `expire_error`
310
+ - `ttl_before`, `ttl_after`, `ttl_error`
311
+
312
+ #### 数值操作事件
313
+ - `incr_before`, `incr_after`, `incr_error`
314
+ - `decr_before`, `decr_after`, `decr_error`
315
+ - `incrby_before`, `incrby_after`, `incrby_error`
316
+ - `decrby_before`, `decrby_after`, `decrby_error`
317
+ - `incrbyfloat_before`, `incrbyfloat_after`, `incrbyfloat_error`
318
+
319
+ #### 字符串操作事件
320
+ - `append_before`, `append_after`, `append_error`
321
+ - `strlen_before`, `strlen_after`, `strlen_error`
564
322
 
565
323
  #### 哈希表操作事件
566
324
  - `hset_before`, `hset_after`, `hset_error`
567
325
  - `hget_before`, `hget_after`, `hget_error`
326
+ - `hgetall_before`, `hgetall_after`, `hgetall_error`
568
327
  - `hdel_before`, `hdel_after`, `hdel_error`
569
- - `hkeys_before`, `hkeys_after`, `hkeys_error`
570
- - `hvals_before`, `hvals_after`, `hvals_error`
571
-
572
- #### 列表操作事件
573
- - `lpush_before`, `lpush_after`, `lpush_error`
574
- - `lpop_before`, `lpop_after`, `lpop_error`
575
- - `rpush_before`, `rpush_after`, `rpush_error`
576
- - `rpop_before`, `rpop_after`, `rpop_error`
577
- - `llen_before`, `llen_after`, `llen_error`
578
- - `list_set_before`, `list_set_after`, `list_set_error`
579
- - `list_add_before`, `list_add_after`, `list_add_error`
580
- - `list_clear_before`, `list_clear_after`, `list_clear_error`
581
-
582
- #### 集合操作事件
583
- - `sadd_before`, `sadd_after`, `sadd_error`
584
- - `srem_before`, `srem_after`, `srem_error`
585
- - `smembers_before`, `smembers_after`, `smembers_error`
586
- - `sismember_before`, `sismember_after`, `sismember_error`
587
- - `scard_before`, `scard_after`, `scard_error`
588
-
589
- #### 有序集合操作事件
590
- - `zadd_before`, `zadd_after`, `zadd_error`
591
- - `zrange_before`, `zrange_after`, `zrange_error`
592
- - `zrem_before`, `zrem_after`, `zrem_error`
593
- - `zscore_before`, `zscore_after`, `zscore_error`
594
-
595
- #### 其他操作事件
596
- - `mset_before`, `mset_after`, `mset_error`
597
- - `setex_before`, `setex_after`, `setex_error`
598
- - `setnx_before`, `setnx_after`, `setnx_error`
599
- - `add_before`, `add_after`, `add_error`
600
- - `addFloat_before`, `addFloat_after`, `addFloat_error`
601
- - `addStr_before`, `addStr_after`, `addStr_error`
602
- - `setrange_before`, `setrange_after`, `setrange_error`
603
328
 
604
- ### 取消操作示例
329
+ #### 键操作事件
330
+ - `keys_before`, `keys_after`, `keys_error`
331
+ - `dbsize_before`, `dbsize_after`, `dbsize_error`
332
+ - `flushdb_before`, `flushdb_after`, `flushdb_error`
333
+ - `dispose_before`, `dispose_after`, `dispose_error`
605
334
 
606
- 在前置事件中,你可以通过设置 `cancel` 标志为 `true` 来取消操作:
335
+ ### 事件使用示例
607
336
 
608
337
  ```javascript
338
+ const cache = new CacheBase();
339
+
609
340
  // 监听设置操作的前置事件
610
341
  cache.on('set_before', (data) => {
611
342
  console.log('即将设置键:', data.key, '值:', data.value);
612
343
 
613
- // 检查值是否合法
614
- if (typeof data.value !== 'string' || data.value.length > 100) {
615
- console.log('值不合法,取消设置操作');
344
+ // 数据验证示例
345
+ if (typeof data.value === 'string' && data.value.length > 100) {
346
+ console.log('值长度过长,取消设置');
616
347
  data.cancel = true; // 取消操作
617
348
  }
618
349
  });
619
350
 
620
- // 监听获取操作的前置事件 - 实现访问控制
621
- cache.on('get_before', (data) => {
622
- console.log('尝试获取键:', data.key);
623
-
624
- // 实现简单的访问控制
625
- const restrictedKeys = ['admin_data', 'sensitive_info'];
626
- if (restrictedKeys.includes(data.key) && !userHasPermission()) {
627
- console.log('无权限访问此键,取消获取操作');
628
- data.cancel = true; // 取消操作
629
- }
351
+ // 监听获取操作的后置事件
352
+ cache.on('get_after', (data) => {
353
+ console.log(`获取键 ${data.key} 的结果: ${data.result}`);
630
354
  });
631
355
 
632
- // 监听集合删除操作的前置事件
633
- cache.on('srem_before', (data) => {
634
- console.log('尝试从集合', data.key, '中删除成员:', data.value.member);
635
-
636
- // 防止删除特定成员
637
- if (data.value.member === 'protected_member') {
638
- console.log('保护成员不能删除,取消操作');
639
- data.cancel = true;
640
- }
641
- });
642
-
643
- // 监听删除键操作的前置事件
644
- cache.on('del_before', (data) => {
645
- console.log('尝试删除键:', data.key);
646
-
647
- // 防止删除系统键
648
- if (data.key.startsWith('system:')) {
649
- console.log('系统键不能删除,取消操作');
650
- data.cancel = true;
651
- }
356
+ // 错误事件监听
357
+ cache.on('get_error', (data) => {
358
+ console.error(`获取键 ${data.key} 时出错: ${data.error.message}`);
652
359
  });
653
360
  ```
654
361
 
655
- ### 完整事件系统示例
656
-
657
- 以下是一个完整的示例,展示如何使用事件系统进行缓存操作的全面监控、日志记录和访问控制:
362
+ ## 使用示例
658
363
 
364
+ ### 基本缓存操作
659
365
  ```javascript
660
- const CacheBase = require('./index.js');
366
+ const cache = new CacheBase();
661
367
 
662
- async function eventSystemExample() {
663
- const cache = new CacheBase();
664
-
665
- // 1. 实现统一的操作日志记录
666
- const operations = ['get', 'set', 'del', 'exists', 'hget', 'hset',
667
- 'lpush', 'lpop', 'rpush', 'rpop', 'sadd', 'srem',
668
- 'smembers', 'zadd', 'zrange'];
669
-
670
- // 为所有操作添加日志记录
671
- operations.forEach(op => {
672
- // 记录操作开始
673
- cache.on(`${op}_before`, (data) => {
674
- console.log(`[CACHE] 开始 ${op} 操作`, {
675
- key: data.key,
676
- value: data.value,
677
- timestamp: new Date().toISOString()
678
- });
679
- });
680
-
681
- // 记录操作成功完成
682
- cache.on(`${op}_after`, (data) => {
683
- console.log(`[CACHE] ${op} 操作成功`, {
684
- key: data.key,
685
- result: data.result,
686
- timestamp: new Date().toISOString()
687
- });
688
- });
689
-
690
- // 记录操作失败
691
- cache.on(`${op}_error`, (data) => {
692
- console.error(`[CACHE] ${op} 操作失败`, {
693
- key: data.key,
694
- error: data.error.message,
695
- timestamp: new Date().toISOString()
696
- });
697
- });
698
- });
699
-
700
- // 2. 实现缓存操作统计
701
- const stats = {
702
- totalOperations: 0,
703
- successfulOperations: 0,
704
- failedOperations: 0,
705
- canceledOperations: 0,
706
- operationTypes: {}
707
- };
708
-
709
- // 更新统计信息
710
- operations.forEach(op => {
711
- cache.on(`${op}_before`, () => {
712
- stats.totalOperations++;
713
- stats.operationTypes[op] = (stats.operationTypes[op] || 0) + 1;
714
- });
715
-
716
- cache.on(`${op}_after`, (data) => {
717
- if (op === 'get' && data.result === null) {
718
- // 可以特殊处理缓存未命中的情况
719
- console.log(`[CACHE] 缓存未命中: ${data.key}`);
720
- }
721
- stats.successfulOperations++;
722
- });
723
-
724
- cache.on(`${op}_error`, () => {
725
- stats.failedOperations++;
726
- });
727
- });
728
-
729
- // 3. 实现复杂的访问控制
730
- const accessControl = {
731
- // 定义哪些用户角色可以访问哪些键模式
732
- permissions: {
733
- 'admin': ['*'],
734
- 'user': ['user:*', 'public:*'],
735
- 'guest': ['public:*']
736
- },
737
-
738
- // 当前用户角色
739
- currentRole: 'user'
740
- };
741
-
742
- // 为敏感操作添加访问控制
743
- ['get', 'del', 'hget', 'hdel'].forEach(op => {
744
- cache.on(`${op}_before`, (data) => {
745
- const hasPermission = accessControl.permissions[accessControl.currentRole].some(pattern => {
746
- // 简单的通配符匹配实现
747
- if (pattern === '*') return true;
748
- const regexPattern = pattern.replace(/\*/g, '.*');
749
- const regex = new RegExp(`^${regexPattern}$`);
750
- return regex.test(data.key);
751
- });
752
-
753
- if (!hasPermission) {
754
- console.warn(`[SECURITY] 拒绝访问: 用户 ${accessControl.currentRole} 尝试访问键 ${data.key}`);
755
- data.cancel = true;
756
- stats.canceledOperations++;
757
- }
758
- });
759
- });
760
-
761
- // 4. 执行一些测试操作
762
- console.log('执行测试操作...');
763
-
764
- // 应该成功的操作
765
- await cache.set('user:123:name', '张三');
766
- await cache.hset('user:123:profile', 'email', 'zhangsan@example.com');
767
- await cache.sadd('user:123:tags', 'vip');
768
-
769
- // 尝试访问无权限的键
770
- const restrictedData = await cache.get('admin:settings');
771
- console.log('受限访问结果:', restrictedData); // 应该是 null
368
+ async function example() {
369
+ // 设置缓存
370
+ await cache.set("user", "张三", 60); // 60秒后过期
772
371
 
773
- // 正常访问有权限的键
774
- const userName = await cache.get('user:123:name');
775
- console.log('用户名:', userName);
372
+ // 获取缓存
373
+ const user = await cache.get("user");
374
+ console.log(user); // 输出: 张三
776
375
 
777
- // 5. 显示操作统计
778
- console.log('\n操作统计:');
779
- console.log(stats);
376
+ // 检查是否存在
377
+ const exists = await cache.exists("user");
378
+ console.log(exists); // 输出: 1
780
379
 
781
- // 6. 清理资源
782
- await cache.dispose();
380
+ // 删除缓存
381
+ await cache.del("user");
783
382
  }
784
-
785
- // 运行示例
786
- eventSystemExample().catch(console.error);
787
383
  ```
788
384
 
789
- ### 事件参数格式示例
790
-
791
- #### 基本操作事件数据
385
+ ### 哈希表操作示例
792
386
  ```javascript
793
- // set_before 事件数据
794
- {
795
- key: 'test_key',
796
- value: 'test_value',
797
- cancel: false
798
- }
799
-
800
- // set_after 事件数据
801
- {
802
- key: 'test_key',
803
- value: 'test_value',
804
- result: 1
805
- }
806
-
807
- // get_before 事件数据
808
- {
809
- key: 'test_key',
810
- cancel: false
811
- }
812
-
813
- // get_after 事件数据
814
- {
815
- key: 'test_key',
816
- result: 'test_value'
817
- }
818
-
819
- // exists_before 事件数据
820
- {
821
- key: 'test_key',
822
- cancel: false
823
- }
824
-
825
- // exists_after 事件数据
826
- {
827
- key: 'test_key',
828
- result: 1 // 1表示存在,0表示不存在
829
- }
830
-
831
- // dispose_before 事件数据
832
- {
833
- cancel: false
387
+ async function hashExample() {
388
+ // 设置哈希表字段
389
+ await cache.hset("user:123", "name", "张三");
390
+ await cache.hset("user:123", "age", 30);
391
+ await cache.hset("user:123", "email", "zhangsan@example.com");
392
+
393
+ // 获取哈希表字段
394
+ const name = await cache.hget("user:123", "name");
395
+ console.log(name); // 输出: 张三
396
+
397
+ // 获取所有字段和值
398
+ const user = await cache.hgetall("user:123");
399
+ console.log(user); // 输出: { name: "张三", age: 30, email: "zhangsan@example.com" }
400
+
401
+ // 删除字段
402
+ await cache.hdel("user:123", "email");
834
403
  }
835
-
836
- // dispose_after 事件无参数
837
404
  ```
838
405
 
839
- #### 复合操作事件数据
406
+ ### 数值操作示例
840
407
  ```javascript
841
- // hset_before 事件数据
842
- {
843
- key: 'hash_key',
844
- value: { field: 'field1', value: 'value1' },
845
- cancel: false
846
- }
847
-
848
- // hget_before 事件数据
849
- {
850
- key: 'hash_key',
851
- value: { field: 'field1' },
852
- cancel: false
853
- }
854
-
855
- // lpush_before 事件数据
856
- {
857
- key: 'list_key',
858
- value: { values: ['item1', 'item2'] },
859
- cancel: false
860
- }
861
-
862
- // lpop_before/lpop_after 事件数据
863
- {
864
- key: 'list_key',
865
- cancel: false // lpop_after 中包含 result
866
- }
867
-
868
- // rpop_before/rpop_after 事件数据
869
- {
870
- key: 'list_key',
871
- cancel: false // rpop_after 中包含 result
872
- }
873
-
874
- // llen_before/llen_after 事件数据
875
- {
876
- key: 'list_key',
877
- cancel: false // llen_after 中包含 result
878
- }
879
-
880
- // srem_before 事件数据
881
- {
882
- key: 'set_key',
883
- value: { member: 'member1' },
884
- cancel: false
885
- }
886
-
887
- // smembers_before/smembers_after 事件数据
888
- {
889
- key: 'set_key',
890
- cancel: false // smembers_after 中包含 result 数组
891
- }
892
-
893
- // sismember_before 事件数据
894
- {
895
- key: 'set_key',
896
- value: { member: 'member1' },
897
- cancel: false
898
- }
899
-
900
- // scard_before/scard_after 事件数据
901
- {
902
- key: 'set_key',
903
- cancel: false // scard_after 中包含 result
904
- }
905
-
906
- // zrange_before 事件数据
907
- {
908
- key: 'zset_key',
909
- value: { start: 0, stop: -1, withScores: false },
910
- cancel: false
911
- }
912
-
913
- // zrem_before 事件数据
914
- {
915
- key: 'zset_key',
916
- value: { member: 'zmember1' },
917
- cancel: false
918
- }
919
-
920
- // zscore_before 事件数据
921
- {
922
- key: 'zset_key',
923
- value: { member: 'zmember1' },
924
- cancel: false
408
+ async function numberExample() {
409
+ // 设置初始值
410
+ await cache.set("counter", 10);
411
+
412
+ // 增加1
413
+ const incr = await cache.incr("counter");
414
+ console.log("增加后:", incr); // 输出: 11
415
+
416
+ // 增加指定值
417
+ const incrby = await cache.incrby("counter", 5);
418
+ console.log("增加5后:", incrby); // 输出: 16
419
+
420
+ // 减少1
421
+ const decr = await cache.decr("counter");
422
+ console.log("减少后:", decr); // 输出: 15
423
+
424
+ // 浮点数操作
425
+ await cache.set("price", 99.99);
426
+ const incrFloat = await cache.incrbyfloat("price", 0.01);
427
+ console.log("浮点数增加后:", incrFloat); // 输出: 100
925
428
  }
429
+ ```
926
430
 
927
- #### 过期时间操作事件数据
431
+ ### 批量操作示例
928
432
  ```javascript
929
- // setex_before 事件数据
930
- {
931
- key: 'setex_key',
932
- value: 'setex_value',
933
- ttl: 60,
934
- cancel: false
433
+ async function batchExample() {
434
+ // 批量设置
435
+ await cache.mset(["key1", "key2", "key3"], ["value1", "value2", "value3"]);
436
+
437
+ // 批量获取
438
+ const values = await cache.mget("key1", "key2", "key3");
439
+ console.log("批量获取:", values); // 输出: ["value1", "value2", "value3"]
440
+
441
+ // 检查多个键是否存在
442
+ const existsCount = await cache.exists("key1", "key2", "nonexistent");
443
+ console.log("存在的键数量:", existsCount); // 输出: 2
444
+
445
+ // 获取键数量
446
+ const count = await cache.dbsize();
447
+ console.log("键总数:", count);
448
+
449
+ // 清空所有缓存
450
+ await cache.flushdb();
935
451
  }
936
452
  ```
937
453
 
@@ -939,10 +455,10 @@ eventSystemExample().catch(console.error);
939
455
 
940
456
  1. 所有操作方法都是异步的,需要使用async/await或Promise处理
941
457
  2. 过期时间单位为秒,-1表示永不过期
942
- 3. 数组操作方法只能用于数组类型的缓存值
943
- 4. 键名支持*通配符匹配,可用于批量操作
944
- 5. 缓存数据存储在内存中,重启后数据会丢失
945
- 6. 事件回调函数中的 `cancel` 标志只在前置事件中有效,后置事件中修改不会产生效果
946
- 7. 当List、Set或Sorted Set类型的缓存变为空时,对应的键会被自动删除
947
- 8. 所有事件参数都遵循统一的格式,包含key、value、result、error和cancel等字段
948
- 9. 错误日志都添加了`[cachebase]`前缀,便于日志识别和过滤
458
+ 3. 缓存数据存储在内存中,重启后数据会丢失
459
+ 4. 事件回调函数中的 `cancel` 标志只在前置事件中有效,后置事件中修改不会产生效果
460
+ 5. 所有事件参数都遵循统一的格式,包含key、value、result、error和cancel等字段
461
+
462
+ ## 许可证
463
+
464
+ MIT