Skip to content

Commit

Permalink
Feat/improver (#11)
Browse files Browse the repository at this point in the history
fix: path with "_"
- use gjson
  • Loading branch information
imneov authored Mar 3, 2022
1 parent cdfe372 commit e056c4d
Show file tree
Hide file tree
Showing 10 changed files with 2,086 additions and 828 deletions.
11 changes: 6 additions & 5 deletions collectjs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ type Collect = JSONNode
func New(raw interface{}) *Collect {
switch raw := raw.(type) {
case string:
collect := &Collect{}
collect.path = ""
collect.value = []byte(raw)
collect.datatype = String
return collect
return newCollect([]byte(raw))
case []byte:
return newCollect(raw)
case Result:
Expand All @@ -28,6 +24,8 @@ func New(raw interface{}) *Collect {
return UNDEFINED_RESULT
}



func newCollect(data []byte) *Collect {
collect := &Collect{}
value := make([]byte, len(data))
Expand All @@ -36,6 +34,9 @@ func newCollect(data []byte) *Collect {
collect.value = value
if _, jtype, _, err := jsonparser.Get(data); err == nil {
collect.datatype = datetype(jtype)
if collect.datatype == String{
collect.value = collect.value[1:len(collect.value)-1]
}
} else {
collect.err = err
}
Expand Down
8 changes: 5 additions & 3 deletions collectjs_patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"github.com/tkeel-io/tdtl/pkg/json/gjson"
"github.com/tkeel-io/tdtl/pkg/json/jsonparser"
"github.com/tkeel-io/tdtl/pkg/json/sjson"
"strings"
)

Expand Down Expand Up @@ -35,6 +36,7 @@ func get(raw []byte, path string) *Collect {
ret := gjson.GetBytes(raw, path)
return New(ret)
}

//
//func Get(raw []byte, path string) []byte {
// //keys := path2JSONPARSER(path)
Expand All @@ -51,10 +53,10 @@ func get(raw []byte, path string) *Collect {
// return []byte(ret.String())
//}


func set(raw []byte, path string, value []byte) ([]byte, error) {
keys := path2JSONPARSER(path)
return jsonparser.Set(raw, value, keys...)
//keys := path2JSONPARSER(path)
//return jsonparser.Set(raw, value, keys...)
return sjson.SetRawBytes(raw, path, value)
}
func add(raw []byte, path string, value []byte) ([]byte, error) {
keys := path2JSONPARSER(path)
Expand Down
24 changes: 23 additions & 1 deletion collectjs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
var raw = Byte(`{"cpu":1,"mem": ["lo0", "eth1", "eth2"],"a":[{"v":0},{"v":1},{"v":2}],"b":[{"v":{"cv":1}},{"v":{"cv":2}},{"v":{"cv":3}}],"where": 10,"metadata": {"name": "Light1", "price": 11.05}}`)
var rawArray = Byte(`[{"v":{"cv":1}},{"v":{"cv":2}},{"v":{"cv":3}}]`)
var rawEmptyArray = Byte(`[]`)
var rawEmptyObject = Byte(`{}`)

func TestCollect_Get(t *testing.T) {
tests := []struct {
Expand Down Expand Up @@ -52,7 +53,8 @@ func TestCollect_Set(t *testing.T) {
value *Collect
want interface{}
}{
//{"2", "cpu", StringNode("2"), `{"cpu":2,"mem": ["lo0", "eth1", "eth2"],"a":[{"v":0},{"v":1},{"v":2}],"b":[{"v":{"cv":1}},{"v":{"cv":2}},{"v":{"cv":3}}],"where": 10,"metadata": {"name": "Light1", "price": 11.05}}`},
{"1", "metadata.name", New(`"abc"`), `{"cpu":2,"mem": ["lo0", "eth1", "eth2"],"a":[{"v":0},{"v":1},{"v":2}],"b":[{"v":{"cv":1}},{"v":{"cv":2}},{"v":{"cv":3}}],"where": 10,"metadata": {"name": "Light1", "price": 11.05}}`},
{"2", "cpu", New("2"), `{"cpu":2,"mem": ["lo0", "eth1", "eth2"],"a":[{"v":0},{"v":1},{"v":2}],"b":[{"v":{"cv":1}},{"v":{"cv":2}},{"v":{"cv":3}}],"where": 10,"metadata": {"name": "Light1", "price": 11.05}}`},
{"3", "a", New(`{"v":0}`), `{"cpu":1,"mem": ["lo0", "eth1", "eth2"],"a":{"v":0},"b":[{"v":{"cv":1}},{"v":{"cv":2}},{"v":{"cv":3}}],"where": 10,"metadata": {"name": "Light1", "price": 11.05}}`},
{"4", "a[0]", New(`0`), `{"cpu":1,"mem": ["lo0", "eth1", "eth2"],"a":[0,{"v":1},{"v":2}],"b":[{"v":{"cv":1}},{"v":{"cv":2}},{"v":{"cv":3}}],"where": 10,"metadata": {"name": "Light1", "price": 11.05}}`},
{"5", "a[0].v", New(`{"v":0}`), `{"cpu":1,"mem": ["lo0", "eth1", "eth2"],"a":[{"v":{"v":0}},{"v":1},{"v":2}],"b":[{"v":{"cv":1}},{"v":{"cv":2}},{"v":{"cv":3}}],"where": 10,"metadata": {"name": "Light1", "price": 11.05}}`},
Expand All @@ -68,6 +70,26 @@ func TestCollect_Set(t *testing.T) {
}
}

func TestCollect_Set2(t *testing.T) {
tests := []struct {
name string
path string
value *Collect
want interface{}
}{
{"1", "metadata._name", New(`"abc"`), `{"metadata":{"_name":"abc"}}`},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cc := newCollect(rawEmptyObject)
cc.Set(tt.path, tt.value)
if got := cc.Raw(); !reflect.DeepEqual(string(got), tt.want) {
t.Errorf("\nGet() = %v\nWant() = %v", string(got), tt.want)
}
})
}
}

func TestCollect_Append(t *testing.T) {
tests := []struct {
name string
Expand Down
9 changes: 8 additions & 1 deletion context_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,14 @@ func NewMapContext(values map[string]Node, functions map[string]ContextFunc) Con
//Value get value from context
func (c mapContext) Value(key string) Node {
if ret, ok := c.values[key]; ok {
return ret
switch ret := ret.(type) {
case JSONNode:
return ret.Node()
case *JSONNode:
return ret.Node()
default:
return ret
}
}
return UNDEFINED_RESULT
}
Expand Down
100 changes: 56 additions & 44 deletions pkg/json/gjson/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@
src="logo.png"
width="240" height="78" border="0" alt="GJSON">
<br>
<a href="https://travis-ci.org/tidwall/gjson"><img src="https://img.shields.io/travis/tidwall/gjson.svg?style=flat-square" alt="Build Status"></a>
<a href="https://godoc.org/github.com/tidwall/gjson"><img src="https://img.shields.io/badge/api-reference-blue.svg?style=flat-square" alt="GoDoc"></a>
<a href="http://tidwall.com/gjson-play"><img src="https://img.shields.io/badge/%F0%9F%8F%90-playground-9900cc.svg?style=flat-square" alt="GJSON Playground"></a>
<a href="https://tidwall.com/gjson-play"><img src="https://img.shields.io/badge/%F0%9F%8F%90-playground-9900cc.svg?style=flat-square" alt="GJSON Playground"></a>
<a href="SYNTAX.md"><img src="https://img.shields.io/badge/{}-syntax-33aa33.svg?style=flat-square" alt="GJSON Syntax"></a>

</p>



<p align="center">get json values quickly</a></p>

GJSON is a Go package that provides a [fast](#performance) and [simple](#get-a-value) way to get values from a json document.
It has features such as [one line retrieval](#get-a-value), [dot notation paths](#path-syntax), [iteration](#iterate-through-an-object-or-array), and [parsing json lines](#json-lines).

Also check out [SJSON](https://github.com/tidwall/sjson) for modifying json, and the [JJ](https://github.com/tidwall/jj) command line tool.

This README is a quick overview of how to use GJSON, for more information check out [GJSON Syntax](SYNTAX.md).

Getting Started
===============

Expand Down Expand Up @@ -71,9 +72,9 @@ The dot and wildcard characters can be escaped with '\\'.
"children": ["Sara","Alex","Jack"],
"fav.movie": "Deer Hunter",
"friends": [
{"first": "Dale", "last": "Murphy", "age": 44},
{"first": "Roger", "last": "Craig", "age": 68},
{"first": "Jane", "last": "Murphy", "age": 47}
{"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},
{"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},
{"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}
]
}
```
Expand All @@ -90,17 +91,25 @@ The dot and wildcard characters can be escaped with '\\'.
"friends.1.last" >> "Craig"
```

You can also query an array for the first match by using `#[...]`, or find all matches with `#[...]#`.
Queries support the `==`, `!=`, `<`, `<=`, `>`, `>=` comparison operators and the simple pattern matching `%` (like) and `!%` (not like) operators.
You can also query an array for the first match by using `#(...)`, or find all
matches with `#(...)#`. Queries support the `==`, `!=`, `<`, `<=`, `>`, `>=`
comparison operators and the simple pattern matching `%` (like) and `!%`
(not like) operators.

```
friends.#[last=="Murphy"].first >> "Dale"
friends.#[last=="Murphy"]#.first >> ["Dale","Jane"]
friends.#[age>45]#.last >> ["Craig","Murphy"]
friends.#[first%"D*"].last >> "Murphy"
friends.#[first!%"D*"].last >> "Craig"
friends.#(last=="Murphy").first >> "Dale"
friends.#(last=="Murphy")#.first >> ["Dale","Jane"]
friends.#(age>45)#.last >> ["Craig","Murphy"]
friends.#(first%"D*").last >> "Murphy"
friends.#(first!%"D*").last >> "Craig"
friends.#(nets.#(=="fb"))#.first >> ["Dale","Roger"]
```

*Please note that prior to v1.3.0, queries used the `#[...]` brackets. This was
changed in v1.3.0 as to avoid confusion with the new
[multipath](SYNTAX.md#multipaths) syntax. For backwards compatibility,
`#[...]` will continue to work until the next major release.*

## Result Type

GJSON supports the json types `string`, `number`, `bool`, and `null`.
Expand All @@ -118,11 +127,12 @@ nil, for JSON null
To directly access the value:

```go
result.Type // can be String, Number, True, False, Null, or JSON
result.Str // holds the string
result.Num // holds the float64 number
result.Raw // holds the raw json
result.Index // index of raw value in original json, zero means index unknown
result.Type // can be String, Number, True, False, Null, or JSON
result.Str // holds the string
result.Num // holds the float64 number
result.Raw // holds the raw json
result.Index // index of raw value in original json, zero means index unknown
result.Indexes // indexes of all the elements that match on a path containing the '#' query character.
```

There are a variety of handy functions that work on a result:
Expand All @@ -145,10 +155,6 @@ result.Less(token Result, caseSensitive bool) bool

The `result.Value()` function returns an `interface{}` which requires type assertion and is one of the following Go types:

The `result.Array()` function returns back an array of values.
If the result represents a non-existent value, then an empty array will be returned.
If the result is not a JSON array, the return value will be an array containing one result.

```go
boolean >> bool
number >> float64
Expand All @@ -158,6 +164,10 @@ array >> []interface{}
object >> map[string]interface{}
```

The `result.Array()` function returns back an array of values.
If the result represents a non-existent value, then an empty array will be returned.
If the result is not a JSON array, the return value will be an array containing one result.

### 64-bit integers

The `result.Int()` and `result.Uint()` calls are capable of reading all 64 bits, allowing for large JSON integers.
Expand Down Expand Up @@ -185,11 +195,20 @@ we'll get `children` array and reverse the order:
"children|@reverse|0" >> "Jack"
```

There are currently three built-in modifiers:
There are currently the following built-in modifiers:

- `@reverse`: Reverse an array or the members of an object.
- `@ugly`: Remove all whitespace from a json document.
- `@pretty`: Make the json document more human readable.
- `@this`: Returns the current element. It can be used to retrieve the root element.
- `@valid`: Ensure the json document is valid.
- `@flatten`: Flattens an array.
- `@join`: Joins multiple objects into a single object.
- `@keys`: Returns an array of keys for an object.
- `@values`: Returns an array of values for an object.
- `@tostr`: Converts json to a string. Wraps a json string.
- `@fromstr`: Converts a string from json. Unwraps a json string.
- `@group`: Groups arrays of objects. See [e4fc67c](https://github.com/tidwall/gjson/commit/e4fc67c92aeebf2089fabc7872f010e340d105db).

### Modifier arguments

Expand Down Expand Up @@ -263,7 +282,7 @@ For example:
..1 >> {"name": "Alexa", "age": 34}
..3 >> {"name": "Deloise", "age": 44}
..#.name >> ["Gilbert","Alexa","May","Deloise"]
..#[name="May"].age >> 57
..#(name="May").age >> 57
```

The `ForEachLines` function will iterate through JSON lines.
Expand Down Expand Up @@ -308,7 +327,7 @@ for _, name := range result.Array() {
You can also query an object inside an array:

```go
name := gjson.Get(json, `programmers.#[lastName="Hunter"].firstName`)
name := gjson.Get(json, `programmers.#(lastName="Hunter").firstName`)
println(name.String()) // prints "Elliotte"
```

Expand Down Expand Up @@ -424,14 +443,15 @@ Benchmarks of GJSON alongside [encoding/json](https://golang.org/pkg/encoding/js
and [json-iterator](https://github.com/json-iterator/go)

```
BenchmarkGJSONGet-8 3000000 372 ns/op 0 B/op 0 allocs/op
BenchmarkGJSONUnmarshalMap-8 900000 4154 ns/op 1920 B/op 26 allocs/op
BenchmarkJSONUnmarshalMap-8 600000 9019 ns/op 3048 B/op 69 allocs/op
BenchmarkJSONDecoder-8 300000 14120 ns/op 4224 B/op 184 allocs/op
BenchmarkFFJSONLexer-8 1500000 3111 ns/op 896 B/op 8 allocs/op
BenchmarkEasyJSONLexer-8 3000000 887 ns/op 613 B/op 6 allocs/op
BenchmarkJSONParserGet-8 3000000 499 ns/op 21 B/op 0 allocs/op
BenchmarkJSONIterator-8 3000000 812 ns/op 544 B/op 9 allocs/op
BenchmarkGJSONGet-16 11644512 311 ns/op 0 B/op 0 allocs/op
BenchmarkGJSONUnmarshalMap-16 1122678 3094 ns/op 1920 B/op 26 allocs/op
BenchmarkJSONUnmarshalMap-16 516681 6810 ns/op 2944 B/op 69 allocs/op
BenchmarkJSONUnmarshalStruct-16 697053 5400 ns/op 928 B/op 13 allocs/op
BenchmarkJSONDecoder-16 330450 10217 ns/op 3845 B/op 160 allocs/op
BenchmarkFFJSONLexer-16 1424979 2585 ns/op 880 B/op 8 allocs/op
BenchmarkEasyJSONLexer-16 3000000 729 ns/op 501 B/op 5 allocs/op
BenchmarkJSONParserGet-16 3000000 366 ns/op 21 B/op 0 allocs/op
BenchmarkJSONIterator-16 3000000 869 ns/op 693 B/op 14 allocs/op
```

JSON document used:
Expand Down Expand Up @@ -464,20 +484,12 @@ JSON document used:
}
```

Each operation was rotated though one of the following search paths:
Each operation was rotated through one of the following search paths:

```
widget.window.name
widget.image.hOffset
widget.text.onMouseUp
```

*These benchmarks were run on a MacBook Pro 15" 2.8 GHz Intel Core i7 using Go 1.8 and can be be found [here](https://github.com/tidwall/gjson-benchmarks).*


## Contact
Josh Baker [@tidwall](http://twitter.com/tidwall)

## License

GJSON source code is available under the MIT [License](/LICENSE).
*These benchmarks were run on a MacBook Pro 16" 2.4 GHz Intel Core i9 using Go 1.17 and can be found [here](https://github.com/tidwall/gjson-benchmarks).*
Loading

0 comments on commit e056c4d

Please sign in to comment.