更新 target/redis/conn.lua

This commit is contained in:
2026-01-02 11:08:55 +08:00
parent 50bba5fdf0
commit c452107755

View File

@@ -1,24 +1,513 @@
-- redis_conn.lua
local redis_conn = {}
redis_conn.__index = redis_conn
--[[
创建一个新的 fw_redis_conn 对象
@return 返回一个新的 fw_redis_conn 对象
]]
function redis_conn.new(__module)
local instance = setmetatable({}, redis_conn)
instance.module = __module
return instance
end
--[[
执行 Redis 命令
@param cmd Redis 命令字符串
@return 返回命令执行结果
]]
function redis_conn:command(cmd)
return self.module:command(cmd)
end
return redis_conn
-- redis_conn.lua
local redis_conn = {}
redis_conn.__index = redis_conn
--[[
转义 Redis 参数,处理包含空格等特殊字符的值
@param value 要转义的值
@return 返回转义后的字符串
]]
local function escape_value(value)
if value == nil then
return ""
end
-- 将值转换为字符串
local str = tostring(value)
-- 如果包含空格、引号或特殊字符,使用双引号包裹并转义内部引号
if string.find(str, "[%s\"'\\]") then
-- 转义反斜杠和双引号
str = string.gsub(str, "\\", "\\\\")
str = string.gsub(str, "\"", "\\\"")
return "\"" .. str .. "\""
end
return str
end
--[[
还原 Redis 字符串(去转义)
@param value 被转义的字符串
@return 返回还原后的字符串
]]
local function unescape_value(value)
if value == nil then
return nil
end
local str = tostring(value)
-- 如果是用双引号包住的,去掉包裹并恢复转义
if #str >= 2 and string.sub(str,1,1) == "\"" and string.sub(str,-1,-1) == "\"" then
str = string.sub(str,2,-2)
str = string.gsub(str, "\\\"", "\"")
str = string.gsub(str, "\\\\", "\\")
return str
end
return str
end
--[[
对数组进行去转义处理
@param arr 数组
@return 返回去转义后的数组
]]
local function unescape_array(arr)
if arr == nil or type(arr) ~= "table" then
return arr
end
local result = {}
for i, v in ipairs(arr) do
result[i] = unescape_value(v)
end
return result
end
--[[
构建 Redis 命令字符串
@param cmd 命令名称
@param ... 命令参数
@return 返回构建好的命令字符串
]]
local function build_command(cmd, ...)
local args = {...}
local parts = {cmd}
for i, arg in ipairs(args) do
if arg ~= nil then
table.insert(parts, escape_value(arg))
end
end
return table.concat(parts, " ")
end
--[[
创建一个新的 fw_redis_conn 对象
@return 返回一个新的 fw_redis_conn 对象
]]
function redis_conn.new(__module)
local instance = setmetatable({}, redis_conn)
instance.module = __module
return instance
end
--[[
执行 Redis 命令
@param cmd Redis 命令字符串
@return 返回命令执行结果
]]
function redis_conn:command(cmd)
return self.module:command(cmd)
end
-- ==================== String 操作 ====================
--[[
GET 命令:获取键的值
@param key 键名
@return 返回键的值,不存在返回 nil
]]
function redis_conn:get(key)
local result = self:command(build_command("GET", key))
return unescape_value(result)
end
--[[
SET 命令:设置键值对
@param key 键名
@param value 值(可以是字符串、数字等,会自动处理空格)
@param options 可选参数,如 "EX seconds" 或 "PX milliseconds" 或 "NX" 或 "XX"
@return 返回执行结果
]]
function redis_conn:set(key, value, options)
local cmd = build_command("SET", key, value)
if options then
cmd = cmd .. " " .. options
end
return self:command(cmd)
end
--[[
SETEX 命令:设置键值对并设置过期时间(秒)
@param key 键名
@param seconds 过期时间(秒)
@param value 值
@return 返回执行结果
]]
function redis_conn:setex(key, seconds, value)
return self:command(build_command("SETEX", key, seconds, value))
end
--[[
SETNX 命令:当键不存在时设置键值对
@param key 键名
@param value 值
@return 返回 1 表示设置成功0 表示键已存在
]]
function redis_conn:setnx(key, value)
return self:command(build_command("SETNX", key, value))
end
--[[
DEL 命令:删除一个或多个键
@param ... 键名列表
@return 返回删除的键数量
]]
function redis_conn:del(...)
return self:command(build_command("DEL", ...))
end
--[[
EXISTS 命令:检查键是否存在
@param key 键名
@return 返回 1 表示存在0 表示不存在
]]
function redis_conn:exists(key)
return self:command(build_command("EXISTS", key))
end
--[[
KEYS 命令:查找所有匹配给定模式的键
@param pattern 匹配模式,支持通配符:* 匹配任意字符,? 匹配单个字符,[] 匹配指定字符
@return 返回匹配的键数组
注意:在生产环境中应谨慎使用,建议使用 SCAN 命令替代
]]
function redis_conn:keys(pattern)
local result = self:command(build_command("KEYS", pattern))
return unescape_array(result)
end
--[[
EXPIRE 命令:设置键的过期时间(秒)
@param key 键名
@param seconds 过期时间(秒)
@return 返回 1 表示设置成功0 表示键不存在或设置失败
]]
function redis_conn:expire(key, seconds)
return self:command(build_command("EXPIRE", key, seconds))
end
--[[
TTL 命令:获取键的剩余过期时间(秒)
@param key 键名
@return 返回剩余秒数,-1 表示永不过期,-2 表示键不存在
]]
function redis_conn:ttl(key)
return self:command(build_command("TTL", key))
end
--[[
INCR 命令:将键的值加 1
@param key 键名
@return 返回增加后的值
]]
function redis_conn:incr(key)
return self:command(build_command("INCR", key))
end
--[[
DECR 命令:将键的值减 1
@param key 键名
@return 返回减少后的值
]]
function redis_conn:decr(key)
return self:command(build_command("DECR", key))
end
--[[
INCRBY 命令:将键的值增加指定数值
@param key 键名
@param increment 增量
@return 返回增加后的值
]]
function redis_conn:incrby(key, increment)
return self:command(build_command("INCRBY", key, increment))
end
--[[
DECRBY 命令:将键的值减少指定数值
@param key 键名
@param decrement 减量
@return 返回减少后的值
]]
function redis_conn:decrby(key, decrement)
return self:command(build_command("DECRBY", key, decrement))
end
-- ==================== Hash 操作 ====================
--[[
HGET 命令:获取哈希表中字段的值
@param key 键名
@param field 字段名
@return 返回字段的值,不存在返回 nil
]]
function redis_conn:hget(key, field)
local result = self:command(build_command("HGET", key, field))
return unescape_value(result)
end
--[[
HSET 命令:设置哈希表中字段的值
@param key 键名
@param field 字段名
@param value 值
@return 返回 1 表示新建字段0 表示更新字段
]]
function redis_conn:hset(key, field, value)
return self:command(build_command("HSET", key, field, value))
end
--[[
HDEL 命令:删除哈希表中的一个或多个字段
@param key 键名
@param ... 字段名列表
@return 返回删除的字段数量
]]
function redis_conn:hdel(key, ...)
return self:command(build_command("HDEL", key, ...))
end
--[[
HEXISTS 命令:检查哈希表中字段是否存在
@param key 键名
@param field 字段名
@return 返回 1 表示存在0 表示不存在
]]
function redis_conn:hexists(key, field)
return self:command(build_command("HEXISTS", key, field))
end
--[[
HGETALL 命令:获取哈希表中所有字段和值
@param key 键名
@return 返回字段和值的数组
]]
function redis_conn:hgetall(key)
local result = self:command(build_command("HGETALL", key))
return unescape_array(result)
end
--[[
HKEYS 命令:获取哈希表中所有字段名
@param key 键名
@return 返回字段名数组
]]
function redis_conn:hkeys(key)
local result = self:command(build_command("HKEYS", key))
return unescape_array(result)
end
--[[
HVALS 命令:获取哈希表中所有值
@param key 键名
@return 返回值数组
]]
function redis_conn:hvals(key)
local result = self:command(build_command("HVALS", key))
return unescape_array(result)
end
--[[
HLEN 命令:获取哈希表中字段数量
@param key 键名
@return 返回字段数量
]]
function redis_conn:hlen(key)
return self:command(build_command("HLEN", key))
end
-- ==================== List 操作 ====================
--[[
LPUSH 命令:从列表左端插入一个或多个值
@param key 键名
@param ... 值列表
@return 返回插入后列表的长度
]]
function redis_conn:lpush(key, ...)
return self:command(build_command("LPUSH", key, ...))
end
--[[
RPUSH 命令:从列表右端插入一个或多个值
@param key 键名
@param ... 值列表
@return 返回插入后列表的长度
]]
function redis_conn:rpush(key, ...)
return self:command(build_command("RPUSH", key, ...))
end
--[[
LPOP 命令:从列表左端弹出一个值
@param key 键名
@return 返回弹出的值,列表为空返回 nil
]]
function redis_conn:lpop(key)
local result = self:command(build_command("LPOP", key))
return unescape_value(result)
end
--[[
RPOP 命令:从列表右端弹出一个值
@param key 键名
@return 返回弹出的值,列表为空返回 nil
]]
function redis_conn:rpop(key)
local result = self:command(build_command("RPOP", key))
return unescape_value(result)
end
--[[
LLEN 命令:获取列表长度
@param key 键名
@return 返回列表长度
]]
function redis_conn:llen(key)
return self:command(build_command("LLEN", key))
end
--[[
LRANGE 命令:获取列表指定范围内的元素
@param key 键名
@param start 起始索引(从 0 开始)
@param stop 结束索引(-1 表示最后一个元素)
@return 返回元素数组
]]
function redis_conn:lrange(key, start, stop)
local result = self:command(build_command("LRANGE", key, start, stop))
return unescape_array(result)
end
-- ==================== Set 操作 ====================
--[[
SADD 命令:向集合添加一个或多个成员
@param key 键名
@param ... 成员列表
@return 返回添加的成员数量
]]
function redis_conn:sadd(key, ...)
return self:command(build_command("SADD", key, ...))
end
--[[
SREM 命令:从集合移除一个或多个成员
@param key 键名
@param ... 成员列表
@return 返回移除的成员数量
]]
function redis_conn:srem(key, ...)
return self:command(build_command("SREM", key, ...))
end
--[[
SMEMBERS 命令:获取集合所有成员
@param key 键名
@return 返回成员数组
]]
function redis_conn:smembers(key)
local result = self:command(build_command("SMEMBERS", key))
return unescape_array(result)
end
--[[
SISMEMBER 命令:检查成员是否在集合中
@param key 键名
@param member 成员
@return 返回 1 表示存在0 表示不存在
]]
function redis_conn:sismember(key, member)
return self:command(build_command("SISMEMBER", key, member))
end
--[[
SCARD 命令:获取集合成员数量
@param key 键名
@return 返回成员数量
]]
function redis_conn:scard(key)
return self:command(build_command("SCARD", key))
end
-- ==================== Sorted Set 操作 ====================
--[[
ZADD 命令:向有序集合添加一个或多个成员
@param key 键名
@param score 分数
@param member 成员
@param ... 可选的更多 score-member 对
@return 返回添加的成员数量
]]
function redis_conn:zadd(key, score, member, ...)
local args = {key, score, member, ...}
return self:command(build_command("ZADD", table.unpack(args)))
end
--[[
ZRANGE 命令:获取有序集合指定范围内的成员
@param key 键名
@param start 起始索引
@param stop 结束索引
@param withscores 是否包含分数,默认为 false
@return 返回成员数组(如果 withscores 为 true则包含分数
]]
function redis_conn:zrange(key, start, stop, withscores)
local cmd = build_command("ZRANGE", key, start, stop)
if withscores then
cmd = cmd .. " WITHSCORES"
end
local result = self:command(cmd)
if result == nil or type(result) ~= "table" then
return result
end
-- 如果 withscores 为 true结果是 [member1, score1, member2, score2, ...]
-- 只处理成员部分(奇数索引),分数部分保持不变
if withscores then
local unescaped = {}
for i = 1, #result do
if i % 2 == 1 then
-- 成员(奇数索引)
unescaped[i] = unescape_value(result[i])
else
-- 分数(偶数索引)
unescaped[i] = result[i]
end
end
return unescaped
else
return unescape_array(result)
end
end
--[[
ZREM 命令:从有序集合移除一个或多个成员
@param key 键名
@param ... 成员列表
@return 返回移除的成员数量
]]
function redis_conn:zrem(key, ...)
return self:command(build_command("ZREM", key, ...))
end
--[[
ZCARD 命令:获取有序集合成员数量
@param key 键名
@return 返回成员数量
]]
function redis_conn:zcard(key)
return self:command(build_command("ZCARD", key))
end
--[[
ZSCORE 命令:获取有序集合成员的分数
@param key 键名
@param member 成员
@return 返回分数,成员不存在返回 nil
]]
function redis_conn:zscore(key, member)
local result = self:command(build_command("ZSCORE", key, member))
-- 分数通常是数字,但为了统一处理,也进行去转义
if result ~= nil then
return unescape_value(result)
end
return result
end
return redis_conn