diff --git a/connor/README.md b/connor/README.md deleted file mode 100644 index be16ea54e6..0000000000 --- a/connor/README.md +++ /dev/null @@ -1,155 +0,0 @@ -# Connor -**Flexible condition DSL for Go** - -Connor is a simple condition DSL and evaluator for Go inspired by MongoDB's -query language. It aims to provide a simple and straightforward means to -express conditions against `map[string]interface{}` objects for everything -from rules engines to query tools. - -Connor only implements a subset of MongoDB's query language, the most commonly -used methods, however it has been designed to make adding new operators simple -and straightforward should you require them. - -## Example - -```go -package main - -import ( - "github.com/SierraSoftworks/connor" -) - -func parse(d string) map[string]interface{} { - var v map[string]interface{} - if err := json.NewDecoder(bytes.NewBufferString(d)).Decode(&v); err != nil { - fmt.Fatal(err) - } - - return v -} - -func main() { - conds := parse(`{ - "x": 1, - "y": { "$in": [1, 2, 3] }, - "z": { "$ne": 5 } - }`) - - data := parse(`{ - "x": 1, - "y": 2, - "z": 3 - }`) - - if match, err := connor.Match(conds, data); err != nil { - fmt.Fatal("failed to run match:", err) - } else if match { - fmt.Println("Matched") - } else { - fmt.Println("No Match") - } -} -``` - -## Operators -Connor has a number of built in operators which enable you to quickly compare a number -of common data structures to one another. The following are supported operators for use -in your conditions. - -### Equality `$eq` -```json -{ "$eq": "value" } -``` - -### Inequality `$ne` -```json -{ "$ne": "value" } -``` - -### Greater Than `$gt` -```json -{ "$gt": 5.3 } -``` - -### Greater Than or Equal `$ge` -```json -{ "$ge": 5 } -``` - -### Less Than `$lt` -```json -{ "$lt": 42 } -``` - -### Less Than or Equal `$le` -```json -{ "$le": 42 } -``` - -### Set Contains `$in` -```json -{ "$in": [1, 2, 3] } -``` - -### Set Excludes `$nin` -```json -{ "$nin": [1, 2, 3] } -``` - -### String Contains `$contains` -```json -{ "$contains": "test" } -``` - -### Logical And `$and` -```json -{ "$and": [{ "$gt": 5 }, { "$lt": 10 }]} -``` - -### Logical Or `$or` -```json -{ "$or": [{ "$gt": 10 }, { "$eq": 0 }]} -``` - -## Custom Operators -Connor supports registering your own custom operators for any additional condition -evaluation you wish to perform. These operators are registered using the `Register()` -method and are expected to match the following interface: - -```go -type Operator interface { - Name() string - Evaluate(condition, data interface{}) (bool, error) -} -``` - -The following is an example of an operator which determines whether the data is nil. - -```go -func init() { - connor.Register(&NilOperator{}) -} - -type NilOperator struct {} - -func (o *NilOperator) Name() string { - return "nil" -} - -func (o *NilOperator) Evaluate(condition, data interface{}) (bool, error) { - if c, ok := condition.(bool); ok { - return data != nil ^ c, nil - } else { - return data == nil, nil - } -} -``` - -You can then use this operator as the following example shows, or specify `false` -to check for non-nil values. - -```json -{ - "x": { "$nil": true } -} -``` diff --git a/connor/and.go b/connor/and.go index dacd80eee1..2363c4859c 100644 --- a/connor/and.go +++ b/connor/and.go @@ -2,24 +2,13 @@ package connor import "fmt" -func init() { - Register(&AndOperator{}) -} - -// AndOperator is an operator which allows the evaluation of +// and is an operator which allows the evaluation of // of a number of conditions, matching if all of them match. -type AndOperator struct { -} - -func (o *AndOperator) Name() string { - return "and" -} - -func (o *AndOperator) Evaluate(condition, data interface{}) (bool, error) { +func and(condition, data interface{}) (bool, error) { switch cn := condition.(type) { case []interface{}: for _, c := range cn { - if m, err := MatchWith("$eq", c, data); err != nil { + if m, err := eq(c, data); err != nil { return false, err } else if !m { return false, nil diff --git a/connor/connor.go b/connor/connor.go index 6e4a818e5c..fc47540a68 100644 --- a/connor/connor.go +++ b/connor/connor.go @@ -2,7 +2,6 @@ package connor import ( "fmt" - "strings" "github.com/sourcenetwork/defradb/core" ) @@ -10,21 +9,35 @@ import ( // Match is the default method used in Connor to match some data to a // set of conditions. func Match(conditions map[FilterKey]interface{}, data core.Doc) (bool, error) { - return MatchWith("$eq", conditions, data) + return eq(conditions, data) } -// MatchWith can be used to specify the exact operator to use when performing +// matchWith can be used to specify the exact operator to use when performing // a match operation. This is primarily used when building custom operators or // if you wish to override the behavior of another operator. -func MatchWith(op string, conditions, data interface{}) (bool, error) { - if !strings.HasPrefix(op, "$") { - return false, fmt.Errorf("operator should have '$' prefix") +func matchWith(op string, conditions, data interface{}) (bool, error) { + switch op { + case "_and": + return and(conditions, data) + case "_eq": + return eq(conditions, data) + case "_ge": + return ge(conditions, data) + case "_gt": + return gt(conditions, data) + case "_in": + return in(conditions, data) + case "_le": + return le(conditions, data) + case "_lt": + return lt(conditions, data) + case "_ne": + return ne(conditions, data) + case "_nin": + return nin(conditions, data) + case "_or": + return or(conditions, data) + default: + return false, fmt.Errorf("unknown operator '%s'", op) } - - o, ok := opMap[op[1:]] - if !ok { - return false, fmt.Errorf("unknown operator '%s'", op[1:]) - } - - return o.Evaluate(conditions, data) } diff --git a/connor/contains.go b/connor/contains.go deleted file mode 100644 index 4a06386f1a..0000000000 --- a/connor/contains.go +++ /dev/null @@ -1,30 +0,0 @@ -package connor - -import ( - "fmt" - "strings" -) - -func init() { - Register(&ContainsOperator{}) -} - -// The ContainsOperator determines whether a string contains -// the provided substring. -type ContainsOperator struct{} - -func (o *ContainsOperator) Name() string { - return "contains" -} - -func (o *ContainsOperator) Evaluate(conditions, data interface{}) (bool, error) { - if c, ok := conditions.(string); ok { - if d, ok := data.(string); ok { - return strings.Contains(d, c), nil - } else if data == nil { - return false, nil - } - } - - return false, fmt.Errorf("contains operator only works with strings") -} diff --git a/connor/eq.go b/connor/eq.go index faa0993041..ea2166bc32 100644 --- a/connor/eq.go +++ b/connor/eq.go @@ -7,36 +7,13 @@ import ( "github.com/sourcenetwork/defradb/core" ) -func init() { - Register(&EqualOperator{}) -} - -// EqualOperator is an operator which performs object equality +// eq is an operator which performs object equality // tests. -type EqualOperator struct { -} - -func (o *EqualOperator) Name() string { - return "eq" -} - -func (o *EqualOperator) Evaluate(condition, data interface{}) (bool, error) { +func eq(condition, data interface{}) (bool, error) { switch arr := data.(type) { - case []interface{}: - for _, item := range arr { - m, err := MatchWith("$eq", condition, item) - if err != nil { - return false, err - } - - if m { - return true, nil - } - } - return false, nil case []core.Doc: for _, item := range arr { - m, err := MatchWith("$eq", condition, item) + m, err := eq(condition, item) if err != nil { return false, err } @@ -54,32 +31,23 @@ func (o *EqualOperator) Evaluate(condition, data interface{}) (bool, error) { return d == cn, nil } return false, nil - case int8: - return numbers.Equal(cn, data), nil - case int16: - return numbers.Equal(cn, data), nil - case int32: - return numbers.Equal(cn, data), nil case int64: return numbers.Equal(cn, data), nil - case float32: - return numbers.Equal(cn, data), nil case float64: return numbers.Equal(cn, data), nil case map[FilterKey]interface{}: m := true for prop, cond := range cn { - if !m { - // No need to evaluate after we fail - continue - } - - mm, err := MatchWith(prop.GetOperatorOrDefault("$eq"), cond, prop.GetProp(data)) + var err error + m, err = matchWith(prop.GetOperatorOrDefault("_eq"), cond, prop.GetProp(data)) if err != nil { return false, err } - m = m && mm + if !m { + // No need to evaluate after we fail + break + } } return m, nil diff --git a/connor/fields/fields_suite_test.go b/connor/fields/fields_suite_test.go deleted file mode 100644 index 670aab4ef9..0000000000 --- a/connor/fields/fields_suite_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package fields_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestFields(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Fields Suite") -} diff --git a/connor/fields/get.go b/connor/fields/get.go deleted file mode 100644 index 15959236df..0000000000 --- a/connor/fields/get.go +++ /dev/null @@ -1,41 +0,0 @@ -package fields - -import ( - "strconv" - "strings" -) - -// Get will fetch the specified field from data recursively, if possible.. -func Get(data map[string]interface{}, field string) (interface{}, bool) { - fps := strings.Split(field, ".") - d := interface{}(data) - for _, fp := range fps { - switch td := d.(type) { - case map[string]interface{}: - f, ok := td[fp] - if !ok { - return nil, false - } - - d = f - case []interface{}: - fpi, err := strconv.Atoi(fp) - if err != nil || fpi >= len(td) || fpi < 0 { - return nil, false - } - d = td[fpi] - default: - return nil, false - } - } - - return d, true -} - -// TryGet will attempt to get a field and return nil if it could not -// be found. If you need to differentiate between a field which could -// not be found or one which was equal to nil, use .Get() instead. -func TryGet(data map[string]interface{}, field string) interface{} { - value, _ := Get(data, field) - return value -} diff --git a/connor/fields/get_test.go b/connor/fields/get_test.go deleted file mode 100644 index 7d027773da..0000000000 --- a/connor/fields/get_test.go +++ /dev/null @@ -1,168 +0,0 @@ -package fields_test - -import ( - "encoding/json" - "fmt" - "strings" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "github.com/sourcenetwork/defradb/connor/fields" -) - -var _ = Describe("Get", func() { - type TestCase struct { - field string - value string - found bool - } - - cases := map[string][]TestCase{ - `{"x": 1}`: { - { - "x", - "1", - true, - }, - { - "y", - "null", - false, - }, - { - "x.y", - `null`, - false, - }, - }, - `{"x": null}`: { - { - "x", - "null", - true, - }, - }, - `{"x": { "y": 1 }}`: { - { - "x.y", - "1", - true, - }, - { - "x", - `{ "y": 1 }`, - true, - }, - }, - `{"x": [ { "y": 1 }, { "y" : 2 } ]}`: { - { - "x.0.y", - `1`, - true, - }, - { - "x.1.y", - `2`, - true, - }, - }, - `{"x": [ { "y": [ 5,6] }]}`: { - { - "x.0.y.0", - `5`, - true, - }, - { - "x.0.y.1", - `6`, - true, - }, - { - "x.0.y.2", - `null`, - false, - }, - { - "x.-1.y.2", - `null`, - false, - }, - }, - `{"x": [ { "y": 1 } ]}`: { - { - "x.0.z", - `null`, - false, - }, - { - "x.3.z", - `null`, - false, - }, - }, - } - - for dataStr, cs := range cases { - dataStr := dataStr - cs := cs - Describe(fmt.Sprintf("with %s as data", dataStr), func() { - for _, c := range cs { - c := c - Context(fmt.Sprintf("getting the field %s", c.field), func() { - var ( - data map[string]interface{} - value interface{} - expected interface{} - found bool - ) - - BeforeEach(func() { - Expect(json.NewDecoder(strings.NewReader(dataStr)).Decode(&data)).To(Succeed()) - }) - BeforeEach(func() { - Expect(json.NewDecoder(strings.NewReader(c.value)).Decode(&expected)).To(Succeed()) - }) - - Context("Get()", func() { - JustBeforeEach(func() { - value, found = fields.Get(data, c.field) - }) - - if c.found { - Specify("should find the field", func() { - Expect(found).To(BeTrue()) - }) - } else { - Specify("should not find the field", func() { - Expect(found).To(BeFalse()) - }) - } - - Specify(fmt.Sprintf("should return %s", c.value), func() { - if expected == nil { - Expect(value).To(BeNil()) - } else { - Expect(value).To(BeEquivalentTo(expected)) - } - }) - }) - - Context("TryGet()", func() { - JustBeforeEach(func() { - value = fields.TryGet(data, c.field) - }) - - Specify(fmt.Sprintf("should return %s", c.value), func() { - if expected == nil { - Expect(value).To(BeNil()) - } else { - Expect(value).To(BeEquivalentTo(expected)) - } - }) - }) - }) - } - }) - } -}) diff --git a/connor/ge.go b/connor/ge.go index cf9fcb3c81..0421a8038e 100644 --- a/connor/ge.go +++ b/connor/ge.go @@ -2,32 +2,14 @@ package connor import ( "fmt" - "time" "github.com/sourcenetwork/defradb/connor/numbers" ) -func init() { - Register(&GreaterEqualOperator{}) -} - -// GreaterEqualOperator does value comparisons to determine whether one +// ge does value comparisons to determine whether one // value is strictly larger than or equal to another. -type GreaterEqualOperator struct { -} - -func (o *GreaterEqualOperator) Name() string { - return "ge" -} - -func (o *GreaterEqualOperator) Evaluate(condition, data interface{}) (bool, error) { +func ge(condition, data interface{}) (bool, error) { switch cn := numbers.TryUpcast(condition).(type) { - case string: - switch dn := data.(type) { - case string: - return dn >= cn, nil - } - return false, nil case float64: switch dn := numbers.TryUpcast(data).(type) { case float64: @@ -45,12 +27,6 @@ func (o *GreaterEqualOperator) Evaluate(condition, data interface{}) (bool, erro return dn >= cn, nil } - return false, nil - case time.Time: - switch dn := data.(type) { - case time.Time: - return !dn.Before(cn), nil - } return false, nil default: return false, fmt.Errorf("unknown comparison type '%#v'", condition) diff --git a/connor/gt.go b/connor/gt.go index 2ed8f7b18c..9b8873d0bc 100644 --- a/connor/gt.go +++ b/connor/gt.go @@ -2,32 +2,14 @@ package connor import ( "fmt" - "time" "github.com/sourcenetwork/defradb/connor/numbers" ) -func init() { - Register(&GreaterOperator{}) -} - -// GreaterOperator does value comparisons to determine whether one +// gt does value comparisons to determine whether one // value is strictly larger than another. -type GreaterOperator struct { -} - -func (o *GreaterOperator) Name() string { - return "gt" -} - -func (o *GreaterOperator) Evaluate(condition, data interface{}) (bool, error) { +func gt(condition, data interface{}) (bool, error) { switch cn := numbers.TryUpcast(condition).(type) { - case string: - switch dn := data.(type) { - case string: - return dn > cn, nil - } - return false, nil case float64: switch dn := numbers.TryUpcast(data).(type) { case float64: @@ -45,12 +27,6 @@ func (o *GreaterOperator) Evaluate(condition, data interface{}) (bool, error) { return dn > cn, nil } - return false, nil - case time.Time: - switch dn := data.(type) { - case time.Time: - return dn.After(cn), nil - } return false, nil default: return false, fmt.Errorf("unknown comparison type '%#v'", condition) diff --git a/connor/in.go b/connor/in.go index 37f7457815..06978c55ec 100644 --- a/connor/in.go +++ b/connor/in.go @@ -2,24 +2,13 @@ package connor import "fmt" -func init() { - Register(&InOperator{}) -} - -// InOperator will determine whether a value exists within the +// in will determine whether a value exists within the // condition's array of available values. -type InOperator struct { -} - -func (o *InOperator) Name() string { - return "in" -} - -func (o *InOperator) Evaluate(conditions, data interface{}) (bool, error) { +func in(conditions, data interface{}) (bool, error) { switch cn := conditions.(type) { case []interface{}: for _, ce := range cn { - if m, err := MatchWith("$eq", ce, data); err != nil { + if m, err := eq(ce, data); err != nil { return false, err } else if m { return true, nil diff --git a/connor/le.go b/connor/le.go index 61920e62ed..39f970a7a6 100644 --- a/connor/le.go +++ b/connor/le.go @@ -2,32 +2,14 @@ package connor import ( "fmt" - "time" "github.com/sourcenetwork/defradb/connor/numbers" ) -func init() { - Register(&LessEqualOperator{}) -} - -// LessEqualOperator does value comparisons to determine whether one +// le does value comparisons to determine whether one // value is strictly less than another. -type LessEqualOperator struct { -} - -func (o *LessEqualOperator) Name() string { - return "le" -} - -func (o *LessEqualOperator) Evaluate(condition, data interface{}) (bool, error) { +func le(condition, data interface{}) (bool, error) { switch cn := numbers.TryUpcast(condition).(type) { - case string: - switch dn := data.(type) { - case string: - return dn <= cn, nil - } - return false, nil case float64: switch dn := numbers.TryUpcast(data).(type) { case float64: @@ -45,12 +27,6 @@ func (o *LessEqualOperator) Evaluate(condition, data interface{}) (bool, error) return dn <= cn, nil } - return false, nil - case time.Time: - switch dn := data.(type) { - case time.Time: - return !dn.After(cn), nil - } return false, nil default: return false, fmt.Errorf("unknown comparison type '%#v'", condition) diff --git a/connor/lt.go b/connor/lt.go index cdbad091ba..bf910c1164 100644 --- a/connor/lt.go +++ b/connor/lt.go @@ -2,32 +2,14 @@ package connor import ( "fmt" - "time" "github.com/sourcenetwork/defradb/connor/numbers" ) -func init() { - Register(&LessOperator{}) -} - -// LessOperator does value comparisons to determine whether one +// lt does value comparisons to determine whether one // value is strictly less than another. -type LessOperator struct { -} - -func (o *LessOperator) Name() string { - return "lt" -} - -func (o *LessOperator) Evaluate(condition, data interface{}) (bool, error) { +func lt(condition, data interface{}) (bool, error) { switch cn := numbers.TryUpcast(condition).(type) { - case string: - switch dn := data.(type) { - case string: - return dn < cn, nil - } - return false, nil case float64: switch dn := numbers.TryUpcast(data).(type) { case float64: @@ -45,12 +27,6 @@ func (o *LessOperator) Evaluate(condition, data interface{}) (bool, error) { return dn < cn, nil } - return false, nil - case time.Time: - switch dn := data.(type) { - case time.Time: - return dn.Before(cn), nil - } return false, nil default: return false, fmt.Errorf("unknown comparison type '%#v'", condition) diff --git a/connor/ne.go b/connor/ne.go index 56fdb2f553..2e6f4661fb 100644 --- a/connor/ne.go +++ b/connor/ne.go @@ -1,20 +1,9 @@ package connor -func init() { - Register(&NotEqualOperator{}) -} - -// NotEqualOperator performs object inequality comparisons by inverting +// ne performs object inequality comparisons by inverting // the result of the EqualOperator for non-error cases. -type NotEqualOperator struct { -} - -func (o *NotEqualOperator) Name() string { - return "ne" -} - -func (o *NotEqualOperator) Evaluate(conditions, data interface{}) (bool, error) { - m, err := MatchWith("$eq", conditions, data) +func ne(conditions, data interface{}) (bool, error) { + m, err := eq(conditions, data) if err != nil { return false, err diff --git a/connor/nin.go b/connor/nin.go index d3b18a6256..d8f96a8034 100644 --- a/connor/nin.go +++ b/connor/nin.go @@ -1,20 +1,9 @@ package connor -func init() { - Register(&NotInOperator{}) -} - -// NotInOperator performs set exclusion comparisons by inverting the results +// nin performs set exclusion comparisons by inverting the results // of the InOperator under non-error conditions. -type NotInOperator struct { -} - -func (o *NotInOperator) Name() string { - return "nin" -} - -func (o *NotInOperator) Evaluate(conditions, data interface{}) (bool, error) { - m, err := MatchWith("$in", conditions, data) +func nin(conditions, data interface{}) (bool, error) { + m, err := in(conditions, data) if err != nil { return false, err diff --git a/connor/numbers/equality_test.go b/connor/numbers/equality_test.go deleted file mode 100644 index 5dc6a22dd5..0000000000 --- a/connor/numbers/equality_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package numbers_test - -import ( - "fmt" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "github.com/sourcenetwork/defradb/connor/numbers" -) - -var _ = Describe("Equality", func() { - Describe("Equal", func() { - cases := []struct { - a interface{} - b interface{} - - matches bool - }{ - {int64(10), int64(10), true}, - {int64(10), int64(0), false}, - - {float64(10), int64(10), true}, - {int64(10), float64(10), true}, - {float64(10), int64(12), false}, - {int64(10), float64(12), false}, - - {int8(5), float64(5), true}, - - {"test", int64(5), false}, - {int64(5), "test", false}, - {"test", float64(5), false}, - {float64(5), "test", false}, - {"test", "test", false}, - } - - for _, c := range cases { - a := c.a - b := c.b - - if c.matches { - It(fmt.Sprintf("should determine that %T(%v) == %T(%v)", a, a, b, b), func() { - Expect(numbers.Equal(a, b)).To(BeTrue()) - }) - } else { - It(fmt.Sprintf("should determine that %T(%v) != %T(%v)", a, a, b, b), func() { - Expect(numbers.Equal(a, b)).To(BeFalse()) - }) - } - } - }) -}) diff --git a/connor/numbers/numbers_suite_test.go b/connor/numbers/numbers_suite_test.go deleted file mode 100644 index afc04b606b..0000000000 --- a/connor/numbers/numbers_suite_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package numbers_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestNumbers(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Numbers Suite") -} diff --git a/connor/numbers/upcast_test.go b/connor/numbers/upcast_test.go deleted file mode 100644 index 25109963e0..0000000000 --- a/connor/numbers/upcast_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package numbers_test - -import ( - "fmt" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "github.com/sourcenetwork/defradb/connor/numbers" -) - -var _ = Describe("Upcast", func() { - Describe("TryUpcast", func() { - cases := []struct { - in interface{} - out interface{} - }{ - {int8(10), int64(10)}, - {int16(10), int64(10)}, - {int32(10), int64(10)}, - {int64(10), int64(10)}, - {float32(10), float64(10)}, - {float64(10), float64(10)}, - {"test", "test"}, - } - - for _, c := range cases { - in := c.in - out := c.out - - It(fmt.Sprintf("should convert %T(%v) to %T(%v)", in, in, out, out), func() { - Expect(numbers.TryUpcast(in)).To(Equal(out)) - }) - } - }) -}) diff --git a/connor/operators.go b/connor/operators.go deleted file mode 100644 index a90fb88f29..0000000000 --- a/connor/operators.go +++ /dev/null @@ -1,28 +0,0 @@ -package connor - -var opMap = map[string]Operator{} - -// Operator instances are used by Connor to provide advanced query -// functionality. -type Operator interface { - Name() string - Evaluate(condition, data interface{}) (bool, error) -} - -// Register allows you to add your own operators to Connor or override -// the built in operators if you wish. -func Register(op Operator) { - opMap[op.Name()] = op -} - -// Operators gets the list of all registered operators which can be -// used with Connor -func Operators() []string { - names := []string{} - - for name := range opMap { - names = append(names, name) - } - - return names -} diff --git a/connor/or.go b/connor/or.go index e4ae053024..917fe51978 100644 --- a/connor/or.go +++ b/connor/or.go @@ -2,24 +2,13 @@ package connor import "fmt" -func init() { - Register(&OrOperator{}) -} - -// OrOperator is an operator which allows the evaluation of +// or is an operator which allows the evaluation of // of a number of conditions, matching if any of them match. -type OrOperator struct { -} - -func (o *OrOperator) Name() string { - return "or" -} - -func (o *OrOperator) Evaluate(condition, data interface{}) (bool, error) { +func or(condition, data interface{}) (bool, error) { switch cn := condition.(type) { case []interface{}: for _, c := range cn { - if m, err := MatchWith("$eq", c, data); err != nil { + if m, err := eq(c, data); err != nil { return false, err } else if m { return true, nil diff --git a/connor/suite_test.go b/connor/suite_test.go deleted file mode 100644 index fc57471d6a..0000000000 --- a/connor/suite_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package connor_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestConnor(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Connor Suite") -} diff --git a/query/graphql/mapper/mapper.go b/query/graphql/mapper/mapper.go index b0ba5e4c1a..7b45b17cd2 100644 --- a/query/graphql/mapper/mapper.go +++ b/query/graphql/mapper/mapper.go @@ -532,7 +532,7 @@ func resolveInnerFilterDependencies( newFields := []Requestable{} for key := range source { - if strings.HasPrefix(key, "$") { + if strings.HasPrefix(key, "_") && key != parserTypes.DocKeyFieldName { continue } @@ -663,7 +663,7 @@ func toFilterMap( sourceClause interface{}, mapping *core.DocumentMapping, ) (connor.FilterKey, interface{}) { - if strings.HasPrefix(sourceKey, "$") { + if strings.HasPrefix(sourceKey, "_") && sourceKey != parserTypes.DocKeyFieldName { key := &Operator{ Operation: sourceKey, } @@ -998,5 +998,5 @@ func appendNotNilFilter(field *aggregateRequestTarget, childField string) { } typedChildBlock := childBlock.(map[string]interface{}) - typedChildBlock["$ne"] = nil + typedChildBlock["_ne"] = nil } diff --git a/query/graphql/mapper/targetable.go b/query/graphql/mapper/targetable.go index b25d4d78b7..1918a209e1 100644 --- a/query/graphql/mapper/targetable.go +++ b/query/graphql/mapper/targetable.go @@ -42,7 +42,7 @@ func (k *PropertyIndex) GetOperatorOrDefault(defaultOp string) string { type Operator struct { // The filter operation string that this Operator represents. // - // E.g. "$eq", or "$and". + // E.g. "_eq", or "_and". Operation string } diff --git a/query/graphql/parser/filter.go b/query/graphql/parser/filter.go index cdb0b8f088..c04f91dd47 100644 --- a/query/graphql/parser/filter.go +++ b/query/graphql/parser/filter.go @@ -163,9 +163,6 @@ func parseConditions(stmt *ast.ObjectValue) (interface{}, error) { if err != nil { return nil, err } - if strings.HasPrefix(name, "_") && name != parserTypes.DocKeyFieldName { - name = strings.Replace(name, "_", "$", 1) - } conditions[name] = val } return conditions, nil diff --git a/query/graphql/parser/mutation_test.go b/query/graphql/parser/mutation_test.go index 5af50db82f..b6311d0a7c 100644 --- a/query/graphql/parser/mutation_test.go +++ b/query/graphql/parser/mutation_test.go @@ -208,7 +208,7 @@ func TestMutationParse_Update_Filter(t *testing.T) { assert.NotNil(t, mut.Filter) assert.Equal(t, map[string]interface{}{ "rating": map[string]interface{}{ - "$gt": 4.5, + "_gt": 4.5, }, }, mut.Filter.Conditions) } diff --git a/tests/integration/mutation/simple/delete/explain_simple_delete_test.go b/tests/integration/mutation/simple/delete/explain_simple_delete_test.go index 585ab0eb9f..f8807e02cd 100644 --- a/tests/integration/mutation/simple/delete/explain_simple_delete_test.go +++ b/tests/integration/mutation/simple/delete/explain_simple_delete_test.go @@ -247,7 +247,7 @@ func TestExplainDeletionOfDocumentsWithFilter_Success(t *testing.T) { "deleteNode": dataMap{ "filter": dataMap{ "name": dataMap{ - "$eq": "Shahzad", + "_eq": "Shahzad", }, }, "ids": []string(nil), @@ -318,15 +318,15 @@ func TestExplainDeletionOfDocumentsWithFilter_Success(t *testing.T) { "selectNode": dataMap{ "deleteNode": dataMap{ "filter": dataMap{ - "$and": []interface{}{ + "_and": []interface{}{ dataMap{ "age": dataMap{ - "$lt": int64(26), + "_lt": int64(26), }, }, dataMap{ "verified": dataMap{ - "$eq": true, + "_eq": true, }, }, }, @@ -522,15 +522,15 @@ func TestExplainDeletionUsingMultiIdsAndSingleIdAndFilter_Failure(t *testing.T) "selectNode": dataMap{ "deleteNode": dataMap{ "filter": dataMap{ - "$and": []interface{}{ + "_and": []interface{}{ dataMap{ "age": dataMap{ - "$lt": int64(26), + "_lt": int64(26), }, }, dataMap{ "verified": dataMap{ - "$eq": true, + "_eq": true, }, }, }, @@ -569,7 +569,7 @@ func TestExplainDeletionUsingMultiIdsAndSingleIdAndFilter_Failure(t *testing.T) "deleteNode": dataMap{ "filter": dataMap{ "name": dataMap{ - "$eq": "Shahzad", + "_eq": "Shahzad", }, }, "ids": []string(nil), diff --git a/tests/integration/mutation/simple/update/explain_simple_update_test.go b/tests/integration/mutation/simple/update/explain_simple_update_test.go index 2f1c35dc5e..e0513b5ea0 100644 --- a/tests/integration/mutation/simple/update/explain_simple_update_test.go +++ b/tests/integration/mutation/simple/update/explain_simple_update_test.go @@ -65,7 +65,7 @@ func TestExplainSimpleMutationUpdateWithBooleanFilter(t *testing.T) { }, "filter": dataMap{ "verified": dataMap{ - "$eq": true, + "_eq": true, }, }, "ids": []string(nil), @@ -77,7 +77,7 @@ func TestExplainSimpleMutationUpdateWithBooleanFilter(t *testing.T) { "collectionName": "user", "filter": dataMap{ "verified": dataMap{ - "$eq": true, + "_eq": true, }, }, "spans": []dataMap{}, @@ -289,7 +289,7 @@ func TestExplainSimpleMutationUpdateWithIdAndFilter(t *testing.T) { }, "filter": dataMap{ "verified": dataMap{ - "$eq": true, + "_eq": true, }, }, "ids": []string{ @@ -304,7 +304,7 @@ func TestExplainSimpleMutationUpdateWithIdAndFilter(t *testing.T) { "collectionName": "user", "filter": dataMap{ "verified": dataMap{ - "$eq": true, + "_eq": true, }, }, "spans": []dataMap{ diff --git a/tests/integration/query/simple/explain_with_filter_test.go b/tests/integration/query/simple/explain_with_filter_test.go index 1ac72fa76a..6b873e840e 100644 --- a/tests/integration/query/simple/explain_with_filter_test.go +++ b/tests/integration/query/simple/explain_with_filter_test.go @@ -363,7 +363,7 @@ func TestExplainQuerySimpleWithKeyFilterBlock(t *testing.T) { "collectionName": "users", "filter": dataMap{ "_key": dataMap{ - "$eq": "bae-52b9170d-b77a-5887-b877-cbdbb99b009f", + "_eq": "bae-52b9170d-b77a-5887-b877-cbdbb99b009f", }, }, "spans": []dataMap{ @@ -415,7 +415,7 @@ func TestExplainQuerySimpleWithStringFilterBlock(t *testing.T) { "collectionName": "users", "filter": dataMap{ "Name": dataMap{ - "$eq": "John", + "_eq": "John", }, }, "spans": []dataMap{ @@ -462,7 +462,7 @@ func TestExplainQuerySimpleWithStringFilterBlockAndSelect(t *testing.T) { "collectionName": "users", "filter": dataMap{ "Name": dataMap{ - "$eq": "John", + "_eq": "John", }, }, "spans": []dataMap{ @@ -504,7 +504,7 @@ func TestExplainQuerySimpleWithStringFilterBlockAndSelect(t *testing.T) { "collectionName": "users", "filter": dataMap{ "Name": dataMap{ - "$eq": "John", + "_eq": "John", }, }, "spans": []dataMap{ @@ -547,7 +547,7 @@ func TestExplainQuerySimpleWithStringFilterBlockAndSelect(t *testing.T) { "collectionName": "users", "filter": dataMap{ "Name": dataMap{ - "$eq": "Bob", + "_eq": "Bob", }, }, "spans": []dataMap{ @@ -601,7 +601,7 @@ func TestExplainQuerySimpleWithNumberEqualsFilterBlock(t *testing.T) { "collectionName": "users", "filter": dataMap{ "Age": dataMap{ - "$eq": int64(21), + "_eq": int64(21), }, }, "spans": []dataMap{ @@ -653,7 +653,7 @@ func TestExplainQuerySimpleWithNumberGreaterThanFilterBlock(t *testing.T) { "collectionName": "users", "filter": dataMap{ "Age": dataMap{ - "$gt": int64(20), + "_gt": int64(20), }, }, "spans": []dataMap{ @@ -700,7 +700,7 @@ func TestExplainQuerySimpleWithNumberGreaterThanFilterBlock(t *testing.T) { "collectionName": "users", "filter": dataMap{ "Age": dataMap{ - "$gt": int64(40), + "_gt": int64(40), }, }, "spans": []dataMap{ @@ -748,7 +748,7 @@ func TestExplainQuerySimpleWithNumberGreaterThanFilterBlock(t *testing.T) { "collectionName": "users", "filter": dataMap{ "Age": dataMap{ - "$gt": int64(20), + "_gt": int64(20), }, }, "spans": []dataMap{ @@ -809,15 +809,15 @@ func TestExplainQuerySimpleWithNumberGreaterThanAndNumberLessThanFilter(t *testi "collectionID": "1", "collectionName": "users", "filter": dataMap{ - "$and": []interface{}{ + "_and": []interface{}{ dataMap{ "Age": dataMap{ - "$gt": int64(20), + "_gt": int64(20), }, }, dataMap{ "Age": dataMap{ - "$lt": int64(50), + "_lt": int64(50), }, }, }, @@ -877,15 +877,15 @@ func TestExplainQuerySimpleWithNumberEqualToXOrYFilter(t *testing.T) { "collectionID": "1", "collectionName": "users", "filter": dataMap{ - "$or": []interface{}{ + "_or": []interface{}{ dataMap{ "Age": dataMap{ - "$eq": int64(55), + "_eq": int64(55), }, }, dataMap{ "Age": dataMap{ - "$eq": int64(19), + "_eq": int64(19), }, }, }, @@ -946,7 +946,7 @@ func TestExplainQuerySimpleWithNumberInFilter(t *testing.T) { "collectionName": "users", "filter": dataMap{ "Age": dataMap{ - "$in": []interface{}{ + "_in": []interface{}{ int64(19), int64(40), int64(55),