Files
website/internal/helpers/template/pagination.go

73 lines
1.5 KiB
Go

// internal/helpers/pagination/pagination.go (move out of template/*)
package templateHelper
import (
"context"
"database/sql"
"fmt"
"time"
)
// Whitelist
var allowedTables = map[string]struct{}{
"user_messages": {},
"user_notifications": {},
"results_thunderball": {},
}
// GetTotalPages counts rows and returns (totalPages, totalCount).
func GetTotalPages(ctx context.Context, db *sql.DB, table, whereClause string, args []any, pageSize int) (int, int64, error) {
if pageSize <= 0 {
pageSize = 20
}
if _, ok := allowedTables[table]; !ok {
return 1, 0, fmt.Errorf("table not allowed: %s", table)
}
q := fmt.Sprintf("SELECT COUNT(*) FROM %s", table)
if whereClause != "" {
q += " WHERE " + whereClause
}
var totalCount int64
cctx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel()
if err := db.QueryRowContext(cctx, q, args...).Scan(&totalCount); err != nil {
return 1, 0, fmt.Errorf("count %s: %w", table, err)
}
totalPages := int((totalCount + int64(pageSize) - 1) / int64(pageSize))
if totalPages < 1 {
totalPages = 1
}
return totalPages, totalCount, nil
}
func MakePageRange(current, total int) []int {
if total < 1 {
return []int{1}
}
pages := make([]int, 0, total)
for i := 1; i <= total; i++ {
pages = append(pages, i)
}
return pages
}
func ClampPage(p, total int) int {
if p < 1 {
return 1
}
if p > total {
return total
}
return p
}
func OffsetLimit(page, pageSize int) (int, int) {
if page < 1 {
page = 1
}
return (page - 1) * pageSize, pageSize
}