package pagination import ( "strconv" "github.com/gofiber/fiber/v3" "gorm.io/gorm" ) type Paging struct { Page uint `json:"page_number" example:"5"` Elements uint `json:"elements_per_page" example:"30"` } func (p Paging) Offset() int { return int(p.Elements) * int(p.Page-1) } func (p Paging) Limit() int { return int(p.Elements) } type Found[T any] struct { Items []T `json:"items,omitempty"` Count uint `json:"items_count" example:"56"` } func Paginate[T any](paging Paging, stmt *gorm.DB) (Found[T], error) { var items []T var count int64 base := stmt.Session(&gorm.Session{}) countDB := stmt.Session(&gorm.Session{ NewDB: true, // critical: do NOT reuse statement }) if err := countDB. Table("(?) as sub", base). Count(&count).Error; err != nil { return Found[T]{}, err } err := base. Offset(paging.Offset()). Limit(paging.Limit()). Find(&items). Error if err != nil { return Found[T]{}, err } return Found[T]{ Items: items, Count: uint(count), }, err } func ParsePagination(c *fiber.Ctx) Paging { pageNum, _ := strconv.ParseInt((*c).Query("p", "1"), 10, 64) pageSize, _ := strconv.ParseInt((*c).Query("elems", "10"), 10, 64) return Paging{Page: uint(pageNum), Elements: uint(pageSize)} }