Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return keys from commands #3130

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ type Cmder interface {
// e.g. "set k v ex 10" -> "[set k v ex 10]".
Args() []interface{}

//all keys in command.
Keys() []string

// format request and response string.
// e.g. "set k v ex 10" -> "set k v ex 10: OK", "get k" -> "get k: v".
String() string
Expand Down Expand Up @@ -126,6 +129,7 @@ type baseCmd struct {
args []interface{}
err error
keyPos int8
keys []string
rawVal interface{}
_readTimeout *time.Duration
}
Expand Down Expand Up @@ -159,6 +163,10 @@ func (cmd *baseCmd) Args() []interface{} {
return cmd.args
}

func (cmd *baseCmd) Keys() []string {
return cmd.keys
}

func (cmd *baseCmd) stringArg(pos int) string {
if pos < 0 || pos >= len(cmd.args) {
return ""
Expand Down Expand Up @@ -202,6 +210,22 @@ func (cmd *baseCmd) readRawReply(rd *proto.Reader) (err error) {
return err
}

// getInterleavedArguments returns arguments at even indices starting from index 1.
func (cmd *baseCmd) getInterleavedArguments() []string {
vladvildanov marked this conversation as resolved.
Show resolved Hide resolved
return cmd.getInterleavedArgumentsWithOffset(1)
}

// getInterleavedArgumentsWithOffset returns arguments at even indices starting from the specified offset.
func (cmd *baseCmd) getInterleavedArgumentsWithOffset(offset int) []string {
var matchingArguments []string
for i := offset; i < len(cmd.args); i += 2 {
if arg, ok := cmd.args[i].(string); ok {
matchingArguments = append(matchingArguments, arg)
}
}
return matchingArguments
}

//------------------------------------------------------------------------------

type Cmd struct {
Expand Down
61 changes: 61 additions & 0 deletions commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7279,6 +7279,67 @@ var _ = Describe("Commands", func() {
})
})

var _ = Describe("Keys Extraction Tests", func() {
var client *redis.Client
var ctx = context.TODO()

BeforeEach(func() {
client = redis.NewClient(redisOptions())
Expect(client.FlushDB(ctx).Err()).NotTo(HaveOccurred())
})

AfterEach(func() {
Expect(client.Close()).NotTo(HaveOccurred())
})

// STRING COMMANDS

It("should test Append command", func() {
cmd := client.Append(ctx, "key1", "value")
Expect(cmd.Keys()).To(Equal([]string{"key1"}))
})

It("should test Decr command", func() {
cmd := client.Decr(ctx, "key1")
Expect(cmd.Keys()).To(Equal([]string{"key1"}))
})

It("should test Get command", func() {
cmd := client.Get(ctx, "key1")
Expect(cmd.Keys()).To(Equal([]string{"key1"}))
})

It("should test MGet command", func() {
cmd := client.MGet(ctx, "key1", "key2", "key3")
Expect(cmd.Keys()).To(Equal([]string{"key1", "key2", "key3"}))
})

It("should test Set command", func() {
cmd := client.Set(ctx, "key1", "value", time.Second)
Expect(cmd.Keys()).To(Equal([]string{"key1"}))
})

It("should test MSet command", func() {
cmd := client.MSet(ctx, "key1", "value1", "key2", "value2")
Expect(cmd.Keys()).To(Equal([]string{"key1", "key2"}))
})

It("should test IncrBy command", func() {
cmd := client.IncrBy(ctx, "key1", 10)
Expect(cmd.Keys()).To(Equal([]string{"key1"}))
})

It("should test SetNX command", func() {
cmd := client.SetNX(ctx, "key1", "value", time.Second)
Expect(cmd.Keys()).To(Equal([]string{"key1"}))
})

It("should test GetDel command", func() {
cmd := client.GetDel(ctx, "key1")
Expect(cmd.Keys()).To(Equal([]string{"key1"}))
})
})

type numberStruct struct {
Number int
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ require (
)

retract (
v9.5.3 // This version was accidentally released. Please use version 9.6.0 instead.
v9.5.4 // This version was accidentally released. Please use version 9.6.0 instead.
v9.5.3 // This version was accidentally released. Please use version 9.6.0 instead.
)
23 changes: 21 additions & 2 deletions string_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,37 +32,43 @@ type StringCmdable interface {

func (c cmdable) Append(ctx context.Context, key, value string) *IntCmd {
cmd := NewIntCmd(ctx, "append", key, value)
cmd.keys = append(cmd.keys, key)
vladvildanov marked this conversation as resolved.
Show resolved Hide resolved
_ = c(ctx, cmd)
return cmd
}

func (c cmdable) Decr(ctx context.Context, key string) *IntCmd {
cmd := NewIntCmd(ctx, "decr", key)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}

func (c cmdable) DecrBy(ctx context.Context, key string, decrement int64) *IntCmd {
cmd := NewIntCmd(ctx, "decrby", key, decrement)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}

// Get Redis `GET key` command. It returns redis.Nil error when key does not exist.
func (c cmdable) Get(ctx context.Context, key string) *StringCmd {
cmd := NewStringCmd(ctx, "get", key)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}

func (c cmdable) GetRange(ctx context.Context, key string, start, end int64) *StringCmd {
cmd := NewStringCmd(ctx, "getrange", key, start, end)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}

func (c cmdable) GetSet(ctx context.Context, key string, value interface{}) *StringCmd {
cmd := NewStringCmd(ctx, "getset", key, value)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}
Expand All @@ -83,31 +89,36 @@ func (c cmdable) GetEx(ctx context.Context, key string, expiration time.Duration
}

cmd := NewStringCmd(ctx, args...)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}

// GetDel redis-server version >= 6.2.0.
func (c cmdable) GetDel(ctx context.Context, key string) *StringCmd {
cmd := NewStringCmd(ctx, "getdel", key)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}

func (c cmdable) Incr(ctx context.Context, key string) *IntCmd {
cmd := NewIntCmd(ctx, "incr", key)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}

func (c cmdable) IncrBy(ctx context.Context, key string, value int64) *IntCmd {
cmd := NewIntCmd(ctx, "incrby", key, value)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}

func (c cmdable) IncrByFloat(ctx context.Context, key string, value float64) *FloatCmd {
cmd := NewFloatCmd(ctx, "incrbyfloat", key, value)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}
Expand All @@ -125,6 +136,7 @@ func (c cmdable) MGet(ctx context.Context, keys ...string) *SliceCmd {
args[1+i] = key
}
cmd := NewSliceCmd(ctx, args...)
cmd.keys = append(cmd.keys, keys...)
_ = c(ctx, cmd)
return cmd
}
Expand All @@ -139,6 +151,7 @@ func (c cmdable) MSet(ctx context.Context, values ...interface{}) *StatusCmd {
args[0] = "mset"
args = appendArgs(args, values)
cmd := NewStatusCmd(ctx, args...)
cmd.keys = append(cmd.keys, cmd.getInterleavedArguments()...)
_ = c(ctx, cmd)
return cmd
}
Expand All @@ -153,6 +166,7 @@ func (c cmdable) MSetNX(ctx context.Context, values ...interface{}) *BoolCmd {
args[0] = "msetnx"
args = appendArgs(args, values)
cmd := NewBoolCmd(ctx, args...)
cmd.keys = append(cmd.keys, cmd.getInterleavedArguments()...)
_ = c(ctx, cmd)
return cmd
}
Expand All @@ -179,6 +193,7 @@ func (c cmdable) Set(ctx context.Context, key string, value interface{}, expirat
}

cmd := NewStatusCmd(ctx, args...)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}
Expand Down Expand Up @@ -230,13 +245,15 @@ func (c cmdable) SetArgs(ctx context.Context, key string, value interface{}, a S
}

cmd := NewStatusCmd(ctx, args...)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}

// SetEx Redis `SETEx key expiration value` command.
func (c cmdable) SetEx(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd {
cmd := NewStatusCmd(ctx, "setex", key, formatSec(ctx, expiration), value)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}
Expand All @@ -261,7 +278,7 @@ func (c cmdable) SetNX(ctx context.Context, key string, value interface{}, expir
cmd = NewBoolCmd(ctx, "set", key, value, "ex", formatSec(ctx, expiration), "nx")
}
}

cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}
Expand All @@ -285,19 +302,21 @@ func (c cmdable) SetXX(ctx context.Context, key string, value interface{}, expir
cmd = NewBoolCmd(ctx, "set", key, value, "ex", formatSec(ctx, expiration), "xx")
}
}

cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}

func (c cmdable) SetRange(ctx context.Context, key string, offset int64, value string) *IntCmd {
cmd := NewIntCmd(ctx, "setrange", key, offset, value)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}

func (c cmdable) StrLen(ctx context.Context, key string) *IntCmd {
cmd := NewIntCmd(ctx, "strlen", key)
cmd.keys = append(cmd.keys, key)
_ = c(ctx, cmd)
return cmd
}
Loading