Add option to include null results when filtering
continuous-integration/drone/pr Build is failing
Details
continuous-integration/drone/pr Build is failing
Details
This commit is contained in:
parent
e4bb42b46c
commit
cc688f0594
|
@ -45,6 +45,8 @@ type TaskCollection struct {
|
|||
FilterComparatorArr []string `query:"filter_comparator[]"`
|
||||
// The way all filter conditions are concatenated together, can be either "and" or "or".,
|
||||
FilterConcat string `query:"filter_concat"`
|
||||
// If set to true, the result will also include null values
|
||||
FilterIncludeNulls bool `quiery:"filter_include_nulls"`
|
||||
|
||||
web.CRUDable `xorm:"-" json:"-"`
|
||||
web.Rights `xorm:"-" json:"-"`
|
||||
|
@ -93,6 +95,7 @@ func validateTaskField(fieldName string) error {
|
|||
// @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_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`."
|
||||
// @Security JWTKeyAuth
|
||||
// @Success 200 {array} models.Task "The tasks"
|
||||
// @Failure 500 {object} models.Message "Internal error"
|
||||
|
@ -127,11 +130,12 @@ func (tf *TaskCollection) ReadAll(a web.Auth, search string, page int, perPage i
|
|||
}
|
||||
|
||||
taskopts := &taskOptions{
|
||||
search: search,
|
||||
page: page,
|
||||
perPage: perPage,
|
||||
sortby: sort,
|
||||
filterConcat: taskFilterConcatinator(tf.FilterConcat),
|
||||
search: search,
|
||||
page: page,
|
||||
perPage: perPage,
|
||||
sortby: sort,
|
||||
filterConcat: taskFilterConcatinator(tf.FilterConcat),
|
||||
filterIncludeNulls: tf.FilterIncludeNulls,
|
||||
}
|
||||
|
||||
taskopts.filters, err = getTaskFiltersByCollections(tf)
|
||||
|
|
|
@ -559,9 +559,10 @@ func TestTaskCollection_ReadAll(t *testing.T) {
|
|||
SortBy []string // Is a string, since this is the place where a query string comes from the user
|
||||
OrderBy []string
|
||||
|
||||
FilterBy []string
|
||||
FilterValue []string
|
||||
FilterComparator []string
|
||||
FilterBy []string
|
||||
FilterValue []string
|
||||
FilterComparator []string
|
||||
FilterIncludeNulls bool
|
||||
|
||||
CRUDable web.CRUDable
|
||||
Rights web.Rights
|
||||
|
@ -791,6 +792,50 @@ func TestTaskCollection_ReadAll(t *testing.T) {
|
|||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "range with nulls",
|
||||
fields: fields{
|
||||
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"},
|
||||
FilterIncludeNulls: true,
|
||||
},
|
||||
args: defaultArgs,
|
||||
want: []*Task{
|
||||
task1, // has nil dates
|
||||
task2, // has nil dates
|
||||
task3, // has nil dates
|
||||
task4, // has nil dates
|
||||
task5, // has nil dates
|
||||
task6, // has nil dates
|
||||
task7,
|
||||
task8,
|
||||
task9,
|
||||
task10, // has nil dates
|
||||
task11, // has nil dates
|
||||
task12, // has nil dates
|
||||
task15, // has nil dates
|
||||
task16, // has nil dates
|
||||
task17, // has nil dates
|
||||
task18, // has nil dates
|
||||
task19, // has nil dates
|
||||
task20, // has nil dates
|
||||
task21, // has nil dates
|
||||
task22, // has nil dates
|
||||
task23, // has nil dates
|
||||
task24, // has nil dates
|
||||
task25, // has nil dates
|
||||
task26, // has nil dates
|
||||
task27, // has nil dates
|
||||
task28, // has nil dates
|
||||
task29, // has nil dates
|
||||
task30, // has nil dates
|
||||
task31, // has nil dates
|
||||
task32, // has nil dates
|
||||
task33, // has nil dates
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
@ -802,9 +847,10 @@ func TestTaskCollection_ReadAll(t *testing.T) {
|
|||
SortBy: tt.fields.SortBy,
|
||||
OrderBy: tt.fields.OrderBy,
|
||||
|
||||
FilterBy: tt.fields.FilterBy,
|
||||
FilterValue: tt.fields.FilterValue,
|
||||
FilterComparator: tt.fields.FilterComparator,
|
||||
FilterBy: tt.fields.FilterBy,
|
||||
FilterValue: tt.fields.FilterValue,
|
||||
FilterComparator: tt.fields.FilterComparator,
|
||||
FilterIncludeNulls: tt.fields.FilterIncludeNulls,
|
||||
|
||||
CRUDable: tt.fields.CRUDable,
|
||||
Rights: tt.fields.Rights,
|
||||
|
|
|
@ -133,12 +133,13 @@ const (
|
|||
)
|
||||
|
||||
type taskOptions struct {
|
||||
search string
|
||||
page int
|
||||
perPage int
|
||||
sortby []*sortParam
|
||||
filters []*taskFilter
|
||||
filterConcat taskFilterConcatinator
|
||||
search string
|
||||
page int
|
||||
perPage int
|
||||
sortby []*sortParam
|
||||
filters []*taskFilter
|
||||
filterConcat taskFilterConcatinator
|
||||
filterIncludeNulls bool
|
||||
}
|
||||
|
||||
// ReadAll is a dummy function to still have that endpoint documented
|
||||
|
@ -227,13 +228,29 @@ func getRawTasksForLists(lists []*List, opts *taskOptions) (tasks []*Task, resul
|
|||
case taskFilterComparatorNotEquals:
|
||||
filters = append(filters, &builder.Neq{f.field: f.value})
|
||||
case taskFilterComparatorGreater:
|
||||
filters = append(filters, builder.Or(&builder.Gt{f.field: f.value}, &builder.IsNull{f.field}))
|
||||
if opts.filterIncludeNulls {
|
||||
filters = append(filters, builder.Or(&builder.Gt{f.field: f.value}, &builder.IsNull{f.field}))
|
||||
} else {
|
||||
filters = append(filters, &builder.Gt{f.field: f.value})
|
||||
}
|
||||
case taskFilterComparatorGreateEquals:
|
||||
filters = append(filters, builder.Or(&builder.Gte{f.field: f.value}, &builder.IsNull{f.field}))
|
||||
if opts.filterIncludeNulls {
|
||||
filters = append(filters, builder.Or(&builder.Gte{f.field: f.value}, &builder.IsNull{f.field}))
|
||||
} else {
|
||||
filters = append(filters, &builder.Gte{f.field: f.value})
|
||||
}
|
||||
case taskFilterComparatorLess:
|
||||
filters = append(filters, builder.Or(&builder.Lt{f.field: f.value}, &builder.IsNull{f.field}))
|
||||
if opts.filterIncludeNulls {
|
||||
filters = append(filters, builder.Or(&builder.Lt{f.field: f.value}, &builder.IsNull{f.field}))
|
||||
} else {
|
||||
filters = append(filters, &builder.Lt{f.field: f.value})
|
||||
}
|
||||
case taskFilterComparatorLessEquals:
|
||||
filters = append(filters, builder.Or(&builder.Lte{f.field: f.value}, &builder.IsNull{f.field}))
|
||||
if opts.filterIncludeNulls {
|
||||
filters = append(filters, builder.Or(&builder.Lte{f.field: f.value}, &builder.IsNull{f.field}))
|
||||
} else {
|
||||
filters = append(filters, &builder.Lte{f.field: f.value})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue