forked from free-lancers/electricity_bill_calc_service
合并分支
This commit is contained in:
40
cache/abstract.go
vendored
40
cache/abstract.go
vendored
@@ -40,7 +40,7 @@ func Cache[T interface{}](key string, value *T, expires time.Duration) error {
|
||||
}
|
||||
|
||||
// 从Redis缓存中获取一个数据
|
||||
func Retreive[T interface{}](key string) (*T, error) {
|
||||
func Retrieve[T interface{}](key string) (*T, error) {
|
||||
getCmd := global.Rd.B().Get().Key(key).Build()
|
||||
result := global.Rd.Do(global.Ctx, getCmd)
|
||||
if result.Error() != nil {
|
||||
@@ -81,23 +81,23 @@ func Delete(key string) (bool, error) {
|
||||
return count > 0, err
|
||||
}
|
||||
|
||||
func dissembleScan(result rueidis.RedisResult) (int64, []string, error) {
|
||||
func dissembleScan(result rueidis.RedisResult) (uint64, []string, error) {
|
||||
var (
|
||||
err error
|
||||
cursor int64
|
||||
cursor uint64
|
||||
keys = make([]string, 0)
|
||||
)
|
||||
results, err := result.ToArray()
|
||||
if err != nil {
|
||||
return -1, keys, err
|
||||
return 0, keys, err
|
||||
}
|
||||
cursor, err = results[0].AsInt64()
|
||||
cursor, err = results[0].AsUint64()
|
||||
if err != nil {
|
||||
return -1, keys, err
|
||||
return 0, keys, err
|
||||
}
|
||||
keys, err = results[1].AsStrSlice()
|
||||
if err != nil {
|
||||
return -1, keys, err
|
||||
return 0, keys, err
|
||||
}
|
||||
return cursor, keys, err
|
||||
}
|
||||
@@ -106,7 +106,7 @@ func dissembleScan(result rueidis.RedisResult) (int64, []string, error) {
|
||||
func DeleteAll(pattern string) error {
|
||||
var (
|
||||
err error
|
||||
cursor int64
|
||||
cursor uint64
|
||||
keys = make([]string, 0)
|
||||
sKeys []string
|
||||
)
|
||||
@@ -137,3 +137,27 @@ func CacheKey(category string, ids ...string) string {
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
type ToString[T any] interface {
|
||||
ToString() string
|
||||
*T
|
||||
}
|
||||
|
||||
// 用于生成一个内容可以为空的Redis缓存键,这个键的类型必须实现了`ToString`接口。
|
||||
func NullableConditionKey[P any, T ToString[P]](value T, defaultStr ...string) string {
|
||||
defaultStr = append(defaultStr, "UNDEF")
|
||||
if value == nil {
|
||||
return defaultStr[0]
|
||||
} else {
|
||||
return value.ToString()
|
||||
}
|
||||
}
|
||||
|
||||
// 用于生成一个内容可以为空的字符串指针类型的Redis缓存键。
|
||||
func NullableStringKey(value *string, defaultStr ...string) string {
|
||||
defaultStr = append(defaultStr, "UNDEF")
|
||||
if value == nil {
|
||||
return defaultStr[0]
|
||||
}
|
||||
return *value
|
||||
}
|
||||
|
||||
10
cache/count.go
vendored
10
cache/count.go
vendored
@@ -10,7 +10,7 @@ type _CountRecord struct {
|
||||
Count int64
|
||||
}
|
||||
|
||||
func assembleCountKey(entityName string, additional ...string) string {
|
||||
func AssembleCountKey(entityName string, additional ...string) string {
|
||||
var keys = make([]string, 0)
|
||||
keys = append(keys, strings.ToUpper(entityName))
|
||||
keys = append(keys, additional...)
|
||||
@@ -24,7 +24,7 @@ func assembleCountKey(entityName string, additional ...string) string {
|
||||
|
||||
// 向缓存中缓存模型名称明确的包含指定条件的实体记录数量
|
||||
func CacheCount(relationNames []string, entityName string, count int64, conditions ...string) error {
|
||||
countKey := assembleCountKey(entityName, conditions...)
|
||||
countKey := AssembleCountKey(entityName, conditions...)
|
||||
cacheInstance := &_CountRecord{Count: count}
|
||||
err := Cache(countKey, cacheInstance, 5*time.Minute)
|
||||
for _, relationName := range relationNames {
|
||||
@@ -34,8 +34,8 @@ func CacheCount(relationNames []string, entityName string, count int64, conditio
|
||||
}
|
||||
|
||||
// 从缓存中获取模型名称明确的,包含指定条件的实体记录数量
|
||||
func RetreiveCount(entityName string, condtions ...string) (int64, error) {
|
||||
countKey := assembleCountKey(entityName, condtions...)
|
||||
func RetrieveCount(entityName string, condtions ...string) (int64, error) {
|
||||
countKey := AssembleCountKey(entityName, condtions...)
|
||||
exist, err := Exists(countKey)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
@@ -43,7 +43,7 @@ func RetreiveCount(entityName string, condtions ...string) (int64, error) {
|
||||
if !exist {
|
||||
return -1, nil
|
||||
}
|
||||
instance, err := Retreive[_CountRecord](countKey)
|
||||
instance, err := Retrieve[_CountRecord](countKey)
|
||||
if instance != nil && err == nil {
|
||||
return instance.Count, nil
|
||||
} else {
|
||||
|
||||
12
cache/entity.go
vendored
12
cache/entity.go
vendored
@@ -6,7 +6,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func assembleEntityKey(entityName, id string) string {
|
||||
func AssembleEntityKey(entityName, id string) string {
|
||||
var keys = make([]string, 0)
|
||||
keys = append(keys, strings.ToUpper(entityName), id)
|
||||
var b strings.Builder
|
||||
@@ -19,7 +19,7 @@ func assembleEntityKey(entityName, id string) string {
|
||||
|
||||
// 缓存模型名称明确的,使用ID进行检索的实体内容。
|
||||
func CacheEntity[T any](instance T, relationNames []string, entityName, id string) error {
|
||||
entityKey := assembleEntityKey(entityName, id)
|
||||
entityKey := AssembleEntityKey(entityName, id)
|
||||
err := Cache(entityKey, &instance, 5*time.Minute)
|
||||
for _, relationName := range relationNames {
|
||||
CacheRelation(relationName, STORE_TYPE_KEY, entityKey)
|
||||
@@ -28,15 +28,15 @@ func CacheEntity[T any](instance T, relationNames []string, entityName, id strin
|
||||
}
|
||||
|
||||
// 从缓存中取出模型名称明确的,使用ID进行检索的实体内容。
|
||||
func RetreiveEntity[T any](entityName, id string) (*T, error) {
|
||||
entityKey := assembleEntityKey(entityName, id)
|
||||
instance, err := Retreive[T](entityKey)
|
||||
func RetrieveEntity[T any](entityName, id string) (*T, error) {
|
||||
entityKey := AssembleEntityKey(entityName, id)
|
||||
instance, err := Retrieve[T](entityKey)
|
||||
return instance, err
|
||||
}
|
||||
|
||||
// 精确的从缓存中删除指定模型名称、指定ID的实体内容。
|
||||
func AbolishSpecificEntity(entityName, id string) (bool, error) {
|
||||
entityKey := assembleEntityKey(entityName, id)
|
||||
entityKey := AssembleEntityKey(entityName, id)
|
||||
return Delete(entityKey)
|
||||
}
|
||||
|
||||
|
||||
6
cache/exists.go
vendored
6
cache/exists.go
vendored
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func assembleExistsKey(entityName string, additional ...string) string {
|
||||
func AssembleExistsKey(entityName string, additional ...string) string {
|
||||
var keys = make([]string, 0)
|
||||
keys = append(keys, strings.ToUpper(entityName))
|
||||
keys = append(keys, additional...)
|
||||
@@ -22,7 +22,7 @@ func assembleExistsKey(entityName string, additional ...string) string {
|
||||
|
||||
// 缓存模型名称明确的、包含指定ID以及一些附加条件的记录
|
||||
func CacheExists(relationNames []string, entityName string, conditions ...string) error {
|
||||
existskey := assembleExistsKey(entityName, conditions...)
|
||||
existskey := AssembleExistsKey(entityName, conditions...)
|
||||
err := Cache(existskey, lo.ToPtr(true), 5*time.Minute)
|
||||
for _, relationName := range relationNames {
|
||||
CacheRelation(relationName, STORE_TYPE_KEY, existskey)
|
||||
@@ -32,7 +32,7 @@ func CacheExists(relationNames []string, entityName string, conditions ...string
|
||||
|
||||
// 从缓存中获取模型名称明确、包含指定ID以及一些附加条件的实体是否存在的标记,函数在返回false时不保证数据库中相关记录也不存在
|
||||
func CheckExists(entityName string, condtions ...string) (bool, error) {
|
||||
existsKey := assembleExistsKey(entityName, condtions...)
|
||||
existsKey := AssembleExistsKey(entityName, condtions...)
|
||||
return Exists(existsKey)
|
||||
}
|
||||
|
||||
|
||||
12
cache/relation.go
vendored
12
cache/relation.go
vendored
@@ -15,13 +15,13 @@ const (
|
||||
STORE_TYPE_HASH = "HASH"
|
||||
)
|
||||
|
||||
func assembleRelationKey(relationName string) string {
|
||||
func AssembleRelationKey(relationName string) string {
|
||||
var keys = make([]string, 0)
|
||||
keys = append(keys, strings.ToUpper(relationName))
|
||||
return CacheKey(TAG_RELATION, keys...)
|
||||
}
|
||||
|
||||
func assembleRelationIdentity(storeType, key string, field ...string) string {
|
||||
func AssembleRelationIdentity(storeType, key string, field ...string) string {
|
||||
var identity = make([]string, 0)
|
||||
identity = append(identity, storeType, key)
|
||||
identity = append(identity, field...)
|
||||
@@ -30,8 +30,8 @@ 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...)
|
||||
relationKey := AssembleRelationKey(relationName)
|
||||
relationIdentity := AssembleRelationIdentity(storeType, key, field...)
|
||||
cmd := global.Rd.B().Sadd().Key(relationKey).Member(relationIdentity).Build()
|
||||
result := global.Rd.Do(global.Ctx, cmd)
|
||||
return result.Error()
|
||||
@@ -39,7 +39,7 @@ func CacheRelation(relationName, storeType, key string, field ...string) error {
|
||||
|
||||
// 从缓存中清理指定的关联键
|
||||
func AbolishRelation(relationName string) error {
|
||||
relationKey := assembleRelationKey(relationName)
|
||||
relationKey := AssembleRelationKey(relationName)
|
||||
cmd := global.Rd.B().Smembers().Key(relationKey).Build()
|
||||
relationItems, err := global.Rd.Do(global.Ctx, cmd).AsStrSlice()
|
||||
if err != nil {
|
||||
@@ -74,7 +74,7 @@ func AbolishRelation(relationName string) error {
|
||||
func ClearOrphanRelationItems() error {
|
||||
var (
|
||||
err error
|
||||
cursor int64
|
||||
cursor uint64
|
||||
keys = make([]string, 0)
|
||||
sKeys []string
|
||||
)
|
||||
|
||||
62
cache/search.go
vendored
62
cache/search.go
vendored
@@ -1,12 +1,17 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"electricity_bill_calc/logger"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func assembleSearchKey(entityName string, additional ...string) string {
|
||||
var log = logger.Named("Cache")
|
||||
|
||||
func AssembleSearchKey(entityName string, additional ...string) string {
|
||||
var keys = make([]string, 0)
|
||||
keys = append(keys, strings.ToUpper(entityName))
|
||||
keys = append(keys, additional...)
|
||||
@@ -20,7 +25,7 @@ func assembleSearchKey(entityName string, additional ...string) string {
|
||||
|
||||
// 缓存模型名称明确的,使用或者包含非ID检索条件的实体内容。
|
||||
func CacheSearch[T any](instance T, relationNames []string, entityName string, conditions ...string) error {
|
||||
searchKey := assembleSearchKey(entityName, conditions...)
|
||||
searchKey := AssembleSearchKey(entityName, conditions...)
|
||||
err := Cache(searchKey, &instance, 5*time.Minute)
|
||||
for _, relationName := range relationNames {
|
||||
CacheRelation(relationName, STORE_TYPE_KEY, searchKey)
|
||||
@@ -29,9 +34,9 @@ func CacheSearch[T any](instance T, relationNames []string, entityName string, c
|
||||
}
|
||||
|
||||
// 从缓存中取得模型名称明确的,使用或者包含非ID检索条件的实体内容。
|
||||
func RetreiveSearch[T any](entityName string, conditions ...string) (*T, error) {
|
||||
searchKey := assembleSearchKey(entityName, conditions...)
|
||||
instance, err := Retreive[T](searchKey)
|
||||
func RetrieveSearch[T any](entityName string, conditions ...string) (*T, error) {
|
||||
searchKey := AssembleSearchKey(entityName, conditions...)
|
||||
instance, err := Retrieve[T](searchKey)
|
||||
return instance, err
|
||||
}
|
||||
|
||||
@@ -40,3 +45,50 @@ func AbolishSearch(entityName string) error {
|
||||
pattern := fmt.Sprintf("%s:%s:*", TAG_SEARCH, strings.ToUpper(entityName))
|
||||
return DeleteAll(pattern)
|
||||
}
|
||||
|
||||
// 向缓存中保存指定模型名称的分页检索结果,会同时采用`CacheCount`中的方法保存检索结果的总数量。
|
||||
func CachePagedSearch[T any](instance T, total int64, relationNames []string, entityName string, conditions ...string) error {
|
||||
searchKey := AssembleSearchKey(entityName, conditions...)
|
||||
countKey := AssembleCountKey(entityName, conditions...)
|
||||
err := Cache(searchKey, &instance, 5*time.Minute)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cacheInstance := &_CountRecord{Count: total}
|
||||
err = Cache(countKey, cacheInstance, 5*time.Minute)
|
||||
for _, relationName := range relationNames {
|
||||
CacheRelation(relationName, STORE_TYPE_KEY, searchKey)
|
||||
CacheRelation(relationName, STORE_TYPE_KEY, countKey)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// 从缓存中获取指定模型名称的分页检索结果,会同时采用`RetrieveCount`中的方法获取检索结果的总数量。
|
||||
func RetrievePagedSearch[T any](entityName string, conditions ...string) (*T, int64, error) {
|
||||
searchKey := AssembleSearchKey(entityName, conditions...)
|
||||
countKey := AssembleCountKey(entityName, conditions...)
|
||||
instance, err := Retrieve[T](searchKey)
|
||||
if err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
count, err := Retrieve[_CountRecord](countKey)
|
||||
if err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
if instance == nil || count == nil {
|
||||
log.Warn("检索结果或者检索总数为空。", zap.String("searchKey", searchKey), zap.String("countKey", countKey))
|
||||
return nil, -1, nil
|
||||
}
|
||||
return instance, count.Count, nil
|
||||
}
|
||||
|
||||
// 从缓存中删除指定模型名称的分页检索结果,会同时采用`AbolishCountEntity`中的方法删除检索结果的总数量。
|
||||
func AbolishPagedSearch(entityName string) error {
|
||||
pattern := fmt.Sprintf("%s:%s:*", TAG_SEARCH, strings.ToUpper(entityName))
|
||||
err := DeleteAll(pattern)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pattern = fmt.Sprintf("%s:%s:*", TAG_COUNT, strings.ToUpper(entityName))
|
||||
return DeleteAll(pattern)
|
||||
}
|
||||
|
||||
4
cache/session.go
vendored
4
cache/session.go
vendored
@@ -21,9 +21,9 @@ func CacheSession(session *model.Session) error {
|
||||
return Cache(key, session, config.ServiceSettings.MaxSessionLife)
|
||||
}
|
||||
|
||||
func RetreiveSession(token string) (*model.Session, error) {
|
||||
func RetrieveSession(token string) (*model.Session, error) {
|
||||
key := SessionKey(token)
|
||||
return Retreive[model.Session](key)
|
||||
return Retrieve[model.Session](key)
|
||||
}
|
||||
|
||||
func HasSession(token string) (bool, error) {
|
||||
|
||||
Reference in New Issue
Block a user