1 Star 0 Fork 0

igo/pkg

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
key_prefix.go 8.01 KB
一键复制 编辑 原始数据 按行查看 历史
layte.xiao 提交于 2023-02-24 15:02 . redis支持keyPrefix2
package hooks
import (
"context"
"github.com/redis/go-redis/v9"
"github.com/spf13/cast"
"log"
"net"
"strings"
)
type keyPrefix struct {
prefix string
}
// NewKeyPrefix
// 不支持 migrate
// 不支持Redis Stream
func NewKeyPrefix(prefix string) *keyPrefix {
return &keyPrefix{
prefix: prefix,
}
}
func (k *keyPrefix) DialHook(next redis.DialHook) redis.DialHook {
return func(ctx context.Context, network, addr string) (net.Conn, error) {
return next(ctx, network, addr)
}
}
func (k *keyPrefix) ProcessHook(next redis.ProcessHook) redis.ProcessHook {
return func(ctx context.Context, cmd redis.Cmder) error {
log.Println("old", cmd.Args())
newArgs := k.formatArgs(cmd.Args())
log.Println("new", newArgs)
newCmd := redis.NewCmd(ctx, newArgs...)
return next(ctx, newCmd)
}
}
func (k *keyPrefix) ProcessPipelineHook(next redis.ProcessPipelineHook) redis.ProcessPipelineHook {
return func(ctx context.Context, cmds []redis.Cmder) error {
newCmds := make([]redis.Cmder, 0)
for _, cmd := range cmds {
newArgs := k.formatArgs(cmd.Args())
newCmds = append(newCmds, redis.NewCmd(ctx, newArgs...))
}
return next(ctx, newCmds)
}
}
func (k *keyPrefix) formatArgs(args []any) []any {
if len(args) < 2 {
return args
}
cmd := strings.ToLower(cast.ToString(args[0]))
cmds := k.keyCmd()
val, ok := cmds[cmd]
if !ok {
return args
}
switch cmd {
case "object":
args[2] = k.formatKey(cast.ToString(args[2]))
case "rename", "renamenx", "copy", "brpoplpush", "rpoplpush", "lmove", "blmove", "smove", "zrangestore", "geosearchstore":
args[1] = k.formatKey(cast.ToString(args[1]))
args[2] = k.formatKey(cast.ToString(args[2]))
case "mset", "msetnx":
for i := range args {
if i%2 != 1 {
continue
}
args[i] = k.formatKey(cast.ToString(args[i]))
}
case "bitop", "sintercard", "zintercard", "zdiff":
for i := range args {
if i < 2 {
continue
}
if cast.ToString(args[i]) == "limit" {
break
}
args[i] = k.formatKey(cast.ToString(args[i]))
}
case "blpop", "brpop", "bzpopmin", "bzpopmax":
for i := range args {
if i == len(args)-1 {
continue
}
args[i] = k.formatKey(cast.ToString(args[i]))
}
case "zinterstore", "zinter", "zunion", "zunionstore":
for i := range args {
v := cast.ToString(args[i])
if v == "weights" || v == "aggregate" || v == "withscores" {
break
}
args[i] = k.formatKey(v)
}
case "zdiffstore":
args[1] = k.formatKey(cast.ToString(args[1]))
for i := range args {
if i < 3 {
continue
}
args[i] = k.formatKey(cast.ToString(args[i]))
}
default:
if val == 0 {
args[1] = k.formatKey(cast.ToString(args[1]))
}
if val == 1 {
for i := range args {
if i == 0 {
continue
}
args[i] = k.formatKey(cast.ToString(args[i]))
}
}
}
return args
}
func (k *keyPrefix) formatKey(key string) string {
if strings.HasPrefix(key, k.prefix) {
return key
}
return k.prefix + key
}
func (k *keyPrefix) keyCmd() map[string]any {
return map[string]any{
"del": 1,
"unlink": 1,
"dump": 0,
"exists": 1,
"expire": 0,
"expireat": 0,
"move": 0,
"object": 0, // object key下标为2
"persist": 0,
"pexpire": 0,
"pexpireat": 0,
"pttl": 0,
"rename": 1, // oldkey 与 newkey都要加前缀
"renamenx": 1, // oldkey 与 newkey都要加前缀
"restore": 0,
"sort_ro": 0,
"sort": 0,
"touch": 1,
"ttl": 0,
"type": 0,
"append": 0,
"decr": 0,
"decrby": 0,
"get": 0,
"getrange": 0,
"getset": 0,
"getex": 0,
"getdel": 0,
"incr": 0,
"incrby": 0,
"incrbyfloat": 0,
"mget": 1,
"mset": 0, // 多个key,需特殊处理
"msetnx": 0, // 同mset
"set": 0,
"setex": 0,
"setnx": 0,
"setrange": 0,
"strlen": 0,
"copy": 0, // sourceKey, destKey,需特殊处理
"getbit": 0,
"setbit": 0,
"bitcount": 0,
"bitop": 0, // 需特殊处理,key下标为2
"bitpos": 0,
"bitfield": 0,
"sscan": 0,
"hscan": 0,
"zscan": 0,
"hdel": 0,
"hexists": 0,
"hget": 0,
"hgetall": 0,
"hincrby": 0,
"hincrbyfloat": 0,
"hkeys": 0,
"hlen": 0,
"hmget": 0,
"hset": 0,
"hmset": 0,
"hsetnx": 0,
"hvals": 0,
"hrandfield": 0,
"blpop": 1, // 多个key,但最后一个元素非key,需特殊处理
"brpop": 1, // 多个key,但最后一个元素非key,需特殊处理
"brpoplpush": 0, // 两个key,需特殊处理
"lindex": 0,
"linsert": 0,
"llen": 0,
"lpop": 0,
"lpos": 0,
"lpush": 0,
"lpushx": 0,
"lrange": 0,
"lrem": 0,
"lset": 0,
"ltrim": 0,
"rpop": 0,
"rpoplpush": 0, // 两个key,需特殊处理
"rpush": 0,
"rpushx": 0,
"lmove": 0, // 两个key,需特殊处理
"blmove": 0, // 两个key,需特殊处理
"sadd": 0,
"scard": 0,
"sdiff": 1,
"sdiffstore": 1,
"sinter": 1,
"sintercard": 0, // 需特殊处理,key下标为2, 至limit止
"sinterstore": 0,
"sismember": 0,
"smismember": 0,
"smove": 0, // 两个key,需特殊处理
"spop": 0,
"srandmember": 0,
"srem": 0,
"sunion": 1,
"sunionstore": 1,
"bzpopmax": 1, // 多个key,但最后一个元素非key,需特殊处理
"bzpopmin": 1, // 多个key,但最后一个元素非key,需特殊处理
"zadd": 0,
"zcard": 0,
"zcount": 0,
"zlexcount": 0,
"zincrby": 0,
"zinterstore": 0, // 多个key, 至weights或aggregate止
"zinter": 0, // 多个key, 至weights或aggregate止
"zintercard": 0, // 需特殊处理,key下标为2, 至limit止
"zmscore": 0,
"zpopmax": 0,
"zpopmin": 0,
"zrange": 0,
"zrangebyscore": 0,
"zrangebylex": 0,
"zrangestore": 0, // 两个key,需特殊处理
"zrank": 0,
"zrem": 0,
"zremrangebyrank": 0,
"zremrangebyscore": 0,
"zremrangebylex": 0,
"zrevrange": 0,
"zrevrangebyscore": 0,
"zrevrangebylex": 0,
"zrevrank": 0,
"zscore": 0,
"zunion": 0, // 多个key, 至weights或aggregate止
"zunionstore": 0, // 多个key, 至weights或aggregate止
"zrandmember": 0,
"zdiff": 1, // 需特殊处理,key下标为2,withscores止
"zdiffstore": 0, // 需特殊处理,多个key
"pfadd": 0,
"pfcount": 1,
"pfmerge": 1,
"geoadd": 0,
"georadius_ro": 0,
"georadius": 0,
"georadiusbymember_ro": 0,
"georadiusbymember": 0,
"geosearch": 0,
"geosearchstore": 0, // 两个key,需特殊处理
"geodist": 0,
"geohash": 0,
"geopos": 0,
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/igolang/pkg.git
git@gitee.com:igolang/pkg.git
igolang
pkg
pkg
v1.20.7

搜索帮助