package cache import ( "electricity_bill_calc/logger" "fmt" "strings" "time" "go.uber.org/zap" ) 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...) var b strings.Builder b.WriteString(TAG_SEARCH) for _, s := range keys { fmt.Fprintf(&b, ":%s", s) } return b.String() } // 缓存模型名称明确的,使用或者包含非ID检索条件的实体内容。 func CacheSearch[T any](instance T, relationNames []string, entityName string, conditions ...string) error { searchKey := assembleSearchKey(entityName, conditions...) err := Cache(searchKey, &instance, 5*time.Minute) for _, relationName := range relationNames { CacheRelation(relationName, STORE_TYPE_KEY, searchKey) } return err } // 从缓存中取得模型名称明确的,使用或者包含非ID检索条件的实体内容。 func RetrieveSearch[T any](entityName string, conditions ...string) (*T, error) { searchKey := assembleSearchKey(entityName, conditions...) instance, err := Retrieve[T](searchKey) return instance, err } // 从缓存中删除全部指定模型名称的实体内容。 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) }