forked from free-lancers/electricity_bill_calc_service
build(deps):Redis操作库更改为rueidis。
This commit is contained in:
84
cache/abstract.go
vendored
84
cache/abstract.go
vendored
@@ -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
19
cache/count.go
vendored
@@ -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
20
cache/entity.go
vendored
@@ -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
30
cache/exists.go
vendored
@@ -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
40
cache/relation.go
vendored
@@ -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
20
cache/search.go
vendored
@@ -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)
|
||||
}
|
||||
|
Reference in New Issue
Block a user