Documentation
¶
Index ¶
- Constants
- func DecodeCursor(cursor string) (field string, value string, err error)
- func DecodeMultiCursor(cursor string) ([]multiCursorField, error)
- func EncodeCursor(field string, value any) string
- func EncodeMultiCursor(fields []string, row map[string]any) string
- func OffsetForPage(page, limit int) int
- func ParseCursorPagination(r *http.Request) (cursor string, limit int, direction string)
- func ParsePagination(r *http.Request) (cursor string, limit int, offset int)
- type CursorPage
- type OffsetPage
Constants ¶
const DefaultPageSize = 25
DefaultPageSize is the default number of items per page.
const MaxPageSize = 100
MaxPageSize is the maximum allowed page size.
Variables ¶
This section is empty.
Functions ¶
func DecodeCursor ¶
DecodeCursor decodes a base64 cursor string into its field and value components.
The field name is stripped of control / invisible codepoints: it flows into SQL identifiers (ORDER BY) and allow-lists, where a smuggled zero-width or bidi codepoint makes a parser and a downstream allow-list disagree. The VALUE is returned verbatim, it is compared against the database as a bound arg, never interpolated, so stripping it would not harden anything while breaking the keyset contract: a sort key containing e.g. U+200B must round-trip losslessly or paging resumes before that row and re-serves it.
func DecodeMultiCursor ¶
DecodeMultiCursor returns the ordered list of (column, value) pairs the cursor encoded. Returns the empty slice + an error if the cursor doesn't match the expected shape.
func EncodeCursor ¶
EncodeCursor creates a base64-encoded opaque cursor from a field name and value.
func EncodeMultiCursor ¶
EncodeMultiCursor builds an opaque cursor from an ordered list of (column, value) pairs. Used for composite cursor pagination. ORDER BY composes the fields in the same order, and the WHERE clause becomes a tuple comparison "(c1, c2, …) > ($1, $2, …)".
func OffsetForPage ¶ added in v0.66.0
OffsetForPage returns the row offset for a 1-based page number and a page size, with the integer-overflow guard applied. A caller can request a huge page number (e.g. math.MaxInt) whose (page-1)*limit product wraps: to a negative offset, undefined in most SQL dialects (Postgres rejects it outright) and treated as 0 by SQLite, or, for carefully chosen values, to a small POSITIVE offset that silently serves the wrong window. page>=1 and limit>=1 required, so (page-1)*limit overflows iff (page-1) > math.MaxInt/limit; compute the threshold without the `+1` that previously wrapped to math.MinInt when limit==1. Overflow clamps to 0 (the first window), matching ParsePagination's historical behaviour. Every offset-math call site (buffered list, streaming list, admin table) must go through this, never multiply a client-supplied page by hand.
func ParseCursorPagination ¶
ParseCursorPagination extracts cursor, limit, and direction from query parameters. Direction defaults to "forward"; can be set via ?direction=backward.
Types ¶
type CursorPage ¶
type CursorPage struct {
Data []map[string]any `json:"data"`
Cursor string `json:"cursor"`
HasMore bool `json:"hasMore"`
Total int `json:"total,omitempty"`
}
CursorPage represents a page of results using cursor-based pagination.
func NewCursorPage ¶
func NewCursorPage(data []map[string]any, cursorField string, limit int) CursorPage
NewCursorPage builds a CursorPage from data. It fetches limit+1 rows to determine HasMore, and encodes the next cursor from the last row's cursorField.
type OffsetPage ¶
type OffsetPage struct {
Data []map[string]any `json:"data"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
Total int `json:"total"`
TotalPages int `json:"totalPages"`
}
OffsetPage represents a page of results using offset-based pagination.
func NewOffsetPage ¶
func NewOffsetPage(data []map[string]any, page, pageSize, total int) OffsetPage
NewOffsetPage builds an OffsetPage with computed TotalPages from total and pageSize.