Merge pull request #158 from go-redis/fix/zadd-30

Add ZADD modifiers.
This commit is contained in:
Vladimir Mihailenco 2015-09-03 17:23:59 +03:00
commit dace69da84
3 changed files with 243 additions and 30 deletions

View File

@ -361,7 +361,9 @@ var ok = []byte("OK")
func (cmd *BoolCmd) parseReply(rd *bufio.Reader) error { func (cmd *BoolCmd) parseReply(rd *bufio.Reader) error {
v, err := parseReply(rd, nil) v, err := parseReply(rd, nil)
// `SET key value NX` returns nil when key already exists. // `SET key value NX` returns nil when key already exists, which
// is inconsistent with `SETNX key value`.
// TODO: is this okay?
if err == Nil { if err == Nil {
cmd.val = false cmd.val = false
return nil return nil
@ -476,6 +478,10 @@ func (cmd *FloatCmd) Val() float64 {
return cmd.val return cmd.val
} }
func (cmd *FloatCmd) Result() (float64, error) {
return cmd.Val(), cmd.Err()
}
func (cmd *FloatCmd) String() string { func (cmd *FloatCmd) String() string {
return cmdString(cmd, cmd.val) return cmdString(cmd, cmd.val)
} }

View File

@ -1008,19 +1008,98 @@ type ZStore struct {
Aggregate string Aggregate string
} }
func (c *commandable) ZAdd(key string, members ...Z) *IntCmd { func (c *commandable) zAdd(a []interface{}, n int, members ...Z) *IntCmd {
args := make([]interface{}, 2+2*len(members))
args[0] = "ZADD"
args[1] = key
for i, m := range members { for i, m := range members {
args[2+2*i] = formatFloat(m.Score) a[n+2*i] = formatFloat(m.Score)
args[2+2*i+1] = m.Member a[n+2*i+1] = m.Member
} }
cmd := NewIntCmd(args...) cmd := NewIntCmd(a...)
c.Process(cmd) c.Process(cmd)
return cmd return cmd
} }
// Redis `ZADD key score member [score member ...]` command.
func (c *commandable) ZAdd(key string, members ...Z) *IntCmd {
const n = 2
a := make([]interface{}, n+2*len(members))
a[0], a[1] = "ZADD", key
return c.zAdd(a, n, members...)
}
// Redis `ZADD key NX score member [score member ...]` command.
func (c *commandable) ZAddNX(key string, members ...Z) *IntCmd {
const n = 3
a := make([]interface{}, n+2*len(members))
a[0], a[1], a[2] = "ZADD", key, "NX"
return c.zAdd(a, n, members...)
}
// Redis `ZADD key XX score member [score member ...]` command.
func (c *commandable) ZAddXX(key string, members ...Z) *IntCmd {
const n = 3
a := make([]interface{}, n+2*len(members))
a[0], a[1], a[2] = "ZADD", key, "XX"
return c.zAdd(a, n, members...)
}
// Redis `ZADD key CH score member [score member ...]` command.
func (c *commandable) ZAddCh(key string, members ...Z) *IntCmd {
const n = 3
a := make([]interface{}, n+2*len(members))
a[0], a[1], a[2] = "ZADD", key, "CH"
return c.zAdd(a, n, members...)
}
// Redis `ZADD key NX CH score member [score member ...]` command.
func (c *commandable) ZAddNXCh(key string, members ...Z) *IntCmd {
const n = 4
a := make([]interface{}, n+2*len(members))
a[0], a[1], a[2], a[3] = "ZADD", key, "NX", "CH"
return c.zAdd(a, n, members...)
}
// Redis `ZADD key XX CH score member [score member ...]` command.
func (c *commandable) ZAddXXCh(key string, members ...Z) *IntCmd {
const n = 4
a := make([]interface{}, n+2*len(members))
a[0], a[1], a[2], a[3] = "ZADD", key, "XX", "CH"
return c.zAdd(a, n, members...)
}
func (c *commandable) zIncr(a []interface{}, n int, members ...Z) *FloatCmd {
for i, m := range members {
a[n+2*i] = formatFloat(m.Score)
a[n+2*i+1] = m.Member
}
cmd := NewFloatCmd(a...)
c.Process(cmd)
return cmd
}
// Redis `ZADD key INCR score member` command.
func (c *commandable) ZIncr(key string, member Z) *FloatCmd {
const n = 3
a := make([]interface{}, n+2)
a[0], a[1], a[2] = "ZADD", key, "INCR"
return c.zIncr(a, n, member)
}
// Redis `ZADD key NX INCR score member` command.
func (c *commandable) ZIncrNX(key string, member Z) *FloatCmd {
const n = 4
a := make([]interface{}, n+2)
a[0], a[1], a[2], a[3] = "ZADD", key, "INCR", "NX"
return c.zIncr(a, n, member)
}
// Redis `ZADD key XX INCR score member` command.
func (c *commandable) ZIncrXX(key string, member Z) *FloatCmd {
const n = 4
a := make([]interface{}, n+2)
a[0], a[1], a[2], a[3] = "ZADD", key, "INCR", "XX"
return c.zIncr(a, n, member)
}
func (c *commandable) ZCard(key string) *IntCmd { func (c *commandable) ZCard(key string) *IntCmd {
cmd := NewIntCmd("ZCARD", key) cmd := NewIntCmd("ZCARD", key)
c.Process(cmd) c.Process(cmd)

View File

@ -32,8 +32,6 @@ var _ = Describe("Commands", func() {
Expect(client.Close()).NotTo(HaveOccurred()) Expect(client.Close()).NotTo(HaveOccurred())
}) })
//------------------------------------------------------------------------------
Describe("server", func() { Describe("server", func() {
It("should Auth", func() { It("should Auth", func() {
@ -158,8 +156,6 @@ var _ = Describe("Commands", func() {
}) })
//------------------------------------------------------------------------------
Describe("debugging", func() { Describe("debugging", func() {
It("should DebugObject", func() { It("should DebugObject", func() {
@ -175,8 +171,6 @@ var _ = Describe("Commands", func() {
}) })
//------------------------------------------------------------------------------
Describe("keys", func() { Describe("keys", func() {
It("should Del", func() { It("should Del", func() {
@ -539,8 +533,6 @@ var _ = Describe("Commands", func() {
}) })
//------------------------------------------------------------------------------
Describe("scanning", func() { Describe("scanning", func() {
It("should Scan", func() { It("should Scan", func() {
@ -593,8 +585,6 @@ var _ = Describe("Commands", func() {
}) })
//------------------------------------------------------------------------------
Describe("strings", func() { Describe("strings", func() {
It("should Append", func() { It("should Append", func() {
@ -1004,8 +994,6 @@ var _ = Describe("Commands", func() {
}) })
//------------------------------------------------------------------------------
Describe("hashes", func() { Describe("hashes", func() {
It("should HDel", func() { It("should HDel", func() {
@ -1192,8 +1180,6 @@ var _ = Describe("Commands", func() {
}) })
//------------------------------------------------------------------------------
Describe("lists", func() { Describe("lists", func() {
It("should BLPop", func() { It("should BLPop", func() {
@ -1546,8 +1532,6 @@ var _ = Describe("Commands", func() {
}) })
//------------------------------------------------------------------------------
Describe("sets", func() { Describe("sets", func() {
It("should SAdd", func() { It("should SAdd", func() {
@ -1821,8 +1805,6 @@ var _ = Describe("Commands", func() {
}) })
//------------------------------------------------------------------------------
Describe("sorted sets", func() { Describe("sorted sets", func() {
It("should ZAdd", func() { It("should ZAdd", func() {
@ -1842,9 +1824,9 @@ var _ = Describe("Commands", func() {
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0))) Expect(added).To(Equal(int64(0)))
val, err := client.ZRangeWithScores("zset", 0, -1).Result() vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(val).To(Equal([]redis.Z{{1, "one"}, {1, "uno"}, {3, "two"}})) Expect(vals).To(Equal([]redis.Z{{1, "one"}, {1, "uno"}, {3, "two"}}))
}) })
It("should ZAdd bytes", func() { It("should ZAdd bytes", func() {
@ -1869,6 +1851,154 @@ var _ = Describe("Commands", func() {
Expect(val).To(Equal([]redis.Z{{1, "one"}, {1, "uno"}, {3, "two"}})) Expect(val).To(Equal([]redis.Z{{1, "one"}, {1, "uno"}, {3, "two"}}))
}) })
It("should ZAddNX", func() {
added, err := client.ZAddNX("zset", redis.Z{1, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
added, err = client.ZAddNX("zset", redis.Z{2, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
})
It("should ZAddXX", func() {
added, err := client.ZAddXX("zset", redis.Z{1, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(BeEmpty())
added, err = client.ZAdd("zset", redis.Z{1, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
added, err = client.ZAddXX("zset", redis.Z{2, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(0)))
vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{2, "one"}}))
})
It("should ZAddCh", func() {
changed, err := client.ZAddCh("zset", redis.Z{1, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(changed).To(Equal(int64(1)))
changed, err = client.ZAddCh("zset", redis.Z{1, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(changed).To(Equal(int64(0)))
})
It("should ZAddNXCh", func() {
changed, err := client.ZAddNXCh("zset", redis.Z{1, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(changed).To(Equal(int64(1)))
vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
changed, err = client.ZAddNXCh("zset", redis.Z{2, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(changed).To(Equal(int64(0)))
vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
})
It("should ZAddXXCh", func() {
changed, err := client.ZAddXXCh("zset", redis.Z{1, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(changed).To(Equal(int64(0)))
vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(BeEmpty())
added, err := client.ZAdd("zset", redis.Z{1, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
changed, err = client.ZAddXXCh("zset", redis.Z{2, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(changed).To(Equal(int64(1)))
vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{2, "one"}}))
})
It("should ZIncr", func() {
score, err := client.ZIncr("zset", redis.Z{1, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(score).To(Equal(float64(1)))
vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
score, err = client.ZIncr("zset", redis.Z{1, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(score).To(Equal(float64(2)))
vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{2, "one"}}))
})
It("should ZIncrNX", func() {
score, err := client.ZIncrNX("zset", redis.Z{1, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(score).To(Equal(float64(1)))
vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
score, err = client.ZIncrNX("zset", redis.Z{1, "one"}).Result()
Expect(err).To(Equal(redis.Nil))
Expect(score).To(Equal(float64(0)))
vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
})
It("should ZIncrXX", func() {
score, err := client.ZIncrXX("zset", redis.Z{1, "one"}).Result()
Expect(err).To(Equal(redis.Nil))
Expect(score).To(Equal(float64(0)))
vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(BeEmpty())
added, err := client.ZAdd("zset", redis.Z{1, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(added).To(Equal(int64(1)))
score, err = client.ZIncrXX("zset", redis.Z{1, "one"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(score).To(Equal(float64(2)))
vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(vals).To(Equal([]redis.Z{{2, "one"}}))
})
It("should ZCard", func() { It("should ZCard", func() {
zAdd := client.ZAdd("zset", redis.Z{1, "one"}) zAdd := client.ZAdd("zset", redis.Z{1, "one"})
Expect(zAdd.Err()).NotTo(HaveOccurred()) Expect(zAdd.Err()).NotTo(HaveOccurred())
@ -2334,8 +2464,6 @@ var _ = Describe("Commands", func() {
}) })
//------------------------------------------------------------------------------
Describe("watch/unwatch", func() { Describe("watch/unwatch", func() {
It("should WatchUnwatch", func() { It("should WatchUnwatch", func() {