initial commit. Cloned timetracker repository
This commit is contained in:
63
app/utils/pagination/pagination.go
Normal file
63
app/utils/pagination/pagination.go
Normal file
@@ -0,0 +1,63 @@
|
||||
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)}
|
||||
}
|
||||
Reference in New Issue
Block a user