mirror of
				https://github.com/TomWright/dasel.git
				synced 2022-05-22 02:32:45 +03:00 
			
		
		
		
	Merge pull request #149 from TomWright/not-equal
Add != comparison operator support in dynamic and search selectors
This commit is contained in:
		| @@ -7,7 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | ||||
|  | ||||
| ## [Unreleased] | ||||
|  | ||||
| - Nothing | ||||
| ### Added | ||||
|  | ||||
| - Support for `!=` comparison operator in dynamic and search selectors. | ||||
| - Support for `-`/`keyValue` key in dynamic selectors. | ||||
|  | ||||
| ## [v1.16.1] - 2021-08-02 | ||||
|  | ||||
|   | ||||
| @@ -12,6 +12,16 @@ type EqualCondition struct { | ||||
| 	Key string | ||||
| 	// Value is the value we are looking for. | ||||
| 	Value string | ||||
| 	// Not is true if this is a not equal check. | ||||
| 	Not bool | ||||
| } | ||||
|  | ||||
| func (c EqualCondition) check(a interface{}, b interface{}) (bool, error) { | ||||
| 	var res = fmt.Sprint(a) == b | ||||
| 	if c.Not { | ||||
| 		res = !res | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
|  | ||||
| // Check checks to see if other contains the required key value pair. | ||||
| @@ -23,7 +33,7 @@ func (c EqualCondition) Check(other reflect.Value) (bool, error) { | ||||
| 	value := unwrapValue(other) | ||||
|  | ||||
| 	if c.Key == "value" || c.Key == "." { | ||||
| 		return fmt.Sprint(value.Interface()) == c.Value, nil | ||||
| 		return c.check(value.Interface(), c.Value) | ||||
| 	} | ||||
|  | ||||
| 	switch value.Kind() { | ||||
| @@ -39,7 +49,7 @@ func (c EqualCondition) Check(other reflect.Value) (bool, error) { | ||||
| 			return false, fmt.Errorf("subquery failed: %w", err) | ||||
| 		} | ||||
|  | ||||
| 		return fmt.Sprint(foundNode.InterfaceValue()) == c.Value, nil | ||||
| 		return c.check(foundNode.InterfaceValue(), c.Value) | ||||
| 	} | ||||
|  | ||||
| 	return false, &UnhandledCheckType{Value: value.String()} | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| package dasel | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| ) | ||||
|  | ||||
| @@ -8,6 +9,16 @@ import ( | ||||
| type KeyEqualCondition struct { | ||||
| 	// Value is the value we are looking for. | ||||
| 	Value string | ||||
| 	// Not is true if this is a not equal check. | ||||
| 	Not bool | ||||
| } | ||||
|  | ||||
| func (c KeyEqualCondition) check(a interface{}, b interface{}) (bool, error) { | ||||
| 	var res = fmt.Sprint(a) == b | ||||
| 	if c.Not { | ||||
| 		res = !res | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
|  | ||||
| // Check checks to see if other contains the required key value pair. | ||||
| @@ -18,5 +29,5 @@ func (c KeyEqualCondition) Check(other reflect.Value) (bool, error) { | ||||
|  | ||||
| 	value := unwrapValue(other) | ||||
|  | ||||
| 	return c.Value == value.String(), nil | ||||
| 	return c.check(c.Value, value.String()) | ||||
| } | ||||
|   | ||||
							
								
								
									
										3
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								go.sum
									
									
									
									
									
								
							| @@ -34,7 +34,6 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb | ||||
| github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||
| github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= | ||||
| github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= | ||||
| github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= | ||||
| github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= | ||||
| @@ -101,7 +100,6 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= | ||||
| golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||||
| golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0= | ||||
| golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | ||||
| golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| @@ -121,7 +119,6 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20190311212946-11955173bddd h1:/e+gpKk9r3dJobndpTytxS2gOy6m5uvpg+ISQoEcusQ= | ||||
| golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||||
| google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= | ||||
| google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= | ||||
|   | ||||
| @@ -119,12 +119,21 @@ func findNextAvailableIndex(n *Node, createIfNotExists bool) (reflect.Value, err | ||||
| } | ||||
|  | ||||
| // processFindDynamicItem is used by findValueDynamic. | ||||
| func processFindDynamicItem(n *Node, object reflect.Value) (bool, error) { | ||||
| func processFindDynamicItem(n *Node, object reflect.Value, key string) (bool, error) { | ||||
| 	// Loop through each condition. | ||||
| 	allConditionsMatched := true | ||||
| 	for _, c := range n.Selector.Conditions { | ||||
| 		// If the object doesn't match any checks, return a ValueNotFound. | ||||
| 		found, err := c.Check(object) | ||||
|  | ||||
| 		var found bool | ||||
| 		var err error | ||||
| 		switch cond := c.(type) { | ||||
| 		case *KeyEqualCondition: | ||||
| 			found, err = cond.Check(reflect.ValueOf(key)) | ||||
| 		default: | ||||
| 			found, err = cond.Check(object) | ||||
| 		} | ||||
|  | ||||
| 		if err != nil { | ||||
| 			return false, err | ||||
| 		} | ||||
| @@ -152,7 +161,7 @@ func findValueDynamic(n *Node, createIfNotExists bool) (reflect.Value, error) { | ||||
| 	case reflect.Slice: | ||||
| 		for i := 0; i < value.Len(); i++ { | ||||
| 			object := value.Index(i) | ||||
| 			found, err := processFindDynamicItem(n, object) | ||||
| 			found, err := processFindDynamicItem(n, object, fmt.Sprint(i)) | ||||
| 			if err != nil { | ||||
| 				return nilValue(), err | ||||
| 			} | ||||
| @@ -171,7 +180,7 @@ func findValueDynamic(n *Node, createIfNotExists bool) (reflect.Value, error) { | ||||
| 	case reflect.Map: | ||||
| 		for _, key := range value.MapKeys() { | ||||
| 			object := value.MapIndex(key) | ||||
| 			found, err := processFindDynamicItem(n, object) | ||||
| 			found, err := processFindDynamicItem(n, object, key.String()) | ||||
| 			if err != nil { | ||||
| 				return nilValue(), err | ||||
| 			} | ||||
|   | ||||
| @@ -182,12 +182,21 @@ func findNextAvailableIndexNodes(selector Selector, previousValue reflect.Value, | ||||
| } | ||||
|  | ||||
| // processFindDynamicItems is used by findNodesDynamic. | ||||
| func processFindDynamicItems(selector Selector, object reflect.Value) (bool, error) { | ||||
| func processFindDynamicItems(selector Selector, object reflect.Value, key string) (bool, error) { | ||||
| 	// Loop through each condition. | ||||
| 	allConditionsMatched := true | ||||
| 	for _, c := range selector.Conditions { | ||||
| 		// If the object doesn't match any checks, return a ValueNotFound. | ||||
| 		found, err := c.Check(object) | ||||
|  | ||||
| 		var found bool | ||||
| 		var err error | ||||
| 		switch cond := c.(type) { | ||||
| 		case *KeyEqualCondition: | ||||
| 			found, err = cond.Check(reflect.ValueOf(key)) | ||||
| 		default: | ||||
| 			found, err = cond.Check(object) | ||||
| 		} | ||||
|  | ||||
| 		if err != nil { | ||||
| 			return false, err | ||||
| 		} | ||||
| @@ -215,7 +224,7 @@ func findNodesDynamic(selector Selector, previousValue reflect.Value, createIfNo | ||||
| 		results := make([]*Node, 0) | ||||
| 		for i := 0; i < value.Len(); i++ { | ||||
| 			object := value.Index(i) | ||||
| 			found, err := processFindDynamicItems(selector, object) | ||||
| 			found, err := processFindDynamicItems(selector, object, fmt.Sprint(i)) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| @@ -246,7 +255,7 @@ func findNodesDynamic(selector Selector, previousValue reflect.Value, createIfNo | ||||
| 		results := make([]*Node, 0) | ||||
| 		for _, key := range value.MapKeys() { | ||||
| 			object := value.MapIndex(key) | ||||
| 			found, err := processFindDynamicItems(selector, object) | ||||
| 			found, err := processFindDynamicItems(selector, object, key.String()) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
|   | ||||
							
								
								
									
										77
									
								
								node_test.go
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								node_test.go
									
									
									
									
									
								
							| @@ -181,6 +181,19 @@ func TestParseSelector(t *testing.T) { | ||||
| 			}, | ||||
| 		}, | ||||
| 	})) | ||||
| 	t.Run("SearchNotEqual", testParseSelector(".(?:name!=asd)", dasel.Selector{ | ||||
| 		Raw:       ".(?:name!=asd)", | ||||
| 		Current:   ".(?:name!=asd)", | ||||
| 		Remaining: "", | ||||
| 		Type:      "SEARCH", | ||||
| 		Conditions: []dasel.Condition{ | ||||
| 			&dasel.EqualCondition{ | ||||
| 				Key:   "name", | ||||
| 				Value: "asd", | ||||
| 				Not:   true, | ||||
| 			}, | ||||
| 		}, | ||||
| 	})) | ||||
| 	t.Run("SearchMoreThan", testParseSelector(".(?:name.[#]>3)", dasel.Selector{ | ||||
| 		Raw:       ".(?:name.[#]>3)", | ||||
| 		Current:   ".(?:name.[#]>3)", | ||||
| @@ -244,6 +257,41 @@ func TestParseSelector(t *testing.T) { | ||||
| 			}, | ||||
| 		}, | ||||
| 	})) | ||||
| 	t.Run("SearchKeyNotEqual", testParseSelector(".(?:-!=asd)", dasel.Selector{ | ||||
| 		Raw:       ".(?:-!=asd)", | ||||
| 		Current:   ".(?:-!=asd)", | ||||
| 		Remaining: "", | ||||
| 		Type:      "SEARCH", | ||||
| 		Conditions: []dasel.Condition{ | ||||
| 			&dasel.KeyEqualCondition{ | ||||
| 				Value: "asd", | ||||
| 				Not:   true, | ||||
| 			}, | ||||
| 		}, | ||||
| 	})) | ||||
| 	t.Run("DynamicKey", testParseSelector(".(-=asd)", dasel.Selector{ | ||||
| 		Raw:       ".(-=asd)", | ||||
| 		Current:   ".(-=asd)", | ||||
| 		Remaining: "", | ||||
| 		Type:      "DYNAMIC", | ||||
| 		Conditions: []dasel.Condition{ | ||||
| 			&dasel.KeyEqualCondition{ | ||||
| 				Value: "asd", | ||||
| 			}, | ||||
| 		}, | ||||
| 	})) | ||||
| 	t.Run("DynamicKeyNotEqual", testParseSelector(".(-!=asd)", dasel.Selector{ | ||||
| 		Raw:       ".(-!=asd)", | ||||
| 		Current:   ".(-!=asd)", | ||||
| 		Remaining: "", | ||||
| 		Type:      "DYNAMIC", | ||||
| 		Conditions: []dasel.Condition{ | ||||
| 			&dasel.KeyEqualCondition{ | ||||
| 				Value: "asd", | ||||
| 				Not:   true, | ||||
| 			}, | ||||
| 		}, | ||||
| 	})) | ||||
| 	t.Run("DynamicEqual", testParseSelector(".(name=asd)", dasel.Selector{ | ||||
| 		Raw:       ".(name=asd)", | ||||
| 		Current:   ".(name=asd)", | ||||
| @@ -256,6 +304,19 @@ func TestParseSelector(t *testing.T) { | ||||
| 			}, | ||||
| 		}, | ||||
| 	})) | ||||
| 	t.Run("DynamicNotEqual", testParseSelector(".(name!=asd)", dasel.Selector{ | ||||
| 		Raw:       ".(name!=asd)", | ||||
| 		Current:   ".(name!=asd)", | ||||
| 		Remaining: "", | ||||
| 		Type:      "DYNAMIC", | ||||
| 		Conditions: []dasel.Condition{ | ||||
| 			&dasel.EqualCondition{ | ||||
| 				Key:   "name", | ||||
| 				Value: "asd", | ||||
| 				Not:   true, | ||||
| 			}, | ||||
| 		}, | ||||
| 	})) | ||||
| 	t.Run("DynamicMoreThan", testParseSelector(".(name.[#]>3)", dasel.Selector{ | ||||
| 		Raw:       ".(name.[#]>3)", | ||||
| 		Current:   ".(name.[#]>3)", | ||||
| @@ -380,10 +441,22 @@ func TestNode_QueryMultiple(t *testing.T) { | ||||
| 	t.Run("SingleResult", testNodeQueryMultipleArray(".[0].name", []interface{}{ | ||||
| 		"Tom", | ||||
| 	})) | ||||
| 	t.Run("SingleResultDynamic", testNodeQueryMultipleArray(".(age=25).name", []interface{}{ | ||||
| 	t.Run("SingleResultDynamicEqual", testNodeQueryMultipleArray(".(age=25).name", []interface{}{ | ||||
| 		"Amelia", | ||||
| 	})) | ||||
| 	t.Run("SingleResultDynamic", testNodeQueryMultipleArray(".(age=27).name", []interface{}{ | ||||
| 	t.Run("SingleResultDynamicNotEqual", testNodeQueryMultipleArray(".(age!=27).name", []interface{}{ | ||||
| 		"Amelia", | ||||
| 	})) | ||||
| 	t.Run("SingleResultDynamicKeyEqual", testNodeQueryMultipleArray(".(-=0).name", []interface{}{ | ||||
| 		"Tom", | ||||
| 	})) | ||||
| 	t.Run("MultipleResultDynamicKeyNotEqual", testNodeQueryMultipleArray(".(-!=0).name", []interface{}{ | ||||
| 		"Jim", "Amelia", | ||||
| 	})) | ||||
| 	t.Run("MultipleResultSearchKeyNotEqual", testNodeQueryMultipleArray(".[*].(?:-!=name)", []interface{}{ | ||||
| 		"27", "27", "25", | ||||
| 	})) | ||||
| 	t.Run("MultipleResultDynamic", testNodeQueryMultipleArray(".(age=27).name", []interface{}{ | ||||
| 		"Tom", | ||||
| 		"Jim", | ||||
| 	})) | ||||
|   | ||||
| @@ -46,6 +46,66 @@ func ParseSelector(selector string) (Selector, error) { | ||||
| 	return sel, err | ||||
| } | ||||
|  | ||||
| func getCondition(parts DynamicSelectorParts) (Condition, error) { | ||||
| 	switch parts.Key { | ||||
| 	case "-", "keyValue": | ||||
| 		switch parts.Comparison { | ||||
| 		case "=": | ||||
| 			return &KeyEqualCondition{ | ||||
| 				Value: parts.Value, | ||||
| 			}, nil | ||||
| 		case "!=": | ||||
| 			return &KeyEqualCondition{ | ||||
| 				Value: parts.Value, | ||||
| 				Not:   true, | ||||
| 			}, nil | ||||
| 		default: | ||||
| 			return nil, &UnknownComparisonOperatorErr{Operator: parts.Comparison} | ||||
| 		} | ||||
| 	default: | ||||
|  | ||||
| 		switch parts.Comparison { | ||||
| 		case "=": | ||||
| 			return &EqualCondition{ | ||||
| 				Key:   parts.Key, | ||||
| 				Value: parts.Value, | ||||
| 			}, nil | ||||
| 		case "!=": | ||||
| 			return &EqualCondition{ | ||||
| 				Key:   parts.Key, | ||||
| 				Value: parts.Value, | ||||
| 				Not:   true, | ||||
| 			}, nil | ||||
| 		case ">=": | ||||
| 			return &SortedComparisonCondition{ | ||||
| 				Key:   parts.Key, | ||||
| 				Value: parts.Value, | ||||
| 				Equal: true, | ||||
| 				After: true, | ||||
| 			}, nil | ||||
| 		case ">": | ||||
| 			return &SortedComparisonCondition{ | ||||
| 				Key:   parts.Key, | ||||
| 				Value: parts.Value, | ||||
| 				After: true, | ||||
| 			}, nil | ||||
| 		case "<=": | ||||
| 			return &SortedComparisonCondition{ | ||||
| 				Key:   parts.Key, | ||||
| 				Value: parts.Value, | ||||
| 				Equal: true, | ||||
| 			}, nil | ||||
| 		case "<": | ||||
| 			return &SortedComparisonCondition{ | ||||
| 				Key:   parts.Key, | ||||
| 				Value: parts.Value, | ||||
| 			}, nil | ||||
| 		default: | ||||
| 			return nil, &UnknownComparisonOperatorErr{Operator: parts.Comparison} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func processParseSelectorDynamic(selector string, sel Selector) (Selector, error) { | ||||
| 	sel.Type = "DYNAMIC" | ||||
| 	dynamicGroups, err := DynamicSelectorToGroups(selector) | ||||
| @@ -54,44 +114,14 @@ func processParseSelectorDynamic(selector string, sel Selector) (Selector, error | ||||
| 	} | ||||
|  | ||||
| 	for _, g := range dynamicGroups { | ||||
| 		m := FindDynamicSelectorParts(g) | ||||
|  | ||||
| 		var cond Condition | ||||
| 		switch m.Comparison { | ||||
| 		case "=": | ||||
| 			cond = &EqualCondition{ | ||||
| 				Key:   m.Key, | ||||
| 				Value: m.Value, | ||||
| 			} | ||||
| 		case ">=": | ||||
| 			cond = &SortedComparisonCondition{ | ||||
| 				Key:   m.Key, | ||||
| 				Value: m.Value, | ||||
| 				Equal: true, | ||||
| 				After: true, | ||||
| 			} | ||||
| 		case ">": | ||||
| 			cond = &SortedComparisonCondition{ | ||||
| 				Key:   m.Key, | ||||
| 				Value: m.Value, | ||||
| 				After: true, | ||||
| 			} | ||||
| 		case "<=": | ||||
| 			cond = &SortedComparisonCondition{ | ||||
| 				Key:   m.Key, | ||||
| 				Value: m.Value, | ||||
| 				Equal: true, | ||||
| 			} | ||||
| 		case "<": | ||||
| 			cond = &SortedComparisonCondition{ | ||||
| 				Key:   m.Key, | ||||
| 				Value: m.Value, | ||||
| 			} | ||||
| 		default: | ||||
| 			return sel, &UnknownComparisonOperatorErr{Operator: m.Comparison} | ||||
| 		parts := FindDynamicSelectorParts(g) | ||||
| 		cond, err := getCondition(parts) | ||||
| 		if err != nil { | ||||
| 			return sel, err | ||||
| 		} | ||||
| 		if cond != nil { | ||||
| 			sel.Conditions = append(sel.Conditions, cond) | ||||
| 		} | ||||
|  | ||||
| 		sel.Conditions = append(sel.Conditions, cond) | ||||
| 	} | ||||
|  | ||||
| 	return sel, nil | ||||
| @@ -109,58 +139,15 @@ func processParseSelectorSearch(selector string, sel Selector) (Selector, error) | ||||
| 	} | ||||
|  | ||||
| 	for _, g := range dynamicGroups { | ||||
| 		m := FindDynamicSelectorParts(g) | ||||
|  | ||||
| 		m.Key = strings.TrimPrefix(m.Key, "?:") | ||||
|  | ||||
| 		var cond Condition | ||||
| 		switch m.Key { | ||||
| 		case "-", "keyValue": | ||||
| 			switch m.Comparison { | ||||
| 			case "=": | ||||
| 				cond = &KeyEqualCondition{ | ||||
| 					Value: m.Value, | ||||
| 				} | ||||
| 			default: | ||||
| 				return sel, &UnknownComparisonOperatorErr{Operator: m.Comparison} | ||||
| 			} | ||||
| 		default: | ||||
| 			switch m.Comparison { | ||||
| 			case "=": | ||||
| 				cond = &EqualCondition{ | ||||
| 					Key:   m.Key, | ||||
| 					Value: m.Value, | ||||
| 				} | ||||
| 			case ">=": | ||||
| 				cond = &SortedComparisonCondition{ | ||||
| 					Key:   m.Key, | ||||
| 					Value: m.Value, | ||||
| 					Equal: true, | ||||
| 					After: true, | ||||
| 				} | ||||
| 			case ">": | ||||
| 				cond = &SortedComparisonCondition{ | ||||
| 					Key:   m.Key, | ||||
| 					Value: m.Value, | ||||
| 					After: true, | ||||
| 				} | ||||
| 			case "<=": | ||||
| 				cond = &SortedComparisonCondition{ | ||||
| 					Key:   m.Key, | ||||
| 					Value: m.Value, | ||||
| 					Equal: true, | ||||
| 				} | ||||
| 			case "<": | ||||
| 				cond = &SortedComparisonCondition{ | ||||
| 					Key:   m.Key, | ||||
| 					Value: m.Value, | ||||
| 				} | ||||
| 			default: | ||||
| 				return sel, &UnknownComparisonOperatorErr{Operator: m.Comparison} | ||||
| 			} | ||||
| 		parts := FindDynamicSelectorParts(g) | ||||
| 		parts.Key = strings.TrimPrefix(parts.Key, "?:") | ||||
| 		cond, err := getCondition(parts) | ||||
| 		if err != nil { | ||||
| 			return sel, err | ||||
| 		} | ||||
| 		if cond != nil { | ||||
| 			sel.Conditions = append(sel.Conditions, cond) | ||||
| 		} | ||||
|  | ||||
| 		sel.Conditions = append(sel.Conditions, cond) | ||||
| 	} | ||||
|  | ||||
| 	return sel, nil | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Tom Wright
					Tom Wright