From b55bf2390b883d6b8f971bf4121446a0763141e2 Mon Sep 17 00:00:00 2001 From: itchyny Date: Tue, 30 Aug 2022 19:24:03 +0900 Subject: [PATCH] add notes to prohibit using values sharing same data for arguments (ref #188) --- README.md | 2 +- compiler.go | 1 + query.go | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c57a6eb3..dacec5a9 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ func main() { - Firstly, use [`gojq.Parse(string) (*Query, error)`](https://pkg.go.dev/github.com/itchyny/gojq#Parse) to get the query from a string. - Secondly, get the result iterator - using [`query.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Query.Run) or [`query.RunWithContext`](https://pkg.go.dev/github.com/itchyny/gojq#Query.RunWithContext) - - or alternatively, compile the query using [`gojq.Compile`](https://pkg.go.dev/github.com/itchyny/gojq#Compile) and then [`code.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Code.Run) or [`code.RunWithContext`](https://pkg.go.dev/github.com/itchyny/gojq#Code.RunWithContext). You can reuse the `*Code` against multiple inputs to avoid compilation of the same query. + - or alternatively, compile the query using [`gojq.Compile`](https://pkg.go.dev/github.com/itchyny/gojq#Compile) and then [`code.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Code.Run) or [`code.RunWithContext`](https://pkg.go.dev/github.com/itchyny/gojq#Code.RunWithContext). You can reuse the `*Code` against multiple inputs to avoid compilation of the same query. But for arguments of `code.Run`, do not give values sharing same data between multiple calls. - In either case, you cannot use custom type values as the query input. The type should be `[]interface{}` for an array and `map[string]interface{}` for a map (just like decoded to an `interface{}` using the [encoding/json](https://golang.org/pkg/encoding/json/) package). You can't use `[]int` or `map[string]string`, for example. If you want to query your custom struct, marshal to JSON, unmarshal to `interface{}` and use it as the query input. - Thirdly, iterate through the results using [`iter.Next() (interface{}, bool)`](https://pkg.go.dev/github.com/itchyny/gojq#Iter). The iterator can emit an error so make sure to handle it. The method returns `true` with results, and `false` when the iterator terminates. - The return type is not `(interface{}, error)` because iterators can emit multiple errors and you can continue after an error. It is difficult for the iterator to tell the termination in this situation. diff --git a/compiler.go b/compiler.go index a312b4d5..098b44e6 100644 --- a/compiler.go +++ b/compiler.go @@ -34,6 +34,7 @@ type Code struct { // a result iterator. // // It is safe to call this method in goroutines, to reuse a compiled [*Code]. +// But for arguments, do not give values sharing same data between goroutines. func (c *Code) Run(v interface{}, values ...interface{}) Iter { return c.RunWithContext(context.Background(), v, values...) } diff --git a/query.go b/query.go index 2823f7e0..4bba2d2a 100644 --- a/query.go +++ b/query.go @@ -20,6 +20,7 @@ type Query struct { // Run the query. // // It is safe to call this method in goroutines, to reuse a parsed [*Query]. +// But for arguments, do not give values sharing same data between goroutines. func (e *Query) Run(v interface{}) Iter { return e.RunWithContext(context.Background(), v) }