mirror of https://github.com/tidwall/tile38.git
added [NX|XX] to SET, fixes #60
This commit is contained in:
parent
a13f735061
commit
46072f614f
|
@ -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) {
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue