Documentation
¶
Overview ¶
Package pagination implements bounded offset and authenticated cursor pagination.
Index ¶
- func CalculateOffset(p Offset) (int, error)
- func OffsetSQL(dialect, template string, args []any, p Offset, options ...OffsetConfig) (string, []any, error)
- func ValidateOffset(p Offset, options ...OffsetConfig) error
- type Codec
- func (c Codec) DecodeCursor(token, query, filter string) (Cursor, error)
- func (c Codec) DecodeCursorContext(ctx context.Context, token, query, filter string) (Cursor, error)
- func (c Codec) EncodeCursor(v Cursor) (string, error)
- func (c Codec) EncodeCursorContext(ctx context.Context, v Cursor) (string, error)
- func (c Codec) ValidateCursor(token, query, filter string) error
- type Cursor
- type CursorMeta
- type CursorRequest
- type CursorResult
- type KeyProvider
- type KeyRing
- type KeyType
- type Offset
- type OffsetConfig
- type OffsetMeta
- type Query
- type SQLPage
- type SelectFunc
- type Sort
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CalculateOffset ¶
CalculateOffset returns a validated zero-based SQL offset.
func OffsetSQL ¶
func OffsetSQL(dialect, template string, args []any, p Offset, options ...OffsetConfig) (string, []any, error)
OffsetSQL expands explicit {{limit}}/{{offset}} markers with bound values and validates configured offset limits.
func ValidateOffset ¶
func ValidateOffset(p Offset, options ...OffsetConfig) error
ValidateOffset enforces bounds without computing an overflowing offset.
Types ¶
type Codec ¶
type Codec struct {
Provider KeyProvider
ActiveKey string
Keys map[string][]byte
TTL time.Duration
MaxBytes int
Now func() time.Time
}
Codec keys must be at least 32 random bytes. Keep previous keys available during rotation.
func (Codec) DecodeCursor ¶
DecodeCursor verifies size, signature, expiration and query/filter binding before returning keys.
func (Codec) DecodeCursorContext ¶
func (c Codec) DecodeCursorContext(ctx context.Context, token, query, filter string) (Cursor, error)
DecodeCursorContext verifies keys obtained from a cancelable provider.
func (Codec) EncodeCursor ¶
EncodeCursor authenticates cursor contents with the configured active HMAC key.
func (Codec) EncodeCursorContext ¶
EncodeCursorContext supports cancelable external key providers.
func (Codec) ValidateCursor ¶
ValidateCursor verifies a cursor without returning its decoded payload.
type Cursor ¶
type Cursor struct {
Version int `json:"v"`
KeyID string `json:"kid"`
Direction string `json:"direction"`
Keys []json.RawMessage `json:"keys"`
Query string `json:"query"`
Filter string `json:"filter"`
Expires int64 `json:"exp,omitempty"`
}
Cursor contains versioned, query-bound composite pagination keys.
type CursorMeta ¶
type CursorMeta struct {
Type string `json:"type"`
Limit int `json:"limit"`
Total *int64 `json:"total_records,omitempty"`
Next string `json:"next_cursor,omitempty"`
Previous string `json:"previous_cursor,omitempty"`
HasNext bool `json:"has_next"`
HasPrevious bool `json:"has_previous"`
}
CursorMeta describes a limit+1 query. Previous navigation requires reversing all sort directions then reversing the returned rows.
func NewCursorMeta ¶
func NewCursorMeta(next, previous string) CursorMeta
NewCursorMeta constructs navigation metadata from issued cursors.
type CursorRequest ¶
CursorRequest contains bounded query parameters. Ordering direction is authenticated inside the cursor.
func ParseCursor ¶
func ParseCursor(r *http.Request) (CursorRequest, error)
ParseCursor parses bounded cursor and limit request parameters.
type CursorResult ¶
type CursorResult[T any] struct { Data []T `json:"data"` Meta CursorMeta `json:"meta"` }
CursorResult contains final presentation order and signed navigation cursors.
func FetchCursor ¶
func FetchCursor[T any](ctx context.Context, selectRows SelectFunc, q Query, request CursorRequest, codec Codec, keys func(T) ([]any, error), count func(context.Context) (int64, error)) (CursorResult[T], error)
FetchCursor executes limit+1 rows and implements genuine reverse navigation by reversing SQL sort and presentation order. Keys must return values in Sort order. Count is optional and must count the same server-bound filter set.
type KeyProvider ¶
type KeyProvider interface {
Active(context.Context) (string, []byte, error)
Key(context.Context, string) ([]byte, error)
}
KeyProvider is the consumer boundary for in-memory key rings, KMS-backed stores or other application-owned key sources.
type KeyRing ¶
type KeyRing struct {
// contains filtered or unexported fields
}
KeyRing supports atomic rotation. Keys are copied on write/read so callers cannot mutate concurrent signing material.
func NewKeyRing ¶
NewKeyRing validates the active key and retains previous verification keys for rotating cursors.
type KeyType ¶
type KeyType string
KeyType fixes each decoded cursor parameter's type; no float64 intermediary is used for integer IDs.
type Offset ¶
Offset contains a validated page number and bounded page size.
func ParseOffset ¶
func ParseOffset(r *http.Request, options ...OffsetConfig) (Offset, error)
ParseOffset parses and validates page/limit query parameters.
type OffsetConfig ¶
type OffsetConfig struct{ DefaultLimit, MaxLimit, MaxOffset int }
OffsetConfig can reduce the default/max page size and bound database offsets. MaxOffset=0 disables the additional offset cap.
type OffsetMeta ¶
type OffsetMeta struct {
Type string `json:"type"`
Offset
Total int64 `json:"total_records"`
Pages int64 `json:"total_pages"`
HasNext bool `json:"has_next"`
HasPrevious bool `json:"has_previous"`
}
OffsetMeta contains offset pagination totals and navigation flags.
func NewOffsetMeta ¶
func NewOffsetMeta(p Offset, total int64) (OffsetMeta, error)
NewOffsetMeta calculates page counts and navigation flags without overflowing totals.
type Query ¶
type Query struct {
Dialect, Template, Identity, Filter string
Args []any
Columns map[string]string
Sort []Sort
KeyTypes []KeyType
}
Query describes a developer-owned SQL template containing exactly one {{where}}, {{order}} and {{limit}} marker. Args bind base filters, whose placeholders must precede generated placeholders. Never put user input in Template or Columns.
type SQLPage ¶
SQLPage contains bound seek SQL and its required result ordering.
func Keyset ¶
func Keyset(dialect string, allow map[string]string, sorts []Sort, values []any, previous bool, start int) (SQLPage, error)
Keyset builds a lexicographic seek predicate. Values are in Sort order; nil represents SQL NULL. PostgreSQL placeholders start at start+1. MySQL uses ?. Previous pages must reverse result rows.
type SelectFunc ¶
SelectFunc matches both SQL adapters without importing either driver. It must fill a slice pointer and close its streams.