golang-server-template/internal/data/filters.go
2024-07-08 17:36:56 +08:00

68 lines
1.6 KiB
Go

package data
import (
"math"
"strings"
"greenlight.alexedwards.net/internal/validator"
)
type Filters struct {
Page int
PageSize int
Sort string
SortSafelist []string
}
type Metadata struct {
CurrentPage int `json:"current_page,omitempty"`
PageSize int `json:"page_size,omitempty"`
FirstPage int `json:"first_page,omitempty"`
LastPage int `json:"last_page,omitempty"`
TotalRecords int `json:"total_records,omitempty"`
}
func ValidateFilters(v *validator.Validator, f Filters) {
v.Check(f.Page > 0, "page", "must be greater than zero")
v.Check(f.Page <= 10_000_000, "page", "must be a maximum of 10,000,000")
v.Check(f.PageSize > 0, "page_size", "must be greater than zero")
v.Check(f.Page <= 100, "page_size", "must be a maximum of 100")
v.Check(validator.PermittedValue(f.Sort, f.SortSafelist...), "sort", "invalid sort value")
}
func (f Filters) limit() int {
return f.PageSize
}
func (f Filters) offset() int {
return (f.Page - 1) * f.PageSize
}
func calculateMetadata(totalRecords, page, pageSize int) Metadata {
if totalRecords == 0 {
return Metadata{}
}
return Metadata{
CurrentPage: page,
PageSize: pageSize,
FirstPage: 1,
LastPage: int(math.Ceil(float64(totalRecords) / float64(pageSize))),
TotalRecords: totalRecords,
}
}
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"
}