mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 18:52:56 +00:00
dev day #65
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user