mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 10:42:57 +00:00
122 lines
3.1 KiB
Go
122 lines
3.1 KiB
Go
package controllers
|
|
|
|
import (
|
|
"math"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// PaginationHelper provides pagination utilities
|
|
type PaginationHelper struct{}
|
|
|
|
// PaginationParams represents pagination parameters
|
|
type PaginationParams struct {
|
|
Page int `json:"page"`
|
|
PageSize int `json:"page_size"`
|
|
Offset int `json:"-"`
|
|
}
|
|
|
|
// PaginationMeta represents pagination metadata
|
|
type PaginationMeta struct {
|
|
Page int `json:"page"`
|
|
PageSize int `json:"page_size"`
|
|
Total int64 `json:"total"`
|
|
TotalPages int `json:"total_pages"`
|
|
HasNext bool `json:"has_next"`
|
|
HasPrev bool `json:"has_prev"`
|
|
}
|
|
|
|
// NewPaginationHelper creates a new PaginationHelper instance
|
|
func NewPaginationHelper() *PaginationHelper {
|
|
return &PaginationHelper{}
|
|
}
|
|
|
|
// GetPaginationParams extracts pagination parameters from the request
|
|
// Defaults: page=1, pageSize=20
|
|
func (ph *PaginationHelper) GetPaginationParams(c *gin.Context) PaginationParams {
|
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
|
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
|
|
|
// Validate and constrain values
|
|
if page < 1 {
|
|
page = 1
|
|
}
|
|
if pageSize < 1 {
|
|
pageSize = 20
|
|
}
|
|
if pageSize > 100 {
|
|
pageSize = 100 // Max page size to prevent abuse
|
|
}
|
|
|
|
offset := (page - 1) * pageSize
|
|
|
|
return PaginationParams{
|
|
Page: page,
|
|
PageSize: pageSize,
|
|
Offset: offset,
|
|
}
|
|
}
|
|
|
|
// BuildPaginationMeta creates pagination metadata
|
|
func (ph *PaginationHelper) BuildPaginationMeta(params PaginationParams, total int64) PaginationMeta {
|
|
totalPages := int(math.Ceil(float64(total) / float64(params.PageSize)))
|
|
|
|
return PaginationMeta{
|
|
Page: params.Page,
|
|
PageSize: params.PageSize,
|
|
Total: total,
|
|
TotalPages: totalPages,
|
|
HasNext: params.Page < totalPages,
|
|
HasPrev: params.Page > 1,
|
|
}
|
|
}
|
|
|
|
// Paginate applies pagination to a GORM query and returns the paginated results with metadata
|
|
func (ph *PaginationHelper) Paginate(c *gin.Context, db *gorm.DB, dest interface{}) (PaginationMeta, error) {
|
|
params := ph.GetPaginationParams(c)
|
|
|
|
// Count total records
|
|
var total int64
|
|
if err := db.Count(&total).Error; err != nil {
|
|
return PaginationMeta{}, err
|
|
}
|
|
|
|
// Apply pagination
|
|
if err := db.Offset(params.Offset).Limit(params.PageSize).Find(dest).Error; err != nil {
|
|
return PaginationMeta{}, err
|
|
}
|
|
|
|
meta := ph.BuildPaginationMeta(params, total)
|
|
return meta, nil
|
|
}
|
|
|
|
// PaginateWithPreload applies pagination with preloading associations
|
|
func (ph *PaginationHelper) PaginateWithPreload(c *gin.Context, db *gorm.DB, dest interface{}, preloads ...string) (PaginationMeta, error) {
|
|
params := ph.GetPaginationParams(c)
|
|
|
|
// Count total records (without preload)
|
|
var total int64
|
|
if err := db.Count(&total).Error; err != nil {
|
|
return PaginationMeta{}, err
|
|
}
|
|
|
|
// Apply preloads
|
|
query := db
|
|
for _, preload := range preloads {
|
|
query = query.Preload(preload)
|
|
}
|
|
|
|
// Apply pagination
|
|
if err := query.Offset(params.Offset).Limit(params.PageSize).Find(dest).Error; err != nil {
|
|
return PaginationMeta{}, err
|
|
}
|
|
|
|
meta := ph.BuildPaginationMeta(params, total)
|
|
return meta, nil
|
|
}
|
|
|
|
// Global PaginationHelper instance for convenience
|
|
var Paginator = NewPaginationHelper()
|