From 8dc7e3d6de1b508fca48c8c33ee2c4d0b547a7c9 Mon Sep 17 00:00:00 2001 From: Yader Velasquez Date: Thu, 15 Feb 2024 18:27:43 -0600 Subject: [PATCH] Fixing psql syntax errors in search --- api/graph/schema.resolvers.go | 14 ++++++++------ api/loaders/loaders.go | 4 +++- core/routes.go | 3 ++- helpers.go | 7 +++++++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/api/graph/schema.resolvers.go b/api/graph/schema.resolvers.go index a5f4036..088ab80 100644 --- a/api/graph/schema.resolvers.go +++ b/api/graph/schema.resolvers.go @@ -3752,10 +3752,11 @@ func (r *queryResolver) GetUsers(ctx context.Context, input *model.GetUserInput) if input.Search != nil && *input.Search != "" { // We want to search for partial match + s := links.ParseSearch(*input.Search) opts.Filter = sq.And{ opts.Filter, sq.Expr(`to_tsvector('simple', u.full_name || ' ' || u.email || ' ' || o.slug) - @@ to_tsquery('simple', ?)`, *input.Search+":*"), + @@ to_tsquery('simple', ?)`, s), } } @@ -3913,10 +3914,11 @@ func (r *queryResolver) GetAdminOrganizations(ctx context.Context, input *model. if input.Search != nil && *input.Search != "" { // We want to search for partial match + s := links.ParseSearch(*input.Search) opts.Filter = sq.And{ opts.Filter, sq.Expr(`to_tsvector('simple', o.name || ' ' || o.slug ) - @@ to_tsquery('simple', ?)`, *input.Search+":*"), + @@ to_tsquery('simple', ?)`, s), } } @@ -4192,11 +4194,11 @@ func (r *queryResolver) GetAdminDomains(ctx context.Context, input *model.GetAdm } if input.Search != nil && *input.Search != "" { - // We want to search for partial match + s := links.ParseSearch(*input.Search) opts.Filter = sq.And{ opts.Filter, sq.Expr(`to_tsvector('simple', d.name || ' ' || d.lookup_name ) - @@ to_tsquery('simple', ?)`, *input.Search+":*"), + @@ to_tsquery('simple', ?)`, s), } } @@ -4752,11 +4754,11 @@ func (r *queryResolver) GetOrgLinks(ctx context.Context, input *model.GetLinkInp } if input.Search != nil && *input.Search != "" { - // We want to search for partial match + s := links.ParseSearch(*input.Search) linkOpts.Filter = sq.And{ linkOpts.Filter, sq.Expr(`to_tsvector('simple', ol.title || ' ' || ol.description || ' ' || ol.url) - @@ to_tsquery('simple', ?)`, *input.Search+":*"), + @@ to_tsquery('simple', ?)`, s), } } diff --git a/api/loaders/loaders.go b/api/loaders/loaders.go index 4596b33..a3d99dd 100644 --- a/api/loaders/loaders.go +++ b/api/loaders/loaders.go @@ -2,6 +2,7 @@ package loaders import ( "context" + "links" "links/models" "strings" "time" @@ -71,10 +72,11 @@ func getPopularLinks(ctx context.Context) func(key []string) ([][]*models.BaseUR } if q != "" { + s := links.ParseSearch(q) opts.Filter = sq.And{ opts.Filter, sq.Expr(`to_tsvector('simple', b.title || ' ' || b.url) - @@ to_tsquery('simple', ?)`, q+":*"), + @@ to_tsquery('simple', ?)`, s), } } diff --git a/core/routes.go b/core/routes.go index 6c5e28b..30fa83c 100644 --- a/core/routes.go +++ b/core/routes.go @@ -2350,9 +2350,10 @@ func (s *Service) TagAutocomplete(c echo.Context) error { var tags []*models.Tag var err error if q != "" { + s := links.ParseSearch(q) opts := &database.FilterOptions{ Filter: sq.And{ - sq.Expr(`to_tsvector('simple', t.name) @@ to_tsquery('simple', ?)`, q+":*"), + sq.Expr(`to_tsvector('simple', t.name) @@ to_tsquery('simple', ?)`, s), sq.Or{ sq.Eq{"ol.user_id": user.ID}, sq.Eq{"ll.user_id": user.ID}, diff --git a/helpers.go b/helpers.go index 992d1d6..4516867 100644 --- a/helpers.go +++ b/helpers.go @@ -757,6 +757,13 @@ func (t TagQuery) GetSubQuery(inputTag, inputExcludeTag *string) (string, []inte return subQ.ToSql() } +// We need to do some parsing to avoid systax error +// for some string chars +func ParseSearch(s string) string { + s = strings.Replace(s, ":", "\\:", -1) + return strings.Replace(s, " ", ":* & ", -1) + ":*" +} + func AddQueryElement(q template.URL, param, val string) template.URL { query, err := url.ParseQuery(string(q)) if err != nil { -- 2.45.2