From 46072f614ff3dfa0acf4ddf51e7ef4e7979a1dfd Mon Sep 17 00:00:00 2001 From: Josh Baker Date: Mon, 3 Oct 2016 08:31:13 -0700 Subject: [PATCH] added [NX|XX] to SET, fixes #60 --- controller/crud.go | 42 ++++++++++++++++++++++++++++++++++++++++-- core/commands.json | 12 ++++++++++++ core/commands_gen.go | 12 ++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/controller/crud.go b/controller/crud.go index 1ea0eb10..ed927b88 100644 --- a/controller/crud.go +++ b/controller/crud.go @@ -398,6 +398,7 @@ func (c *Controller) cmdFlushDB(msg *server.Message) (res string, d commandDetai func (c *Controller) parseSetArgs(vs []resp.Value) ( d commandDetailsT, fields []string, values []float64, + xx, nx bool, expires *float64, etype string, evs []resp.Value, err error, ) { var ok bool @@ -465,6 +466,24 @@ func (c *Controller) parseSetArgs(vs []resp.Value) ( expires = &v 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 } 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() vs := msg.Values[1:] + var fmap map[string]int var fields []string var values []float64 + var xx, nx bool var ex *float64 - d, fields, values, ex, _, _, err = c.parseSetArgs(vs) + d, fields, values, xx, nx, ex, _, _, err = c.parseSetArgs(vs) if err != nil { return } ex = ex col := c.getCol(d.key) if col == nil { + if xx { + goto notok + } col = collection.New() c.setCol(d.key, col) } + if nx { + _, _, ok := col.Get(d.id) + if ok { + goto notok + } + } c.clearIDExpires(d.key, d.id) d.oldObj, d.oldFields, d.fields = col.ReplaceOrInsert(d.id, d.obj, fields, values) d.command = "set" 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) for key, idx := range fmap { d.fmap[key] = idx @@ -654,6 +684,14 @@ func (c *Controller) cmdSet(msg *server.Message) (res string, d commandDetailsT, res = "+OK\r\n" } 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) { diff --git a/core/commands.json b/core/commands.json index 71243d39..4c864ae7 100644 --- a/core/commands.json +++ b/core/commands.json @@ -24,6 +24,18 @@ "type": ["string", "double"], "optional": true, "multiple": false + }, + { + "name": "type", + "optional": true, + "enumargs": [ + { + "name": "NX" + }, + { + "name": "XX" + } + ] }, { "name": "value", diff --git a/core/commands_gen.go b/core/commands_gen.go index 0b7e175b..ec17f27a 100644 --- a/core/commands_gen.go +++ b/core/commands_gen.go @@ -186,6 +186,18 @@ var commandsJSON = `{ "type": ["string", "double"], "optional": true, "multiple": false + }, + { + "name": "type", + "optional": true, + "enumargs": [ + { + "name": "NX" + }, + { + "name": "XX" + } + ] }, { "name": "value",