55 lines
975 B
Go
55 lines
975 B
Go
package pagination
|
|
|
|
import (
|
|
"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
|
|
}
|