From 1b768850405d25256bc32e0584a22680aad0607b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ran=E4=B8=B6?= <3246617572@qq.com> Date: Fri, 12 Dec 2025 23:18:46 +0800 Subject: [PATCH] feat(redis): add redis command for getex (#5323) --- core/stores/redis/redis.go | 22 +++++++++++++++++++ core/stores/redis/redis_test.go | 39 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/core/stores/redis/redis.go b/core/stores/redis/redis.go index d15c8ba9b..1dec67c7c 100644 --- a/core/stores/redis/redis.go +++ b/core/stores/redis/redis.go @@ -664,6 +664,28 @@ func (s *Redis) GetDelCtx(ctx context.Context, key string) (string, error) { return val, err } +// GetEx is the implementation of redis getex command. +// Available since: redis version 6.2.0 +func (s *Redis) GetEx(key string, seconds int) (string, error) { + return s.GetExCtx(context.Background(), key, seconds) +} + +// GetExCtx is the implementation of redis getex command. +// Available since: redis version 6.2.0 +func (s *Redis) GetExCtx(ctx context.Context, key string, seconds int) (string, error) { + conn, err := getRedis(s) + if err != nil { + return "", err + } + + val, err := conn.GetEx(ctx, key, time.Duration(seconds)*time.Second).Result() + if errors.Is(err, red.Nil) { + return "", nil + } + + return val, err +} + // GetSet is the implementation of redis getset command. func (s *Redis) GetSet(key, value string) (string, error) { return s.GetSetCtx(context.Background(), key, value) diff --git a/core/stores/redis/redis_test.go b/core/stores/redis/redis_test.go index be0ad3d9a..a84dc585e 100644 --- a/core/stores/redis/redis_test.go +++ b/core/stores/redis/redis_test.go @@ -1104,6 +1104,45 @@ func TestRedis_GetDel(t *testing.T) { }) } +func TestRedis_GetEx(t *testing.T) { + t.Run("get_ex", func(t *testing.T) { + runOnRedis(t, func(client *Redis) { + val, err := client.GetEx("getex_key", 10) + assert.Equal(t, "", val) + assert.Nil(t, err) + + err = client.Set("getex_key", "getex_value") + assert.Nil(t, err) + + val, err = client.GetEx("getex_key", 10) + assert.Nil(t, err) + assert.Equal(t, "getex_value", val) + val, err = client.Get("getex_key") + assert.Nil(t, err) + assert.Equal(t, "getex_value", val) + + ttl, err := client.Ttl("getex_key") + assert.Nil(t, err) + assert.True(t, ttl > 0 && ttl <= 10) + + val, err = client.GetEx("getex_key", 5) + assert.Nil(t, err) + assert.Equal(t, "getex_value", val) + + ttl, err = client.Ttl("getex_key") + assert.Nil(t, err) + assert.True(t, ttl > 0 && ttl <= 5) + }) + }) + + t.Run("get_ex_with_error", func(t *testing.T) { + runOnRedisWithError(t, func(client *Redis) { + _, err := newRedis(client.Addr, badType()).GetEx("hello", 10) + assert.Error(t, err) + }) + }) +} + func TestRedis_GetSet(t *testing.T) { t.Run("set_get", func(t *testing.T) { runOnRedis(t, func(client *Redis) {