diff --git a/commands.go b/commands.go index c4b9d9408b..342fb1f636 100644 --- a/commands.go +++ b/commands.go @@ -696,6 +696,21 @@ func (c *commandable) HMSet(key, field, value string, pairs ...string) *StatusCm return cmd } +func (c *commandable) HMSetMap(key string, fields map[string]string) *StatusCmd { + args := make([]interface{}, 2+len(fields)*2) + args[0] = "HMSET" + args[1] = key + i := 2 + for k, v := range fields { + args[i] = k + args[i+1] = v + i += 2 + } + cmd := NewStatusCmd(args...) + c.Process(cmd) + return cmd +} + func (c *commandable) HSet(key, field, value string) *BoolCmd { cmd := NewBoolCmd("HSET", key, field, value) c.Process(cmd) @@ -944,12 +959,20 @@ func (c *commandable) SMove(source, destination string, member interface{}) *Boo return cmd } +// Redis `SPOP key` command. func (c *commandable) SPop(key string) *StringCmd { cmd := NewStringCmd("SPOP", key) c.Process(cmd) return cmd } +// Redis `SPOP key count` command. +func (c *commandable) SPopN(key string, count int64) *StringSliceCmd { + cmd := NewStringSliceCmd("SPOP", key, count) + c.Process(cmd) + return cmd +} + // Redis `SRANDMEMBER key` command. func (c *commandable) SRandMember(key string) *StringCmd { cmd := NewStringCmd("SRANDMEMBER", key) diff --git a/commands_test.go b/commands_test.go index eb0d52372b..21bfd74258 100644 --- a/commands_test.go +++ b/commands_test.go @@ -1195,6 +1195,23 @@ var _ = Describe("Commands", func() { Expect(hGet.Val()).To(Equal("hello2")) }) + It("should HMSetMap", func() { + hMSetMap := client.HMSetMap("hash", map[string]string{ + "key3": "hello3", + "key4": "hello4", + }) + Expect(hMSetMap.Err()).NotTo(HaveOccurred()) + Expect(hMSetMap.Val()).To(Equal("OK")) + + hGet := client.HGet("hash", "key3") + Expect(hGet.Err()).NotTo(HaveOccurred()) + Expect(hGet.Val()).To(Equal("hello3")) + + hGet = client.HGet("hash", "key4") + Expect(hGet.Err()).NotTo(HaveOccurred()) + Expect(hGet.Val()).To(Equal("hello4")) + }) + It("should HSet", func() { hSet := client.HSet("hash", "key", "hello") Expect(hSet.Err()).NotTo(HaveOccurred()) @@ -1802,6 +1819,34 @@ var _ = Describe("Commands", func() { sMembers := client.SMembers("set") Expect(sMembers.Err()).NotTo(HaveOccurred()) Expect(sMembers.Val()).To(HaveLen(2)) + + }) + + It("should SPopN", func() { + sAdd := client.SAdd("set", "one") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + sAdd = client.SAdd("set", "two") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + sAdd = client.SAdd("set", "three") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + sAdd = client.SAdd("set", "four") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + + sPopN := client.SPopN("set", 1) + Expect(sPopN.Err()).NotTo(HaveOccurred()) + Expect(sPopN.Val()).NotTo(Equal([]string{""})) + + sMembers := client.SMembers("set") + Expect(sMembers.Err()).NotTo(HaveOccurred()) + Expect(sMembers.Val()).To(HaveLen(3)) + + sPopN = client.SPopN("set", 4) + Expect(sPopN.Err()).NotTo(HaveOccurred()) + Expect(sPopN.Val()).To(HaveLen(3)) + + sMembers = client.SMembers("set") + Expect(sMembers.Err()).NotTo(HaveOccurred()) + Expect(sMembers.Val()).To(HaveLen(0)) }) It("should SRandMember and SRandMemberN", func() { diff --git a/parser.go b/parser.go index 0798857952..1c3a1dda08 100644 --- a/parser.go +++ b/parser.go @@ -1,6 +1,7 @@ package redis import ( + "bufio" "errors" "fmt" "net" @@ -19,9 +20,7 @@ const ( type multiBulkParser func(cn *pool.Conn, n int64) (interface{}, error) -var ( - errReaderTooSmall = errors.New("redis: reader is too small") -) +var errEmptyReply = errors.New("redis: reply is empty") //------------------------------------------------------------------------------ @@ -227,10 +226,13 @@ func scan(b []byte, val interface{}) error { func readLine(cn *pool.Conn) ([]byte, error) { line, isPrefix, err := cn.Rd.ReadLine() if err != nil { - return line, err + return nil, err } if isPrefix { - return line, errReaderTooSmall + return nil, bufio.ErrBufferFull + } + if len(line) == 0 { + return nil, errEmptyReply } if isNilReply(line) { return nil, Nil diff --git a/race_test.go b/race_test.go index 1ce8430a88..5fc185cb1c 100644 --- a/race_test.go +++ b/race_test.go @@ -120,7 +120,6 @@ var _ = Describe("races", func() { Expect(got).To(Equal(bigVal)) } }) - }) It("should handle big vals in Set", func() {