mirror of
https://github.com/pocket-id/pocket-id.git
synced 2025-12-06 13:22:57 +03:00
78 lines
2.0 KiB
Go
78 lines
2.0 KiB
Go
package utils
|
|
|
|
import (
|
|
"gorm.io/gorm"
|
|
"reflect"
|
|
)
|
|
|
|
type PaginationResponse struct {
|
|
TotalPages int64 `json:"totalPages"`
|
|
TotalItems int64 `json:"totalItems"`
|
|
CurrentPage int `json:"currentPage"`
|
|
ItemsPerPage int `json:"itemsPerPage"`
|
|
}
|
|
|
|
type SortedPaginationRequest struct {
|
|
Pagination struct {
|
|
Page int `form:"pagination[page]"`
|
|
Limit int `form:"pagination[limit]"`
|
|
} `form:"pagination"`
|
|
Sort struct {
|
|
Column string `form:"sort[column]"`
|
|
Direction string `form:"sort[direction]"`
|
|
} `form:"sort"`
|
|
}
|
|
|
|
func PaginateAndSort(sortedPaginationRequest SortedPaginationRequest, query *gorm.DB, result interface{}) (PaginationResponse, error) {
|
|
pagination := sortedPaginationRequest.Pagination
|
|
sort := sortedPaginationRequest.Sort
|
|
|
|
capitalizedSortColumn := CapitalizeFirstLetter(sort.Column)
|
|
|
|
sortField, sortFieldFound := reflect.TypeOf(result).Elem().Elem().FieldByName(capitalizedSortColumn)
|
|
isSortable := sortField.Tag.Get("sortable") == "true"
|
|
isValidSortOrder := sort.Direction == "asc" || sort.Direction == "desc"
|
|
|
|
if sortFieldFound && isSortable && isValidSortOrder {
|
|
query = query.Order(CamelCaseToSnakeCase(sort.Column) + " " + sort.Direction)
|
|
}
|
|
|
|
return Paginate(pagination.Page, pagination.Limit, query, result)
|
|
|
|
}
|
|
|
|
func Paginate(page int, pageSize int, query *gorm.DB, result interface{}) (PaginationResponse, error) {
|
|
if page < 1 {
|
|
page = 1
|
|
}
|
|
|
|
if pageSize < 1 {
|
|
pageSize = 10
|
|
} else if pageSize > 100 {
|
|
pageSize = 100
|
|
}
|
|
|
|
offset := (page - 1) * pageSize
|
|
|
|
var totalItems int64
|
|
if err := query.Count(&totalItems).Error; err != nil {
|
|
return PaginationResponse{}, err
|
|
}
|
|
|
|
if err := query.Offset(offset).Limit(pageSize).Find(result).Error; err != nil {
|
|
return PaginationResponse{}, err
|
|
}
|
|
|
|
totalPages := (totalItems + int64(pageSize) - 1) / int64(pageSize)
|
|
if totalItems == 0 {
|
|
totalPages = 1
|
|
}
|
|
|
|
return PaginationResponse{
|
|
TotalPages: totalPages,
|
|
TotalItems: totalItems,
|
|
CurrentPage: page,
|
|
ItemsPerPage: pageSize,
|
|
}, nil
|
|
}
|