Documentation
¶
Index ¶
- Constants
- func ApplyCursorToQuery[T Paginatable](query *bun.SelectQuery, r *CursorRequest, model T, order OrderDirection) (*bun.SelectQuery, error)
- func EncodeCursor(c Cursor) (string, error)
- func SetSigningKey(key []byte)
- type Cursor
- type CursorRequest
- type CursorResponse
- type OrderDirection
- type Paginatable
Constants ¶
const ( MAX_PAGE_SIZE = 1000 DEFAULT_LIMIT = 50 )
Variables ¶
This section is empty.
Functions ¶
func ApplyCursorToQuery ¶
func ApplyCursorToQuery[T Paginatable](query *bun.SelectQuery, r *CursorRequest, model T, order OrderDirection) (*bun.SelectQuery, error)
ApplyCursorToQuery adds cursor-based pagination to a bun query based on the Paginatable model. The order parameter is of type OrderDirection, ensuring that only valid order directions are used.
func EncodeCursor ¶
EncodeCursor creates a base64 encoded cursor from a Cursor struct, signed when a signing key has been set with SetSigningKey
func SetSigningKey ¶ added in v1.16.0
func SetSigningKey(key []byte)
SetSigningKey enables HMAC-SHA256 signing of cursors so clients cannot forge pagination positions. Once a key is set, EncodeCursor appends a signature and DecodeCursor rejects cursors with a missing or invalid signature.
Enabling signing (or changing the key) invalidates every cursor issued before the key was set. Passing an empty key disables signing and restores unsigned cursors.
Types ¶
type Cursor ¶
type Cursor struct {
SortField string `json:"sort_field"`
SortValue interface{} `json:"sort_value"`
UniqueField string `json:"unique_field"`
UniqueValue interface{} `json:"unique_value"`
}
Cursor holds the values needed for pagination
func DecodeCursor ¶
DecodeCursor decodes a base64 encoded cursor string into a Cursor struct, verifying its signature when a signing key has been set with SetSigningKey.
Numeric SortValue and UniqueValue are decoded without loss of precision: integers come back as int64 (so values above 2^53, such as snowflake IDs or unix nanoseconds, survive the round trip) and other numbers as float64. Strings, bools and nil are returned unchanged.
type CursorRequest ¶
type CursorRequest struct {
Limit int `json:"limit"`
Cursor string `json:"cursor"`
Filter []query.Filter `json:"-"` // Server-side only: Field and Comparison are interpolated into SQL and must never come from client input
}
CursorRequest represents a cursor paginated request
func (*CursorRequest) Validate ¶
func (r *CursorRequest) Validate() error
type CursorResponse ¶
type CursorResponse struct {
NextCursor string `json:"next_cursor,omitempty"`
HasNextPage bool `json:"has_next_page"`
Hash string `json:"hash,omitempty"` // SHA-256 hash of the items for data freshness validation
// contains filtered or unexported fields
}
CursorResponse represents a cursor paginated response
func BuildCursorResponse ¶
func BuildCursorResponse[T Paginatable](items []T, limit int) (*CursorResponse, error)
BuildCursorResponse processes the query results and creates a paginated response
func (*CursorResponse) GetItems ¶
func (r *CursorResponse) GetItems() interface{}
GetItems returns the underlying items of the response
type OrderDirection ¶
type OrderDirection string
OrderDirection represents the allowed direction for pagination.
const ( ASC OrderDirection = "asc" DESC OrderDirection = "desc" )
type Paginatable ¶
type Paginatable interface {
GetSortField() string // Returns sort field name without table prefix
GetSortValue() interface{} // Returns the value for the sort field
GetUniqueField() string // Returns unique field name without table prefix
GetUniqueValue() interface{} // Returns the value for the unique field
}
Paginatable interface that models must implement to use pagination
GetSortField and GetUniqueField are interpolated raw into SQL (to support expressions like LENGTH(unit.name)), so they must return compile-time constants and never client input.