plugins/wasm-go/pkg/wrapper/redis_wrapper.go (796 lines of code) (raw):
// Copyright (c) 2022 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package wrapper
import (
"bytes"
"encoding/base64"
"errors"
"fmt"
"io"
"github.com/google/uuid"
"github.com/higress-group/proxy-wasm-go-sdk/proxywasm"
"github.com/tidwall/resp"
)
type RedisResponseCallback func(response resp.Value)
type RedisClient interface {
Init(username, password string, timeout int64, opts ...optionFunc) error
// return whether redis client is ready
Ready() bool
// with this function, you can call redis as if you are using redis-cli
Command(cmds []interface{}, callback RedisResponseCallback) error
Eval(script string, numkeys int, keys, args []interface{}, callback RedisResponseCallback) error
// Key
Del(key string, callback RedisResponseCallback) error
Exists(key string, callback RedisResponseCallback) error
Expire(key string, ttl int, callback RedisResponseCallback) error
Persist(key string, callback RedisResponseCallback) error
// String
Get(key string, callback RedisResponseCallback) error
Set(key string, value interface{}, callback RedisResponseCallback) error
SetEx(key string, value interface{}, ttl int, callback RedisResponseCallback) error
SetNX(key string, value interface{}, ttl int, callback RedisResponseCallback) error
MGet(keys []string, callback RedisResponseCallback) error
MSet(kvMap map[string]interface{}, callback RedisResponseCallback) error
Incr(key string, callback RedisResponseCallback) error
Decr(key string, callback RedisResponseCallback) error
IncrBy(key string, delta int, callback RedisResponseCallback) error
DecrBy(key string, delta int, callback RedisResponseCallback) error
// List
LLen(key string, callback RedisResponseCallback) error
RPush(key string, vals []interface{}, callback RedisResponseCallback) error
RPop(key string, callback RedisResponseCallback) error
LPush(key string, vals []interface{}, callback RedisResponseCallback) error
LPop(key string, callback RedisResponseCallback) error
LIndex(key string, index int, callback RedisResponseCallback) error
LRange(key string, start, stop int, callback RedisResponseCallback) error
LRem(key string, count int, value interface{}, callback RedisResponseCallback) error
LInsertBefore(key string, pivot, value interface{}, callback RedisResponseCallback) error
LInsertAfter(key string, pivot, value interface{}, callback RedisResponseCallback) error
// Hash
HExists(key, field string, callback RedisResponseCallback) error
HDel(key string, fields []string, callback RedisResponseCallback) error
HLen(key string, callback RedisResponseCallback) error
HGet(key, field string, callback RedisResponseCallback) error
HSet(key, field string, value interface{}, callback RedisResponseCallback) error
HMGet(key string, fields []string, callback RedisResponseCallback) error
HMSet(key string, kvMap map[string]interface{}, callback RedisResponseCallback) error
HKeys(key string, callback RedisResponseCallback) error
HVals(key string, callback RedisResponseCallback) error
HGetAll(key string, callback RedisResponseCallback) error
HIncrBy(key, field string, delta int, callback RedisResponseCallback) error
HIncrByFloat(key, field string, delta float64, callback RedisResponseCallback) error
// Set
SCard(key string, callback RedisResponseCallback) error
SAdd(key string, value []interface{}, callback RedisResponseCallback) error
SRem(key string, values []interface{}, callback RedisResponseCallback) error
SIsMember(key string, value interface{}, callback RedisResponseCallback) error
SMembers(key string, callback RedisResponseCallback) error
SDiff(key1, key2 string, callback RedisResponseCallback) error
SDiffStore(destination, key1, key2 string, callback RedisResponseCallback) error
SInter(key1, key2 string, callback RedisResponseCallback) error
SInterStore(destination, key1, key2 string, callback RedisResponseCallback) error
SUnion(key1, key2 string, callback RedisResponseCallback) error
SUnionStore(destination, key1, key2 string, callback RedisResponseCallback) error
// Sorted Set
ZCard(key string, callback RedisResponseCallback) error
ZAdd(key string, msMap map[string]interface{}, callback RedisResponseCallback) error
ZCount(key string, min interface{}, max interface{}, callback RedisResponseCallback) error
ZIncrBy(key string, member string, delta interface{}, callback RedisResponseCallback) error
ZScore(key, member string, callback RedisResponseCallback) error
ZRank(key, member string, callback RedisResponseCallback) error
ZRevRank(key, member string, callback RedisResponseCallback) error
ZRem(key string, members []string, callback RedisResponseCallback) error
ZRange(key string, start, stop int, callback RedisResponseCallback) error
ZRevRange(key string, start, stop int, callback RedisResponseCallback) error
}
type RedisClusterClient[C Cluster] struct {
cluster C
ready bool
checkReadyFunc func() error
option redisOption
}
type redisOption struct {
dataBase int
}
type optionFunc func(*redisOption)
func WithDataBase(dataBase int) optionFunc {
return func(o *redisOption) {
o.dataBase = dataBase
}
}
func NewRedisClusterClient[C Cluster](cluster C) *RedisClusterClient[C] {
return &RedisClusterClient[C]{
cluster: cluster,
checkReadyFunc: func() error {
return errors.New("redis client is not ready, please call Init() first")
},
}
}
func RedisCall(cluster Cluster, respQuery []byte, callback RedisResponseCallback) error {
requestID := uuid.New().String()
_, err := proxywasm.DispatchRedisCall(
cluster.ClusterName(),
respQuery,
func(status int, responseSize int) {
response, err := proxywasm.GetRedisCallResponse(0, responseSize)
var responseValue resp.Value
if status != 0 {
proxywasm.LogCriticalf("Error occured while calling redis, it seems cannot connect to the redis cluster. request-id: %s", requestID)
responseValue = resp.ErrorValue(fmt.Errorf("cannot connect to redis cluster"))
} else {
if err != nil {
proxywasm.LogCriticalf("failed to get redis response body, request-id: %s, error: %v", requestID, err)
responseValue = resp.ErrorValue(fmt.Errorf("cannot get redis response"))
} else {
rd := resp.NewReader(bytes.NewReader(response))
value, _, err := rd.ReadValue()
if err != nil && err != io.EOF {
proxywasm.LogCriticalf("failed to read redis response body, request-id: %s, error: %v", requestID, err)
responseValue = resp.ErrorValue(fmt.Errorf("cannot read redis response"))
} else {
responseValue = value
proxywasm.LogDebugf("redis call end, request-id: %s, respQuery: %s, respValue: %s",
requestID, base64.StdEncoding.EncodeToString([]byte(respQuery)), base64.StdEncoding.EncodeToString(response))
}
}
}
if callback != nil {
callback(responseValue)
}
})
if err != nil {
proxywasm.LogCriticalf("redis call failed, request-id: %s, error: %v", requestID, err)
} else {
proxywasm.LogDebugf("redis call start, request-id: %s, respQuery: %s", requestID, base64.StdEncoding.EncodeToString([]byte(respQuery)))
}
return err
}
func respString(args []interface{}) []byte {
var buf bytes.Buffer
wr := resp.NewWriter(&buf)
arr := make([]resp.Value, 0)
for _, arg := range args {
arr = append(arr, resp.StringValue(fmt.Sprint(arg)))
}
wr.WriteArray(arr)
return buf.Bytes()
}
func (c *RedisClusterClient[C]) Ready() bool {
return c.ready
}
func (c *RedisClusterClient[C]) Init(username, password string, timeout int64, opts ...optionFunc) error {
for _, opt := range opts {
opt(&c.option)
}
clusterName := c.cluster.ClusterName()
if c.option.dataBase != 0 {
clusterName = fmt.Sprintf("%s?db=%d", clusterName, c.option.dataBase)
}
err := proxywasm.RedisInit(clusterName, username, password, uint32(timeout))
if err != nil {
c.checkReadyFunc = func() error {
if c.ready {
return nil
}
initErr := proxywasm.RedisInit(clusterName, username, password, uint32(timeout))
if initErr != nil {
return initErr
}
c.ready = true
return nil
}
proxywasm.LogWarnf("failed to init redis: %v, will retry after", err)
return nil
}
c.checkReadyFunc = func() error { return nil }
c.ready = true
return nil
}
func (c *RedisClusterClient[C]) Command(cmds []interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
return RedisCall(c.cluster, respString(cmds), callback)
}
func (c *RedisClusterClient[C]) Eval(script string, numkeys int, keys, args []interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
params := make([]interface{}, 0)
params = append(params, "eval")
params = append(params, script)
params = append(params, numkeys)
params = append(params, keys...)
params = append(params, args...)
return RedisCall(c.cluster, respString(params), callback)
}
// Key
func (c *RedisClusterClient[C]) Del(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "del")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) Exists(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "exists")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) Expire(key string, ttl int, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "expire")
args = append(args, key)
args = append(args, ttl)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) Persist(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "persist")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
// String
func (c *RedisClusterClient[C]) Get(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "get")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) Set(key string, value interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "set")
args = append(args, key)
args = append(args, value)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) SetEx(key string, value interface{}, ttl int, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "set")
args = append(args, key)
args = append(args, value)
args = append(args, "ex")
args = append(args, ttl)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) SetNX(key string, value interface{}, ttl int, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "set")
args = append(args, key)
args = append(args, value)
args = append(args, "nx")
if ttl > 0 {
args = append(args, "ex")
args = append(args, ttl)
}
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) MGet(keys []string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "mget")
for _, k := range keys {
args = append(args, k)
}
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) MSet(kvMap map[string]interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "mset")
for k, v := range kvMap {
args = append(args, k)
args = append(args, v)
}
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) Incr(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "incr")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) Decr(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "decr")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) IncrBy(key string, delta int, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "incrby")
args = append(args, key)
args = append(args, delta)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) DecrBy(key string, delta int, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "decrby")
args = append(args, key)
args = append(args, delta)
return RedisCall(c.cluster, respString(args), callback)
}
// List
func (c *RedisClusterClient[C]) LLen(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "llen")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) RPush(key string, vals []interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "rpush")
args = append(args, key)
for _, val := range vals {
args = append(args, val)
}
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) RPop(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "rpop")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) LPush(key string, vals []interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "lpush")
args = append(args, key)
for _, val := range vals {
args = append(args, val)
}
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) LPop(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "lpop")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) LIndex(key string, index int, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "lindex")
args = append(args, key)
args = append(args, index)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) LRange(key string, start, stop int, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "lrange")
args = append(args, key)
args = append(args, start)
args = append(args, stop)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) LRem(key string, count int, value interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "lrem")
args = append(args, key)
args = append(args, count)
args = append(args, value)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) LInsertBefore(key string, pivot, value interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "linsert")
args = append(args, key)
args = append(args, "before")
args = append(args, pivot)
args = append(args, value)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) LInsertAfter(key string, pivot, value interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "linsert")
args = append(args, key)
args = append(args, "after")
args = append(args, pivot)
args = append(args, value)
return RedisCall(c.cluster, respString(args), callback)
}
// Hash
func (c *RedisClusterClient[C]) HExists(key, field string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "hexists")
args = append(args, key)
args = append(args, field)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) HDel(key string, fields []string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "hdel")
args = append(args, key)
for _, field := range fields {
args = append(args, field)
}
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) HLen(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "hlen")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) HGet(key, field string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "hget")
args = append(args, key)
args = append(args, field)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) HSet(key, field string, value interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "hset")
args = append(args, key)
args = append(args, field)
args = append(args, value)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) HMGet(key string, fields []string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "hmget")
args = append(args, key)
for _, field := range fields {
args = append(args, field)
}
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) HMSet(key string, kvMap map[string]interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "hmset")
args = append(args, key)
for k, v := range kvMap {
args = append(args, k)
args = append(args, v)
}
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) HKeys(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "hkeys")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) HVals(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "hvals")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) HGetAll(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "hgetall")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) HIncrBy(key, field string, delta int, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "hincrby")
args = append(args, key)
args = append(args, field)
args = append(args, delta)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) HIncrByFloat(key, field string, delta float64, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "hincrbyfloat")
args = append(args, key)
args = append(args, field)
args = append(args, delta)
return RedisCall(c.cluster, respString(args), callback)
}
// Set
func (c *RedisClusterClient[C]) SCard(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "scard")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) SAdd(key string, vals []interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "sadd")
args = append(args, key)
for _, val := range vals {
args = append(args, val)
}
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) SRem(key string, vals []interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "srem")
args = append(args, key)
for _, val := range vals {
args = append(args, val)
}
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) SIsMember(key string, value interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "sismember")
args = append(args, key)
args = append(args, value)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) SMembers(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "smembers")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) SDiff(key1, key2 string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "sdiff")
args = append(args, key1)
args = append(args, key2)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) SDiffStore(destination, key1, key2 string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "sdiffstore")
args = append(args, destination)
args = append(args, key1)
args = append(args, key2)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) SInter(key1, key2 string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "sinter")
args = append(args, key1)
args = append(args, key2)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) SInterStore(destination, key1, key2 string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "sinterstore")
args = append(args, destination)
args = append(args, key1)
args = append(args, key2)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) SUnion(key1, key2 string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "sunion")
args = append(args, key1)
args = append(args, key2)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) SUnionStore(destination, key1, key2 string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "sunionstore")
args = append(args, destination)
args = append(args, key1)
args = append(args, key2)
return RedisCall(c.cluster, respString(args), callback)
}
// ZSet
func (c *RedisClusterClient[C]) ZCard(key string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "zcard")
args = append(args, key)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) ZAdd(key string, msMap map[string]interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "zadd")
args = append(args, key)
for m, s := range msMap {
args = append(args, s)
args = append(args, m)
}
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) ZCount(key string, min interface{}, max interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "zcount")
args = append(args, key)
args = append(args, min)
args = append(args, max)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) ZIncrBy(key string, member string, delta interface{}, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "zincrby")
args = append(args, key)
args = append(args, delta)
args = append(args, member)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) ZScore(key, member string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "zscore")
args = append(args, key)
args = append(args, member)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) ZRank(key, member string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "zrank")
args = append(args, key)
args = append(args, member)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) ZRevRank(key, member string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "zrevrank")
args = append(args, key)
args = append(args, member)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) ZRem(key string, members []string, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "zrem")
args = append(args, key)
for _, m := range members {
args = append(args, m)
}
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) ZRange(key string, start, stop int, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "zrange")
args = append(args, key)
args = append(args, start)
args = append(args, stop)
return RedisCall(c.cluster, respString(args), callback)
}
func (c *RedisClusterClient[C]) ZRevRange(key string, start, stop int, callback RedisResponseCallback) error {
if err := c.checkReadyFunc(); err != nil {
return err
}
args := make([]interface{}, 0)
args = append(args, "zrevrange")
args = append(args, key)
args = append(args, start)
args = append(args, stop)
return RedisCall(c.cluster, respString(args), callback)
}