From dd27e478918168142008ba75d2a3ce399f3dc60a Mon Sep 17 00:00:00 2001 From: CrazyZard <33921085+CrazyZard@users.noreply.github.com> Date: Tue, 14 Dec 2021 14:39:06 +0800 Subject: [PATCH 1/6] commit `decr ` `decrby` `lindex` missing method for redis --- core/stores/kv/store.go | 30 ++++++++++++++++++++++++ core/stores/kv/store_test.go | 35 ++++++++++++++++++++++++++++ core/stores/redis/redis.go | 45 ++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) diff --git a/core/stores/kv/store.go b/core/stores/kv/store.go index aa0a499a2389..1a611fe5938c 100644 --- a/core/stores/kv/store.go +++ b/core/stores/kv/store.go @@ -36,7 +36,10 @@ type ( Hvals(key string) ([]string, error) Incr(key string) (int64, error) Incrby(key string, increment int64) (int64, error) + Decr(key string) (int64, error) + Decrby(key string, increment int64) (int64, error) Llen(key string) (int, error) + Lindex(key string, index int64) (string, error) Lpop(key string) (string, error) Lpush(key string, values ...interface{}) (int, error) Lrange(key string, start, stop int) ([]string, error) @@ -294,6 +297,24 @@ func (cs clusterStore) Incrby(key string, increment int64) (int64, error) { return node.Incrby(key, increment) } +func (cs clusterStore) Decr(key string) (int64, error) { + node, err := cs.getRedis(key) + if err != nil { + return 0, err + } + + return node.Decr(key) +} + +func (cs clusterStore) Decrby(key string, increment int64) (int64, error) { + node, err := cs.getRedis(key) + if err != nil { + return 0, err + } + + return node.Decrby(key, increment) +} + func (cs clusterStore) Llen(key string) (int, error) { node, err := cs.getRedis(key) if err != nil { @@ -303,6 +324,15 @@ func (cs clusterStore) Llen(key string) (int, error) { return node.Llen(key) } +func (cs clusterStore) Lindex(key string, index int64) (string, error) { + node, err := cs.getRedis(key) + if err != nil { + return "", err + } + + return node.Lindex(key, index) +} + func (cs clusterStore) Lpop(key string) (string, error) { node, err := cs.getRedis(key) if err != nil { diff --git a/core/stores/kv/store_test.go b/core/stores/kv/store_test.go index c26a42310927..3514b6333972 100644 --- a/core/stores/kv/store_test.go +++ b/core/stores/kv/store_test.go @@ -205,6 +205,21 @@ func TestRedis_Incr(t *testing.T) { }) } +func TestRedis_Decr(t *testing.T) { + store := clusterStore{dispatcher: hash.NewConsistentHash()} + _, err := store.Decr("a") + assert.NotNil(t, err) + + runOnCluster(t, func(client Store) { + val, err := client.Decr("a") + assert.Nil(t, err) + assert.Equal(t, int64(-1), val) + val, err = client.Decr("a") + assert.Nil(t, err) + assert.Equal(t, int64(-2), val) + }) +} + func TestRedis_IncrBy(t *testing.T) { store := clusterStore{dispatcher: hash.NewConsistentHash()} _, err := store.Incrby("a", 2) @@ -220,6 +235,21 @@ func TestRedis_IncrBy(t *testing.T) { }) } +func TestRedis_DecrBy(t *testing.T) { + store := clusterStore{dispatcher: hash.NewConsistentHash()} + _, err := store.Incrby("a", 2) + assert.NotNil(t, err) + + runOnCluster(t, func(client Store) { + val, err := client.Decrby("a", 2) + assert.Nil(t, err) + assert.Equal(t, int64(-2), val) + val, err = client.Decrby("a", 3) + assert.Nil(t, err) + assert.Equal(t, int64(5), val) + }) +} + func TestRedis_List(t *testing.T) { store := clusterStore{dispatcher: hash.NewConsistentHash()} _, err := store.Lpush("key", "value1", "value2") @@ -234,6 +264,8 @@ func TestRedis_List(t *testing.T) { assert.NotNil(t, err) _, err = store.Lrem("key", 0, "val") assert.NotNil(t, err) + _, err = store.Lindex("key", 0) + assert.NotNil(t, err) runOnCluster(t, func(client Store) { val, err := client.Lpush("key", "value1", "value2") @@ -245,6 +277,9 @@ func TestRedis_List(t *testing.T) { val, err = client.Llen("key") assert.Nil(t, err) assert.Equal(t, 4, val) + value, err := client.Lindex("key", 0) + assert.Nil(t, err) + assert.Equal(t, "value2", value) vals, err := client.Lrange("key", 0, 10) assert.Nil(t, err) assert.EqualValues(t, []string{"value2", "value1", "value3", "value4"}, vals) diff --git a/core/stores/redis/redis.go b/core/stores/redis/redis.go index 3fa001c466e7..3759ac13c5ca 100644 --- a/core/stores/redis/redis.go +++ b/core/stores/redis/redis.go @@ -730,6 +730,36 @@ func (s *Redis) Incrby(key string, increment int64) (val int64, err error) { return } +// Decr is the implementation of redis decr command. +func (s *Redis) Decr(key string) (val int64, err error) { + err = s.brk.DoWithAcceptable(func() error { + conn, err := getRedis(s) + if err != nil { + return err + } + + val, err = conn.Decr(key).Result() + return err + }, acceptable) + + return +} + +// Decrby is the implementation of redis decrby command. +func (s *Redis) Decrby(key string, increment int64) (val int64, err error) { + err = s.brk.DoWithAcceptable(func() error { + conn, err := getRedis(s) + if err != nil { + return err + } + + val, err = conn.DecrBy(key, increment).Result() + return err + }, acceptable) + + return +} + // Keys is the implementation of redis keys command. func (s *Redis) Keys(pattern string) (val []string, err error) { err = s.brk.DoWithAcceptable(func() error { @@ -765,6 +795,21 @@ func (s *Redis) Llen(key string) (val int, err error) { return } +// Lindex is the implementation of redis lindex command. +func (s *Redis) Lindex(key string, index int64) (val string, err error) { + err = s.brk.DoWithAcceptable(func() error { + conn, err := getRedis(s) + if err != nil { + return err + } + + val, err = conn.LIndex(key, index).Result() + return err + }, acceptable) + + return +} + // Lpop is the implementation of redis lpop command. func (s *Redis) Lpop(key string) (val string, err error) { err = s.brk.DoWithAcceptable(func() error { From acfa0ad5a41dfd60fb798810ca03653fcec467c2 Mon Sep 17 00:00:00 2001 From: CrazyZard <33921085+CrazyZard@users.noreply.github.com> Date: Tue, 14 Dec 2021 15:52:54 +0800 Subject: [PATCH 2/6] fix(store_test):TestRedis_DecrBy --- core/stores/kv/store_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/stores/kv/store_test.go b/core/stores/kv/store_test.go index 3514b6333972..73da809feb91 100644 --- a/core/stores/kv/store_test.go +++ b/core/stores/kv/store_test.go @@ -246,7 +246,7 @@ func TestRedis_DecrBy(t *testing.T) { assert.Equal(t, int64(-2), val) val, err = client.Decrby("a", 3) assert.Nil(t, err) - assert.Equal(t, int64(5), val) + assert.Equal(t, int64(-5), val) }) } From e3258f0a5eb9824ce6c9465537adffed8c32fac7 Mon Sep 17 00:00:00 2001 From: CrazyZard <33921085+CrazyZard@users.noreply.github.com> Date: Tue, 14 Dec 2021 16:14:35 +0800 Subject: [PATCH 3/6] add unit tests for redis commands. And put the functions in alphabetical order --- core/stores/redis/redis.go | 60 ++++++++++++++++----------------- core/stores/redis/redis_test.go | 26 ++++++++++++++ 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/core/stores/redis/redis.go b/core/stores/redis/redis.go index 3759ac13c5ca..d6fad30803b7 100644 --- a/core/stores/redis/redis.go +++ b/core/stores/redis/redis.go @@ -238,6 +238,36 @@ func (s *Redis) BlpopEx(redisNode RedisNode, key string) (string, bool, error) { return vals[1], true, nil } +// Decr is the implementation of redis decr command. +func (s *Redis) Decr(key string) (val int64, err error) { + err = s.brk.DoWithAcceptable(func() error { + conn, err := getRedis(s) + if err != nil { + return err + } + + val, err = conn.Decr(key).Result() + return err + }, acceptable) + + return +} + +// Decrby is the implementation of redis decrby command. +func (s *Redis) Decrby(key string, increment int64) (val int64, err error) { + err = s.brk.DoWithAcceptable(func() error { + conn, err := getRedis(s) + if err != nil { + return err + } + + val, err = conn.DecrBy(key, increment).Result() + return err + }, acceptable) + + return +} + // Del deletes keys. func (s *Redis) Del(keys ...string) (val int, err error) { err = s.brk.DoWithAcceptable(func() error { @@ -730,36 +760,6 @@ func (s *Redis) Incrby(key string, increment int64) (val int64, err error) { return } -// Decr is the implementation of redis decr command. -func (s *Redis) Decr(key string) (val int64, err error) { - err = s.brk.DoWithAcceptable(func() error { - conn, err := getRedis(s) - if err != nil { - return err - } - - val, err = conn.Decr(key).Result() - return err - }, acceptable) - - return -} - -// Decrby is the implementation of redis decrby command. -func (s *Redis) Decrby(key string, increment int64) (val int64, err error) { - err = s.brk.DoWithAcceptable(func() error { - conn, err := getRedis(s) - if err != nil { - return err - } - - val, err = conn.DecrBy(key, increment).Result() - return err - }, acceptable) - - return -} - // Keys is the implementation of redis keys command. func (s *Redis) Keys(pattern string) (val []string, err error) { err = s.brk.DoWithAcceptable(func() error { diff --git a/core/stores/redis/redis_test.go b/core/stores/redis/redis_test.go index 1e9251e129e1..c9db5a6f1573 100644 --- a/core/stores/redis/redis_test.go +++ b/core/stores/redis/redis_test.go @@ -14,6 +14,32 @@ import ( "github.com/tal-tech/go-zero/core/stringx" ) +func TestRedis_Decr(t *testing.T) { + runOnRedis(t, func(client *Redis) { + _, err := New(client.Addr, badType()).Decr("a") + assert.NotNil(t, err) + val, err := client.Decr("a") + assert.Nil(t, err) + assert.Equal(t, int64(-1), val) + val, err = client.Decr("a") + assert.Nil(t, err) + assert.Equal(t, int64(-2), val) + }) +} + +func TestRedis_DecrBy(t *testing.T) { + runOnRedis(t, func(client *Redis) { + _, err := New(client.Addr, badType()).Decrby("a", 2) + assert.NotNil(t, err) + val, err := client.Decrby("a", 2) + assert.Nil(t, err) + assert.Equal(t, int64(-2), val) + val, err = client.Decrby("a", 3) + assert.Nil(t, err) + assert.Equal(t, int64(-5), val) + }) +} + func TestRedis_Exists(t *testing.T) { runOnRedis(t, func(client *Redis) { _, err := New(client.Addr, badType()).Exists("a") From 5cfeeead845bccfb4d016a9edbc46915d830ce81 Mon Sep 17 00:00:00 2001 From: CrazyZard <33921085+CrazyZard@users.noreply.github.com> Date: Tue, 14 Dec 2021 16:20:04 +0800 Subject: [PATCH 4/6] put the functions in alphabetical order --- core/stores/kv/store_test.go | 60 ++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/core/stores/kv/store_test.go b/core/stores/kv/store_test.go index 73da809feb91..ee7cd0472f02 100644 --- a/core/stores/kv/store_test.go +++ b/core/stores/kv/store_test.go @@ -17,6 +17,36 @@ var ( s2, _ = miniredis.Run() ) +func TestRedis_Decr(t *testing.T) { + store := clusterStore{dispatcher: hash.NewConsistentHash()} + _, err := store.Decr("a") + assert.NotNil(t, err) + + runOnCluster(t, func(client Store) { + val, err := client.Decr("a") + assert.Nil(t, err) + assert.Equal(t, int64(-1), val) + val, err = client.Decr("a") + assert.Nil(t, err) + assert.Equal(t, int64(-2), val) + }) +} + +func TestRedis_DecrBy(t *testing.T) { + store := clusterStore{dispatcher: hash.NewConsistentHash()} + _, err := store.Incrby("a", 2) + assert.NotNil(t, err) + + runOnCluster(t, func(client Store) { + val, err := client.Decrby("a", 2) + assert.Nil(t, err) + assert.Equal(t, int64(-2), val) + val, err = client.Decrby("a", 3) + assert.Nil(t, err) + assert.Equal(t, int64(-5), val) + }) +} + func TestRedis_Exists(t *testing.T) { store := clusterStore{dispatcher: hash.NewConsistentHash()} _, err := store.Exists("foo") @@ -205,21 +235,6 @@ func TestRedis_Incr(t *testing.T) { }) } -func TestRedis_Decr(t *testing.T) { - store := clusterStore{dispatcher: hash.NewConsistentHash()} - _, err := store.Decr("a") - assert.NotNil(t, err) - - runOnCluster(t, func(client Store) { - val, err := client.Decr("a") - assert.Nil(t, err) - assert.Equal(t, int64(-1), val) - val, err = client.Decr("a") - assert.Nil(t, err) - assert.Equal(t, int64(-2), val) - }) -} - func TestRedis_IncrBy(t *testing.T) { store := clusterStore{dispatcher: hash.NewConsistentHash()} _, err := store.Incrby("a", 2) @@ -235,21 +250,6 @@ func TestRedis_IncrBy(t *testing.T) { }) } -func TestRedis_DecrBy(t *testing.T) { - store := clusterStore{dispatcher: hash.NewConsistentHash()} - _, err := store.Incrby("a", 2) - assert.NotNil(t, err) - - runOnCluster(t, func(client Store) { - val, err := client.Decrby("a", 2) - assert.Nil(t, err) - assert.Equal(t, int64(-2), val) - val, err = client.Decrby("a", 3) - assert.Nil(t, err) - assert.Equal(t, int64(-5), val) - }) -} - func TestRedis_List(t *testing.T) { store := clusterStore{dispatcher: hash.NewConsistentHash()} _, err := store.Lpush("key", "value1", "value2") From 3faa0502b0abd39b16637451fb7a25d88c78fa69 Mon Sep 17 00:00:00 2001 From: CrazyZard <33921085+CrazyZard@users.noreply.github.com> Date: Tue, 14 Dec 2021 22:29:57 +0800 Subject: [PATCH 5/6] add `lindex` unit test --- core/stores/redis/redis_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/stores/redis/redis_test.go b/core/stores/redis/redis_test.go index c9db5a6f1573..49aee63831e1 100644 --- a/core/stores/redis/redis_test.go +++ b/core/stores/redis/redis_test.go @@ -321,6 +321,11 @@ func TestRedis_List(t *testing.T) { val, err = client.Llen("key") assert.Nil(t, err) assert.Equal(t, 4, val) + _, err = New(client.Addr, badType()).Lindex("key", 1) + assert.NotNil(t, err) + value, err := client.Lindex("key", 0) + assert.Nil(t, err) + assert.Equal(t, "value2", value) vals, err := client.Lrange("key", 0, 10) assert.Nil(t, err) assert.EqualValues(t, []string{"value2", "value1", "value3", "value4"}, vals) From 8bb3a07d5750290a810dbe775e23f9f8738baf86 Mon Sep 17 00:00:00 2001 From: CrazyZard <33921085+CrazyZard@users.noreply.github.com> Date: Tue, 14 Dec 2021 22:35:16 +0800 Subject: [PATCH 6/6] sort func --- core/stores/kv/store.go | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/core/stores/kv/store.go b/core/stores/kv/store.go index 1a611fe5938c..c43dcb9f5664 100644 --- a/core/stores/kv/store.go +++ b/core/stores/kv/store.go @@ -16,6 +16,8 @@ var ErrNoRedisNode = errors.New("no redis node") type ( // Store interface represents a KV store. Store interface { + Decr(key string) (int64, error) + Decrby(key string, increment int64) (int64, error) Del(keys ...string) (int, error) Eval(script, key string, args ...interface{}) (interface{}, error) Exists(key string) (bool, error) @@ -36,8 +38,6 @@ type ( Hvals(key string) ([]string, error) Incr(key string) (int64, error) Incrby(key string, increment int64) (int64, error) - Decr(key string) (int64, error) - Decrby(key string, increment int64) (int64, error) Llen(key string) (int, error) Lindex(key string, index int64) (string, error) Lpop(key string) (string, error) @@ -105,6 +105,24 @@ func NewStore(c KvConf) Store { } } +func (cs clusterStore) Decr(key string) (int64, error) { + node, err := cs.getRedis(key) + if err != nil { + return 0, err + } + + return node.Decr(key) +} + +func (cs clusterStore) Decrby(key string, increment int64) (int64, error) { + node, err := cs.getRedis(key) + if err != nil { + return 0, err + } + + return node.Decrby(key, increment) +} + func (cs clusterStore) Del(keys ...string) (int, error) { var val int var be errorx.BatchError @@ -297,24 +315,6 @@ func (cs clusterStore) Incrby(key string, increment int64) (int64, error) { return node.Incrby(key, increment) } -func (cs clusterStore) Decr(key string) (int64, error) { - node, err := cs.getRedis(key) - if err != nil { - return 0, err - } - - return node.Decr(key) -} - -func (cs clusterStore) Decrby(key string, increment int64) (int64, error) { - node, err := cs.getRedis(key) - if err != nil { - return 0, err - } - - return node.Decrby(key, increment) -} - func (cs clusterStore) Llen(key string) (int, error) { node, err := cs.getRedis(key) if err != nil {