diff --git a/internal/data/filters.go b/internal/data/filters.go index d92e738..6b7b5cd 100644 --- a/internal/data/filters.go +++ b/internal/data/filters.go @@ -1,6 +1,10 @@ package data -import "gitea.local.lab/Lbenedar/greenlight/internal/validator" +import ( + "strings" + + "gitea.local.lab/Lbenedar/greenlight/internal/validator" +) type Filters struct { Page int @@ -17,3 +21,20 @@ func ValidateFilters(v *validator.Validator, f Filters) { v.Check(validator.PermittedValue(f.Sort, f.SortSafelist...), "sort", "invalid sort values") } + +func (f Filters) sortColumn() string { + for _, safeValue := range f.SortSafelist { + if f.Sort == safeValue { + return strings.TrimPrefix(f.Sort, "-") + } + } + + panic("unsafe sort parameter: " + f.Sort) +} + +func (f Filters) sortDirection() string { + if strings.HasPrefix(f.Sort, "-") { + return "DESC" + } + return "ASC" +} diff --git a/internal/data/movies.go b/internal/data/movies.go index ca2a50e..1c78110 100644 --- a/internal/data/movies.go +++ b/internal/data/movies.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "errors" + "fmt" "time" "gitea.local.lab/Lbenedar/greenlight/internal/validator" @@ -135,12 +136,12 @@ func (m MovieModel) Delete(id int64) error { } func (m MovieModel) GetAll(title string, genres []string, filter Filters) ([]*Movie, error) { - query := ` + query := fmt.Sprintf(` SELECT id, created_at, title, year, runtime, genres, version FROM movies WHERE (to_tsvector('simple', title) @@ plainto_tsquery('simple', $1) OR $1 = '') AND (genres @> $2 OR $2 = '{}') - ORDER BY id` + ORDER BY %s %s, id ASC`, filter.sortColumn(), filter.sortDirection()) ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel()