From 7aa0130b2e568a6c0e540e3cce65f3a23e9b8f7b Mon Sep 17 00:00:00 2001 From: Crimson Date: Sun, 19 Nov 2017 17:36:23 +0100 Subject: [PATCH 1/2] Add SMembersMap function --- command.go | 38 ++++++++++++++++++++++++++++++++++++++ commands.go | 7 +++++++ commands_test.go | 11 +++++++++++ parser.go | 14 ++++++++++++++ 4 files changed, 70 insertions(+) diff --git a/command.go b/command.go index d2688082a..601a2882d 100644 --- a/command.go +++ b/command.go @@ -675,6 +675,44 @@ func (cmd *StringIntMapCmd) readReply(cn *pool.Conn) error { //------------------------------------------------------------------------------ +type StringStructMapCmd struct { + baseCmd + + val map[string]struct{} +} + +var _ Cmder = (*StringStructMapCmd)(nil) + +func NewStringStructMapCmd(args ...interface{}) *StringStructMapCmd { + return &StringStructMapCmd{ + baseCmd: baseCmd{_args: args}, + } +} + +func (cmd *StringStructMapCmd) Val() map[string]struct{} { + return cmd.val +} + +func (cmd *StringStructMapCmd) Result() (map[string]struct{}, error) { + return cmd.val, cmd.err +} + +func (cmd *StringStructMapCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *StringStructMapCmd) readReply(cn *pool.Conn) error { + var v interface{} + v, cmd.err = cn.Rd.ReadArrayReply(stringStructMapParser) + if cmd.err != nil { + return cmd.err + } + cmd.val = v.(map[string]struct{}) + return nil +} + +//------------------------------------------------------------------------------ + type ZSliceCmd struct { baseCmd diff --git a/commands.go b/commands.go index c04b3c49b..7a9637547 100644 --- a/commands.go +++ b/commands.go @@ -143,6 +143,7 @@ type Cmdable interface { SInterStore(destination string, keys ...string) *IntCmd SIsMember(key string, member interface{}) *BoolCmd SMembers(key string) *StringSliceCmd + SMembersMap(key string) *StringStructMapCmd SMove(source, destination string, member interface{}) *BoolCmd SPop(key string) *StringCmd SPopN(key string, count int64) *StringSliceCmd @@ -1169,6 +1170,12 @@ func (c *cmdable) SMembers(key string) *StringSliceCmd { return cmd } +func (c *cmdable) SMembersMap(key string) *StringStructMapCmd { + cmd := NewStringStructMapCmd("smembers", key) + c.process(cmd) + return cmd +} + func (c *cmdable) SMove(source, destination string, member interface{}) *BoolCmd { cmd := NewBoolCmd("smove", source, destination, member) c.process(cmd) diff --git a/commands_test.go b/commands_test.go index 6b81f23cf..715379556 100644 --- a/commands_test.go +++ b/commands_test.go @@ -1848,6 +1848,17 @@ var _ = Describe("Commands", func() { Expect(sMembers.Val()).To(ConsistOf([]string{"Hello", "World"})) }) + It("should SMembersMap", func() { + sAdd := client.SAdd("set", "Hello") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + sAdd = client.SAdd("set", "World") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + + sMembersMap := client.SMembersMap("set") + Expect(sMembersMap.Err()).NotTo(HaveOccurred()) + Expect(sMembersMap.Val()).To(Equal(map[string]struct{}{"Hello": struct{}{}, "World": struct{}{}})) + }) + It("should SMove", func() { sAdd := client.SAdd("set1", "one") Expect(sAdd.Err()).NotTo(HaveOccurred()) diff --git a/parser.go b/parser.go index 1d7ec630e..b378abc4e 100644 --- a/parser.go +++ b/parser.go @@ -97,6 +97,20 @@ func stringIntMapParser(rd *proto.Reader, n int64) (interface{}, error) { return m, nil } +// Implements proto.MultiBulkParse +func stringStructMapParser(rd *proto.Reader, n int64) (interface{}, error) { + m := make(map[string]struct{}, n) + for i := int64(0); i < n; i++ { + key, err := rd.ReadStringReply() + if err != nil { + return nil, err + } + + m[key] = struct{}{} + } + return m, nil +} + // Implements proto.MultiBulkParse func zSliceParser(rd *proto.Reader, n int64) (interface{}, error) { zz := make([]Z, n/2) From b2e8f5832a8679ff5c2d3b602433ca62b0a281ac Mon Sep 17 00:00:00 2001 From: Crimson Date: Sun, 19 Nov 2017 17:56:54 +0100 Subject: [PATCH 2/2] Add godoc commentary to SMembers and SMembersMap --- commands.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/commands.go b/commands.go index 7a9637547..aa98aa736 100644 --- a/commands.go +++ b/commands.go @@ -1164,12 +1164,14 @@ func (c *cmdable) SIsMember(key string, member interface{}) *BoolCmd { return cmd } +// Redis `SMEMBERS key` command output as a slice func (c *cmdable) SMembers(key string) *StringSliceCmd { cmd := NewStringSliceCmd("smembers", key) c.process(cmd) return cmd } +// Redis `SMEMBERS key` command output as a map func (c *cmdable) SMembersMap(key string) *StringStructMapCmd { cmd := NewStringStructMapCmd("smembers", key) c.process(cmd)