basic string support

This commit is contained in:
Josh Baker 2016-07-10 22:40:18 -06:00
parent fbe19564b9
commit 02ff2a70bf
4 changed files with 114 additions and 4 deletions

View File

@ -46,7 +46,6 @@ func (i *itemT) Less(item btree.Item, ctx int) bool {
// the values match so we will compare the ids, which are always unique. // the values match so we will compare the ids, which are always unique.
return i.id < item.(*itemT).id return i.id < item.(*itemT).id
} }
} }
func (i *itemT) Rect() (minX, minY, maxX, maxY float64) { func (i *itemT) Rect() (minX, minY, maxX, maxY float64) {
@ -412,3 +411,5 @@ func (c *Collection) Intersects(cursor uint64, sparse uint8, obj geojson.Object,
return true return true
}) })
} }
func (c *Collection) SearchValues(pivot string, desc bool, iterator func(id string, obj geojson.Object, fields []float64) bool) {
}

View File

@ -329,7 +329,7 @@ func (c *Controller) handleInputCommand(conn *server.Conn, msg *server.Message,
if c.config.ReadOnly { if c.config.ReadOnly {
return writeErr(errors.New("read only")) return writeErr(errors.New("read only"))
} }
case "get", "keys", "scan", "nearby", "within", "intersects", "hooks": case "get", "keys", "scan", "nearby", "within", "intersects", "hooks": //, "search":
// read operations // read operations
c.mu.RLock() c.mu.RLock()
defer c.mu.RUnlock() defer c.mu.RUnlock()
@ -434,6 +434,8 @@ func (c *Controller) command(msg *server.Message, w io.Writer) (res string, d co
res, err = c.cmdWithin(msg) res, err = c.cmdWithin(msg)
case "intersects": case "intersects":
res, err = c.cmdIntersects(msg) res, err = c.cmdIntersects(msg)
case "search":
res, err = c.cmdSearch(msg)
case "get": case "get":
res, err = c.cmdGet(msg) res, err = c.cmdGet(msg)
case "keys": case "keys":

View File

@ -311,7 +311,9 @@ func (c *Controller) cmdWithinOrIntersects(cmd string, msg *server.Message) (res
if sw.col == nil { if sw.col == nil {
return "", errKeyNotFound return "", errKeyNotFound
} }
if msg.OutputType == server.JSON {
wr.WriteString(`{"ok":true`) wr.WriteString(`{"ok":true`)
}
sw.writeHead() sw.writeHead()
if cmd == "within" { if cmd == "within" {
s.cursor = sw.col.Within(s.cursor, s.sparse, s.o, s.minLat, s.minLon, s.maxLat, s.maxLon, s.cursor = sw.col.Within(s.cursor, s.sparse, s.o, s.minLat, s.minLon, s.maxLat, s.maxLon,
@ -327,6 +329,101 @@ func (c *Controller) cmdWithinOrIntersects(cmd string, msg *server.Message) (res
) )
} }
sw.writeFoot(s.cursor) sw.writeFoot(s.cursor)
if msg.OutputType == server.JSON {
wr.WriteString(`,"elapsed":"` + time.Now().Sub(start).String() + "\"}") wr.WriteString(`,"elapsed":"` + time.Now().Sub(start).String() + "\"}")
}
return string(wr.Bytes()), nil
}
func (c *Controller) cmdSearch(msg *server.Message) (res string, err error) {
start := time.Now()
vs := msg.Values[1:]
var ok bool
var key string
if vs, key, ok = tokenval(vs); !ok || key == "" {
err = errInvalidNumberOfArguments
return
}
col := c.getCol(key)
if col == nil {
err = errKeyNotFound
return
}
var tok string
var pivot string
var pivoton bool
var limiton bool
var limit int
var descon bool
var desc bool
for {
if vs, tok, ok = tokenval(vs); !ok || tok == "" {
break
}
switch strings.ToLower(tok) {
default:
err = errInvalidArgument(tok)
return
case "pivot":
if pivoton {
err = errInvalidArgument(tok)
return
}
pivoton = true
if vs, pivot, ok = tokenval(vs); !ok || pivot == "" {
err = errInvalidNumberOfArguments
return
}
case "limit":
if limiton {
err = errInvalidArgument(tok)
return
}
limiton = true
if vs, tok, ok = tokenval(vs); !ok || tok == "" {
err = errInvalidNumberOfArguments
return
}
n, err2 := strconv.ParseUint(tok, 10, 64)
if err2 != nil {
err = errInvalidArgument(tok)
return
}
limit = int(n)
case "asc", "desc":
if descon {
err = errInvalidArgument(tok)
return
}
descon = true
switch strings.ToLower(tok) {
case "asc":
desc = false
case "desc":
desc = true
}
}
}
println(pivoton, pivot)
println(limiton, limit)
println(descon, desc)
wr := &bytes.Buffer{}
if msg.OutputType == server.JSON {
wr.WriteString(`{"ok":true,"objects":[`)
}
n := 0
col.SearchValues(pivot, desc, func(id string, obj geojson.Object, fields []float64) bool {
if msg.OutputType == server.JSON {
if n > 0 {
wr.WriteString(`,`)
}
wr.WriteString(`{"id":` + jsonString(id) + `,"object":` + obj.JSON() + `}`)
n++
}
return true
})
if msg.OutputType == server.JSON {
wr.WriteString(`],"elapsed":"` + time.Now().Sub(start).String() + "\"}")
}
return string(wr.Bytes()), nil return string(wr.Bytes()), nil
} }

View File

@ -159,6 +159,16 @@ reading:
values = append(values, resp.StringValue(string(line))) values = append(values, resp.StringValue(string(line)))
break break
} }
if line[0] == '"' && line[len(line)-1] == '"' {
if len(values) > 0 &&
strings.ToLower(values[0].String()) == "set" &&
strings.ToLower(values[len(values)-1].String()) == "string" {
// Setting a string value that is contained inside double quotes.
// This is only because of the boundary issues of the native protocol.
values = append(values, resp.StringValue(string(line[1:len(line)-1])))
break
}
}
i := 0 i := 0
for ; i < len(line); i++ { for ; i < len(line); i++ {
if line[i] == ' ' { if line[i] == ' ' {