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