From 8758fb6ac5aaee6c95464f6aa666b3d1d56a4c6d Mon Sep 17 00:00:00 2001 From: konrad Date: Fri, 15 May 2020 14:12:20 +0000 Subject: [PATCH] Fix case-insensitive task search for postgresql (#524) "Fix" gocyclo Fix case-insensitive task search for postgresql Co-authored-by: kolaente Reviewed-on: https://kolaente.dev/vikunja/api/pulls/524 --- Makefile | 2 +- pkg/integrations/task_collection_test.go | 18 ++++++++++++++++++ pkg/models/tasks.go | 15 +++++++++++++-- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 850e5a01a4..161537923c 100644 --- a/Makefile +++ b/Makefile @@ -219,7 +219,7 @@ gocyclo-check: go get -u github.com/fzipp/gocyclo; \ go install $(GOFLAGS) github.com/fzipp/gocyclo; \ fi - for S in $(GOFILES); do gocyclo -over 27 $$S || exit 1; done; + for S in $(GOFILES); do gocyclo -over 28 $$S || exit 1; done; .PHONY: static-check static-check: diff --git a/pkg/integrations/task_collection_test.go b/pkg/integrations/task_collection_test.go index db134b0f03..ce90c7b19f 100644 --- a/pkg/integrations/task_collection_test.go +++ b/pkg/integrations/task_collection_test.go @@ -89,6 +89,24 @@ func TestTaskCollection(t *testing.T) { assert.NotContains(t, rec.Body.String(), `task #13`) assert.NotContains(t, rec.Body.String(), `task #14`) }) + t.Run("Search case insensitive", func(t *testing.T) { + rec, err := testHandler.testReadAllWithUser(url.Values{"s": []string{"tASk #6"}}, urlParams) + assert.NoError(t, err) + assert.NotContains(t, rec.Body.String(), `task #1`) + assert.NotContains(t, rec.Body.String(), `task #2`) + assert.NotContains(t, rec.Body.String(), `task #3`) + assert.NotContains(t, rec.Body.String(), `task #4`) + assert.NotContains(t, rec.Body.String(), `task #5`) + assert.Contains(t, rec.Body.String(), `task #6`) + assert.NotContains(t, rec.Body.String(), `task #7`) + assert.NotContains(t, rec.Body.String(), `task #8`) + assert.NotContains(t, rec.Body.String(), `task #9`) + assert.NotContains(t, rec.Body.String(), `task #10`) + assert.NotContains(t, rec.Body.String(), `task #11`) + assert.NotContains(t, rec.Body.String(), `task #12`) + assert.NotContains(t, rec.Body.String(), `task #13`) + assert.NotContains(t, rec.Body.String(), `task #14`) + }) t.Run("Sort Order", func(t *testing.T) { // TODO: Add more cases // should equal priority asc diff --git a/pkg/models/tasks.go b/pkg/models/tasks.go index 3671df1174..d33ea233c6 100644 --- a/pkg/models/tasks.go +++ b/pkg/models/tasks.go @@ -17,6 +17,7 @@ package models import ( + "code.vikunja.io/api/pkg/config" "code.vikunja.io/api/pkg/files" "code.vikunja.io/api/pkg/metrics" "code.vikunja.io/api/pkg/timeutil" @@ -235,8 +236,18 @@ func getRawTasksForLists(lists []*List, opts *taskOptions) (tasks []*Task, resul queryCount := x.NewSession() if len(opts.search) > 0 { - query = query.Where("text LIKE ?", "%"+opts.search+"%") - queryCount = queryCount.Where("text LIKE ?", "%"+opts.search+"%") + // Postgres' is case sensitive by default. + // To work around this, we're using ILIKE as opposed to normal LIKE statements. + // ILIKE is preferred over LOWER(text) LIKE for performance reasons. + // See https://stackoverflow.com/q/7005302/10924593 + // Seems okay to use that now, we may need to find a better solution overall in the future. + if config.DatabaseType.GetString() == "postgres" { + query = query.Where("text ILIKE ?", "%"+opts.search+"%") + queryCount = queryCount.Where("text ILIKE ?", "%"+opts.search+"%") + } else { + query = query.Where("text LIKE ?", "%"+opts.search+"%") + queryCount = queryCount.Where("text LIKE ?", "%"+opts.search+"%") + } } if len(listIDs) > 0 {