query

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 5, 2018 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package query performs JSONPath-like queries on a TOML document.

The query path implementation is based loosely on the JSONPath specification: http://goessner.net/articles/JsonPath/.

The idea behind a query path is to allow quick access to any element, or set of elements within TOML document, with a single expression.

result, err := query.CompileAndExecute("$.foo.bar.baz", tree)

This is roughly equivalent to:

next := tree.Get("foo")
if next != nil {
  next = next.Get("bar")
  if next != nil {
    next = next.Get("baz")
  }
}
result := next

err is nil if any parsing exception occurs.

If no node in the tree matches the query, result will simply contain an empty list of items.

As illustrated above, the query path is much more efficient, especially since the structure of the TOML file can vary. Rather than making assumptions about a document's structure, a query allows the programmer to make structured requests into the document, and get zero or more values as a result.

Query syntax

The syntax of a query begins with a root token, followed by any number sub-expressions:

$
                 Root of the TOML tree.  This must always come first.
.name
                 Selects child of this node, where 'name' is a TOML key
                 name.
['name']
                 Selects child of this node, where 'name' is a string
                 containing a TOML key name.
[index]
                 Selcts child array element at 'index'.
..expr
                 Recursively selects all children, filtered by an a union,
                 index, or slice expression.
..*
                 Recursive selection of all nodes at this point in the
                 tree.
.*
                 Selects all children of the current node.
[expr,expr]
                 Union operator - a logical 'or' grouping of two or more
                 sub-expressions: index, key name, or filter.
[start:end:step]
                 Slice operator - selects array elements from start to
                 end-1, at the given step.  All three arguments are
                 optional.
[?(filter)]
                 Named filter expression - the function 'filter' is
                 used to filter children at this node.

Query Indexes And Slices

Index expressions perform no bounds checking, and will contribute no values to the result set if the provided index or index range is invalid. Negative indexes represent values from the end of the array, counting backwards.

// select the last index of the array named 'foo'
query.CompileAndExecute("$.foo[-1]", tree)

Slice expressions are supported, by using ':' to separate a start/end index pair.

// select up to the first five elements in the array
query.CompileAndExecute("$.foo[0:5]", tree)

Slice expressions also allow negative indexes for the start and stop arguments.

// select all array elements.
query.CompileAndExecute("$.foo[0:-1]", tree)

Slice expressions may have an optional stride/step parameter:

// select every other element
query.CompileAndExecute("$.foo[0:-1:2]", tree)

Slice start and end parameters are also optional:

// these are all equivalent and select all the values in the array
query.CompileAndExecute("$.foo[:]", tree)
query.CompileAndExecute("$.foo[0:]", tree)
query.CompileAndExecute("$.foo[:-1]", tree)
query.CompileAndExecute("$.foo[0:-1:]", tree)
query.CompileAndExecute("$.foo[::1]", tree)
query.CompileAndExecute("$.foo[0::1]", tree)
query.CompileAndExecute("$.foo[:-1:1]", tree)
query.CompileAndExecute("$.foo[0:-1:1]", tree)

Query Filters

Query filters are used within a Union [,] or single Filter [] expression. A filter only allows nodes that qualify through to the next expression, and/or into the result set.

// returns children of foo that are permitted by the 'bar' filter.
query.CompileAndExecute("$.foo[?(bar)]", tree)

There are several filters provided with the library:

tree
       Allows nodes of type Tree.
int
       Allows nodes of type int64.
float
       Allows nodes of type float64.
string
       Allows nodes of type string.
time
       Allows nodes of type time.Time.
bool
       Allows nodes of type bool.

Query Results

An executed query returns a Result object. This contains the nodes in the TOML tree that qualify the query expression. Position information is also available for each value in the set.

// display the results of a query
results := query.CompileAndExecute("$.foo.bar.baz", tree)
for idx, value := results.Values() {
    fmt.Println("%v: %v", results.Positions()[idx], value)
}

Compiled Queries

Queries may be executed directly on a Tree object, or compiled ahead of time and executed discretely. The former is more convenient, but has the penalty of having to recompile the query expression each time.

// basic query
results := query.CompileAndExecute("$.foo.bar.baz", tree)

// compiled query
query, err := toml.Compile("$.foo.bar.baz")
results := query.Execute(tree)

// run the compiled query again on a different tree
moreResults := query.Execute(anotherTree)

User Defined Query Filters

Filter expressions may also be user defined by using the SetFilter() function on the Query object. The function must return true/false, which signifies if the passed node is kept or discarded, respectively.

// create a query that references a user-defined filter
query, _ := query.Compile("$[?(bazOnly)]")

// define the filter, and assign it to the query
query.SetFilter("bazOnly", func(node interface{}) bool{
    if tree, ok := node.(*Tree); ok {
        return tree.Has("baz")
    }
    return false  // reject all other node types
})

// run the query
query.Execute(tree)

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type NodeFilterFn

type NodeFilterFn func(node interface{}) bool

NodeFilterFn represents a user-defined filter function, for use with Query.SetFilter().

The return value of the function must indicate if 'node' is to be included at this stage of the TOML path. Returning true will include the node, and returning false will exclude it.

NOTE: Care should be taken to write script callbacks such that they are safe to use from multiple goroutines.

Example (FilterExample)
tree, _ := toml.Load(`
      [struct_one]
      foo = "foo"
      bar = "bar"

      [struct_two]
      baz = "baz"
      gorf = "gorf"
    `)

// create a query that references a user-defined-filter
query, _ := Compile("$[?(bazOnly)]")

// define the filter, and assign it to the query
query.SetFilter("bazOnly", func(node interface{}) bool {
	if tree, ok := node.(*toml.Tree); ok {
		return tree.Has("baz")
	}
	return false // reject all other node types
})

// results contain only the 'struct_two' Tree
query.Execute(tree)
Output:

type Query

type Query struct {
	// contains filtered or unexported fields
}

A Query is the representation of a compiled TOML path. A Query is safe for concurrent use by multiple goroutines.

Example (QueryExample)
config, _ := toml.Load(`
      [[book]]
      title = "The Stand"
      author = "Stephen King"
      [[book]]
      title = "For Whom the Bell Tolls"
      author = "Ernest Hemmingway"
      [[book]]
      title = "Neuromancer"
      author = "William Gibson"
    `)

// find and print all the authors in the document
query, _ := Compile("$.book.author")
authors := query.Execute(config)
for _, name := range authors.Values() {
	fmt.Println(name)
}
Output:

func Compile

func Compile(path string) (*Query, error)

Compile compiles a TOML path expression. The returned Query can be used to match elements within a Tree and its descendants. See Execute.

func (*Query) Execute

func (q *Query) Execute(tree *toml.Tree) *Result

Execute executes a query against a Tree, and returns the result of the query.

func (*Query) SetFilter

func (q *Query) SetFilter(name string, fn NodeFilterFn)

SetFilter sets a user-defined filter function. These may be used inside "?(..)" query expressions to filter TOML document elements within a query.

type Result

type Result struct {
	// contains filtered or unexported fields
}

Result is the result of Executing a Query.

func CompileAndExecute

func CompileAndExecute(path string, tree *toml.Tree) (*Result, error)

CompileAndExecute is a shorthand for Compile(path) followed by Execute(tree).

func (Result) Positions

func (r Result) Positions() []toml.Position

Positions is a set of positions for values within a Result. Each index in Positions() corresponds to the entry in Value() of the same index.

func (Result) Values

func (r Result) Values() []interface{}

Values is a set of values within a Result. The order of values is not guaranteed to be in document order, and may be different each time a query is executed.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL