From 307ffe11c4ce31df98db3164cc7d21412839d886 Mon Sep 17 00:00:00 2001 From: kolaente Date: Thu, 9 Nov 2023 13:34:31 +0100 Subject: [PATCH] feat(filters): very basic filter parsing --- go.sum | 6 ++++++ pkg/models/task_collection.go | 13 ++++++++----- pkg/models/task_collection_filter.go | 20 +++++++++++++++----- pkg/models/task_collection_test.go | 5 +++++ pkg/models/tasks.go | 1 + 5 files changed, 35 insertions(+), 10 deletions(-) diff --git a/go.sum b/go.sum index 1fed95db1..eecaface0 100644 --- a/go.sum +++ b/go.sum @@ -109,6 +109,12 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/ganigeorgiev/fexpr v0.3.0 h1:RwSyJBME+g/XdzlUW0paH/4VXhLHPg+rErtLeC7K8Ew= +github.com/ganigeorgiev/fexpr v0.3.0/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE= +github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= +github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/getsentry/sentry-go v0.26.0 h1:IX3++sF6/4B5JcevhdZfdKIHfyvMmAq/UnqcyT2H6mA= +github.com/getsentry/sentry-go v0.26.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= diff --git a/pkg/models/task_collection.go b/pkg/models/task_collection.go index 25b78e463..99fc58431 100644 --- a/pkg/models/task_collection.go +++ b/pkg/models/task_collection.go @@ -33,17 +33,20 @@ type TaskCollection struct { OrderBy []string `query:"order_by" json:"order_by"` OrderByArr []string `query:"order_by[]" json:"-"` - // The field name of the field to filter by + // Deprecated: The field name of the field to filter by FilterBy []string `query:"filter_by" json:"filter_by"` FilterByArr []string `query:"filter_by[]" json:"-"` - // The value of the field name to filter by + // Deprecated: The value of the field name to filter by FilterValue []string `query:"filter_value" json:"filter_value"` FilterValueArr []string `query:"filter_value[]" json:"-"` - // The comparator for field and value + // Deprecated: The comparator for field and value FilterComparator []string `query:"filter_comparator" json:"filter_comparator"` FilterComparatorArr []string `query:"filter_comparator[]" json:"-"` - // The way all filter conditions are concatenated together, can be either "and" or "or"., + // Deprecated: The way all filter conditions are concatenated together, can be either "and" or "or"., FilterConcat string `query:"filter_concat" json:"filter_concat"` + + Filter string `query:"filter" json:"filter"` + // If set to true, the result will also include null values FilterIncludeNulls bool `query:"filter_include_nulls" json:"filter_include_nulls"` @@ -110,8 +113,8 @@ func getTaskFilterOptsFromCollection(tf *TaskCollection) (opts *taskSearchOption opts = &taskSearchOptions{ sortby: sort, - filterConcat: taskFilterConcatinator(tf.FilterConcat), filterIncludeNulls: tf.FilterIncludeNulls, + filter: tf.Filter, } opts.filters, err = getTaskFiltersByCollections(tf) diff --git a/pkg/models/task_collection_filter.go b/pkg/models/task_collection_filter.go index c9db96210..ab87b3902 100644 --- a/pkg/models/task_collection_filter.go +++ b/pkg/models/task_collection_filter.go @@ -18,6 +18,7 @@ package models import ( "fmt" + "github.com/ganigeorgiev/fexpr" "reflect" "strconv" "strings" @@ -108,11 +109,20 @@ func getTaskFiltersByCollections(c *TaskCollection) (filters []*taskFilter, err } } - filters = make([]*taskFilter, 0, len(c.FilterBy)) - for i, f := range c.FilterBy { - filter := &taskFilter{ - field: f, - comparator: taskFilterComparatorEquals, + parsedFilter, err := fexpr.Parse(c.Filter) + if err != nil { + return nil, err + } + + filters = make([]*taskFilter, 0, len(parsedFilter)) + for i, f := range parsedFilter { + + filter := &taskFilter{} + switch v := f.Item.(type) { + case fexpr.Expr: + filter.field = v.Left.Literal + filter.comparator = v.Op + filter.value = v.Right.Literal // TODO: nesting } if len(c.FilterComparator) > i { diff --git a/pkg/models/task_collection_test.go b/pkg/models/task_collection_test.go index d87e9da0b..77830979a 100644 --- a/pkg/models/task_collection_test.go +++ b/pkg/models/task_collection_test.go @@ -680,6 +680,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { FilterComparator []string FilterIncludeNulls bool + Filter string + CRUDable web.CRUDable Rights web.Rights } @@ -795,6 +797,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { FilterBy: []string{"start_date", "end_date"}, FilterValue: []string{"2018-12-11T03:46:40+00:00", "2018-12-13T11:20:01+00:00"}, FilterComparator: []string{"greater", "less"}, + Filter: "start_date>'2018-12-11T03:46:40+00:00' || end_date<'2018-12-13T11:20:01+00:00'", }, args: defaultArgs, want: []*Task{ @@ -1339,6 +1342,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { FilterComparator: tt.fields.FilterComparator, FilterIncludeNulls: tt.fields.FilterIncludeNulls, + Filter: tt.fields.Filter, + CRUDable: tt.fields.CRUDable, Rights: tt.fields.Rights, } diff --git a/pkg/models/tasks.go b/pkg/models/tasks.go index be21e9f00..7b0f2a36c 100644 --- a/pkg/models/tasks.go +++ b/pkg/models/tasks.go @@ -174,6 +174,7 @@ type taskSearchOptions struct { filters []*taskFilter filterConcat taskFilterConcatinator filterIncludeNulls bool + filter string projectIDs []int64 }