From 6ea137c362eeac9d4e2ff43caa1bbca516ff8cc5 Mon Sep 17 00:00:00 2001 From: AndrewSisley Date: Wed, 29 Jun 2022 09:04:10 -0400 Subject: [PATCH] refactor: Trim imported connor package (#530) * Remove unused case Could be re-added in some form when adding filters for inline-arrays perhaps * Our filters can never contain these types (always .*64) * We dont support these operators for strings * Make MatchWith private We dont need to worry about this being called outside of this lib * Remove unused Operators func * Reduce connor state I think this simplifies the code futher, feel very free to contradict me. Inits had to be preserved as Golang doesnt seem to treat static functions as constants and complained about an infinate init loop * Simplify condition recursion No need for runtime string matching etc * Simplify operator safety check No need to bother with prefix, so long as it wont panic any unknown operators will be caught on the next few lines. * Use '_' as operator prefix. Allows removal of prefix swap, and (I think) makes the explain results more user friendly. * Remove unused fields sub package * Remove unfriendly test suite stuff * Remove out of date readme * Remove unsupported time checks We will probably add this back in at somepoint, but it is easy to do so and at the moment it is dead code * Remove unsupported contains operator * Replace map, init funcs, and type, with simple switch * Dont bother skipping first rune in switch I wonder if there is a very tiny performance cost to doing this, but I like the removal of the extra code branch and possible error. * Stop looping on eq failure --- connor/README.md | 155 ---------------- connor/and.go | 17 +- connor/connor.go | 39 ++-- connor/contains.go | 30 ---- connor/eq.go | 50 +----- connor/fields/fields_suite_test.go | 13 -- connor/fields/get.go | 41 ----- connor/fields/get_test.go | 168 ------------------ connor/ge.go | 28 +-- connor/gt.go | 28 +-- connor/in.go | 17 +- connor/le.go | 28 +-- connor/lt.go | 28 +-- connor/ne.go | 17 +- connor/nin.go | 17 +- connor/numbers/equality_test.go | 52 ------ connor/numbers/numbers_suite_test.go | 13 -- connor/numbers/upcast_test.go | 36 ---- connor/operators.go | 28 --- connor/or.go | 17 +- connor/suite_test.go | 13 -- query/graphql/mapper/mapper.go | 6 +- query/graphql/mapper/targetable.go | 2 +- query/graphql/parser/filter.go | 3 - query/graphql/parser/mutation_test.go | 2 +- .../delete/explain_simple_delete_test.go | 16 +- .../update/explain_simple_update_test.go | 8 +- .../query/simple/explain_with_filter_test.go | 32 ++-- 28 files changed, 91 insertions(+), 813 deletions(-) delete mode 100644 connor/README.md delete mode 100644 connor/contains.go delete mode 100644 connor/fields/fields_suite_test.go delete mode 100644 connor/fields/get.go delete mode 100644 connor/fields/get_test.go delete mode 100644 connor/numbers/equality_test.go delete mode 100644 connor/numbers/numbers_suite_test.go delete mode 100644 connor/numbers/upcast_test.go delete mode 100644 connor/operators.go delete mode 100644 connor/suite_test.go 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),