diff options
Diffstat (limited to 'utils/meta/pagination.go')
| -rw-r--r-- | utils/meta/pagination.go | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/utils/meta/pagination.go b/utils/meta/pagination.go new file mode 100644 index 0000000..9244294 --- /dev/null +++ b/utils/meta/pagination.go @@ -0,0 +1,84 @@ +package meta + +import ( + "dove/types" + "strconv" + + "github.com/gofiber/fiber/v2" + "gorm.io/gorm" +) + +func Paginate(context *fiber.Ctx) Pagination { + requestData := Request(context) + + page := DEFAULT_PAGE + perPage := DEFAULT_PER_PAGE + + if requestData != nil { + if pageValue := requestData.Query("page"); pageValue != nil { + parsed, _ := strconv.Atoi(pageValue.String()) + if parsed >= DEFAULT_PAGE { + page = parsed + } + } + + if perPageValue := requestData.Query("per_page"); perPageValue != nil { + parsed, _ := strconv.Atoi(perPageValue.String()) + if parsed >= DEFAULT_PAGE && parsed <= MAX_PER_PAGE { + perPage = parsed + } + } + } + + return Pagination{Page: page, PerPage: perPage} +} + +func Sort(context *fiber.Ctx, allowedFields []string, fallbackField string) Sorting { + requestData := Request(context) + + field := fallbackField + direction := "desc" + + if requestData != nil { + if sortValue := requestData.Query("sort"); sortValue != nil { + for _, allowedField := range allowedFields { + if sortValue.String() == allowedField { + field = sortValue.String() + break + } + } + } + + if orderValue := requestData.Query("order"); orderValue != nil { + switch orderValue.String() { + case "asc", "desc": + direction = orderValue.String() + } + } + } + + return Sorting{Field: field, Direction: direction} +} + +func (self Pagination) Apply(query *gorm.DB) *gorm.DB { + return query.Offset((self.Page - 1) * self.PerPage).Limit(self.PerPage) +} + +func (self Sorting) Apply(query *gorm.DB) *gorm.DB { + return query.Order(self.Field + " " + self.Direction) +} + +func (self Pagination) Response(items any, total int64) types.PaginatedResponse { + totalPages := int(total) / self.PerPage + if int(total)%self.PerPage > 0 { + totalPages++ + } + + return types.PaginatedResponse{ + Items: items, + Total: total, + Page: self.Page, + PerPage: self.PerPage, + TotalPages: totalPages, + } +} |
