Documentation
¶
Overview ¶
Package pagination provides types and helpers for offset-based and cursor-based pagination.
Offset pagination ¶
OffsetPager carries page/pageSize input for SQL OFFSET/LIMIT queries. NewOffsetPager clamps both values to safe ranges (page ≥ 1, 1 ≤ pageSize ≤ MaxPageSize by default). Override the bounds per call site with WithDefaultPageSize / WithMaxPageSize — e.g. a higher cap for an internal API: pagination.NewOffsetPager(page, pageSize, pagination.WithMaxPageSize(500)). Page wraps the result set with total-count metadata:
pager := pagination.NewOffsetPager(page, pageSize) // from query params
var rows []User
var total int64
db.Model(&User{}).Count(&total).
Offset(pager.Offset()).Limit(pager.Limit()).Find(&rows)
result := pagination.NewPage(rows, total, pager)
// result.TotalPages(), result.HasNext(), result.HasPrev()
Cursor pagination ¶
CursorPager carries an opaque cursor token and a limit for keyset-style queries. NewCursorPager clamps the limit the same way NewOffsetPager clamps page size — override with WithDefaultLimit / WithMaxLimit. A cursor is one or more base64-encoded raw values — one per ORDER BY column, in column order — so multi-column sorts (e.g. created_at, id) stay stable across pages without skipping or repeating rows on ties. CursorPage wraps the result set with encoded next/prev cursor tokens:
pager := pagination.NewCursorPager(cursorParam, limitParam)
vals, err := pager.DecodedCursor() // []string{createdAt, id} for WHERE (created_at, id) > (?, ?)
// after fetching items, encode the boundary values in the same column order:
last, first := items[len(items)-1], items[0]
result := pagination.NewCursorPage(items,
[]string{last.CreatedAt.Format(time.RFC3339Nano), last.ID.String()},
[]string{first.CreatedAt.Format(time.RFC3339Nano), first.ID.String()},
)
// result.NextCursor, result.PrevCursor, result.HasNext, result.HasPrev
A single-column sort works the same way with one-element slices — pagination.NewCursorPage(items, []string{last.ID.String()}, []string{first.ID.String()}).
Index ¶
Constants ¶
const ( DefaultPage = 1 DefaultPageSize = 20 MaxPageSize = 100 )
const DefaultCursorLimit = 20
Variables ¶
This section is empty.
Functions ¶
func DecodeCursor ¶
DecodeCursor decodes an opaque cursor token back to its raw values, in the same order they were passed to EncodeCursor.
func EncodeCursor ¶
EncodeCursor encodes one or more raw values into a single opaque cursor token. Pass one value per ORDER BY column, in column order, to keep multi-column sorts stable across pages (e.g. EncodeCursor(createdAt, id)).
Types ¶
type CursorOption ¶
type CursorOption func(*cursorLimits)
CursorOption configures the bounds NewCursorPager clamps its limit against.
func WithDefaultLimit ¶
func WithDefaultLimit(n int) CursorOption
WithDefaultLimit overrides the limit used when the caller passes a value below 1 (e.g. an absent query parameter). Defaults to DefaultCursorLimit.
func WithMaxLimit ¶
func WithMaxLimit(n int) CursorOption
WithMaxLimit overrides the upper bound the limit is clamped to. Defaults to MaxPageSize.
type CursorPage ¶
type CursorPage[T any] struct { Items []T NextCursor string PrevCursor string HasNext bool HasPrev bool }
CursorPage is a cursor-paginated result set.
func NewCursorPage ¶
func NewCursorPage[T any](items []T, nextVals, prevVals []string) CursorPage[T]
NewCursorPage builds a CursorPage. nextVals and prevVals are the raw cursor values of the last/first item — one per ORDER BY column, in the same order (e.g. []string{createdAt, id}). Pass nil (or empty) for nextVals/prevVals if there is no next/prev page.
type CursorPager ¶
type CursorPager struct {
// Cursor is an opaque token pointing to the last seen item. Empty means start from beginning.
Cursor string
Limit int
}
CursorPager holds cursor-based pagination input for repository queries.
func NewCursorPager ¶
func NewCursorPager(cursor string, limit int, opts ...CursorOption) CursorPager
NewCursorPager creates a CursorPager with a valid limit. By default the limit defaults to DefaultCursorLimit and is capped at MaxPageSize. Override either bound with WithDefaultLimit or WithMaxLimit — e.g. to allow larger pages on an internal API:
pager := pagination.NewCursorPager(cursor, limit, pagination.WithMaxLimit(500))
func (CursorPager) DecodedCursor ¶
func (p CursorPager) DecodedCursor() ([]string, error)
DecodedCursor decodes the opaque cursor to its raw values (e.g. the last-seen sort-key values used to keep a multi-column ORDER BY stable, such as []string{createdAt, id}). Returns nil if cursor is empty (first page).
type OffsetOption ¶
type OffsetOption func(*offsetLimits)
OffsetOption configures the bounds NewOffsetPager clamps page size against.
func WithDefaultPageSize ¶
func WithDefaultPageSize(n int) OffsetOption
WithDefaultPageSize overrides the page size used when the caller passes a value below 1 (e.g. an absent query parameter). Defaults to DefaultPageSize.
func WithMaxPageSize ¶
func WithMaxPageSize(n int) OffsetOption
WithMaxPageSize overrides the upper bound page size is clamped to. Defaults to MaxPageSize.
type OffsetPager ¶
OffsetPager holds offset-based pagination input for repository queries.
func NewOffsetPager ¶
func NewOffsetPager(page, pageSize int, opts ...OffsetOption) OffsetPager
NewOffsetPager creates an OffsetPager, clamping values to valid ranges. By default page defaults to DefaultPage, pageSize to DefaultPageSize, and is capped at MaxPageSize. Override either bound with WithDefaultPageSize or WithMaxPageSize — e.g. to allow larger pages on an internal API:
pager := pagination.NewOffsetPager(page, pageSize, pagination.WithMaxPageSize(500))
func (OffsetPager) Limit ¶
func (p OffsetPager) Limit() int
Limit returns the DB limit (same as PageSize).
func (OffsetPager) Offset ¶
func (p OffsetPager) Offset() int
Offset returns the DB offset for this page.
type Page ¶
Page is a paginated result set for offset-based pagination.
func NewPage ¶
func NewPage[T any](items []T, total int64, pager OffsetPager) Page[T]
NewPage creates a Page from query results and the originating OffsetPager.
func (Page[T]) TotalPages ¶
TotalPages returns the number of pages for the total count.