mirror of https://github.com/tidwall/tile38.git
Merge branch 'fset_multi_xx' of https://github.com/rshura/tile38 into rshura-fset_multi_xx
This commit is contained in:
commit
fb6c29203b
|
@ -233,6 +233,24 @@ func (c *Collection) SetField(id, field string, value float64) (obj geojson.Obje
|
|||
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) {
|
||||
idx, ok := c.fieldMap[field]
|
||||
if !ok {
|
||||
|
|
|
@ -780,8 +780,9 @@ notok:
|
|||
return
|
||||
}
|
||||
|
||||
func (c *Controller) parseFSetArgs(vs []resp.Value) (d commandDetailsT, err error) {
|
||||
var svalue string
|
||||
func (c *Controller) parseFSetArgs(vs []resp.Value) (
|
||||
d commandDetailsT, fields []string, values []float64, xx bool, err error,
|
||||
) {
|
||||
var ok bool
|
||||
if vs, d.key, ok = tokenval(vs); !ok || d.key == "" {
|
||||
err = errInvalidNumberOfArguments
|
||||
|
@ -791,26 +792,33 @@ func (c *Controller) parseFSetArgs(vs []resp.Value) (d commandDetailsT, err erro
|
|||
err = errInvalidNumberOfArguments
|
||||
return
|
||||
}
|
||||
if vs, d.field, ok = tokenval(vs); !ok || d.field == "" {
|
||||
err = errInvalidNumberOfArguments
|
||||
return
|
||||
}
|
||||
if isReservedFieldName(d.field) {
|
||||
err = errInvalidNumberOfArguments
|
||||
return
|
||||
}
|
||||
if vs, svalue, ok = tokenval(vs); !ok || svalue == "" {
|
||||
err = errInvalidNumberOfArguments
|
||||
return
|
||||
}
|
||||
if len(vs) != 0 {
|
||||
err = errInvalidNumberOfArguments
|
||||
return
|
||||
}
|
||||
d.value, err = strconv.ParseFloat(svalue, 64)
|
||||
if err != nil {
|
||||
err = errInvalidArgument(svalue)
|
||||
return
|
||||
for len(vs) > 0 {
|
||||
var name string
|
||||
if vs, name, ok = tokenval(vs); !ok || name == "" {
|
||||
err = errInvalidNumberOfArguments
|
||||
return
|
||||
}
|
||||
if lc(name, "xx") {
|
||||
xx = true
|
||||
continue
|
||||
}
|
||||
if isReservedFieldName(name) {
|
||||
err = errInvalidArgument(name)
|
||||
return
|
||||
}
|
||||
var svalue string
|
||||
var value float64
|
||||
if vs, svalue, ok = tokenval(vs); !ok || svalue == "" {
|
||||
err = errInvalidNumberOfArguments
|
||||
return
|
||||
}
|
||||
value, err = strconv.ParseFloat(svalue, 64)
|
||||
if err != nil {
|
||||
err = errInvalidArgument(svalue)
|
||||
return
|
||||
}
|
||||
fields = append(fields, name)
|
||||
values = append(values, value)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -818,35 +826,39 @@ func (c *Controller) parseFSetArgs(vs []resp.Value) (d commandDetailsT, err erro
|
|||
func (c *Controller) cmdFset(msg *server.Message) (res resp.Value, d commandDetailsT, err error) {
|
||||
start := time.Now()
|
||||
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)
|
||||
if col == nil {
|
||||
err = errKeyNotFound
|
||||
return
|
||||
}
|
||||
var ok bool
|
||||
d.obj, d.fields, d.updated, ok = col.SetField(d.id, d.field, d.value)
|
||||
if !ok {
|
||||
d.obj, d.fields, updated_count, ok = col.SetFields(d.id, fields, values)
|
||||
if !(ok || xx) {
|
||||
err = errIDNotFound
|
||||
return
|
||||
}
|
||||
d.command = "fset"
|
||||
d.timestamp = time.Now()
|
||||
fmap := col.FieldMap()
|
||||
d.fmap = make(map[string]int)
|
||||
for key, idx := range fmap {
|
||||
d.fmap[key] = idx
|
||||
if ok {
|
||||
d.command = "fset"
|
||||
d.timestamp = time.Now()
|
||||
d.updated = updated_count > 0
|
||||
fmap := col.FieldMap()
|
||||
d.fmap = make(map[string]int)
|
||||
for key, idx := range fmap {
|
||||
d.fmap[key] = idx
|
||||
}
|
||||
}
|
||||
|
||||
switch msg.OutputType {
|
||||
case server.JSON:
|
||||
res = resp.StringValue(`{"ok":true,"elapsed":"` + time.Now().Sub(start).String() + "\"}")
|
||||
case server.RESP:
|
||||
if d.updated {
|
||||
res = resp.IntegerValue(1)
|
||||
} else {
|
||||
res = resp.IntegerValue(0)
|
||||
}
|
||||
res = resp.IntegerValue(updated_count)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -165,7 +165,7 @@
|
|||
"group": "keys"
|
||||
},
|
||||
"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)",
|
||||
"arguments":[
|
||||
{
|
||||
|
@ -177,12 +177,15 @@
|
|||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "field",
|
||||
"type": "string"
|
||||
"command": "XX",
|
||||
"name": [],
|
||||
"type": [],
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": "double"
|
||||
"name": ["field","value"],
|
||||
"type": ["string","double"],
|
||||
"multiple": true
|
||||
}
|
||||
],
|
||||
"since": "1.0.0",
|
||||
|
@ -499,12 +502,12 @@
|
|||
"type": "pattern",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"command": "DISTANCE",
|
||||
"name": [],
|
||||
"type": [],
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"command": "DISTANCE",
|
||||
"name": [],
|
||||
"type": [],
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"command": "WHERE",
|
||||
"name": ["field","min","max"],
|
||||
|
|
|
@ -80,9 +80,16 @@ func keys_FSET_test(mc *mockServer) error {
|
|||
{"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7]"},
|
||||
{"FSET", "mykey", "myid", "f1", 105.6}, {1},
|
||||
{"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},
|
||||
{"GET", "mykey", "myid", "WITHFIELDS", "HASH", 7}, {"[9my5xp7 [f2 22.22]]"},
|
||||
{"FSET", "mykey", "myid", "f2", 0}, {1},
|
||||
{"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"},
|
||||
{"GET", "mykey", "myid"}, {nil},
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue