Skip to content

Commit 9d52b1f

Browse files
committed
Merge branch 'zaddincr'
2 parents dab6094 + 6cadb42 commit 9d52b1f

File tree

3 files changed

+79
-13
lines changed

3 files changed

+79
-13
lines changed

cmd_sorted_set.go

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@ func (m *Miniredis) cmdZadd(c *server.Peer, cmd string, args []string) {
5555
nx = false
5656
xx = false
5757
ch = false
58+
incr = false
5859
elems = map[string]float64{}
5960
)
61+
62+
outer:
6063
for len(args) > 0 {
6164
switch strings.ToUpper(args[0]) {
6265
case "NX":
@@ -71,21 +74,29 @@ func (m *Miniredis) cmdZadd(c *server.Peer, cmd string, args []string) {
7174
ch = true
7275
args = args[1:]
7376
continue
77+
case "INCR":
78+
incr = true
79+
args = args[1:]
80+
continue
7481
default:
75-
if len(args) < 2 {
76-
setDirty(c)
77-
c.WriteError(msgSyntaxError)
78-
return
79-
}
80-
score, err := strconv.ParseFloat(args[0], 64)
81-
if err != nil {
82-
setDirty(c)
83-
c.WriteError(msgInvalidFloat)
84-
return
85-
}
86-
elems[args[1]] = score
87-
args = args[2:]
82+
break outer
83+
}
84+
}
85+
86+
if len(args) == 0 || len(args)%2 != 0 {
87+
setDirty(c)
88+
c.WriteError(msgSyntaxError)
89+
return
90+
}
91+
for len(args) > 0 {
92+
score, err := strconv.ParseFloat(args[0], 64)
93+
if err != nil {
94+
setDirty(c)
95+
c.WriteError(msgInvalidFloat)
96+
return
8897
}
98+
elems[args[1]] = score
99+
args = args[2:]
89100
}
90101

91102
if xx && nx {
@@ -94,6 +105,12 @@ func (m *Miniredis) cmdZadd(c *server.Peer, cmd string, args []string) {
94105
return
95106
}
96107

108+
if incr && len(elems) > 1 {
109+
setDirty(c)
110+
c.WriteError(msgSingleElementPair)
111+
return
112+
}
113+
97114
withTx(m, c, func(c *server.Peer, ctx *connCtx) {
98115
db := m.db(ctx.selectedDB)
99116

@@ -102,6 +119,22 @@ func (m *Miniredis) cmdZadd(c *server.Peer, cmd string, args []string) {
102119
return
103120
}
104121

122+
if incr {
123+
for member, delta := range elems {
124+
if nx && db.ssetExists(key, member) {
125+
c.WriteNull()
126+
return
127+
}
128+
if xx && !db.ssetExists(key, member) {
129+
c.WriteNull()
130+
return
131+
}
132+
newScore := db.ssetIncrby(key, member, delta)
133+
c.WriteBulk(formatFloat(newScore))
134+
}
135+
return
136+
}
137+
105138
res := 0
106139
for member, score := range elems {
107140
if nx && db.ssetExists(key, member) {

cmd_sorted_set_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,34 @@ func TestSortedSetAdd(t *testing.T) {
172172
ok(t, err)
173173
equals(t, 1, b)
174174

175+
n, err := redis.Float64(c.Do("ZADD", "z", "INCR", 1.2, "one"))
176+
ok(t, err)
177+
equals(t, 2.4, n)
178+
179+
z, err := c.Do("ZADD", "z", "INCR", "NX", 1.2, "one")
180+
ok(t, err)
181+
equals(t, nil, z)
182+
183+
n, err = redis.Float64(c.Do("ZADD", "z", "INCR", "XX", 1.2, "one"))
184+
ok(t, err)
185+
equals(t, 3.6, n)
186+
187+
z, err = c.Do("ZADD", "q", "INCR", "XX", 1.2, "one")
188+
ok(t, err)
189+
equals(t, nil, z)
190+
191+
n, err = redis.Float64(c.Do("ZADD", "q", "INCR", "NX", 1.2, "one"))
192+
ok(t, err)
193+
equals(t, 1.2, n)
194+
195+
z, err = c.Do("ZADD", "q", "INCR", "NX", 1.2, "one")
196+
ok(t, err)
197+
equals(t, nil, z)
198+
199+
// CH is ignored with INCR
200+
n, err = redis.Float64(c.Do("ZADD", "z", "INCR", "CH", 1.2, "one"))
201+
ok(t, err)
202+
equals(t, 4.8, n)
175203
}
176204

177205
// Error cases
@@ -192,8 +220,12 @@ func TestSortedSetAdd(t *testing.T) {
192220
assert(t, err != nil, "ZADD error")
193221
_, err = redis.String(c.Do("ZADD", "set", "MX", 1.0))
194222
assert(t, err != nil, "ZADD error")
223+
_, err = redis.String(c.Do("ZADD", "set", 1.0, "key", "MX"))
224+
assert(t, err != nil, "ZADD error")
195225
_, err = redis.String(c.Do("ZADD", "set", "MX", "XX", 1.0, "foo"))
196226
assert(t, err != nil, "ZADD error")
227+
_, err = redis.String(c.Do("ZADD", "set", "INCR", 1.0, "foo", 2.3, "bar"))
228+
assert(t, err != nil, "ZADD error")
197229
}
198230
}
199231

redis.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const (
2929
msgInvalidKeysNumber = "ERR Number of keys can't be greater than number of args"
3030
msgNegativeKeysNumber = "ERR Number of keys can't be negative"
3131
msgScriptUsage = "ERR Unknown SCRIPT subcommand or wrong # of args."
32+
msgSingleElementPair = "ERR INCR option supports a single increment-element pair"
3233
msgNoScriptFound = "NOSCRIPT No matching script. Please use EVAL."
3334
)
3435

0 commit comments

Comments
 (0)