Add "like" filter comparator

This commit is contained in:
kolaente 2020-12-19 13:56:55 +01:00
parent b2e4fde63a
commit 90817b6dae
No known key found for this signature in database
GPG key ID: F40E70337AB24C9B
8 changed files with 43 additions and 7 deletions

View file

@ -737,7 +737,7 @@ func (err ErrInvalidTaskFilterConcatinator) HTTPError() web.HTTPError {
// ErrInvalidTaskFilterValue represents an error where the provided task filter value is invalid // ErrInvalidTaskFilterValue represents an error where the provided task filter value is invalid
type ErrInvalidTaskFilterValue struct { type ErrInvalidTaskFilterValue struct {
Value string Value interface{}
Field string Field string
} }
@ -748,7 +748,7 @@ func IsErrInvalidTaskFilterValue(err error) bool {
} }
func (err ErrInvalidTaskFilterValue) Error() string { func (err ErrInvalidTaskFilterValue) Error() string {
return fmt.Sprintf("Task filter value is invalid [Value: %s, Field: %s]", err.Value, err.Field) return fmt.Sprintf("Task filter value is invalid [Value: %v, Field: %s]", err.Value, err.Field)
} }
// ErrCodeInvalidTaskFilterValue holds the unique world-error code of this error // ErrCodeInvalidTaskFilterValue holds the unique world-error code of this error

View file

@ -93,7 +93,7 @@ func validateTaskField(fieldName string) error {
// @Param order_by query string false "The ordering parameter. Possible values to order by are `asc` or `desc`. Default is `asc`." // @Param order_by query string false "The ordering parameter. Possible values to order by are `asc` or `desc`. Default is `asc`."
// @Param filter_by query string false "The name of the field to filter by. Accepts an array for multiple filters which will be chanied together, all supplied filter must match." // @Param filter_by query string false "The name of the field to filter by. Accepts an array for multiple filters which will be chanied together, all supplied filter must match."
// @Param filter_value query string false "The value to filter for." // @Param filter_value query string false "The value to filter for."
// @Param filter_comparator query string false "The comparator to use for a filter. Available values are `equals`, `greater`, `greater_equals`, `less` and `less_equals`. Defaults to `equals`" // @Param filter_comparator query string false "The comparator to use for a filter. Available values are `equals`, `greater`, `greater_equals`, `less`, `less_equals` and `like`. Defaults to `equals`"
// @Param filter_concat query string false "The concatinator to use for filters. Available values are `and` or `or`. Defaults to `or`." // @Param filter_concat query string false "The concatinator to use for filters. Available values are `and` or `or`. Defaults to `or`."
// @Param filter_include_nulls query string false "If set to true the result will include filtered fields whose value is set to `null`. Available values are `true` or `false`. Defaults to `false`." // @Param filter_include_nulls query string false "If set to true the result will include filtered fields whose value is set to `null`. Available values are `true` or `false`. Defaults to `false`."
// @Security JWTKeyAuth // @Security JWTKeyAuth

View file

@ -39,6 +39,7 @@ const (
taskFilterComparatorLess taskFilterComparator = "<" taskFilterComparatorLess taskFilterComparator = "<"
taskFilterComparatorLessEquals taskFilterComparator = "<=" taskFilterComparatorLessEquals taskFilterComparator = "<="
taskFilterComparatorNotEquals taskFilterComparator = "!=" taskFilterComparatorNotEquals taskFilterComparator = "!="
taskFilterComparatorLike taskFilterComparator = "like"
) )
type taskFilter struct { type taskFilter struct {
@ -111,7 +112,8 @@ func validateTaskFieldComparator(comparator taskFilterComparator) error {
taskFilterComparatorGreateEquals, taskFilterComparatorGreateEquals,
taskFilterComparatorLess, taskFilterComparatorLess,
taskFilterComparatorLessEquals, taskFilterComparatorLessEquals,
taskFilterComparatorNotEquals: taskFilterComparatorNotEquals,
taskFilterComparatorLike:
return nil return nil
case taskFilterComparatorInvalid: case taskFilterComparatorInvalid:
fallthrough fallthrough
@ -134,6 +136,8 @@ func getFilterComparatorFromString(comparator string) (taskFilterComparator, err
return taskFilterComparatorLessEquals, nil return taskFilterComparatorLessEquals, nil
case "not_equals": case "not_equals":
return taskFilterComparatorNotEquals, nil return taskFilterComparatorNotEquals, nil
case "like":
return taskFilterComparatorLike, nil
default: default:
return taskFilterComparatorInvalid, ErrInvalidTaskFilterComparator{Comparator: taskFilterComparator(comparator)} return taskFilterComparatorInvalid, ErrInvalidTaskFilterComparator{Comparator: taskFilterComparator(comparator)}
} }

View file

@ -858,6 +858,27 @@ func TestTaskCollection_ReadAll(t *testing.T) {
// Task 34 is also a favorite, but on a list user 1 has no access to. // Task 34 is also a favorite, but on a list user 1 has no access to.
}, },
}, },
{
name: "filtered with like",
fields: fields{
FilterBy: []string{"title"},
FilterValue: []string{"with"},
FilterComparator: []string{"like"},
},
args: defaultArgs,
want: []*Task{
task7,
task8,
task9,
task27,
task28,
task29,
task30,
task31,
task33,
},
wantErr: false,
},
} }
for _, tt := range tests { for _, tt := range tests {

View file

@ -247,6 +247,17 @@ func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []
} else { } else {
filters = append(filters, &builder.Lte{f.field: f.value}) filters = append(filters, &builder.Lte{f.field: f.value})
} }
case taskFilterComparatorLike:
val, is := f.value.(string)
if !is {
return nil, 0, 0, ErrInvalidTaskFilterValue{Field: f.field, Value: f.value}
}
c := &builder.Like{f.field, "%" + val + "%"}
if opts.filterIncludeNulls {
filters = append(filters, builder.Or(c, &builder.IsNull{f.field}))
} else {
filters = append(filters, c)
}
case taskFilterComparatorInvalid: case taskFilterComparatorInvalid:
// Nothing to do // Nothing to do
} }

View file

@ -1904,7 +1904,7 @@ var doc = `{
}, },
{ {
"type": "string", "type": "string",
"description": "The comparator to use for a filter. Available values are ` + "`" + `equals` + "`" + `, ` + "`" + `greater` + "`" + `, ` + "`" + `greater_equals` + "`" + `, ` + "`" + `less` + "`" + ` and ` + "`" + `less_equals` + "`" + `. Defaults to ` + "`" + `equals` + "`" + `", "description": "The comparator to use for a filter. Available values are ` + "`" + `equals` + "`" + `, ` + "`" + `greater` + "`" + `, ` + "`" + `greater_equals` + "`" + `, ` + "`" + `less` + "`" + `, ` + "`" + `less_equals` + "`" + ` and ` + "`" + `like` + "`" + `. Defaults to ` + "`" + `equals` + "`" + `",
"name": "filter_comparator", "name": "filter_comparator",
"in": "query" "in": "query"
}, },

View file

@ -1887,7 +1887,7 @@
}, },
{ {
"type": "string", "type": "string",
"description": "The comparator to use for a filter. Available values are `equals`, `greater`, `greater_equals`, `less` and `less_equals`. Defaults to `equals`", "description": "The comparator to use for a filter. Available values are `equals`, `greater`, `greater_equals`, `less`, `less_equals` and `like`. Defaults to `equals`",
"name": "filter_comparator", "name": "filter_comparator",
"in": "query" "in": "query"
}, },

View file

@ -2451,7 +2451,7 @@ paths:
in: query in: query
name: filter_value name: filter_value
type: string type: string
- description: The comparator to use for a filter. Available values are `equals`, `greater`, `greater_equals`, `less` and `less_equals`. Defaults to `equals` - description: The comparator to use for a filter. Available values are `equals`, `greater`, `greater_equals`, `less`, `less_equals` and `like`. Defaults to `equals`
in: query in: query
name: filter_comparator name: filter_comparator
type: string type: string