feat(cache):实验性增加缓存操作函数。
This commit is contained in:
parent
4aa7221158
commit
4025965e98
8
cache/abstract.go
vendored
8
cache/abstract.go
vendored
|
@ -10,6 +10,14 @@ import (
|
|||
"github.com/vmihailenco/msgpack/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
TAG_ENTITY = "ENTITY"
|
||||
TAG_COUNT = "COUNT"
|
||||
TAG_SEARCH = "SEARCH"
|
||||
TAG_EXISTS = "CHECK"
|
||||
TAG_SESSION = "SESSION"
|
||||
)
|
||||
|
||||
// 向Redis缓存中保存一个数据
|
||||
// ! 如果需要长期保存一个数据,那么需要向expires传入0。
|
||||
func Cache[T interface{}](key string, value *T, expires time.Duration) error {
|
||||
|
|
52
cache/count.go
vendored
Normal file
52
cache/count.go
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
package cache
|
||||
|
||||
import (
|
||||
"electricity_bill_calc/global"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func assembleCountKey(entityName string) string {
|
||||
var keys = make([]string, 0)
|
||||
keys = append(keys, strings.ToUpper(entityName))
|
||||
return CacheKey(TAG_COUNT, keys...)
|
||||
}
|
||||
|
||||
func assembleCountIdentification(additional ...string) string {
|
||||
var b strings.Builder
|
||||
for _, s := range additional {
|
||||
fmt.Fprintf(&b, ":%s", s)
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// 向缓存中缓存模型名称明确的包含指定条件的实体记录数量
|
||||
func CacheCount(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})
|
||||
return result.Err()
|
||||
}
|
||||
|
||||
// 从缓存中获取模型名称明确的,包含指定条件的实体记录数量
|
||||
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)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// 删除指定模型名称的数量缓存
|
||||
func AbolishCountEntity(entityName string) error {
|
||||
countKey := assembleCountKey(entityName)
|
||||
result := global.RedisConn.Del(global.Ctx, countKey)
|
||||
return result.Err()
|
||||
}
|
61
cache/entity.go
vendored
Normal file
61
cache/entity.go
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
package cache
|
||||
|
||||
import (
|
||||
"electricity_bill_calc/global"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func assembleEntityKey(entityName, id string) string {
|
||||
var keys = make([]string, 0)
|
||||
keys = append(keys, TAG_ENTITY)
|
||||
keys = append(keys, strings.ToUpper(entityName), id)
|
||||
var b strings.Builder
|
||||
for _, s := range keys {
|
||||
fmt.Fprintf(&b, ":%s", s)
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// 缓存模型名称明确的,使用ID进行检索的实体内容。
|
||||
func CacheEntity[T any](instance T, entityName, id string) error {
|
||||
entityKey := assembleEntityKey(entityName, id)
|
||||
err := Cache(entityKey, &instance, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// 从缓存中取出模型名称明确的,使用ID进行检索的实体内容。
|
||||
func RetreiveEntity[T any](entityName, id string) (T, error) {
|
||||
entityKey := assembleEntityKey(entityName, id)
|
||||
instance, err := Retreive[T](entityKey)
|
||||
return *instance, err
|
||||
}
|
||||
|
||||
// 精确的从缓存中删除指定模型名称、指定ID的实体内容。
|
||||
func AbolishSpecificEntity(entityName, id string) (bool, error) {
|
||||
entityKey := assembleEntityKey(entityName, id)
|
||||
return Delete(entityKey)
|
||||
}
|
||||
|
||||
// 从缓存中删除指定模型名称的所有内容。
|
||||
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
|
||||
}
|
70
cache/exists.go
vendored
Normal file
70
cache/exists.go
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
package cache
|
||||
|
||||
import (
|
||||
"electricity_bill_calc/global"
|
||||
"electricity_bill_calc/tools"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func assembleExistsKey(entityName string) string {
|
||||
var keys = make([]string, 0)
|
||||
keys = append(keys, strings.ToUpper(entityName))
|
||||
return CacheKey(TAG_EXISTS, keys...)
|
||||
}
|
||||
|
||||
func assembleExistsIdentification(id string, additional ...string) string {
|
||||
var b strings.Builder
|
||||
b.WriteString(id)
|
||||
for _, s := range additional {
|
||||
fmt.Fprintf(&b, ":%s", s)
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// 缓存模型名称明确的、包含指定ID以及一些附加条件的记录
|
||||
func CacheExists(entityName, id string, conditions ...string) error {
|
||||
existskey := assembleExistsKey(entityName)
|
||||
identification := assembleExistsIdentification(id, conditions...)
|
||||
result := global.RedisConn.SAdd(global.Ctx, existskey, identification)
|
||||
return result.Err()
|
||||
}
|
||||
|
||||
// 从缓存中获取模型名称明确、包含指定ID以及一些附加条件的实体是否存在的标记,函数在返回false时不保证数据库中相关记录也不存在
|
||||
func CheckExists(entityName, id string, condtions ...string) (bool, error) {
|
||||
existsKey := assembleExistsKey(entityName)
|
||||
identification := assembleExistsIdentification(id, condtions...)
|
||||
result := global.RedisConn.SIsMember(global.Ctx, existsKey, identification)
|
||||
return result.Val(), result.Err()
|
||||
}
|
||||
|
||||
// 从缓存中删除模型名称明确、包含指定ID的全部实体存在标记
|
||||
func AbolishExists(entityName, id string) error {
|
||||
existsKey := assembleExistsKey(entityName)
|
||||
pattern := fmt.Sprintf("%s*", id)
|
||||
var (
|
||||
cursor uint64
|
||||
elems = make([]string, 0)
|
||||
)
|
||||
for {
|
||||
k, cursor, err := global.RedisConn.SScan(global.Ctx, existsKey, cursor, pattern, 20).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
elems = append(elems, k...)
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
pipeline := global.RedisConn.Pipeline()
|
||||
pipeline.SRem(global.Ctx, existsKey, tools.ConvertSliceToInterfaceSlice(elems)...)
|
||||
_, err := pipeline.Exec(global.Ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// 从缓存中删除指定模型名称的全部存在标记
|
||||
func AbolishExistsEntity(entityName string) error {
|
||||
existskey := assembleExistsKey(entityName)
|
||||
result := global.RedisConn.Del(global.Ctx, existskey)
|
||||
return result.Err()
|
||||
}
|
56
cache/search.go
vendored
Normal file
56
cache/search.go
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
package cache
|
||||
|
||||
import (
|
||||
"electricity_bill_calc/global"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func assembleSearchKey(entityName string, additional ...string) string {
|
||||
var keys = make([]string, 0)
|
||||
keys = append(keys, TAG_SEARCH)
|
||||
keys = append(keys, strings.ToUpper(entityName))
|
||||
keys = append(keys, additional...)
|
||||
var b strings.Builder
|
||||
for _, s := range keys {
|
||||
fmt.Fprintf(&b, ":%s", s)
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// 缓存模型名称明确的,使用或者包含非ID检索条件的实体内容。
|
||||
func CacheSearch[T any](instance T, entityName string, conditions ...string) error {
|
||||
searchKey := assembleSearchKey(entityName, conditions...)
|
||||
err := Cache(searchKey, &instance, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// 从缓存中取得模型名称明确的,使用或者包含非ID检索条件的实体内容。
|
||||
func RetreiveSearch[T any](entityName string, conditions ...string) (T, error) {
|
||||
searchKey := assembleSearchKey(entityName, conditions...)
|
||||
instance, err := Retreive[T](searchKey)
|
||||
return *instance, err
|
||||
}
|
||||
|
||||
// 从缓存中删除全部指定模型名称的实体内容。
|
||||
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
|
||||
}
|
2
cache/session.go
vendored
2
cache/session.go
vendored
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
func SessionKey(keys ...string) string {
|
||||
var b strings.Builder
|
||||
b.WriteString("session")
|
||||
b.WriteString(TAG_SESSION)
|
||||
for _, s := range keys {
|
||||
fmt.Fprintf(&b, ":%s", s)
|
||||
}
|
||||
|
|
|
@ -30,3 +30,11 @@ func ConvertStructToMap[T any](origin T) map[string]interface{} {
|
|||
json.Unmarshal(incr, &dest)
|
||||
return dest
|
||||
}
|
||||
|
||||
func ConvertSliceToInterfaceSlice[T any](origin []T) []interface{} {
|
||||
dest := make([]interface{}, len(origin))
|
||||
for i, e := range origin {
|
||||
dest[i] = e
|
||||
}
|
||||
return dest
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user