Merge branch 'fset_multi_xx' of https://github.com/rshura/tile38 into rshura-fset_multi_xx

This commit is contained in:
Josh Baker 2017-11-16 18:06:40 -07:00
commit fb6c29203b
4 changed files with 88 additions and 48 deletions

View File

@ -233,6 +233,24 @@ func (c *Collection) SetField(id, field string, value float64) (obj geojson.Obje
return item.object, c.getFieldValues(id), updated, true return item.object, c.getFieldValues(id), updated, true
} }
// SetFields is similar to SetField, just setting multiple fields at once
func (c *Collection) SetFields(id string, in_fields []string, in_values []float64) (
obj geojson.Object, fields []float64, updated_count int, ok bool,
) {
i := c.items.Get(&itemT{id: id})
if i == nil {
ok = false
return
}
item := i.(*itemT)
for idx, field := range in_fields {
if c.setField(item, field, in_values[idx]) {
updated_count++
}
}
return item.object, c.getFieldValues(id), updated_count, true
}
func (c *Collection) setField(item *itemT, field string, value float64) (updated bool) { func (c *Collection) setField(item *itemT, field string, value float64) (updated bool) {
idx, ok := c.fieldMap[field] idx, ok := c.fieldMap[field]
if !ok { if !ok {

View File

@ -780,8 +780,9 @@ notok:
return return
} }
func (c *Controller) parseFSetArgs(vs []resp.Value) (d commandDetailsT, err error) { func (c *Controller) parseFSetArgs(vs []resp.Value) (
var svalue string d commandDetailsT, fields []string, values []float64, xx bool, err error,
) {
var ok bool var ok bool
if vs, d.key, ok = tokenval(vs); !ok || d.key == "" { if vs, d.key, ok = tokenval(vs); !ok || d.key == "" {
err = errInvalidNumberOfArguments err = errInvalidNumberOfArguments
@ -791,62 +792,73 @@ func (c *Controller) parseFSetArgs(vs []resp.Value) (d commandDetailsT, err erro
err = errInvalidNumberOfArguments err = errInvalidNumberOfArguments
return return
} }
if vs, d.field, ok = tokenval(vs); !ok || d.field == "" { for len(vs) > 0 {
var name string
if vs, name, ok = tokenval(vs); !ok || name == "" {
err = errInvalidNumberOfArguments err = errInvalidNumberOfArguments
return return
} }
if isReservedFieldName(d.field) { if lc(name, "xx") {
err = errInvalidNumberOfArguments xx = true
continue
}
if isReservedFieldName(name) {
err = errInvalidArgument(name)
return return
} }
var svalue string
var value float64
if vs, svalue, ok = tokenval(vs); !ok || svalue == "" { if vs, svalue, ok = tokenval(vs); !ok || svalue == "" {
err = errInvalidNumberOfArguments err = errInvalidNumberOfArguments
return return
} }
if len(vs) != 0 { value, err = strconv.ParseFloat(svalue, 64)
err = errInvalidNumberOfArguments
return
}
d.value, err = strconv.ParseFloat(svalue, 64)
if err != nil { if err != nil {
err = errInvalidArgument(svalue) err = errInvalidArgument(svalue)
return return
} }
fields = append(fields, name)
values = append(values, value)
}
return return
} }
func (c *Controller) cmdFset(msg *server.Message) (res resp.Value, d commandDetailsT, err error) { func (c *Controller) cmdFset(msg *server.Message) (res resp.Value, d commandDetailsT, err error) {
start := time.Now() start := time.Now()
vs := msg.Values[1:] vs := msg.Values[1:]
d, err = c.parseFSetArgs(vs) var fields []string
var values []float64
var xx bool
var updated_count int
d, fields, values, xx, err = c.parseFSetArgs(vs)
col := c.getCol(d.key) col := c.getCol(d.key)
if col == nil { if col == nil {
err = errKeyNotFound err = errKeyNotFound
return return
} }
var ok bool var ok bool
d.obj, d.fields, d.updated, ok = col.SetField(d.id, d.field, d.value) d.obj, d.fields, updated_count, ok = col.SetFields(d.id, fields, values)
if !ok { if !(ok || xx) {
err = errIDNotFound err = errIDNotFound
return return
} }
if ok {
d.command = "fset" d.command = "fset"
d.timestamp = time.Now() d.timestamp = time.Now()
d.updated = updated_count > 0
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
} }
}
switch msg.OutputType { switch msg.OutputType {
case server.JSON: case server.JSON:
res = resp.StringValue(`{"ok":true,"elapsed":"` + time.Now().Sub(start).String() + "\"}") res = resp.StringValue(`{"ok":true,"elapsed":"` + time.Now().Sub(start).String() + "\"}")
case server.RESP: case server.RESP:
if d.updated { res = resp.IntegerValue(updated_count)
res = resp.IntegerValue(1)
} else {
res = resp.IntegerValue(0)
}
} }
return return
} }

View File

@ -165,7 +165,7 @@
"group": "keys" "group": "keys"
}, },
"FSET": { "FSET": {
"summary": "Set the value for a single field of an id", "summary": "Set the value for one or more fields of an id",
"complexity": "O(1)", "complexity": "O(1)",
"arguments":[ "arguments":[
{ {
@ -177,12 +177,15 @@
"type": "string" "type": "string"
}, },
{ {
"name": "field", "command": "XX",
"type": "string" "name": [],
"type": [],
"optional": true
}, },
{ {
"name": "value", "name": ["field","value"],
"type": "double" "type": ["string","double"],
"multiple": true
} }
], ],
"since": "1.0.0", "since": "1.0.0",

View File

@ -80,9 +80,16 @@ func keys_FSET_test(mc *mockServer) error {
{"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7]"}, {"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7]"},
{"FSET", "mykey", "myid", "f1", 105.6}, {1}, {"FSET", "mykey", "myid", "f1", 105.6}, {1},
{"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7 [f1 105.6]]"}, {"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7 [f1 105.6]]"},
{"FSET", "mykey", "myid", "f1", 1.1, "f2", 2.2}, {2},
{"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7 [f1 1.1 f2 2.2]]"},
{"FSET", "mykey", "myid", "f1", 1.1, "f2", 22.22}, {1},
{"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7 [f1 1.1 f2 22.22]]"},
{"FSET", "mykey", "myid", "f1", 0}, {1}, {"FSET", "mykey", "myid", "f1", 0}, {1},
{"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7 [f2 22.22]]"},
{"FSET", "mykey", "myid", "f2", 0}, {1},
{"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7]"}, {"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7]"},
{"FSET", "mykey", "myid", "f1", 0}, {0}, {"FSET", "mykey", "myid2", "xx", "f1", 1.1, "f2", 2.2}, {0},
{"GET", "mykey", "myid2"}, {nil},
{"DEL", "mykey", "myid"}, {"1"}, {"DEL", "mykey", "myid"}, {"1"},
{"GET", "mykey", "myid"}, {nil}, {"GET", "mykey", "myid"}, {nil},
}) })