1
0

Add task filter for reminders (#745)

Update swagger docs about reminders

Fix filter concat for reminders

Add task filter for reminders

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/745
Co-Authored-By: konrad <konrad@kola-entertainments.de>
Co-Committed-By: konrad <konrad@kola-entertainments.de>
This commit is contained in:
konrad
2020-12-19 15:14:20 +00:00
parent 9508d0faee
commit 92bcce3f7c
7 changed files with 91 additions and 45 deletions

View File

@ -156,6 +156,37 @@ func (t *Task) ReadAll(a web.Auth, search string, page int, perPage int) (result
return nil, 0, 0, nil
}
func getFilterCond(f *taskFilter, includeNulls bool) (cond builder.Cond, err error) {
switch f.comparator {
case taskFilterComparatorEquals:
cond = &builder.Eq{f.field: f.value}
case taskFilterComparatorNotEquals:
cond = &builder.Neq{f.field: f.value}
case taskFilterComparatorGreater:
cond = &builder.Gt{f.field: f.value}
case taskFilterComparatorGreateEquals:
cond = &builder.Gte{f.field: f.value}
case taskFilterComparatorLess:
cond = &builder.Lt{f.field: f.value}
case taskFilterComparatorLessEquals:
cond = &builder.Lte{f.field: f.value}
case taskFilterComparatorLike:
val, is := f.value.(string)
if !is {
return nil, ErrInvalidTaskFilterValue{Field: f.field, Value: f.value}
}
cond = &builder.Like{f.field, "%" + val + "%"}
case taskFilterComparatorInvalid:
// Nothing to do
}
if includeNulls {
cond = builder.Or(cond, &builder.IsNull{f.field})
}
return
}
//nolint:gocyclo
func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []*Task, resultCount int, totalItems int64, err error) {
@ -215,52 +246,27 @@ func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []
}
}
// Reminder filters need a special treatment since they are in a separate database
reminderFilters := []builder.Cond{}
var filters = make([]builder.Cond, 0, len(opts.filters))
// To still find tasks with nil values, we exclude 0s when comparing with >/< values.
for _, f := range opts.filters {
switch f.comparator {
case taskFilterComparatorEquals:
filters = append(filters, &builder.Eq{f.field: f.value})
case taskFilterComparatorNotEquals:
filters = append(filters, &builder.Neq{f.field: f.value})
case taskFilterComparatorGreater:
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})
if f.field == "reminders" {
f.field = "reminder" // This is the name in the db
filter, err := getFilterCond(f, opts.filterIncludeNulls)
if err != nil {
return nil, 0, 0, err
}
case taskFilterComparatorGreateEquals:
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:
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:
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})
}
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:
// Nothing to do
reminderFilters = append(reminderFilters, filter)
continue
}
filter, err := getFilterCond(f, opts.filterIncludeNulls)
if err != nil {
return nil, 0, 0, err
}
filters = append(filters, filter)
}
// Then return all tasks for that lists
@ -308,6 +314,25 @@ func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []
listCond = builder.Or(listIDCond, builder.And(builder.Eq{"is_favorite": true}, builder.In("list_id", userListIDs)))
}
if len(reminderFilters) > 0 {
var filtercond builder.Cond
if opts.filterConcat == filterConcatOr {
filtercond = builder.Or(reminderFilters...)
}
if opts.filterConcat == filterConcatAnd {
filtercond = builder.And(reminderFilters...)
}
reminderFilter := builder.In(
"id",
builder.
Select("task_id").
From("task_reminders").
Where(filtercond),
)
filters = append(filters, reminderFilter)
}
query = query.Where(listCond)
queryCount = queryCount.Where(listCond)