added [NX|XX] to SET, fixes #60

This commit is contained in:
Josh Baker 2016-10-03 08:31:13 -07:00
parent a13f735061
commit 46072f614f
3 changed files with 64 additions and 2 deletions

View File

@ -398,6 +398,7 @@ func (c *Controller) cmdFlushDB(msg *server.Message) (res string, d commandDetai
func (c *Controller) parseSetArgs(vs []resp.Value) ( func (c *Controller) parseSetArgs(vs []resp.Value) (
d commandDetailsT, fields []string, values []float64, d commandDetailsT, fields []string, values []float64,
xx, nx bool,
expires *float64, etype string, evs []resp.Value, err error, expires *float64, etype string, evs []resp.Value, err error,
) { ) {
var ok bool var ok bool
@ -465,6 +466,24 @@ func (c *Controller) parseSetArgs(vs []resp.Value) (
expires = &v expires = &v
continue continue
} }
if lc(arg, "xx") {
vs = nvs
if nx {
err = errInvalidArgument(arg)
return
}
xx = true
continue
}
if lc(arg, "nx") {
vs = nvs
if xx {
err = errInvalidArgument(arg)
return
}
nx = true
continue
}
break break
} }
if vs, typ, ok = tokenval(vs); !ok || typ == "" { if vs, typ, ok = tokenval(vs); !ok || typ == "" {
@ -621,24 +640,35 @@ func (c *Controller) cmdSet(msg *server.Message) (res string, d commandDetailsT,
} }
start := time.Now() start := time.Now()
vs := msg.Values[1:] vs := msg.Values[1:]
var fmap map[string]int
var fields []string var fields []string
var values []float64 var values []float64
var xx, nx bool
var ex *float64 var ex *float64
d, fields, values, ex, _, _, err = c.parseSetArgs(vs) d, fields, values, xx, nx, ex, _, _, err = c.parseSetArgs(vs)
if err != nil { if err != nil {
return return
} }
ex = ex ex = ex
col := c.getCol(d.key) col := c.getCol(d.key)
if col == nil { if col == nil {
if xx {
goto notok
}
col = collection.New() col = collection.New()
c.setCol(d.key, col) c.setCol(d.key, col)
} }
if nx {
_, _, ok := col.Get(d.id)
if ok {
goto notok
}
}
c.clearIDExpires(d.key, d.id) c.clearIDExpires(d.key, d.id)
d.oldObj, d.oldFields, d.fields = col.ReplaceOrInsert(d.id, d.obj, fields, values) d.oldObj, d.oldFields, d.fields = col.ReplaceOrInsert(d.id, d.obj, fields, values)
d.command = "set" d.command = "set"
d.updated = true // perhaps we should do a diff on the previous object? d.updated = true // perhaps we should do a diff on the previous object?
fmap := col.FieldMap() fmap = col.FieldMap()
d.fmap = make(map[string]int) d.fmap = make(map[string]int)
for key, idx := range fmap { for key, idx := range fmap {
d.fmap[key] = idx d.fmap[key] = idx
@ -654,6 +684,14 @@ func (c *Controller) cmdSet(msg *server.Message) (res string, d commandDetailsT,
res = "+OK\r\n" res = "+OK\r\n"
} }
return return
notok:
switch msg.OutputType {
case server.JSON:
res = `{"ok":false,"elapsed":"` + time.Now().Sub(start).String() + "\"}"
case server.RESP:
res = "$-1\r\n"
}
return
} }
func (c *Controller) parseFSetArgs(vs []resp.Value) (d commandDetailsT, err error) { func (c *Controller) parseFSetArgs(vs []resp.Value) (d commandDetailsT, err error) {

View File

@ -24,6 +24,18 @@
"type": ["string", "double"], "type": ["string", "double"],
"optional": true, "optional": true,
"multiple": false "multiple": false
},
{
"name": "type",
"optional": true,
"enumargs": [
{
"name": "NX"
},
{
"name": "XX"
}
]
}, },
{ {
"name": "value", "name": "value",

View File

@ -186,6 +186,18 @@ var commandsJSON = `{
"type": ["string", "double"], "type": ["string", "double"],
"optional": true, "optional": true,
"multiple": false "multiple": false
},
{
"name": "type",
"optional": true,
"enumargs": [
{
"name": "NX"
},
{
"name": "XX"
}
]
}, },
{ {
"name": "value", "name": "value",