gitee.com/h79/goutils@v1.22.10/dao/redis/pool/kv.go (about) 1 package pool 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/go-redis/redis/v8" 9 ) 10 11 // GetSet 的包装 12 func (c *Client) GetSet(ctx context.Context, key string, value interface{}) (string, error) { 13 client, cErr := getClusterClient(c) 14 15 if cErr != nil { 16 return "", cErr 17 } 18 19 res := "" 20 var err error 21 22 res, err = client.GetSet(ctx, key, value).Result() 23 24 return res, err 25 } 26 27 // Set 对于Set 28 func (c *Client) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) (string, error) { 29 client, cErr := getClusterClient(c) 30 31 if cErr != nil { 32 return "", cErr 33 } 34 return client.Set(ctx, key, value, expiration).Result() 35 36 } 37 38 // 对于SetNX 的包装 39 func (c *Client) SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) (bool, error) { 40 client, cErr := getClusterClient(c) 41 42 if cErr != nil { 43 return false, cErr 44 } 45 46 return client.SetNX(ctx, key, value, expiration).Result() 47 48 } 49 50 func (c *Client) SetWithKeys(ctx context.Context, keys []string, value interface{}, expiration time.Duration) (string, error) { 51 client, cErr := getClusterClient(c) 52 53 if cErr != nil { 54 return "", cErr 55 } 56 57 res := "" 58 var err error 59 60 cmds, err := client.Pipelined(ctx, func(pipe redis.Pipeliner) error { 61 for _, key := range keys { 62 pipe.Set(ctx, key, value, expiration) 63 } 64 return nil 65 }) 66 67 for _, cmd := range cmds { 68 if value, ok := cmd.(*redis.StatusCmd); ok { 69 res, err = value.Result() 70 if err != nil { 71 return res, err 72 } 73 } 74 } 75 76 return res, err 77 } 78 79 // Sets 对于Set和SetNX 的包装 80 func (c *Client) SetNXWithKeys(ctx context.Context, keys []string, value interface{}, expiration time.Duration) (bool, error) { 81 client, cErr := getClusterClient(c) 82 83 if cErr != nil { 84 return false, cErr 85 } 86 87 res := true 88 var err error 89 90 cmds, err := client.Pipelined(ctx, func(pipe redis.Pipeliner) error { 91 for _, key := range keys { 92 pipe.SetNX(ctx, key, value, expiration) 93 } 94 return nil 95 }) 96 97 for _, cmd := range cmds { 98 if value, ok := cmd.(*redis.BoolCmd); ok { 99 res, err = value.Result() 100 if err != nil { 101 return res, err 102 } 103 } 104 //switch value := cmd.(type) { 105 //case *redis.StatusCmd: 106 // _, err = value.Result() 107 //case *redis.BoolCmd: 108 // res, err = value.Result() 109 // 110 //} 111 // 112 //if err != nil { 113 // return res, err 114 //} 115 } 116 117 return res, err 118 } 119 120 //Get 获取字段 121 func (c *Client) Get(ctx context.Context, key string) (string, error) { 122 client, cErr := getClusterClient(c) 123 124 if cErr != nil { 125 return "", cErr 126 } 127 128 return client.Get(ctx, key).Result() 129 } 130 131 //MSetReq MSets的参数 132 type MSetReq struct { 133 Key string 134 Value interface{} 135 } 136 137 //MSet 批量设置 138 func (c *Client) MSet(ctx context.Context, req ...*MSetReq) (string, error) { 139 client, cErr := getClusterClient(c) 140 141 if cErr != nil { 142 return "", cErr 143 } 144 145 slotsMap := make(map[int][]*MSetReq) 146 for _, r := range req { 147 slot := Slot(r.Key) 148 if _, ok := slotsMap[slot]; !ok { 149 slotsMap[slot] = make([]*MSetReq, 0) 150 } 151 slotsMap[slot] = append(slotsMap[slot], r) 152 } 153 154 cmds, err := client.Pipelined(ctx, func(pipe redis.Pipeliner) error { 155 for _, r := range slotsMap { 156 pairs := make([]interface{}, 0) 157 for _, p := range r { 158 pairs = append(pairs, p.Key, p.Value) 159 } 160 err := pipe.MSet(ctx, pairs...).Err() 161 if err != nil { 162 return err 163 } 164 } 165 return nil 166 }) 167 168 var res string 169 for _, cmd := range cmds { 170 res, err = cmd.(*redis.StatusCmd).Result() 171 if err != nil { 172 return res, err 173 } 174 } 175 176 return res, err 177 } 178 179 //KeyValue key-value数对 180 type KeyValue struct { 181 Key string 182 Value string 183 Err error 184 } 185 186 //MGet 批量设置 187 func (c *Client) MGet(ctx context.Context, keys ...string) ([]*KeyValue, error) { 188 client, cErr := getClusterClient(c) 189 190 if cErr != nil { 191 return nil, cErr 192 } 193 194 slotsMap := make(map[int][]string) 195 for _, k := range keys { 196 slot := Slot(k) 197 if _, ok := slotsMap[slot]; !ok { 198 slotsMap[slot] = make([]string, 0) 199 } 200 slotsMap[slot] = append(slotsMap[slot], k) 201 } 202 203 slotsSlice := make([][]string, 0) 204 205 for _, s := range slotsMap { 206 slotsSlice = append(slotsSlice, s) 207 } 208 209 res := make([]*KeyValue, 0) 210 cmds, err := client.Pipelined(ctx, func(pipe redis.Pipeliner) error { 211 for _, k := range slotsSlice { 212 pipe.MGet(ctx, k...) 213 } 214 return nil 215 }) 216 217 if err != nil { 218 return nil, err 219 } 220 221 if len(cmds) != len(slotsSlice) { 222 return nil, fmt.Errorf("MGet fail, keys = %v", keys) 223 } 224 225 i := 0 226 for _, slot := range slotsSlice { 227 // fmt.Println(i) 228 r, err := cmds[i].(*redis.SliceCmd).Result() 229 if len(slot) != len(r) { 230 return nil, fmt.Errorf("MGet fail, keys = %v", keys) 231 } 232 233 for j, k := range slot { 234 v := "" 235 if r[j] != nil { 236 v = r[j].(string) 237 238 res = append(res, &KeyValue{ 239 Key: k, 240 Value: v, 241 Err: err, 242 }) 243 } 244 } 245 i++ 246 } 247 248 return res, nil 249 } 250 251 //HSet Hash table 插入 252 func (c *Client) HSet(ctx context.Context, key, field string, value interface{}) (int64, error) { 253 client, cErr := getClusterClient(c) 254 255 if cErr != nil { 256 return 0, cErr 257 } 258 return client.HSet(ctx, key, field, value).Result() 259 } 260 261 //HSet Hash table 插入 262 func (c *Client) HSetNX(ctx context.Context, key, field string, value interface{}) (bool, error) { 263 client, cErr := getClusterClient(c) 264 265 if cErr != nil { 266 return false, cErr 267 } 268 269 return client.HSetNX(ctx, key, field, value).Result() 270 271 }