From 3e6dd2b433fade29a909ac38912086a0706d62c2 Mon Sep 17 00:00:00 2001 From: Anuragkillswitch <70265851+Anuragkillswitch@users.noreply.github.com> Date: Mon, 13 Feb 2023 12:49:57 +0530 Subject: [PATCH 01/11] feat(lmpop): add LMPOP --- commands.go | 18 ++++++++++++++++++ commands_test.go | 23 +++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/commands.go b/commands.go index c09f91bee..fa216695b 100644 --- a/commands.go +++ b/commands.go @@ -223,6 +223,7 @@ type Cmdable interface { LInsertBefore(ctx context.Context, key string, pivot, value interface{}) *IntCmd LInsertAfter(ctx context.Context, key string, pivot, value interface{}) *IntCmd LLen(ctx context.Context, key string) *IntCmd + LMPop(ctx context.Context, direction string, count int64, keys ...string) *StringSliceCmd LPop(ctx context.Context, key string) *StringCmd LPopCount(ctx context.Context, key string, count int) *StringSliceCmd LPos(ctx context.Context, key string, value string, args LPosArgs) *IntCmd @@ -1449,6 +1450,23 @@ func (c cmdable) LIndex(ctx context.Context, key string, index int64) *StringCmd return cmd } +func (c cmdable) LMPop(ctx context.Context, direction string, count int64, keys ...string) *StringSliceCmd { + args := make([]interface{}, 4+len(keys)) + args[0] = "lmpop" + numkeys := int64(0) + for i, key := range keys { + args[2+i] = key + numkeys++ + } + args[1] = numkeys + args[2+numkeys] = strings.ToLower(direction) + args[3+numkeys] = "count" + args[4+numkeys] = count + cmd := NewStringSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + func (c cmdable) LInsert(ctx context.Context, key, op string, pivot, value interface{}) *IntCmd { cmd := NewIntCmd(ctx, "linsert", key, op, pivot, value) _ = c(ctx, cmd) diff --git a/commands_test.go b/commands_test.go index 9bc277d45..2f153f7c3 100644 --- a/commands_test.go +++ b/commands_test.go @@ -2179,6 +2179,29 @@ var _ = Describe("Commands", func() { Expect(lIndex.Val()).To(Equal("")) }) + It("should LMPOP", func() { + rPush := client.RPush(ctx, "list1", "one") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list1", "two") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list2", "three") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list2", "four") + Expect(rPush.Err()).NotTo(HaveOccurred()) + + lMPOP := client.LMPOP(ctx, "list1", "list2", "LEFT", 1) + Expect(lMPOP.Err()).NotTo(HaveOccurred()) + Expect(lMPOP.Val()).To(Equal([]string{"one", "three"})) + + lRange1 := client.LRange(ctx, "list1", 0, -1) + Expect(lRange1.Err()).NotTo(HaveOccurred()) + Expect(lRange1.Val()).To(Equal([]string{"two"})) + + lRange2 := client.LRange(ctx, "list2", 0, -1) + Expect(lRange2.Err()).NotTo(HaveOccurred()) + Expect(lRange2.Val()).To(Equal([]string{"four"})) + }) + It("should LInsert", func() { rPush := client.RPush(ctx, "list", "Hello") Expect(rPush.Err()).NotTo(HaveOccurred()) From 14ae0c21a77ffd07d73457b57b6053a3c194c2c0 Mon Sep 17 00:00:00 2001 From: Anuragkillswitch <70265851+Anuragkillswitch@users.noreply.github.com> Date: Mon, 13 Feb 2023 12:59:24 +0530 Subject: [PATCH 02/11] fix: adding correct args --- commands_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands_test.go b/commands_test.go index 2f153f7c3..a5dfb2dec 100644 --- a/commands_test.go +++ b/commands_test.go @@ -2189,7 +2189,7 @@ var _ = Describe("Commands", func() { rPush = client.RPush(ctx, "list2", "four") Expect(rPush.Err()).NotTo(HaveOccurred()) - lMPOP := client.LMPOP(ctx, "list1", "list2", "LEFT", 1) + lMPOP := client.LMPop(ctx, "LEFT", 1, "list1", "list2") Expect(lMPOP.Err()).NotTo(HaveOccurred()) Expect(lMPOP.Val()).To(Equal([]string{"one", "three"})) From dc3ebf7831f4c29e481fa06b9efb6f684f0f4d01 Mon Sep 17 00:00:00 2001 From: Anuragkillswitch <70265851+Anuragkillswitch@users.noreply.github.com> Date: Mon, 13 Feb 2023 13:29:40 +0530 Subject: [PATCH 03/11] fix: length of args fix --- commands.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands.go b/commands.go index 7492940d2..6264a423c 100644 --- a/commands.go +++ b/commands.go @@ -1465,7 +1465,7 @@ func (c cmdable) LIndex(ctx context.Context, key string, index int64) *StringCmd } func (c cmdable) LMPop(ctx context.Context, direction string, count int64, keys ...string) *StringSliceCmd { - args := make([]interface{}, 4+len(keys)) + args := make([]interface{}, 5+len(keys)) args[0] = "lmpop" numkeys := int64(0) for i, key := range keys { From 068299af73d3c4ddebae3fc8d7d95ecf2c4132b8 Mon Sep 17 00:00:00 2001 From: Anuragkillswitch <70265851+Anuragkillswitch@users.noreply.github.com> Date: Mon, 13 Feb 2023 14:04:21 +0530 Subject: [PATCH 04/11] fix: fixing tests and expectation --- commands_test.go | 54 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/commands_test.go b/commands_test.go index f7300dec5..7ba825895 100644 --- a/commands_test.go +++ b/commands_test.go @@ -2258,27 +2258,45 @@ var _ = Describe("Commands", func() { }) It("should LMPOP", func() { - rPush := client.RPush(ctx, "list1", "one") - Expect(rPush.Err()).NotTo(HaveOccurred()) - rPush = client.RPush(ctx, "list1", "two") - Expect(rPush.Err()).NotTo(HaveOccurred()) - rPush = client.RPush(ctx, "list2", "three") - Expect(rPush.Err()).NotTo(HaveOccurred()) - rPush = client.RPush(ctx, "list2", "four") - Expect(rPush.Err()).NotTo(HaveOccurred()) - + + err := client.RPush(ctx, "list1", "one").Err() + Expect(err).NotTo(HaveOccurred()) + err = client.RPush(ctx, "list1", "two").Err() + Expect(err).NotTo(HaveOccurred()) + err = client.RPush(ctx, "list2", "three").Err() + Expect(err).NotTo(HaveOccurred()) + err = client.RPush(ctx, "list2", "four").Err() + Expect(err).NotTo(HaveOccurred()) + + // Call the LMPOP command lMPOP := client.LMPop(ctx, "LEFT", 1, "list1", "list2") Expect(lMPOP.Err()).NotTo(HaveOccurred()) - Expect(lMPOP.Val()).To(Equal([]string{"one", "three"})) - - lRange1 := client.LRange(ctx, "list1", 0, -1) - Expect(lRange1.Err()).NotTo(HaveOccurred()) - Expect(lRange1.Val()).To(Equal([]string{"two"})) - - lRange2 := client.LRange(ctx, "list2", 0, -1) - Expect(lRange2.Err()).NotTo(HaveOccurred()) - Expect(lRange2.Val()).To(Equal([]string{"four"})) + + // Verify that the returned value is a two-element array + result := lMPOP.Val() + Expect(len(result)).To(Equal(2)) + + // Verify that the first element is the name of the key from which elements were popped + keyName := result[0] + Expect(keyName).To(SatisfyAny(Equal("list1"), Equal("list2"))) + + // Verify that the second element is an array of elements + elements := result[1].([]string) + Expect(len(elements)).To(Equal(1)) + Expect(elements[0]).To(SatisfyAny(Equal("one"), Equal("three"))) + + // Verify that the correct elements have been removed from the corresponding lists + if keyName == "list1" { + lRange := client.LRange(ctx, "list1", 0, -1) + Expect(lRange.Err()).NotTo(HaveOccurred()) + Expect(lRange.Val()).To(Equal([]string{"two"})) + } else { + lRange := client.LRange(ctx, "list2", 0, -1) + Expect(lRange.Err()).NotTo(HaveOccurred()) + Expect(lRange.Val()).To(Equal([]string{"four"})) + } }) + It("should LInsert", func() { rPush := client.RPush(ctx, "list", "Hello") From a7c9317bc6789c0ba107cbfcdfd2a32e6549597a Mon Sep 17 00:00:00 2001 From: Anuragkillswitch <70265851+Anuragkillswitch@users.noreply.github.com> Date: Mon, 13 Feb 2023 15:11:55 +0530 Subject: [PATCH 05/11] fix: decoupling resp array part and normal part --- commands_test.go | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/commands_test.go b/commands_test.go index 7ba825895..99e7fb676 100644 --- a/commands_test.go +++ b/commands_test.go @@ -2268,33 +2268,19 @@ var _ = Describe("Commands", func() { err = client.RPush(ctx, "list2", "four").Err() Expect(err).NotTo(HaveOccurred()) - // Call the LMPOP command lMPOP := client.LMPop(ctx, "LEFT", 1, "list1", "list2") Expect(lMPOP.Err()).NotTo(HaveOccurred()) - // Verify that the returned value is a two-element array result := lMPOP.Val() Expect(len(result)).To(Equal(2)) - // Verify that the first element is the name of the key from which elements were popped keyName := result[0] Expect(keyName).To(SatisfyAny(Equal("list1"), Equal("list2"))) - // Verify that the second element is an array of elements - elements := result[1].([]string) + elements := result[1] Expect(len(elements)).To(Equal(1)) - Expect(elements[0]).To(SatisfyAny(Equal("one"), Equal("three"))) - - // Verify that the correct elements have been removed from the corresponding lists - if keyName == "list1" { - lRange := client.LRange(ctx, "list1", 0, -1) - Expect(lRange.Err()).NotTo(HaveOccurred()) - Expect(lRange.Val()).To(Equal([]string{"two"})) - } else { - lRange := client.LRange(ctx, "list2", 0, -1) - Expect(lRange.Err()).NotTo(HaveOccurred()) - Expect(lRange.Val()).To(Equal([]string{"four"})) - } + Expect(elements).To(SatisfyAny(Equal("one"), Equal("three"))) + }) From 7d050ecd56803b77d5d5da190258884905f1711d Mon Sep 17 00:00:00 2001 From: Anuragkillswitch <70265851+Anuragkillswitch@users.noreply.github.com> Date: Mon, 13 Feb 2023 15:19:42 +0530 Subject: [PATCH 06/11] fix: fixing tests --- commands_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands_test.go b/commands_test.go index 99e7fb676..a990a4335 100644 --- a/commands_test.go +++ b/commands_test.go @@ -2268,7 +2268,7 @@ var _ = Describe("Commands", func() { err = client.RPush(ctx, "list2", "four").Err() Expect(err).NotTo(HaveOccurred()) - lMPOP := client.LMPop(ctx, "LEFT", 1, "list1", "list2") + lMPOP := client.LMPop(ctx, "LEFT", 1, "list1") Expect(lMPOP.Err()).NotTo(HaveOccurred()) result := lMPOP.Val() From 946560b0d1070722ebda58356b172163a87029a5 Mon Sep 17 00:00:00 2001 From: Anuragkillswitch <70265851+Anuragkillswitch@users.noreply.github.com> Date: Mon, 13 Feb 2023 16:53:38 +0530 Subject: [PATCH 07/11] fix: adding tests as a sliceCmd --- commands.go | 6 +++--- commands_test.go | 40 ++++++++++++++-------------------------- 2 files changed, 17 insertions(+), 29 deletions(-) diff --git a/commands.go b/commands.go index 6264a423c..8e5af81a4 100644 --- a/commands.go +++ b/commands.go @@ -225,7 +225,7 @@ type Cmdable interface { LInsertBefore(ctx context.Context, key string, pivot, value interface{}) *IntCmd LInsertAfter(ctx context.Context, key string, pivot, value interface{}) *IntCmd LLen(ctx context.Context, key string) *IntCmd - LMPop(ctx context.Context, direction string, count int64, keys ...string) *StringSliceCmd + LMPop(ctx context.Context, direction string, count int64, keys ...string) *SliceCmd LPop(ctx context.Context, key string) *StringCmd LPopCount(ctx context.Context, key string, count int) *StringSliceCmd LPos(ctx context.Context, key string, value string, args LPosArgs) *IntCmd @@ -1464,7 +1464,7 @@ func (c cmdable) LIndex(ctx context.Context, key string, index int64) *StringCmd return cmd } -func (c cmdable) LMPop(ctx context.Context, direction string, count int64, keys ...string) *StringSliceCmd { +func (c cmdable) LMPop(ctx context.Context, direction string, count int64, keys ...string) *SliceCmd { args := make([]interface{}, 5+len(keys)) args[0] = "lmpop" numkeys := int64(0) @@ -1476,7 +1476,7 @@ func (c cmdable) LMPop(ctx context.Context, direction string, count int64, keys args[2+numkeys] = strings.ToLower(direction) args[3+numkeys] = "count" args[4+numkeys] = count - cmd := NewStringSliceCmd(ctx, args...) + cmd := NewSliceCmd(ctx, args...) _ = c(ctx, cmd) return cmd } diff --git a/commands_test.go b/commands_test.go index a990a4335..4aff1ef34 100644 --- a/commands_test.go +++ b/commands_test.go @@ -1272,6 +1272,20 @@ var _ = Describe("Commands", func() { Expect(incrByFloat.Val()).To(Equal(float64(996945661))) }) + It("should LMPop",func(){ + rPush := client.RPush(ctx, "list", "one") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list", "two") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list", "three") + Expect(rPush.Err()).NotTo(HaveOccurred()) + + lMPOP := client.LMPop(ctx, "LEFT", 1, "list1") + Expect(lMPOP.Err()).NotTo(HaveOccurred()) + Expect(lMPOP.Val()).To(Equal([]interface{}{"list1",[]string{"one"}})) + + }) + It("should MSetMGet", func() { mSet := client.MSet(ctx, "key1", "hello1", "key2", "hello2") Expect(mSet.Err()).NotTo(HaveOccurred()) @@ -2257,32 +2271,6 @@ var _ = Describe("Commands", func() { Expect(lIndex.Val()).To(Equal("")) }) - It("should LMPOP", func() { - - err := client.RPush(ctx, "list1", "one").Err() - Expect(err).NotTo(HaveOccurred()) - err = client.RPush(ctx, "list1", "two").Err() - Expect(err).NotTo(HaveOccurred()) - err = client.RPush(ctx, "list2", "three").Err() - Expect(err).NotTo(HaveOccurred()) - err = client.RPush(ctx, "list2", "four").Err() - Expect(err).NotTo(HaveOccurred()) - - lMPOP := client.LMPop(ctx, "LEFT", 1, "list1") - Expect(lMPOP.Err()).NotTo(HaveOccurred()) - - result := lMPOP.Val() - Expect(len(result)).To(Equal(2)) - - keyName := result[0] - Expect(keyName).To(SatisfyAny(Equal("list1"), Equal("list2"))) - - elements := result[1] - Expect(len(elements)).To(Equal(1)) - Expect(elements).To(SatisfyAny(Equal("one"), Equal("three"))) - - }) - It("should LInsert", func() { rPush := client.RPush(ctx, "list", "Hello") From f2bbdef773b30b99f47eea48a978eda179405340 Mon Sep 17 00:00:00 2001 From: Anuragkillswitch <70265851+Anuragkillswitch@users.noreply.github.com> Date: Mon, 13 Feb 2023 17:42:23 +0530 Subject: [PATCH 08/11] fix: string slice attempt --- commands_test.go | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/commands_test.go b/commands_test.go index 4aff1ef34..797b9196d 100644 --- a/commands_test.go +++ b/commands_test.go @@ -1272,20 +1272,6 @@ var _ = Describe("Commands", func() { Expect(incrByFloat.Val()).To(Equal(float64(996945661))) }) - It("should LMPop",func(){ - rPush := client.RPush(ctx, "list", "one") - Expect(rPush.Err()).NotTo(HaveOccurred()) - rPush = client.RPush(ctx, "list", "two") - Expect(rPush.Err()).NotTo(HaveOccurred()) - rPush = client.RPush(ctx, "list", "three") - Expect(rPush.Err()).NotTo(HaveOccurred()) - - lMPOP := client.LMPop(ctx, "LEFT", 1, "list1") - Expect(lMPOP.Err()).NotTo(HaveOccurred()) - Expect(lMPOP.Val()).To(Equal([]interface{}{"list1",[]string{"one"}})) - - }) - It("should MSetMGet", func() { mSet := client.MSet(ctx, "key1", "hello1", "key2", "hello2") Expect(mSet.Err()).NotTo(HaveOccurred()) @@ -2271,7 +2257,6 @@ var _ = Describe("Commands", func() { Expect(lIndex.Val()).To(Equal("")) }) - It("should LInsert", func() { rPush := client.RPush(ctx, "list", "Hello") Expect(rPush.Err()).NotTo(HaveOccurred()) @@ -2287,6 +2272,20 @@ var _ = Describe("Commands", func() { Expect(lRange.Val()).To(Equal([]string{"Hello", "There", "World"})) }) + It("should LMPop", func() { + rPush := client.RPush(ctx, "list", "one") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list", "two") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list", "three") + Expect(rPush.Err()).NotTo(HaveOccurred()) + + lMPOP := client.LMPop(ctx, "LEFT", 1, "list") + Expect(lMPOP.Err()).NotTo(HaveOccurred()) + Expect(lMPOP.Val()).To(Equal([]interface{}{"list", []string{"one"}})) + + }) + It("should LLen", func() { lPush := client.LPush(ctx, "list", "World") Expect(lPush.Err()).NotTo(HaveOccurred()) From 586b7819c2c8fd365b735f8c63013c97be2dd134 Mon Sep 17 00:00:00 2001 From: Anuragkillswitch <70265851+Anuragkillswitch@users.noreply.github.com> Date: Mon, 13 Feb 2023 17:51:10 +0530 Subject: [PATCH 09/11] fix: adding tests as sliceCmd and using nested interfaces --- commands_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands_test.go b/commands_test.go index 797b9196d..25c0aa0b9 100644 --- a/commands_test.go +++ b/commands_test.go @@ -2282,7 +2282,7 @@ var _ = Describe("Commands", func() { lMPOP := client.LMPop(ctx, "LEFT", 1, "list") Expect(lMPOP.Err()).NotTo(HaveOccurred()) - Expect(lMPOP.Val()).To(Equal([]interface{}{"list", []string{"one"}})) + Expect(lMPOP.Val()).To(Equal([]interface{}{"list", []interface{}{"one"}})) }) From d63389a1e7a66afbfc78e0299b4f0abb1525cfda Mon Sep 17 00:00:00 2001 From: Anuragkillswitch <70265851+Anuragkillswitch@users.noreply.github.com> Date: Mon, 13 Feb 2023 18:43:48 +0530 Subject: [PATCH 10/11] feat: adding more test scenarios --- commands_test.go | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/commands_test.go b/commands_test.go index 25c0aa0b9..95ae83b8b 100644 --- a/commands_test.go +++ b/commands_test.go @@ -2280,10 +2280,25 @@ var _ = Describe("Commands", func() { rPush = client.RPush(ctx, "list", "three") Expect(rPush.Err()).NotTo(HaveOccurred()) - lMPOP := client.LMPop(ctx, "LEFT", 1, "list") - Expect(lMPOP.Err()).NotTo(HaveOccurred()) - Expect(lMPOP.Val()).To(Equal([]interface{}{"list", []interface{}{"one"}})) + lMPop := client.LMPop(ctx, "LEFT", 1, "list") + Expect(lMPop.Err()).NotTo(HaveOccurred()) + Expect(lMPop.Val()).To(Equal([]interface{}{"list", []interface{}{"one"}})) + lMPop = client.LMPop(ctx,"LEFT",1,"non-existing-key") + Expect(lMPop.Err()).NotTo(HaveOccurred()) + Expect(lMPop.Val()).To(Equal(nil)) + + rPush = client.RPush(ctx, "list1", "one") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list1", "two") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list1", "three") + Expect(rPush.Err()).NotTo(HaveOccurred()) + + + lMPop = client.LMPop(ctx,"RIGHT",2,"list1") + Expect(lMPop.Err()).NotTo(HaveOccurred()) + Expect(lMPop.Val()).To(Equal([]interface{}{"list1", []interface{}{"two", "one"}})) }) It("should LLen", func() { From ab94b08c25713b5825d3830e154de3601ca3e5fd Mon Sep 17 00:00:00 2001 From: monkey92t Date: Mon, 13 Feb 2023 22:36:01 +0800 Subject: [PATCH 11/11] feat: add lmpop command Signed-off-by: monkey92t --- command.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ commands.go | 19 +++++++-------- commands_test.go | 53 +++++++++++++++++++++++++---------------- 3 files changed, 103 insertions(+), 31 deletions(-) diff --git a/command.go b/command.go index bea76c223..da044caa2 100644 --- a/command.go +++ b/command.go @@ -3690,3 +3690,65 @@ func (cmd *MapStringStringSliceCmd) readReply(rd *proto.Reader) error { } return nil } + +//------------------------------------------------------------------------------ + +type ListElementCmd struct { + baseCmd + + key string + val []string +} + +var _ Cmder = (*ListElementCmd)(nil) + +func NewListElementCmd(ctx context.Context, args ...interface{}) *ListElementCmd { + return &ListElementCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *ListElementCmd) SetVal(key string, val []string) { + cmd.key = key + cmd.val = val +} + +func (cmd *ListElementCmd) Val() (string, []string) { + return cmd.key, cmd.val +} + +func (cmd *ListElementCmd) Result() (string, []string, error) { + return cmd.key, cmd.val, cmd.err +} + +func (cmd *ListElementCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *ListElementCmd) readReply(rd *proto.Reader) (err error) { + if err = rd.ReadFixedArrayLen(2); err != nil { + return err + } + + cmd.key, err = rd.ReadString() + if err != nil { + return err + } + + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + cmd.val = make([]string, n) + for i := 0; i < n; i++ { + cmd.val[i], err = rd.ReadString() + if err != nil { + return err + } + } + + return nil +} diff --git a/commands.go b/commands.go index 8e5af81a4..61b1bac36 100644 --- a/commands.go +++ b/commands.go @@ -225,7 +225,7 @@ type Cmdable interface { LInsertBefore(ctx context.Context, key string, pivot, value interface{}) *IntCmd LInsertAfter(ctx context.Context, key string, pivot, value interface{}) *IntCmd LLen(ctx context.Context, key string) *IntCmd - LMPop(ctx context.Context, direction string, count int64, keys ...string) *SliceCmd + LMPop(ctx context.Context, direction string, count int64, keys ...string) *ListElementCmd LPop(ctx context.Context, key string) *StringCmd LPopCount(ctx context.Context, key string, count int) *StringSliceCmd LPos(ctx context.Context, key string, value string, args LPosArgs) *IntCmd @@ -1464,19 +1464,18 @@ func (c cmdable) LIndex(ctx context.Context, key string, index int64) *StringCmd return cmd } -func (c cmdable) LMPop(ctx context.Context, direction string, count int64, keys ...string) *SliceCmd { - args := make([]interface{}, 5+len(keys)) +// LMPop Pops one or more elements from the first non-empty list key from the list of provided key names. +// direction: left or right, count: > 0 +// example: client.LMPop(ctx, "left", 3, "key1", "key2") +func (c cmdable) LMPop(ctx context.Context, direction string, count int64, keys ...string) *ListElementCmd { + args := make([]interface{}, 2+len(keys), 5+len(keys)) args[0] = "lmpop" - numkeys := int64(0) + args[1] = len(keys) for i, key := range keys { args[2+i] = key - numkeys++ } - args[1] = numkeys - args[2+numkeys] = strings.ToLower(direction) - args[3+numkeys] = "count" - args[4+numkeys] = count - cmd := NewSliceCmd(ctx, args...) + args = append(args, strings.ToLower(direction), "count", count) + cmd := NewListElementCmd(ctx, args...) _ = c(ctx, cmd) return cmd } diff --git a/commands_test.go b/commands_test.go index 95ae83b8b..95fb21461 100644 --- a/commands_test.go +++ b/commands_test.go @@ -2273,32 +2273,43 @@ var _ = Describe("Commands", func() { }) It("should LMPop", func() { - rPush := client.RPush(ctx, "list", "one") - Expect(rPush.Err()).NotTo(HaveOccurred()) - rPush = client.RPush(ctx, "list", "two") - Expect(rPush.Err()).NotTo(HaveOccurred()) - rPush = client.RPush(ctx, "list", "three") - Expect(rPush.Err()).NotTo(HaveOccurred()) + err := client.LPush(ctx, "list1", "one", "two", "three", "four", "five").Err() + Expect(err).NotTo(HaveOccurred()) - lMPop := client.LMPop(ctx, "LEFT", 1, "list") - Expect(lMPop.Err()).NotTo(HaveOccurred()) - Expect(lMPop.Val()).To(Equal([]interface{}{"list", []interface{}{"one"}})) + err = client.LPush(ctx, "list2", "a", "b", "c", "d", "e").Err() + Expect(err).NotTo(HaveOccurred()) - lMPop = client.LMPop(ctx,"LEFT",1,"non-existing-key") - Expect(lMPop.Err()).NotTo(HaveOccurred()) - Expect(lMPop.Val()).To(Equal(nil)) + key, elems, err := client.LMPop(ctx, "left", 3, "list1", "list2").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(key).To(Equal("list1")) + Expect(elems).To(Equal([]string{"five", "four", "three"})) - rPush = client.RPush(ctx, "list1", "one") - Expect(rPush.Err()).NotTo(HaveOccurred()) - rPush = client.RPush(ctx, "list1", "two") - Expect(rPush.Err()).NotTo(HaveOccurred()) - rPush = client.RPush(ctx, "list1", "three") - Expect(rPush.Err()).NotTo(HaveOccurred()) + key, elems, err = client.LMPop(ctx, "right", 3, "list1", "list2").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(key).To(Equal("list1")) + Expect(elems).To(Equal([]string{"one", "two"})) + + key, elems, err = client.LMPop(ctx, "left", 1, "list1", "list2").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(key).To(Equal("list2")) + Expect(elems).To(Equal([]string{"e"})) + key, elems, err = client.LMPop(ctx, "right", 10, "list1", "list2").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(key).To(Equal("list2")) + Expect(elems).To(Equal([]string{"a", "b", "c", "d"})) - lMPop = client.LMPop(ctx,"RIGHT",2,"list1") - Expect(lMPop.Err()).NotTo(HaveOccurred()) - Expect(lMPop.Val()).To(Equal([]interface{}{"list1", []interface{}{"two", "one"}})) + err = client.LMPop(ctx, "left", 10, "list1", "list2").Err() + Expect(err).To(Equal(redis.Nil)) + + err = client.Set(ctx, "list3", 1024, 0).Err() + Expect(err).NotTo(HaveOccurred()) + + err = client.LMPop(ctx, "left", 10, "list1", "list2", "list3").Err() + Expect(err.Error()).To(Equal("WRONGTYPE Operation against a key holding the wrong kind of value")) + + err = client.LMPop(ctx, "right", 0, "list1", "list2").Err() + Expect(err).To(HaveOccurred()) }) It("should LLen", func() {