Added QueryResult and patched bugs

QueryResult now stores result items and position data, which aligns more
strongly with the rest of the library features than a plain
[]interface[}.  The design of the parser_test unittest was revised to
use array/map/scalar serialization (like match_test), since Go 1.3
redesigned maps to randomly order their keys. Since naive comparisons of
map data is now no longer possible, the unittest now sorts map
keys:value combinations.

* Patched a bug where getPosition("") was returning an invalid Position
* Revised parser_test to use serialization for comparisons for Go 1.3
This commit is contained in:
eanderton
2014-09-09 22:31:41 -04:00
parent 7f30fba1e6
commit 2811a1a3c9
6 changed files with 101 additions and 87 deletions
+46 -18
View File
@@ -1,21 +1,44 @@
package jpath
import (
_ "github.com/pelletier/go-toml"
. "github.com/pelletier/go-toml"
)
type nodeFilterFn func(node interface{}) bool
type nodeFn func(node interface{}) interface{}
// runtime context for executing query paths
type queryContext struct {
filters *map[string]nodeFilterFn
scripts *map[string]nodeFn
results []interface{}
type QueryResult struct {
items []interface{}
positions []Position
}
func (c *queryContext) appendResult(value interface{}) {
c.results = append(c.results, value)
// TODO: modify after merging with rest of lib
func (r *QueryResult) appendResult(node interface{}) {
r.items = append(r.items, node)
switch castNode := node.(type) {
case *TomlTree:
r.positions = append(r.positions, castNode.GetPosition(""))
//r.positions = append(r.positions, castNode.position)
//case *tomlValue:
//r.positions = append(r.positions, castNode.position)
default:
r.positions = append(r.positions, Position{})
}
}
func (r *QueryResult) Values() []interface{} {
return r.items
}
func (r *QueryResult) Positions() []Position {
return r.positions
}
// runtime context for executing query paths
type queryContext struct {
result *QueryResult
filters *map[string]nodeFilterFn
scripts *map[string]nodeFn
}
// generic path functor interface
@@ -56,17 +79,22 @@ func Compile(path string) *Query {
return parse(flow)
}
func (q *Query) Execute(node interface{}) interface{} {
func (q *Query) Execute(tree *TomlTree) *QueryResult {
result := &QueryResult {
items: []interface{}{},
positions: []Position{},
}
if q.root == nil {
return []interface{}{node} // identity query for no predicates
}
ctx := &queryContext{
filters: q.filters,
scripts: q.scripts,
results: []interface{}{},
}
q.root.Call(node, ctx)
return ctx.results
result.appendResult(tree)
} else {
ctx := &queryContext{
result: result,
filters: q.filters,
scripts: q.scripts,
}
q.root.Call(tree, ctx)
}
return result
}
func (q *Query) SetFilter(name string, fn nodeFilterFn) {