更新 target/redis/conn.lua
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user