feat(redis): add Do/DoCtx for generic command execution #5417 (#5442)

This commit is contained in:
Ran丶
2026-03-22 20:26:53 +08:00
committed by GitHub
parent ba9c275853
commit 0069721586
2 changed files with 50 additions and 0 deletions

View File

@@ -65,6 +65,7 @@ type (
// RedisNode interface represents a redis node.
RedisNode interface {
red.Cmdable
Do(ctx context.Context, args ...any) *red.Cmd
}
// GeoLocation is used with GeoAdd to add geospatial location.
@@ -421,6 +422,25 @@ func (s *Redis) EvalCtx(ctx context.Context, script string, keys []string,
return conn.Eval(ctx, script, keys, args...).Result()
}
// Do executes a generic redis command with given arguments.
func (s *Redis) Do(args ...any) (any, error) {
return s.DoCtx(context.Background(), args...)
}
// DoCtx executes a generic redis command with given arguments using the provided context.
func (s *Redis) DoCtx(ctx context.Context, args ...any) (any, error) {
if len(args) == 0 {
return nil, errors.New("missing redis command")
}
conn, err := getRedis(s)
if err != nil {
return nil, err
}
return conn.Do(ctx, args...).Result()
}
// EvalSha is the implementation of redis evalsha command.
func (s *Redis) EvalSha(sha string, keys []string, args ...any) (any, error) {
return s.EvalShaCtx(context.Background(), sha, keys, args...)

View File

@@ -275,6 +275,36 @@ func TestRedis_Eval(t *testing.T) {
})
}
func TestRedis_Do(t *testing.T) {
runOnRedis(t, func(client *Redis) {
_, err := newRedis(client.Addr, badType()).Do("PING")
assert.NotNil(t, err)
pong, err := client.Do("PING")
assert.Nil(t, err)
assert.Equal(t, "PONG", pong)
ok, err := client.Do("SET", "key1", "value1")
assert.Nil(t, err)
assert.Equal(t, "OK", ok)
val, err := client.Do("GET", "key1")
assert.Nil(t, err)
assert.Equal(t, "value1", val)
_, err = client.Do("GET", "not_exist")
assert.Equal(t, Nil, err)
_, err = client.Do()
assert.NotNil(t, err)
ctx, cancel := context.WithCancel(context.Background())
cancel()
_, err = client.DoCtx(ctx, "PING")
assert.Equal(t, context.Canceled, err)
})
}
func TestRedis_ScriptRun(t *testing.T) {
runOnRedis(t, func(client *Redis) {
sc := NewScript(`redis.call("EXISTS", KEYS[1])`)