forked from ebhomengo/niki
1
0
Fork 0
niki/vendor/github.com/redis/go-redis/v9/commands.go

1229 lines
20 KiB
Go
Raw Normal View History

2024-02-18 10:42:21 +00:00
package redis
import (
"context"
"encoding"
"errors"
"fmt"
"io"
"net"
"reflect"
"runtime"
"strings"
"time"
"github.com/redis/go-redis/v9/internal"
)
// KeepTTL is a Redis KEEPTTL option to keep existing TTL, it requires your redis-server version >= 6.0,
2024-02-18 10:42:21 +00:00
// otherwise you will receive an error: (error) ERR syntax error.
2024-02-18 10:42:21 +00:00
// For example:
2024-02-18 10:42:21 +00:00
//
2024-02-18 10:42:21 +00:00
// rdb.Set(ctx, key, value, redis.KeepTTL)
2024-02-18 10:42:21 +00:00
const KeepTTL = -1
func usePrecise(dur time.Duration) bool {
2024-02-18 10:42:21 +00:00
return dur < time.Second || dur%time.Second != 0
2024-02-18 10:42:21 +00:00
}
func formatMs(ctx context.Context, dur time.Duration) int64 {
2024-02-18 10:42:21 +00:00
if dur > 0 && dur < time.Millisecond {
2024-02-18 10:42:21 +00:00
internal.Logger.Printf(
2024-02-18 10:42:21 +00:00
ctx,
2024-02-18 10:42:21 +00:00
"specified duration is %s, but minimal supported value is %s - truncating to 1ms",
2024-02-18 10:42:21 +00:00
dur, time.Millisecond,
)
2024-02-18 10:42:21 +00:00
return 1
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return int64(dur / time.Millisecond)
2024-02-18 10:42:21 +00:00
}
func formatSec(ctx context.Context, dur time.Duration) int64 {
2024-02-18 10:42:21 +00:00
if dur > 0 && dur < time.Second {
2024-02-18 10:42:21 +00:00
internal.Logger.Printf(
2024-02-18 10:42:21 +00:00
ctx,
2024-02-18 10:42:21 +00:00
"specified duration is %s, but minimal supported value is %s - truncating to 1s",
2024-02-18 10:42:21 +00:00
dur, time.Second,
)
2024-02-18 10:42:21 +00:00
return 1
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return int64(dur / time.Second)
2024-02-18 10:42:21 +00:00
}
func appendArgs(dst, src []interface{}) []interface{} {
2024-02-18 10:42:21 +00:00
if len(src) == 1 {
2024-02-18 10:42:21 +00:00
return appendArg(dst, src[0])
2024-02-18 10:42:21 +00:00
}
dst = append(dst, src...)
2024-02-18 10:42:21 +00:00
return dst
2024-02-18 10:42:21 +00:00
}
func appendArg(dst []interface{}, arg interface{}) []interface{} {
2024-02-18 10:42:21 +00:00
switch arg := arg.(type) {
2024-02-18 10:42:21 +00:00
case []string:
2024-02-18 10:42:21 +00:00
for _, s := range arg {
2024-02-18 10:42:21 +00:00
dst = append(dst, s)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return dst
2024-02-18 10:42:21 +00:00
case []interface{}:
2024-02-18 10:42:21 +00:00
dst = append(dst, arg...)
2024-02-18 10:42:21 +00:00
return dst
2024-02-18 10:42:21 +00:00
case map[string]interface{}:
2024-02-18 10:42:21 +00:00
for k, v := range arg {
2024-02-18 10:42:21 +00:00
dst = append(dst, k, v)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return dst
2024-02-18 10:42:21 +00:00
case map[string]string:
2024-02-18 10:42:21 +00:00
for k, v := range arg {
2024-02-18 10:42:21 +00:00
dst = append(dst, k, v)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return dst
2024-02-18 10:42:21 +00:00
case time.Time, time.Duration, encoding.BinaryMarshaler, net.IP:
2024-02-18 10:42:21 +00:00
return append(dst, arg)
2024-02-18 10:42:21 +00:00
default:
2024-02-18 10:42:21 +00:00
// scan struct field
2024-02-18 10:42:21 +00:00
v := reflect.ValueOf(arg)
2024-02-18 10:42:21 +00:00
if v.Type().Kind() == reflect.Ptr {
2024-02-18 10:42:21 +00:00
if v.IsNil() {
2024-02-18 10:42:21 +00:00
// error: arg is not a valid object
2024-02-18 10:42:21 +00:00
return dst
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
v = v.Elem()
2024-02-18 10:42:21 +00:00
}
if v.Type().Kind() == reflect.Struct {
2024-02-18 10:42:21 +00:00
return appendStructField(dst, v)
2024-02-18 10:42:21 +00:00
}
return append(dst, arg)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
// appendStructField appends the field and value held by the structure v to dst, and returns the appended dst.
2024-02-18 10:42:21 +00:00
func appendStructField(dst []interface{}, v reflect.Value) []interface{} {
2024-02-18 10:42:21 +00:00
typ := v.Type()
2024-02-18 10:42:21 +00:00
for i := 0; i < typ.NumField(); i++ {
2024-02-18 10:42:21 +00:00
tag := typ.Field(i).Tag.Get("redis")
2024-02-18 10:42:21 +00:00
if tag == "" || tag == "-" {
2024-02-18 10:42:21 +00:00
continue
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
name, opt, _ := strings.Cut(tag, ",")
2024-02-18 10:42:21 +00:00
if name == "" {
2024-02-18 10:42:21 +00:00
continue
2024-02-18 10:42:21 +00:00
}
field := v.Field(i)
// miss field
2024-02-18 10:42:21 +00:00
if omitEmpty(opt) && isEmptyValue(field) {
2024-02-18 10:42:21 +00:00
continue
2024-02-18 10:42:21 +00:00
}
if field.CanInterface() {
2024-02-18 10:42:21 +00:00
dst = append(dst, name, field.Interface())
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
return dst
2024-02-18 10:42:21 +00:00
}
func omitEmpty(opt string) bool {
2024-02-18 10:42:21 +00:00
for opt != "" {
2024-02-18 10:42:21 +00:00
var name string
2024-02-18 10:42:21 +00:00
name, opt, _ = strings.Cut(opt, ",")
2024-02-18 10:42:21 +00:00
if name == "omitempty" {
2024-02-18 10:42:21 +00:00
return true
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return false
2024-02-18 10:42:21 +00:00
}
func isEmptyValue(v reflect.Value) bool {
2024-02-18 10:42:21 +00:00
switch v.Kind() {
2024-02-18 10:42:21 +00:00
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
2024-02-18 10:42:21 +00:00
return v.Len() == 0
2024-02-18 10:42:21 +00:00
case reflect.Bool:
2024-02-18 10:42:21 +00:00
return !v.Bool()
2024-02-18 10:42:21 +00:00
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
2024-02-18 10:42:21 +00:00
return v.Int() == 0
2024-02-18 10:42:21 +00:00
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
2024-02-18 10:42:21 +00:00
return v.Uint() == 0
2024-02-18 10:42:21 +00:00
case reflect.Float32, reflect.Float64:
2024-02-18 10:42:21 +00:00
return v.Float() == 0
2024-02-18 10:42:21 +00:00
case reflect.Interface, reflect.Pointer:
2024-02-18 10:42:21 +00:00
return v.IsNil()
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return false
2024-02-18 10:42:21 +00:00
}
type Cmdable interface {
Pipeline() Pipeliner
2024-02-18 10:42:21 +00:00
Pipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder, error)
TxPipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder, error)
2024-02-18 10:42:21 +00:00
TxPipeline() Pipeliner
Command(ctx context.Context) *CommandsInfoCmd
2024-02-18 10:42:21 +00:00
CommandList(ctx context.Context, filter *FilterBy) *StringSliceCmd
2024-02-18 10:42:21 +00:00
CommandGetKeys(ctx context.Context, commands ...interface{}) *StringSliceCmd
2024-02-18 10:42:21 +00:00
CommandGetKeysAndFlags(ctx context.Context, commands ...interface{}) *KeyFlagsCmd
2024-02-18 10:42:21 +00:00
ClientGetName(ctx context.Context) *StringCmd
2024-02-18 10:42:21 +00:00
Echo(ctx context.Context, message interface{}) *StringCmd
2024-02-18 10:42:21 +00:00
Ping(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
Quit(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
Unlink(ctx context.Context, keys ...string) *IntCmd
BgRewriteAOF(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
BgSave(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
ClientKill(ctx context.Context, ipPort string) *StatusCmd
2024-02-18 10:42:21 +00:00
ClientKillByFilter(ctx context.Context, keys ...string) *IntCmd
2024-02-18 10:42:21 +00:00
ClientList(ctx context.Context) *StringCmd
2024-02-18 10:42:21 +00:00
ClientInfo(ctx context.Context) *ClientInfoCmd
2024-02-18 10:42:21 +00:00
ClientPause(ctx context.Context, dur time.Duration) *BoolCmd
2024-02-18 10:42:21 +00:00
ClientUnpause(ctx context.Context) *BoolCmd
2024-02-18 10:42:21 +00:00
ClientID(ctx context.Context) *IntCmd
2024-02-18 10:42:21 +00:00
ClientUnblock(ctx context.Context, id int64) *IntCmd
2024-02-18 10:42:21 +00:00
ClientUnblockWithError(ctx context.Context, id int64) *IntCmd
2024-02-18 10:42:21 +00:00
ConfigGet(ctx context.Context, parameter string) *MapStringStringCmd
2024-02-18 10:42:21 +00:00
ConfigResetStat(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
ConfigSet(ctx context.Context, parameter, value string) *StatusCmd
2024-02-18 10:42:21 +00:00
ConfigRewrite(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
DBSize(ctx context.Context) *IntCmd
2024-02-18 10:42:21 +00:00
FlushAll(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
FlushAllAsync(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
FlushDB(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
FlushDBAsync(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
Info(ctx context.Context, section ...string) *StringCmd
2024-02-18 10:42:21 +00:00
LastSave(ctx context.Context) *IntCmd
2024-02-18 10:42:21 +00:00
Save(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
Shutdown(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
ShutdownSave(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
ShutdownNoSave(ctx context.Context) *StatusCmd
2024-02-18 10:42:21 +00:00
SlaveOf(ctx context.Context, host, port string) *StatusCmd
2024-02-18 10:42:21 +00:00
SlowLogGet(ctx context.Context, num int64) *SlowLogCmd
2024-02-18 10:42:21 +00:00
Time(ctx context.Context) *TimeCmd
2024-02-18 10:42:21 +00:00
DebugObject(ctx context.Context, key string) *StringCmd
2024-02-18 10:42:21 +00:00
MemoryUsage(ctx context.Context, key string, samples ...int) *IntCmd
ModuleLoadex(ctx context.Context, conf *ModuleLoadexConfig) *StringCmd
ACLCmdable
2024-02-18 10:42:21 +00:00
BitMapCmdable
2024-02-18 10:42:21 +00:00
ClusterCmdable
2024-02-18 10:42:21 +00:00
GearsCmdable
2024-02-18 10:42:21 +00:00
GenericCmdable
2024-02-18 10:42:21 +00:00
GeoCmdable
2024-02-18 10:42:21 +00:00
HashCmdable
2024-02-18 10:42:21 +00:00
HyperLogLogCmdable
2024-02-18 10:42:21 +00:00
ListCmdable
2024-02-18 10:42:21 +00:00
ProbabilisticCmdable
2024-02-18 10:42:21 +00:00
PubSubCmdable
2024-02-18 10:42:21 +00:00
ScriptingFunctionsCmdable
2024-02-18 10:42:21 +00:00
SetCmdable
2024-02-18 10:42:21 +00:00
SortedSetCmdable
2024-02-18 10:42:21 +00:00
StringCmdable
2024-02-18 10:42:21 +00:00
StreamCmdable
2024-02-18 10:42:21 +00:00
TimeseriesCmdable
2024-02-18 10:42:21 +00:00
JSONCmdable
}
type StatefulCmdable interface {
Cmdable
2024-02-18 10:42:21 +00:00
Auth(ctx context.Context, password string) *StatusCmd
2024-02-18 10:42:21 +00:00
AuthACL(ctx context.Context, username, password string) *StatusCmd
2024-02-18 10:42:21 +00:00
Select(ctx context.Context, index int) *StatusCmd
2024-02-18 10:42:21 +00:00
SwapDB(ctx context.Context, index1, index2 int) *StatusCmd
2024-02-18 10:42:21 +00:00
ClientSetName(ctx context.Context, name string) *BoolCmd
2024-02-18 10:42:21 +00:00
ClientSetInfo(ctx context.Context, info LibraryInfo) *StatusCmd
2024-02-18 10:42:21 +00:00
Hello(ctx context.Context, ver int, username, password, clientName string) *MapStringInterfaceCmd
}
var (
_ Cmdable = (*Client)(nil)
2024-02-18 10:42:21 +00:00
_ Cmdable = (*Tx)(nil)
2024-02-18 10:42:21 +00:00
_ Cmdable = (*Ring)(nil)
2024-02-18 10:42:21 +00:00
_ Cmdable = (*ClusterClient)(nil)
)
type cmdable func(ctx context.Context, cmd Cmder) error
type statefulCmdable func(ctx context.Context, cmd Cmder) error
//------------------------------------------------------------------------------
func (c statefulCmdable) Auth(ctx context.Context, password string) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "auth", password)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// AuthACL Perform an AUTH command, using the given user and pass.
2024-02-18 10:42:21 +00:00
// Should be used to authenticate the current connection with one of the connections defined in the ACL list
2024-02-18 10:42:21 +00:00
// when connecting to a Redis 6.0 instance, or greater, that is using the Redis ACL system.
2024-02-18 10:42:21 +00:00
func (c statefulCmdable) AuthACL(ctx context.Context, username, password string) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "auth", username, password)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) Wait(ctx context.Context, numSlaves int, timeout time.Duration) *IntCmd {
2024-02-18 10:42:21 +00:00
cmd := NewIntCmd(ctx, "wait", numSlaves, int(timeout/time.Millisecond))
2024-02-18 10:42:21 +00:00
cmd.setReadTimeout(timeout)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) WaitAOF(ctx context.Context, numLocal, numSlaves int, timeout time.Duration) *IntCmd {
2024-02-18 10:42:21 +00:00
cmd := NewIntCmd(ctx, "waitAOF", numLocal, numSlaves, int(timeout/time.Millisecond))
2024-02-18 10:42:21 +00:00
cmd.setReadTimeout(timeout)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c statefulCmdable) Select(ctx context.Context, index int) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "select", index)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c statefulCmdable) SwapDB(ctx context.Context, index1, index2 int) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "swapdb", index1, index2)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// ClientSetName assigns a name to the connection.
2024-02-18 10:42:21 +00:00
func (c statefulCmdable) ClientSetName(ctx context.Context, name string) *BoolCmd {
2024-02-18 10:42:21 +00:00
cmd := NewBoolCmd(ctx, "client", "setname", name)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// ClientSetInfo sends a CLIENT SETINFO command with the provided info.
2024-02-18 10:42:21 +00:00
func (c statefulCmdable) ClientSetInfo(ctx context.Context, info LibraryInfo) *StatusCmd {
2024-02-18 10:42:21 +00:00
err := info.Validate()
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
panic(err.Error())
2024-02-18 10:42:21 +00:00
}
var cmd *StatusCmd
2024-02-18 10:42:21 +00:00
if info.LibName != nil {
2024-02-18 10:42:21 +00:00
libName := fmt.Sprintf("go-redis(%s,%s)", *info.LibName, runtime.Version())
2024-02-18 10:42:21 +00:00
cmd = NewStatusCmd(ctx, "client", "setinfo", "LIB-NAME", libName)
2024-02-18 10:42:21 +00:00
} else {
2024-02-18 10:42:21 +00:00
cmd = NewStatusCmd(ctx, "client", "setinfo", "LIB-VER", *info.LibVer)
2024-02-18 10:42:21 +00:00
}
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// Validate checks if only one field in the struct is non-nil.
2024-02-18 10:42:21 +00:00
func (info LibraryInfo) Validate() error {
2024-02-18 10:42:21 +00:00
if info.LibName != nil && info.LibVer != nil {
2024-02-18 10:42:21 +00:00
return errors.New("both LibName and LibVer cannot be set at the same time")
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
if info.LibName == nil && info.LibVer == nil {
2024-02-18 10:42:21 +00:00
return errors.New("at least one of LibName and LibVer should be set")
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return nil
2024-02-18 10:42:21 +00:00
}
// Hello Set the resp protocol used.
2024-02-18 10:42:21 +00:00
func (c statefulCmdable) Hello(ctx context.Context,
2024-02-18 10:42:21 +00:00
ver int, username, password, clientName string,
2024-02-18 10:42:21 +00:00
) *MapStringInterfaceCmd {
2024-02-18 10:42:21 +00:00
args := make([]interface{}, 0, 7)
2024-02-18 10:42:21 +00:00
args = append(args, "hello", ver)
2024-02-18 10:42:21 +00:00
if password != "" {
2024-02-18 10:42:21 +00:00
if username != "" {
2024-02-18 10:42:21 +00:00
args = append(args, "auth", username, password)
2024-02-18 10:42:21 +00:00
} else {
2024-02-18 10:42:21 +00:00
args = append(args, "auth", "default", password)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
if clientName != "" {
2024-02-18 10:42:21 +00:00
args = append(args, "setname", clientName)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd := NewMapStringInterfaceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
//------------------------------------------------------------------------------
func (c cmdable) Command(ctx context.Context) *CommandsInfoCmd {
2024-02-18 10:42:21 +00:00
cmd := NewCommandsInfoCmd(ctx, "command")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// FilterBy is used for the `CommandList` command parameter.
2024-02-18 10:42:21 +00:00
type FilterBy struct {
Module string
ACLCat string
2024-02-18 10:42:21 +00:00
Pattern string
}
func (c cmdable) CommandList(ctx context.Context, filter *FilterBy) *StringSliceCmd {
2024-02-18 10:42:21 +00:00
args := make([]interface{}, 0, 5)
2024-02-18 10:42:21 +00:00
args = append(args, "command", "list")
2024-02-18 10:42:21 +00:00
if filter != nil {
2024-02-18 10:42:21 +00:00
if filter.Module != "" {
2024-02-18 10:42:21 +00:00
args = append(args, "filterby", "module", filter.Module)
2024-02-18 10:42:21 +00:00
} else if filter.ACLCat != "" {
2024-02-18 10:42:21 +00:00
args = append(args, "filterby", "aclcat", filter.ACLCat)
2024-02-18 10:42:21 +00:00
} else if filter.Pattern != "" {
2024-02-18 10:42:21 +00:00
args = append(args, "filterby", "pattern", filter.Pattern)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd := NewStringSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) CommandGetKeys(ctx context.Context, commands ...interface{}) *StringSliceCmd {
2024-02-18 10:42:21 +00:00
args := make([]interface{}, 2+len(commands))
2024-02-18 10:42:21 +00:00
args[0] = "command"
2024-02-18 10:42:21 +00:00
args[1] = "getkeys"
2024-02-18 10:42:21 +00:00
copy(args[2:], commands)
2024-02-18 10:42:21 +00:00
cmd := NewStringSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) CommandGetKeysAndFlags(ctx context.Context, commands ...interface{}) *KeyFlagsCmd {
2024-02-18 10:42:21 +00:00
args := make([]interface{}, 2+len(commands))
2024-02-18 10:42:21 +00:00
args[0] = "command"
2024-02-18 10:42:21 +00:00
args[1] = "getkeysandflags"
2024-02-18 10:42:21 +00:00
copy(args[2:], commands)
2024-02-18 10:42:21 +00:00
cmd := NewKeyFlagsCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// ClientGetName returns the name of the connection.
2024-02-18 10:42:21 +00:00
func (c cmdable) ClientGetName(ctx context.Context) *StringCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStringCmd(ctx, "client", "getname")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) Echo(ctx context.Context, message interface{}) *StringCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStringCmd(ctx, "echo", message)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) Ping(ctx context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "ping")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) Quit(_ context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
panic("not implemented")
2024-02-18 10:42:21 +00:00
}
//------------------------------------------------------------------------------
func (c cmdable) BgRewriteAOF(ctx context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "bgrewriteaof")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) BgSave(ctx context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "bgsave")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) ClientKill(ctx context.Context, ipPort string) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "client", "kill", ipPort)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// ClientKillByFilter is new style syntax, while the ClientKill is old
2024-02-18 10:42:21 +00:00
//
2024-02-18 10:42:21 +00:00
// CLIENT KILL <option> [value] ... <option> [value]
2024-02-18 10:42:21 +00:00
func (c cmdable) ClientKillByFilter(ctx context.Context, keys ...string) *IntCmd {
2024-02-18 10:42:21 +00:00
args := make([]interface{}, 2+len(keys))
2024-02-18 10:42:21 +00:00
args[0] = "client"
2024-02-18 10:42:21 +00:00
args[1] = "kill"
2024-02-18 10:42:21 +00:00
for i, key := range keys {
2024-02-18 10:42:21 +00:00
args[2+i] = key
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd := NewIntCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) ClientList(ctx context.Context) *StringCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStringCmd(ctx, "client", "list")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) ClientPause(ctx context.Context, dur time.Duration) *BoolCmd {
2024-02-18 10:42:21 +00:00
cmd := NewBoolCmd(ctx, "client", "pause", formatMs(ctx, dur))
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) ClientUnpause(ctx context.Context) *BoolCmd {
2024-02-18 10:42:21 +00:00
cmd := NewBoolCmd(ctx, "client", "unpause")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) ClientID(ctx context.Context) *IntCmd {
2024-02-18 10:42:21 +00:00
cmd := NewIntCmd(ctx, "client", "id")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) ClientUnblock(ctx context.Context, id int64) *IntCmd {
2024-02-18 10:42:21 +00:00
cmd := NewIntCmd(ctx, "client", "unblock", id)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) ClientUnblockWithError(ctx context.Context, id int64) *IntCmd {
2024-02-18 10:42:21 +00:00
cmd := NewIntCmd(ctx, "client", "unblock", id, "error")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) ClientInfo(ctx context.Context) *ClientInfoCmd {
2024-02-18 10:42:21 +00:00
cmd := NewClientInfoCmd(ctx, "client", "info")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// ------------------------------------------------------------------------------------------------
func (c cmdable) ConfigGet(ctx context.Context, parameter string) *MapStringStringCmd {
2024-02-18 10:42:21 +00:00
cmd := NewMapStringStringCmd(ctx, "config", "get", parameter)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) ConfigResetStat(ctx context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "config", "resetstat")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) ConfigSet(ctx context.Context, parameter, value string) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "config", "set", parameter, value)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) ConfigRewrite(ctx context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "config", "rewrite")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) DBSize(ctx context.Context) *IntCmd {
2024-02-18 10:42:21 +00:00
cmd := NewIntCmd(ctx, "dbsize")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) FlushAll(ctx context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "flushall")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) FlushAllAsync(ctx context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "flushall", "async")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) FlushDB(ctx context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "flushdb")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) FlushDBAsync(ctx context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "flushdb", "async")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) Info(ctx context.Context, sections ...string) *StringCmd {
2024-02-18 10:42:21 +00:00
args := make([]interface{}, 1+len(sections))
2024-02-18 10:42:21 +00:00
args[0] = "info"
2024-02-18 10:42:21 +00:00
for i, section := range sections {
2024-02-18 10:42:21 +00:00
args[i+1] = section
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd := NewStringCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) InfoMap(ctx context.Context, sections ...string) *InfoCmd {
2024-02-18 10:42:21 +00:00
args := make([]interface{}, 1+len(sections))
2024-02-18 10:42:21 +00:00
args[0] = "info"
2024-02-18 10:42:21 +00:00
for i, section := range sections {
2024-02-18 10:42:21 +00:00
args[i+1] = section
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd := NewInfoCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) LastSave(ctx context.Context) *IntCmd {
2024-02-18 10:42:21 +00:00
cmd := NewIntCmd(ctx, "lastsave")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) Save(ctx context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "save")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) shutdown(ctx context.Context, modifier string) *StatusCmd {
2024-02-18 10:42:21 +00:00
var args []interface{}
2024-02-18 10:42:21 +00:00
if modifier == "" {
2024-02-18 10:42:21 +00:00
args = []interface{}{"shutdown"}
2024-02-18 10:42:21 +00:00
} else {
2024-02-18 10:42:21 +00:00
args = []interface{}{"shutdown", modifier}
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
if err := cmd.Err(); err != nil {
2024-02-18 10:42:21 +00:00
if err == io.EOF {
2024-02-18 10:42:21 +00:00
// Server quit as expected.
2024-02-18 10:42:21 +00:00
cmd.err = nil
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
} else {
2024-02-18 10:42:21 +00:00
// Server did not quit. String reply contains the reason.
2024-02-18 10:42:21 +00:00
cmd.err = errors.New(cmd.val)
2024-02-18 10:42:21 +00:00
cmd.val = ""
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) Shutdown(ctx context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
return c.shutdown(ctx, "")
2024-02-18 10:42:21 +00:00
}
func (c cmdable) ShutdownSave(ctx context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
return c.shutdown(ctx, "save")
2024-02-18 10:42:21 +00:00
}
func (c cmdable) ShutdownNoSave(ctx context.Context) *StatusCmd {
2024-02-18 10:42:21 +00:00
return c.shutdown(ctx, "nosave")
2024-02-18 10:42:21 +00:00
}
func (c cmdable) SlaveOf(ctx context.Context, host, port string) *StatusCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, "slaveof", host, port)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) SlowLogGet(ctx context.Context, num int64) *SlowLogCmd {
2024-02-18 10:42:21 +00:00
cmd := NewSlowLogCmd(context.Background(), "slowlog", "get", num)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) Sync(_ context.Context) {
2024-02-18 10:42:21 +00:00
panic("not implemented")
2024-02-18 10:42:21 +00:00
}
func (c cmdable) Time(ctx context.Context) *TimeCmd {
2024-02-18 10:42:21 +00:00
cmd := NewTimeCmd(ctx, "time")
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) DebugObject(ctx context.Context, key string) *StringCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStringCmd(ctx, "debug", "object", key)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) MemoryUsage(ctx context.Context, key string, samples ...int) *IntCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"memory", "usage", key}
2024-02-18 10:42:21 +00:00
if len(samples) > 0 {
2024-02-18 10:42:21 +00:00
if len(samples) != 1 {
2024-02-18 10:42:21 +00:00
panic("MemoryUsage expects single sample count")
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
args = append(args, "SAMPLES", samples[0])
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd := NewIntCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
cmd.SetFirstKeyPos(2)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
//------------------------------------------------------------------------------
// ModuleLoadexConfig struct is used to specify the arguments for the MODULE LOADEX command of redis.
2024-02-18 10:42:21 +00:00
// `MODULE LOADEX path [CONFIG name value [CONFIG name value ...]] [ARGS args [args ...]]`
2024-02-18 10:42:21 +00:00
type ModuleLoadexConfig struct {
Path string
2024-02-18 10:42:21 +00:00
Conf map[string]interface{}
2024-02-18 10:42:21 +00:00
Args []interface{}
}
func (c *ModuleLoadexConfig) toArgs() []interface{} {
2024-02-18 10:42:21 +00:00
args := make([]interface{}, 3, 3+len(c.Conf)*3+len(c.Args)*2)
2024-02-18 10:42:21 +00:00
args[0] = "MODULE"
2024-02-18 10:42:21 +00:00
args[1] = "LOADEX"
2024-02-18 10:42:21 +00:00
args[2] = c.Path
2024-02-18 10:42:21 +00:00
for k, v := range c.Conf {
2024-02-18 10:42:21 +00:00
args = append(args, "CONFIG", k, v)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
for _, arg := range c.Args {
2024-02-18 10:42:21 +00:00
args = append(args, "ARGS", arg)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return args
2024-02-18 10:42:21 +00:00
}
// ModuleLoadex Redis `MODULE LOADEX path [CONFIG name value [CONFIG name value ...]] [ARGS args [args ...]]` command.
2024-02-18 10:42:21 +00:00
func (c cmdable) ModuleLoadex(ctx context.Context, conf *ModuleLoadexConfig) *StringCmd {
2024-02-18 10:42:21 +00:00
cmd := NewStringCmd(ctx, conf.toArgs()...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
/*
2024-02-18 10:42:21 +00:00
Monitor - represents a Redis MONITOR command, allowing the user to capture
2024-02-18 10:42:21 +00:00
and process all commands sent to a Redis server. This mimics the behavior of
2024-02-18 10:42:21 +00:00
MONITOR in the redis-cli.
2024-02-18 10:42:21 +00:00
Notes:
2024-02-18 10:42:21 +00:00
- Using MONITOR blocks the connection to the server for itself. It needs a dedicated connection
2024-02-18 10:42:21 +00:00
- The user should create a channel of type string
2024-02-18 10:42:21 +00:00
- This runs concurrently in the background. Trigger via the Start and Stop functions
2024-02-18 10:42:21 +00:00
See further: Redis MONITOR command: https://redis.io/commands/monitor
2024-02-18 10:42:21 +00:00
*/
2024-02-18 10:42:21 +00:00
func (c cmdable) Monitor(ctx context.Context, ch chan string) *MonitorCmd {
2024-02-18 10:42:21 +00:00
cmd := newMonitorCmd(ctx, ch)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}