build(deps):Redis操作库更改为rueidis。

This commit is contained in:
徐涛
2022-08-27 12:37:31 +08:00
parent 4baadda299
commit 306ef3e1d9
9 changed files with 144 additions and 141 deletions

84
cache/abstract.go vendored
View File

@@ -6,8 +6,7 @@ import (
"strings"
"time"
"github.com/go-redis/redis/v8"
"github.com/vmihailenco/msgpack/v5"
"github.com/rueian/rueidis"
)
const (
@@ -22,27 +21,27 @@ const (
// 向Redis缓存中保存一个数据
// ! 如果需要长期保存一个数据那么需要向expires传入0。
func Cache[T interface{}](key string, value *T, expires time.Duration) error {
serializedValue, err := msgpack.Marshal(value)
if err != nil {
return err
}
cmd := global.RedisConn.Set(global.Ctx, key, serializedValue, expires)
return cmd.Err()
setCmd := global.RedisConn.B().Set().
Key(key).Value(rueidis.JSON(value)).
ExSeconds(int64(expires.Seconds())).
Build()
err := global.RedisConn.Do(global.Ctx, setCmd).Error()
return err
}
// 从Redis缓存中获取一个数据
func Retreive[T interface{}](key string) (*T, error) {
result, err := global.RedisConn.Get(global.Ctx, key).Result()
if err != nil {
if err == redis.Nil {
getCmd := global.RedisConn.B().Get().Key(key).Build()
result := global.RedisConn.Do(global.Ctx, getCmd)
if result.Error() != nil {
if rueidis.IsRedisNil(result.Error()) {
return nil, nil
} else {
return nil, err
return nil, result.Error()
}
}
value := new(T)
err = msgpack.Unmarshal([]byte(result), value)
err := result.DecodeJSON(value)
if err != nil {
return nil, err
}
@@ -51,42 +50,71 @@ func Retreive[T interface{}](key string) (*T, error) {
// 检查Redis缓存中是否存在指定键的记录
func Exists(key string) (bool, error) {
result, err := global.RedisConn.Exists(global.Ctx, key).Result()
if err != nil {
return false, err
existsCmd := global.RedisConn.B().Exists().Key(key).Build()
result := global.RedisConn.Do(global.Ctx, existsCmd)
if result.Error() != nil {
return false, result.Error()
}
return result > 0, nil
count, err := result.AsInt64()
return count > 0, err
}
// 从Redis缓存中删除指定键
// ! 如果指定键已不存在那么本函数一样会返回false
func Delete(key string) (bool, error) {
result, err := global.RedisConn.Del(global.Ctx, key).Result()
if err != nil {
return false, err
deleteCmd := global.RedisConn.B().Del().Key(key).Build()
result := global.RedisConn.Do(global.Ctx, deleteCmd)
if result.Error() != nil {
return false, result.Error()
}
return result > 0, nil
count, err := result.AsInt64()
return count > 0, err
}
func dissembleScan(result rueidis.RedisResult) (int64, []string, error) {
var (
err error
cursor int64
keys = make([]string, 0)
)
results, err := result.ToArray()
if err != nil {
return -1, keys, err
}
cursor, err = results[0].AsInt64()
if err != nil {
return -1, keys, err
}
keys, err = results[1].AsStrSlice()
if err != nil {
return -1, keys, err
}
return cursor, keys, err
}
// 从Redis缓存中批量删除符合pattern的键这里的pattern直接使用Redis的pattern规则
func DeleteAll(pattern string) error {
var (
cursor uint64
err error
cursor int64
keys = make([]string, 0)
sKeys []string
)
for {
k, cursor, err := global.RedisConn.Scan(global.Ctx, cursor, pattern, 20).Result()
scanCmd := global.RedisConn.B().Scan().Cursor(cursor).Match(pattern).Count(20).Build()
results := global.RedisConn.Do(global.Ctx, scanCmd)
cursor, sKeys, err = dissembleScan(results)
if err != nil {
return err
}
keys = append(keys, k...)
keys = append(keys, sKeys...)
if cursor == 0 {
break
}
}
pipeline := global.RedisConn.Pipeline()
pipeline.Del(global.Ctx, keys...)
_, err := pipeline.Exec(global.Ctx)
delCmd := global.RedisConn.B().Del().Key(keys...).Build()
err = global.RedisConn.Do(global.Ctx, delCmd).Error()
return err
}

19
cache/count.go vendored
View File

@@ -20,31 +20,30 @@ func assembleCountIdentification(additional ...string) string {
func CacheCount(relationNames []string, entityName string, count int64, conditions ...string) error {
countKey := assembleCountKey(entityName)
identification := assembleCountIdentification(conditions...)
result := global.RedisConn.HSet(global.Ctx, countKey, map[string]interface{}{identification: count})
cmd := global.RedisConn.B().Hset().Key(countKey).FieldValue().FieldValue(identification, strconv.FormatInt(count, 10)).Build()
result := global.RedisConn.Do(global.Ctx, cmd)
for _, relationName := range relationNames {
CacheRelation(relationName, STORE_TYPE_HASH, countKey, identification)
}
return result.Err()
return result.Error()
}
// 从缓存中获取模型名称明确的,包含指定条件的实体记录数量
func RetreiveCount(entityName string, condtions ...string) (int64, error) {
countKey := assembleCountKey(entityName)
identification := assembleCountIdentification(condtions...)
result := global.RedisConn.HGet(global.Ctx, countKey, identification)
if result.Err() != nil {
return -1, result.Err()
}
count, err := strconv.ParseInt(result.Val(), 10, 64)
cmd := global.RedisConn.B().Hget().Key(countKey).Field(identification).Build()
result, err := global.RedisConn.Do(global.Ctx, cmd).AsInt64()
if err != nil {
return -1, err
}
return count, nil
return result, nil
}
// 删除指定模型名称的数量缓存
func AbolishCountEntity(entityName string) error {
countKey := assembleCountKey(entityName)
result := global.RedisConn.Del(global.Ctx, countKey)
return result.Err()
cmd := global.RedisConn.B().Del().Key(countKey).Build()
err := global.RedisConn.Do(global.Ctx, cmd).Error()
return err
}

20
cache/entity.go vendored
View File

@@ -1,7 +1,6 @@
package cache
import (
"electricity_bill_calc/global"
"fmt"
"strings"
)
@@ -42,23 +41,6 @@ func AbolishSpecificEntity(entityName, id string) (bool, error) {
// 从缓存中删除指定模型名称的所有内容。
func AbolishEntity(entityName string) error {
var (
cursor uint64
keys = make([]string, 0)
)
pattern := fmt.Sprintf("%s:%s:*", TAG_ENTITY, strings.ToUpper(entityName))
for {
k, cursor, err := global.RedisConn.Scan(global.Ctx, cursor, pattern, 20).Result()
if err != nil {
return err
}
keys = append(keys, k...)
if cursor == 0 {
break
}
}
pipeline := global.RedisConn.Pipeline()
pipeline.Del(global.Ctx, keys...)
_, err := pipeline.Exec(global.Ctx)
return err
return DeleteAll(pattern)
}

30
cache/exists.go vendored
View File

@@ -2,7 +2,6 @@ package cache
import (
"electricity_bill_calc/global"
"electricity_bill_calc/tools"
"fmt"
"strings"
)
@@ -21,19 +20,21 @@ func assembleExistsIdentification(additional ...string) string {
func CacheExists(relationNames []string, entityName string, conditions ...string) error {
existskey := assembleExistsKey(entityName)
identification := assembleExistsIdentification(conditions...)
result := global.RedisConn.SAdd(global.Ctx, existskey, identification)
cmd := global.RedisConn.B().Sadd().Key(existskey).Member(identification).Build()
err := global.RedisConn.Do(global.Ctx, cmd).Error()
for _, relationName := range relationNames {
CacheRelation(relationName, STORE_TYPE_SET, existskey, identification)
}
return result.Err()
return err
}
// 从缓存中获取模型名称明确、包含指定ID以及一些附加条件的实体是否存在的标记函数在返回false时不保证数据库中相关记录也不存在
func CheckExists(entityName string, condtions ...string) (bool, error) {
existsKey := assembleExistsKey(entityName)
identification := assembleExistsIdentification(condtions...)
result := global.RedisConn.SIsMember(global.Ctx, existsKey, identification)
return result.Val(), result.Err()
cmd := global.RedisConn.B().Sismember().Key(existsKey).Member(identification).Build()
result, err := global.RedisConn.Do(global.Ctx, cmd).ToBool()
return result, err
}
// 从缓存中删除模型名称明确、包含指定ID的全部实体存在标记
@@ -41,28 +42,31 @@ func AbolishExists(entityName, id string) error {
existsKey := assembleExistsKey(entityName)
pattern := fmt.Sprintf("%s*", id)
var (
cursor uint64
err error
cursor int64
elems = make([]string, 0)
sElem []string
)
for {
k, cursor, err := global.RedisConn.SScan(global.Ctx, existsKey, cursor, pattern, 20).Result()
cmd := global.RedisConn.B().Sscan().Key(existsKey).Cursor(cursor).Match(pattern).Count(20).Build()
result := global.RedisConn.Do(global.Ctx, cmd)
cursor, sElem, err = dissembleScan(result)
if err != nil {
return err
}
elems = append(elems, k...)
elems = append(elems, sElem...)
if cursor == 0 {
break
}
}
pipeline := global.RedisConn.Pipeline()
pipeline.SRem(global.Ctx, existsKey, tools.ConvertSliceToInterfaceSlice(elems)...)
_, err := pipeline.Exec(global.Ctx)
cmd := global.RedisConn.B().Srem().Key(existsKey).Member(elems...).Build()
err = global.RedisConn.Do(global.Ctx, cmd).Error()
return err
}
// 从缓存中删除指定模型名称的全部存在标记
func AbolishExistsEntity(entityName string) error {
existskey := assembleExistsKey(entityName)
result := global.RedisConn.Del(global.Ctx, existskey)
return result.Err()
_, err := Delete(existskey)
return err
}

40
cache/relation.go vendored
View File

@@ -2,8 +2,10 @@ package cache
import (
"electricity_bill_calc/global"
"electricity_bill_calc/tools"
"strings"
"github.com/rueian/rueidis"
"github.com/samber/lo"
)
const (
@@ -29,31 +31,41 @@ func assembleRelationIdentity(storeType, key string, field ...string) string {
func CacheRelation(relationName, storeType, key string, field ...string) error {
relationKey := assembleRelationKey(relationName)
relationIdentity := assembleRelationIdentity(storeType, key, field...)
result := global.RedisConn.SAdd(global.Ctx, relationKey, relationIdentity)
return result.Err()
cmd := global.RedisConn.B().Sadd().Key(relationKey).Member(relationIdentity).Build()
result := global.RedisConn.Do(global.Ctx, cmd)
return result.Error()
}
// 从缓存中清理指定的关联键
func AbolishRelation(relationName string) error {
relationKey := assembleRelationKey(relationName)
result := global.RedisConn.SMembers(global.Ctx, relationKey)
if result.Err() != nil {
return result.Err()
cmd := global.RedisConn.B().Smembers().Key(relationKey).Build()
relationItems, err := global.RedisConn.Do(global.Ctx, cmd).AsStrSlice()
if err != nil {
return err
}
relationItems := result.Val()
pipeline := global.RedisConn.Pipeline()
var cmds = make(rueidis.Commands, 0)
for _, item := range relationItems {
separated := strings.Split(item, ";")
switch separated[0] {
case STORE_TYPE_KEY:
pipeline.Del(global.Ctx, separated[1])
cmd := global.RedisConn.B().Del().Key(separated[1]).Build()
cmds = append(cmds, cmd)
case STORE_TYPE_HASH:
pipeline.HDel(global.Ctx, separated[1], separated[2:]...)
cmd := global.RedisConn.B().Hdel().Key(separated[1]).Field(separated[2:]...).Build()
cmds = append(cmds, cmd)
case STORE_TYPE_SET:
pipeline.SRem(global.Ctx, separated[1], tools.ConvertSliceToInterfaceSlice(separated[2:])...)
cmd := global.RedisConn.B().Srem().Key(separated[1]).Member(separated[2:]...).Build()
cmds = append(cmds, cmd)
}
}
pipeline.Del(global.Ctx, relationKey)
_, err := pipeline.Exec(global.Ctx)
return err
errs := global.RedisConn.DoMulti(global.Ctx, cmds...)
firstErr, has := lo.Find(errs, func(elem rueidis.RedisResult) bool {
return elem.Error() != nil
})
if has {
return firstErr.Error()
} else {
return nil
}
}

20
cache/search.go vendored
View File

@@ -1,7 +1,6 @@
package cache
import (
"electricity_bill_calc/global"
"fmt"
"strings"
)
@@ -37,23 +36,6 @@ func RetreiveSearch[T any](entityName string, conditions ...string) (*T, error)
// 从缓存中删除全部指定模型名称的实体内容。
func AbolishSearch(entityName string) error {
var (
cursor uint64
keys = make([]string, 0)
)
pattern := fmt.Sprintf("%s:%s:*", TAG_SEARCH, strings.ToUpper(entityName))
for {
k, cursor, err := global.RedisConn.Scan(global.Ctx, cursor, pattern, 20).Result()
if err != nil {
return err
}
keys = append(keys, k...)
if cursor == 0 {
break
}
}
pipeline := global.RedisConn.Pipeline()
pipeline.Del(global.Ctx, keys...)
_, err := pipeline.Exec(global.Ctx)
return err
return DeleteAll(pattern)
}