-
Notifications
You must be signed in to change notification settings - Fork 18
Description
Pull Request Overview
补充并完善 mock Redis 客户端缺失的常用命令,实现与真实 Redis API 更高的兼容性,并修复过期管理方法错误仅限 HyperLogLog 的问题。
新增字符串、过期控制、键管理、数值操作等 18 个常用方法
修复 pExpire/pTTL/pExpireAt 仅适用于 HyperLogLog 的错误实现
增强键重命名与过期处理、随机键、数据库统计等辅助能力
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
packages/core/src/core/db/redis/mock/index.ts
评论行 +326 到 +331
async setNX (key: string, value: string | Buffer): Promise {
if (this.store[key] && !this.checkExpire(key)) {
return false
}
await this.set(key, value, { NX: true })
return true
https://github.com/apps/copilot-pull-request-reviewer AI
1分钟前
The return type deviates from Redis semantics; SETNX returns an integer reply (1 if a key was set, 0 otherwise) rather than a boolean. To maintain API compatibility, change the return type to Promise and return 1/0.
Suggested change
async setNX (key: string, value: string | Buffer): Promise {
if (this.store[key] && !this.checkExpire(key)) {
return false
}
await this.set(key, value, { NX: true })
return true
async setNX (key: string, value: string | Buffer): Promise {
if (this.store[key] && !this.checkExpire(key)) {
return 0
}
await this.set(key, value, { NX: true })
return 1
Copilot 使用 AI。请检查错误。
@sj817 回复...
packages/core/src/core/db/redis/mock/index.ts
评论行 +511 到 +553
async rename (key: string, newKey: string): Promise {
if (!this.store[key]) throw new Error('no such key')
// 获取原键的数据
const { type, expire } = this.store[key]
const value = this.getValueStringByKey(key)
// 删除旧键
this.#del(key)
// 创建新键
this.store[newKey] = { type, expire }
// 根据类型设置值
switch (type) {
case Key.STR:
this.#str[newKey] = value
break
case Key.NUM:
this.#num[newKey] = Number(value)
break
case Key.HASH:
this.#hash[newKey] = JSON.parse(value)
break
case Key.LIST:
this.#list[newKey] = JSON.parse(value)
break
case Key.SET:
this.#set[newKey] = new Set(JSON.parse(value))
break
case Key.ZSET:
this.#zset[newKey] = JSON.parse(value)
break
case Key.PF:
this.#pf[newKey] = new Set(JSON.parse(value))
break
case Key.BIT:
this.#bit[newKey] = Buffer.from(value, 'base64')
break
}
this.#sqlite.set(newKey, value, type, expire)
return 'OK'
https://github.com/apps/copilot-pull-request-reviewer AI
1分钟前
When newKey already exists, Redis RENAME overwrites the destination, but this implementation does not remove existing type-specific data for newKey before assignment, potentially leaving orphaned data (e.g., stale this.#hash[newKey]). Add a pre-step to delete newKey (if different from key) via this.#del(newKey) to avoid inconsistent internal state, and optionally guard key === newKey to mimic Redis error semantics.
Copilot 使用 AI。请检查错误。
@sj817 回复...
packages/core/src/core/db/redis/mock/index.ts
评论行 +561 到 +567
async renameNX (key: string, newKey: string): Promise {
if (!this.store[key]) return 0
if (this.store[newKey] && !this.checkExpire(newKey)) return 0
await this.rename(key, newKey)
return 1
}
https://github.com/apps/copilot-pull-request-reviewer AI
1分钟前
renameNX should fail (return 0) if key === newKey per Redis semantics (identical source/destination not allowed), but current logic delegates to rename and returns 1. Add an early check if (key === newKey) return 0 (or throw) for fidelity.
Copilot 使用 AI。请检查错误。
@sj817 回复...
packages/core/src/core/db/redis/mock/index.ts
评论行 +674 到 +685
async incrByFloat (key: string, increment: number): Promise {
if (!this.#num[key]) {
this.#num[key] = 0
this.store[key] = { type: Key.NUM, expire: -1 }
} else if (this.checkExpire(key, false)) {
this.store[key].expire = -1
this.#num[key] = 0
}
this.#num[key] += increment
this.#sqlite.set(key, String(this.#num[key]), Key.NUM, this.store[key].expire)
return this.#num[key]
https://github.com/apps/copilot-pull-request-reviewer AI
1分钟前
INCRBYFLOAT in Redis returns the new value as a bulk string; returning a number here introduces an incompatibility for consumers expecting string output. Consider returning String(this.#num[key]) (and adjusting the return type) to align with Redis behavior.