hybrid pagination

This commit is contained in:
Mazyar
2026-05-17 17:21:36 +03:30
parent 42d0a47226
commit 6dac5b482a
39 changed files with 696 additions and 386 deletions
+23 -15
View File
@@ -13,15 +13,17 @@ const pageCursorVersion = 1
// pageCursor is an opaque pagination token for keyset (cursor) pagination.
type pageCursor struct {
V int `json:"v"`
SortField string `json:"sort_field"`
SortOrder int `json:"sort_order"`
ValueType string `json:"value_type"` // i64, f64, str, oid
SortValue string `json:"sort_value"`
ID string `json:"id"`
V int `json:"v"`
SortField string `json:"sort_field"`
SortOrder int `json:"sort_order"`
ValueType string `json:"value_type"` // i64, f64, str, oid
SortValue string `json:"sort_value"`
ID string `json:"id"`
FiltersHash string `json:"filters_hash,omitempty"`
PageOffset int `json:"page_offset,omitempty"`
}
func encodePageCursor(sortField string, sortOrder int, sortValue interface{}, id string) (string, error) {
func encodePageCursor(sortField string, sortOrder int, sortValue interface{}, id, filtersHash string, pageOffset int) (string, error) {
if sortField == "" {
return "", fmt.Errorf("%w: sort field is required", ErrInvalidCursor)
}
@@ -35,22 +37,28 @@ func encodePageCursor(sortField string, sortOrder int, sortValue interface{}, id
}
payload, err := json.Marshal(pageCursor{
V: pageCursorVersion,
SortField: sortField,
SortOrder: sortOrder,
ValueType: valueType,
SortValue: sortValueStr,
ID: id,
V: pageCursorVersion,
SortField: sortField,
SortOrder: sortOrder,
ValueType: valueType,
SortValue: sortValueStr,
ID: id,
FiltersHash: filtersHash,
PageOffset: pageOffset,
})
if err != nil {
return "", fmt.Errorf("failed to marshal cursor: %w", err)
}
return base64.StdEncoding.EncodeToString(payload), nil
return base64.RawURLEncoding.EncodeToString(payload), nil
}
func decodePageCursor(encoded string) (*pageCursor, error) {
cursorBytes, err := base64.StdEncoding.DecodeString(encoded)
cursorBytes, err := base64.RawURLEncoding.DecodeString(encoded)
if err != nil {
// Accept standard Base64 cursors issued before URL-safe encoding.
cursorBytes, err = base64.StdEncoding.DecodeString(encoded)
}
if err != nil {
return nil, fmt.Errorf("%w: invalid cursor encoding", ErrInvalidCursor)
}