5 Star 0 Fork 0

Md / gu

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
manager.go 15.57 KB
一键复制 编辑 原始数据 按行查看 历史
liyafei 提交于 2023-02-28 10:44 . redis 增加 zunionstore
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
package goredis
import (
"context"
"errors"
"fmt"
"reflect"
"strconv"
"time"
"gitee.com/MikeDDD/gu/logs"
"github.com/go-redis/redis/v8"
"github.com/golang/protobuf/proto"
)
func Init(addr, password string, db int32) {
logs.Info("start default redis client addr:%v, password:%v, db:%v", addr, password, db)
defaultClient = &redisClienterInstance{
rc: redis.NewClient(&redis.Options{
Addr: addr,
Password: password,
DB: int(db),
}),
context: context.Background(),
}
}
// 获取slice、map、ptr里结构体最终类型
func getStructType(p any) reflect.Type {
reflectType := reflect.ValueOf(p).Type()
for reflectType.Kind() == reflect.Slice || reflectType.Kind() == reflect.Map || reflectType.Kind() == reflect.Ptr {
reflectType = reflectType.Elem()
}
return reflectType
}
var defaultClient *redisClienterInstance
type redisClienterInstance struct {
rc *redis.Client
context context.Context
}
func (r *redisClienterInstance) ctx() context.Context {
return r.context
}
// EXPIRE 为key设置过期时间, key:键 timestamp:过期时间(秒)
func Expire(key any, t time.Duration) (err error) {
cmd := defaultClient.rc.Expire(defaultClient.ctx(), fmt.Sprintf("%v", key), t)
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis DoExpire error! key=%v, err=%v", key, cmd.Err())
return cmd.Err()
}
return nil
}
func Persist(key any) (err error) {
cmd := defaultClient.rc.Persist(defaultClient.ctx(), fmt.Sprintf("%v", key))
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis DoPersist error! key=%v, err=%v", key, cmd.Err())
return cmd.Err()
}
return nil
}
func TTL(key any) (s time.Duration, err error) {
cmd := defaultClient.rc.TTL(defaultClient.ctx(), fmt.Sprintf("%v", key))
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis DoTTL error! key=%v, err=%v", key, cmd.Err())
return -1, cmd.Err()
}
return cmd.Val(), nil
}
// DEL 删除键, keys:一个或多个键
func Del(keys ...string) error {
res := defaultClient.rc.Del(defaultClient.ctx(), keys...)
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("Del fail", res.Err())
return res.Err()
}
return nil
}
// EXISTS 判断键是否存在, key:键
func ExistsExt(key any) (bool, error) {
res := defaultClient.rc.Exists(defaultClient.ctx(), fmt.Sprintf("%v", key))
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("Redis Do EXISTS error! key=%v, err=%v", key, res.Err())
return false, res.Err()
}
return res.Val() > 0, nil
}
// SET 扩展, rKey:键 p:protobuf结构引用
func SetExt(key any, p any) (err error) {
bytes, err := proto.Marshal(p.(proto.Message))
//bytes, err := json.Marshal(p)
if err != nil {
logs.Error("Protobuf Marshal error:%v", err)
return err
}
res := defaultClient.rc.Set(defaultClient.ctx(), fmt.Sprintf("%v", key), bytes, time.Hour*2)
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("Redis Do HEXISTS error! key=%v, err=%v", key, res.Err())
return res.Err()
}
return nil
}
func Set(key, value string) error {
if res := defaultClient.rc.Set(defaultClient.ctx(), key, value, time.Second*1); res.Err() != nil &&
!errors.Is(res.Err(), redis.Nil) {
logs.Error("Redis set error! %v", res.Err())
return res.Err()
}
return nil
}
// GET 扩展, key:键 p:protobuf结构引用
func GetExt(key any, p any) (exists bool, err error) {
res := defaultClient.rc.Get(defaultClient.ctx(), fmt.Sprintf("%v", key))
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("Redis Do GetExt error! key=%v, err=%v", key, res.Err())
return false, res.Err()
}
if len(res.Val()) < 1 {
return false, nil
}
err = proto.Unmarshal([]byte(res.Val()), p.(proto.Message))
if err != nil {
logs.Error("Redis Do GET Protobuf Unmarshal error! key=%v, err=%v", key, err)
return false, err
}
return true, nil
}
func HGet(key any, field any) string {
res := defaultClient.rc.HGet(defaultClient.ctx(), fmt.Sprintf("%v", key), fmt.Sprintf("%v", field))
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("HGet fail", res.Err())
return ""
}
return res.Val()
}
// HGET 扩展, key:键 field:域 p:protobuf结构引用
func HGetExt(key any, field any, p any) (exists bool, ok bool) {
res := defaultClient.rc.HGet(defaultClient.ctx(), fmt.Sprintf("%v", key), fmt.Sprintf("%v", field))
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("DoHGetExt fail:", res.Err())
return false, false
}
if len(res.Val()) < 1 {
return false, true
}
err := proto.Unmarshal([]byte(res.Val()), p.(proto.Message))
if err != nil {
logs.Error("Redis Do HGET Protobuf Unmarshal error! key=%v, field=%v, err=%v", key, field, err)
return false, false
}
return true, true
}
func HSet(key any, field any, p any) bool {
_, err := defaultClient.rc.HSet(defaultClient.ctx(), fmt.Sprintf("%v", key), fmt.Sprintf("%v", field), fmt.Sprintf("%v", p)).Result()
if err != nil && !errors.Is(err, redis.Nil) {
logs.Error("HSet fail", err, p)
return false
}
return true
}
// HSET 扩展, key:键 field:域 p:protobuf结构引用
func HSetExt(key any, field any, p any) (err error) {
bytes, err := proto.Marshal(p.(proto.Message))
if err != nil && !errors.Is(err, redis.Nil) {
logs.Error("Redis Do HSET Protobuf Marshal error! key=%v, field=%v, err=%v", key, field, err)
return err
}
res := defaultClient.rc.HSet(defaultClient.ctx(), fmt.Sprintf("%v", key), field, bytes)
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("DoHSetExt fail", res.Err())
return res.Err()
}
return nil
}
// HGET 扩展, key:键 p:protobuf结构引用切片
func HValsExt(key any, p any) (err error) {
res := defaultClient.rc.HVals(defaultClient.ctx(), fmt.Sprintf("%v", key))
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("Del fail", res.Err())
return res.Err()
}
results := reflect.ValueOf(p)
if results.Kind() == reflect.Ptr {
results = results.Elem()
}
for _, v := range res.Val() {
newItem := reflect.New(getStructType(p)).Interface()
err = proto.Unmarshal([]byte(v), newItem.(proto.Message))
if err != nil {
logs.Error("Redis Do HVALS Protobuf Unmarshal error! key=%v, err=%v", key, err)
return
}
results.Set(reflect.Append(results, reflect.ValueOf(newItem)))
}
return nil
}
func HLen(key any) (int64, error) {
res := defaultClient.rc.HLen(defaultClient.ctx(), fmt.Sprintf("%v", key))
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error(res.Err())
return 0, res.Err()
}
return res.Val(), nil
}
// HDEL 删除键, key:键, fields:一个或多个域
func HDel(key string, fields ...string) error {
if len(fields) == 0 {
return nil
}
res := defaultClient.rc.HDel(defaultClient.ctx(), key, fields...)
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("HDel fail", res.Err())
return res.Err()
}
return nil
}
// HEXISTS 判断键中域是否存在, key:键, field:域
func HExistsExt(key any, field any) (bool, error) {
res := defaultClient.rc.HExists(defaultClient.ctx(), fmt.Sprintf("%v", key), fmt.Sprintf("%v", field))
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("Redis Do HEXISTS error! key=%v, err=%v", key, res.Err())
return false, res.Err()
}
return res.Val(), nil
}
// HKEYS, key:键 s:域切片
func HKeys(key any) (field []string, err error) {
res := defaultClient.rc.HKeys(defaultClient.ctx(), fmt.Sprintf("%v", key))
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("Redis Do HKEYS error! key=%v, err=%v", key, res.Err())
return field, res.Err()
}
return res.Val(), nil
}
func HIncrBy(rk, hk string, hv int64) int64 {
res := defaultClient.rc.HIncrBy(defaultClient.ctx(), rk, hk, hv)
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("HIncrBy fail", res.Err())
return -1
}
return res.Val()
}
// ZADD, key:键 params=score,member ...
func ZAdd(key any, score, params int64) (err error) {
arg := &redis.Z{}
arg.Score = float64(score)
arg.Member = params
res := defaultClient.rc.ZAdd(defaultClient.ctx(), fmt.Sprintf("%v", key), arg)
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("ZAdd fail", res.Err())
return res.Err()
}
return nil
}
// ZINCRBY, key:键 params=score,member ...
func ZIncrBy(key any, score, params int64) (err error) {
arg := &redis.Z{}
arg.Score = float64(score)
arg.Member = params
res := defaultClient.rc.ZIncrBy(defaultClient.ctx(), fmt.Sprintf("%v", key), float64(score), strconv.Itoa(int(params)))
if res.Err() != nil && !errors.Is(res.Err(), redis.Nil) {
logs.Error("ZIncr fail", res.Err())
return res.Err()
}
return nil
}
// ZREVRANGE, key:键, membersSlicePrt, scoreSlicePrt 切片指针,start, stop 范围(包含)
func ZRevRangeWithScores(key any, start, stop int64) (err error, membersSlicePrt []int64, scoreSlicePrt []int64) {
cmd := defaultClient.rc.ZRevRangeWithScores(defaultClient.ctx(), fmt.Sprintf("%v", key), start, stop)
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis ZRevRangeWithScores error! key=%v, start=%v, stop=%v, err=%v", key, start, stop, err)
return
}
for _, val := range cmd.Val() {
scoreSlicePrt = append(scoreSlicePrt, int64(val.Score))
vm := val.Member.(string)
value, _ := strconv.ParseInt(vm, 10, 64)
membersSlicePrt = append(membersSlicePrt, value)
}
return
}
func ZRevRange(key string, start, stop int64) (err error, membersSlicePrt []int64) {
cmd := defaultClient.rc.ZRevRange(defaultClient.ctx(), fmt.Sprintf("%v", key), start, stop)
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis ZRevRangeWithScores error! key=%v, start=%v, stop=%v, err=%v", key, start, stop, err)
return
}
for _, val := range cmd.Val() {
value, _ := strconv.ParseInt(val, 10, 64)
membersSlicePrt = append(membersSlicePrt, value)
}
return
}
// ZRANGE, key:键, scoreSlicePrt, membersSlicePrt 切片指针,start, stop 范围(包含)
func ZRangeWithScores(key any, start, stop int64) (err error, membersSlicePrt []int64, scoreSlicePrt []int64) {
cmd := defaultClient.rc.ZRangeWithScores(defaultClient.ctx(), fmt.Sprintf("%v", key), start, stop)
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis ZRangeWithScores error! key=%v, start=%v, stop=%v, err=%v", key, start, stop, err)
return
}
for _, val := range cmd.Val() {
scoreSlicePrt = append(scoreSlicePrt, int64(val.Score))
vm := val.Member.(string)
value, _ := strconv.ParseInt(vm, 10, 64)
membersSlicePrt = append(membersSlicePrt, value)
}
return
}
// ZREM 移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。, key:键, member: 一个或多个成员
func ZRem(key any, member ...any) error {
cmd := defaultClient.rc.ZRem(defaultClient.ctx(), fmt.Sprintf("%v", key), member)
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis DoZRem error! key=%v, err=%v", key, cmd.Err())
return cmd.Err()
}
return nil
}
// ZREVRANK key:键, rank排名 第1名为0, 无排名为-1 (降序)
//
// 有数据 cmd.Err()==nil
//
// 无数据 cmd.Err()==redis.Nil
func ZRevRank(key any, member any) (rank int64, err error) {
cmd := defaultClient.rc.ZRevRank(defaultClient.ctx(), fmt.Sprintf("%v", key), fmt.Sprintf("%v", member))
if cmd.Err() == nil {
return cmd.Val(), nil
}
if errors.Is(cmd.Err(), redis.Nil) {
return -1, nil
}
return 0, cmd.Err()
}
// ZSCORE key:键, 返回有序集 key 中,成员 member 的 score 值。
func ZScore(key any, member any) (score int64, err error) {
cmd := defaultClient.rc.ZScore(defaultClient.ctx(), fmt.Sprintf("%v", key), fmt.Sprintf("%v", member))
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis DoZRevRank error! key=%v, err=%v", key, cmd.Err())
return 0, cmd.Err()
}
return int64(cmd.Val()), err
}
func ZCard(key any) (cnt int64, err error) {
cmd := defaultClient.rc.ZCard(defaultClient.ctx(), fmt.Sprintf("%v", key))
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis DoZRevRank error! key=%v, err=%v", key, cmd.Err())
return 0, cmd.Err()
}
return int64(cmd.Val()), err
}
// ZRANK key:键, rank排名 第1名为0, 无排名为-1 (升序)
func ZRank(key any, member any) (rank int64, err error) {
cmd := defaultClient.rc.ZRank(defaultClient.ctx(), fmt.Sprintf("%v", key), fmt.Sprintf("%v", member))
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis ZRANK error! key=%v, err=%v", key, cmd.Err())
return 0, cmd.Err()
}
return cmd.Val(), err
}
// agg: SUM, MIN, MAX
func ZUnionStore(dest, agg string, weight float64, keys ...string) error {
zs := &redis.ZStore{Aggregate: agg}
for _, k := range keys {
zs.Keys = append(zs.Keys, k)
zs.Weights = append(zs.Weights, weight)
}
cmd := defaultClient.rc.ZUnionStore(defaultClient.ctx(), dest, zs)
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis ZUnionStore error! err=%v", cmd.Err())
return cmd.Err()
}
return nil
}
// LPUSH, key:键, p=protobuf结构引用
func LPushExt(key any, p any) (err error) {
bytes, err := proto.Marshal(p.(proto.Message))
if err != nil {
logs.Error("Redis DoLPush Protobuf Marshal error! key=%v, err=%v", key, err)
return err
}
cmd := defaultClient.rc.LPush(defaultClient.ctx(), fmt.Sprintf("%v", key), bytes)
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis DoLPush error! key=%v, err=%v", key, cmd.Err())
return cmd.Err()
}
return nil
}
func RPushExt(key any, p any) (err error) {
bytes, err := proto.Marshal(p.(proto.Message))
if err != nil {
logs.Error("Redis DoLPush Protobuf Marshal error! key=%v, err=%v", key, err)
return err
}
cmd := defaultClient.rc.RPush(defaultClient.ctx(), fmt.Sprintf("%v", key), bytes)
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis DoLPush error! key=%v, err=%v", key, cmd.Err())
return cmd.Err()
}
return nil
}
// LRANGE, key:键, slicePrt=protobuf结构引用切片, start, stop 范围(包含)
func LRangeExt(key any, slicePrt any, start, stop int64) (err error) {
cmd := defaultClient.rc.LRange(defaultClient.ctx(), fmt.Sprintf("%v", key), start, stop)
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis DoLPush error! key=%v, err=%v", key, cmd.Err())
return cmd.Err()
}
results := reflect.ValueOf(slicePrt)
if results.Kind() == reflect.Ptr {
results = results.Elem()
}
for _, v := range cmd.Val() {
newItem := reflect.New(getStructType(slicePrt)).Interface()
err = proto.Unmarshal([]byte(v), newItem.(proto.Message))
if err != nil {
logs.Error("Redis DoLRangeExt Protobuf Unmarshal error! key=%v, err=%v", key, err)
return
}
results.Set(reflect.Append(results, reflect.ValueOf(newItem)))
}
return nil
}
// LLEN, key:键
func LLen(key any) (int64, error) {
cmd := defaultClient.rc.LLen(defaultClient.ctx(), fmt.Sprintf("%v", key))
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis DoLLen error! key=%v, err=%v", key, cmd.Err())
return 0, cmd.Err()
}
return cmd.Val(), nil
}
// DoRPop
func RPop(key any) (rank string, err error) {
cmd := defaultClient.rc.RPop(defaultClient.ctx(), fmt.Sprintf("%v", key))
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis DoRPop error! key=%v, err=%v", key, cmd.Err())
return "", cmd.Err()
}
return cmd.Val(), err
}
func LPop(key any) (rank string, err error) {
cmd := defaultClient.rc.LPop(defaultClient.ctx(), fmt.Sprintf("%v", key))
if cmd.Err() != nil && !errors.Is(cmd.Err(), redis.Nil) {
logs.Error("Redis DoRPop error! key=%v, err=%v", key, cmd.Err())
return "", cmd.Err()
}
return cmd.Val(), err
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/MikeDDD/gu.git
git@gitee.com:MikeDDD/gu.git
MikeDDD
gu
gu
v0.0.46

搜索帮助

344bd9b3 5694891 D2dac590 5694891