|
|
|
|
package grocerystore
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"appPlatform/overall"
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// redis 基础设定
|
|
|
|
|
type RedisStoreType struct {
|
|
|
|
|
Expiration time.Duration
|
|
|
|
|
PreKey string
|
|
|
|
|
Context context.Context
|
|
|
|
|
RedisDb *redis.Client
|
|
|
|
|
RedisDbClan *redis.ClusterClient
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 启动redis
|
|
|
|
|
func RunRedis(redisClient *redis.Client) *RedisStoreType {
|
|
|
|
|
var redisStoreType RedisStoreType
|
|
|
|
|
redisStoreType.Expiration = time.Second * 300
|
|
|
|
|
redisStoreType.PreKey = fmt.Sprintf("%v:", overall.CONSTANT_CONFIG.RedisPrefixStr.PreFix)
|
|
|
|
|
redisStoreType.Context = context.Background()
|
|
|
|
|
redisStoreType.RedisDb = redisClient
|
|
|
|
|
return &redisStoreType
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置键前缀
|
|
|
|
|
func (r *RedisStoreType) SetRedisPrefix(prefix string) {
|
|
|
|
|
r.PreKey = prefix
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置过期时间
|
|
|
|
|
func (r *RedisStoreType) SetRedisTime(timeDate int64) {
|
|
|
|
|
r.Expiration = time.Second * time.Duration(timeDate)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置字符串
|
|
|
|
|
func (r *RedisStoreType) Set(key string, value string) bool {
|
|
|
|
|
err := r.RedisDb.Set(r.Context, r.PreKey+key, value, r.Expiration).Err()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取字符串
|
|
|
|
|
func (r *RedisStoreType) Get(key string) (bool, string) {
|
|
|
|
|
err := r.RedisDb.Get(r.Context, r.PreKey+key)
|
|
|
|
|
if err.Err() != nil {
|
|
|
|
|
return false, ""
|
|
|
|
|
}
|
|
|
|
|
return true, err.Val()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除键
|
|
|
|
|
func (r *RedisStoreType) DelKey(key string) bool {
|
|
|
|
|
err := r.RedisDb.Del(r.Context, r.PreKey+key).Err()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//哈希操作
|
|
|
|
|
/*
|
|
|
|
|
获取单个哈希键值
|
|
|
|
|
@hashName 集合名称
|
|
|
|
|
@hashKey 哈希键
|
|
|
|
|
callback
|
|
|
|
|
errs 状态
|
|
|
|
|
hashVal 获得值
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) HashGet(hashName, hashKey string) (errs bool, hashVal string) {
|
|
|
|
|
err := r.RedisDb.HGet(r.Context, r.PreKey+hashName, hashKey)
|
|
|
|
|
if err.Err() != nil {
|
|
|
|
|
return false, ""
|
|
|
|
|
}
|
|
|
|
|
return true, err.Val()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
为哈希表中的字段赋值 。 单一设置
|
|
|
|
|
@hashName 集合名称
|
|
|
|
|
@hashKey 哈希键
|
|
|
|
|
@hashVal 要添加的值
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) HashSet(hashName, hashKey, hashVal string) bool {
|
|
|
|
|
err := r.RedisDb.HSet(r.Context, r.PreKey+hashName, hashKey, hashVal).Err()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if r.Expiration == 0 {
|
|
|
|
|
r.RedisDb.Persist(r.Context, r.PreKey+hashName)
|
|
|
|
|
} else {
|
|
|
|
|
r.RedisDb.PExpire(r.Context, r.PreKey+hashName, r.Expiration)
|
|
|
|
|
}
|
|
|
|
|
// global.GVA_REDIS.PExpire(r.Context, r.PreKey+hashName, r.Expiration)
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
同时将多个 field-value (字段-值)对设置到哈希表中。
|
|
|
|
|
@hashName 集合名称
|
|
|
|
|
@hashVal 要添加的键与值
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) HashMsetAdd(hashName string, hashVal map[string]interface{}) bool {
|
|
|
|
|
// rdb := RedisInit()
|
|
|
|
|
err := r.RedisDb.HMSet(r.Context, r.PreKey+hashName, hashVal).Err()
|
|
|
|
|
// fmt.Printf("错误sss=========》%v=====2====》%v\n", err, hashVal)
|
|
|
|
|
// err := rdb.HMSet(ctx, "userfg", hashVal).Err()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if r.Expiration == 0 {
|
|
|
|
|
r.RedisDb.Persist(r.Context, r.PreKey+hashName)
|
|
|
|
|
} else {
|
|
|
|
|
r.RedisDb.PExpire(r.Context, r.PreKey+hashName, r.Expiration)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
func (r *RedisStoreType) HashMsetAddinterface(hashName string, hashVal interface{}) bool {
|
|
|
|
|
// rdb := RedisInit()
|
|
|
|
|
err := r.RedisDb.HMSet(r.Context, r.PreKey+hashName, hashVal).Err()
|
|
|
|
|
// fmt.Printf("错误sss=========》%v=====2====》%v\n", err, hashVal)
|
|
|
|
|
// err := rdb.HMSet(ctx, "userfg", hashVal).Err()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if r.Expiration == 0 {
|
|
|
|
|
r.RedisDb.Persist(r.Context, r.PreKey+hashName)
|
|
|
|
|
} else {
|
|
|
|
|
r.RedisDb.PExpire(r.Context, r.PreKey+hashName, r.Expiration)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
func (r *RedisStoreType) HashMsetAddAry(hashName string, hashVal []map[string]interface{}) bool {
|
|
|
|
|
// rdb := RedisInit()
|
|
|
|
|
err := r.RedisDb.HMSet(r.Context, r.PreKey+hashName, hashVal).Err()
|
|
|
|
|
// err := rdb.HMSet(ctx, "userfg", hashVal).Err()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if r.Expiration == 0 {
|
|
|
|
|
r.RedisDb.Persist(r.Context, r.PreKey+hashName)
|
|
|
|
|
} else {
|
|
|
|
|
r.RedisDb.PExpire(r.Context, r.PreKey+hashName, r.Expiration)
|
|
|
|
|
}
|
|
|
|
|
// global.GVA_REDIS.PExpire(r.Context, r.PreKey+hashName, r.Expiration)
|
|
|
|
|
// fmt.Printf("错误sss=========》%v\n", hashVal)
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
返回哈希表中,所有的字段和值。
|
|
|
|
|
@hashName 集合名称
|
|
|
|
|
@hashKey 哈希键
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) HashGetAll(hashName string) (map[string]string, bool) {
|
|
|
|
|
// rdb := RedisInit()
|
|
|
|
|
// fmt.Printf("strKEy:===>%v\n", r.PreKey+hashName)
|
|
|
|
|
val, err := r.RedisDb.HGetAll(r.Context, r.PreKey+hashName).Result()
|
|
|
|
|
// fmt.Printf("strKEy:==1=>%v==1=>%v\n", val, err)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return val, false
|
|
|
|
|
}
|
|
|
|
|
if len(val) == 0 {
|
|
|
|
|
return val, false
|
|
|
|
|
}
|
|
|
|
|
return val, true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Redis 列表(List)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Linsert 命令用于在列表的元素前或者后插入元素。当指定元素不存在于列表中时,不执行任何操作。
|
|
|
|
|
当列表不存在时,被视为空列表,不执行任何操作。
|
|
|
|
|
如果 key 不是列表类型,返回一个错误。
|
|
|
|
|
@key 列表
|
|
|
|
|
@op 插入状态 (1:在pivot之后;2:在pivot之前)
|
|
|
|
|
@pivot 定位值
|
|
|
|
|
@value 要插入值
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Linsert(key string, op int, pivot, value interface{}) (int64, bool) {
|
|
|
|
|
BeforeOrAfter := "BEFORE"
|
|
|
|
|
if op != 1 {
|
|
|
|
|
BeforeOrAfter = "AFTER"
|
|
|
|
|
}
|
|
|
|
|
linsert, linsertErr := r.RedisDb.LInsert(r.Context, key, BeforeOrAfter, pivot, value).Result()
|
|
|
|
|
if linsertErr != nil {
|
|
|
|
|
return 0, false
|
|
|
|
|
}
|
|
|
|
|
return linsert, true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Lindex 命令用于通过索引获取列表中的元素。你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
|
|
|
|
|
@key 列表
|
|
|
|
|
@index 索引
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Lindex(key string, index int64) (val string, err error) {
|
|
|
|
|
val, err = r.RedisDb.LIndex(r.Context, key, index).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Llen 命令用于返回列表的长度。 如果列表 key 不存在,则 key 被解释为一个空列表,返回 0 。 如果 key 不是列表类型,返回一个错误。
|
|
|
|
|
@key 列表
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Llen(key string) (val int64, err error) {
|
|
|
|
|
val, err = r.RedisDb.LLen(r.Context, key).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Lpop 命令用于移除并返回列表的第一个元素。
|
|
|
|
|
@key 列表
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Lpop(key string) (val string, err error) {
|
|
|
|
|
val, err = r.RedisDb.LPop(r.Context, key).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Lpush 命令将一个或多个值插入到列表头部。 如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作。 当 key 存在但不是列表类型时,返回一个错误。
|
|
|
|
|
@key 列表
|
|
|
|
|
@value 要插入的字符串
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Lpush(key string, value ...interface{}) (val int64, err error) {
|
|
|
|
|
val, err = r.RedisDb.LPush(r.Context, key, value).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Lpushx 将一个值插入到已存在的列表头部,列表不存在时操作无效。
|
|
|
|
|
@key 列表
|
|
|
|
|
@value 要插入的字符串
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Lpushx(key, value string) (val int64, err error) {
|
|
|
|
|
val, err = r.RedisDb.LPushX(r.Context, key, value).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Lrange 返回列表中指定区间内的元素,区间以偏移量 START 和 END 指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
|
|
|
|
|
@key 列表
|
|
|
|
|
@start 起始值
|
|
|
|
|
@stop 结束值
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Lrange(key string, start, stop int64) (val []string, err error) {
|
|
|
|
|
val, err = r.RedisDb.LRange(r.Context, key, start, stop).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Lrem 根据参数 COUNT 的值,移除列表中与参数 VALUE 相等的元素。
|
|
|
|
|
COUNT 的值可以是以下几种:
|
|
|
|
|
|
|
|
|
|
count > 0 : 从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT 。
|
|
|
|
|
count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值。
|
|
|
|
|
count = 0 : 移除表中所有与 VALUE 相等的值。
|
|
|
|
|
|
|
|
|
|
@start = COUNT
|
|
|
|
|
@key 列表
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Lrem(key string, start int64, value ...interface{}) (val int64, err error) {
|
|
|
|
|
val, err = r.RedisDb.LRem(r.Context, key, start, value).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Redis Lset 通过索引来设置元素的值。
|
|
|
|
|
|
|
|
|
|
当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误。
|
|
|
|
|
@key 列表
|
|
|
|
|
@indexes 索引值
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Lset(key string, indexes int64, value ...interface{}) (val string, err error) {
|
|
|
|
|
val, err = r.RedisDb.LSet(r.Context, key, indexes, value).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Ltrim 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
|
|
|
|
|
|
|
|
|
|
下标 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
|
|
|
|
|
@key 列表
|
|
|
|
|
@start 起始值
|
|
|
|
|
@stop 结束值
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Ltrim(key string, start, stop int64) (val string, err error) {
|
|
|
|
|
val, err = r.RedisDb.LTrim(r.Context, key, start, stop).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Rpop 命令用于移除列表的最后一个元素,返回值为移除的元素。
|
|
|
|
|
@key 列表
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Rpop(key string) (val string, err error) {
|
|
|
|
|
val, err = r.RedisDb.RPop(r.Context, key).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Rpoplpush 命令用于移除列表的最后一个元素,并将该元素添加到另一个列表并返回。
|
|
|
|
|
@sourceKey 源列表
|
|
|
|
|
@newKey 目标列表
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Rpoplpush(sourceKey, newKey string) (val string, err error) {
|
|
|
|
|
val, err = r.RedisDb.RPopLPush(r.Context, sourceKey, newKey).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Rpush 命令用于将一个或多个值插入到列表的尾部(最右边)。
|
|
|
|
|
如果列表不存在,一个空列表会被创建并执行 RPUSH 操作。 当列表存在但不是列表类型时,返回一个错误。
|
|
|
|
|
@key 列表
|
|
|
|
|
@value 要插入的字符串
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Rpush(key string, value ...interface{}) (val int64, err error) {
|
|
|
|
|
val, err = r.RedisDb.RPush(r.Context, key, value).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Rpushx 命令用于将一个值插入到已存在的列表尾部(最右边)。如果列表不存在,操作无效。
|
|
|
|
|
@key 列表
|
|
|
|
|
@value 要插入的字符串
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Rpushx(key string, value ...interface{}) (val int64, err error) {
|
|
|
|
|
val, err = r.RedisDb.RPushX(r.Context, key, value).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Blpop 命令移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
|
|
|
|
|
@key 列表
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Blpop(key string) (val []string, err error) {
|
|
|
|
|
val, err = r.RedisDb.BLPop(r.Context, r.Expiration, key).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Brpop 命令移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
|
|
|
|
|
@key 列表
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Brpop(key string) (val []string, err error) {
|
|
|
|
|
val, err = r.RedisDb.BRPop(r.Context, r.Expiration, key).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
Brpoplpush 命令从列表中取出最后一个元素,并插入到另外一个列表的头部; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
|
|
|
|
|
@source 源列表
|
|
|
|
|
@destination 目标列表
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Brpoplpush(source, destination string) (val string, err error) {
|
|
|
|
|
val, err = r.RedisDb.BRPopLPush(r.Context, source, destination, r.Expiration).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Redis 键(key)
|
|
|
|
|
Redis 键命令用于管理 redis 的键。
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Redis SCAN 命令
|
|
|
|
|
Redis Scan 命令用于迭代数据库中的数据库键。
|
|
|
|
|
|
|
|
|
|
SCAN 命令是一个基于游标的迭代器,每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。
|
|
|
|
|
|
|
|
|
|
SCAN 返回一个包含两个元素的数组, 第一个元素是用于进行下一次迭代的新游标, 而第二个元素则是一个数组, 这个数组中包含了所有被迭代的元素。如果新游标返回 0 表示迭代已结束。
|
|
|
|
|
|
|
|
|
|
相关命令:
|
|
|
|
|
|
|
|
|
|
SSCAN 命令用于迭代集合键中的元素。
|
|
|
|
|
HSCAN 命令用于迭代哈希键中的键值对。
|
|
|
|
|
ZSCAN 命令用于迭代有序集合中的元素(包括元素成员和元素分值)。
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
func (r *RedisStoreType) Scan(cursor uint64, match string, count int64) (keys []string, cursores uint64, err error) {
|
|
|
|
|
keys, cursores, err = r.RedisDb.Scan(r.Context, cursor, match, count).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*Keys 命令用于查找所有符合给定模式 pattern 的 key 。。
|
|
|
|
|
*/
|
|
|
|
|
func (r *RedisStoreType) Keys(key string) (val []string, err error) {
|
|
|
|
|
val, err = r.RedisDb.Keys(r.Context, key).Result()
|
|
|
|
|
return
|
|
|
|
|
}
|