Refactor pagination system with flexible ordering support

This commit overhauls the pagination system to support flexible ordering
beyond the default created_at timestamp:

- Change CursorKey from fixed byte array to structured object with ID and Value
- Add OrderField and OrderDirection types to support different sorting options
- Update SQLFragment to dynamically generate SQL based on field and direction
- Modify cursor navigation logic to consider custom ordering
- Simplify Position type to use string constants instead of numeric values
- Update Page struct to include reference to Cursor

These changes allow paginated queries to be ordered by different fields
(created_at, updated_at, name) in either ascending or descending order
while maintaining consistent cursor-based pagination behavior.

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-03-18 16:12:04 +01:00
parent b64ab3dac2
commit 709b3363c5
5 changed files with 292 additions and 107 deletions

View File

@@ -16,7 +16,7 @@ package page
type (
Paginable interface {
CursorKey() CursorKey
CursorKey(orderBy OrderField) CursorKey
}
PageInfo struct {
@@ -25,8 +25,9 @@ type (
}
Page[T Paginable] struct {
Info *PageInfo
Data []T
Info *PageInfo
Cursor *Cursor
Data []T
}
)
@@ -73,7 +74,7 @@ func NewPage[T Paginable](data []T, c *Cursor) *Page[T] {
edges = edges[0 : len(edges)-1]
}
if c.Key != nil && *c.Key == firstFromData.CursorKey() {
if c.Key != nil && c.Key.String() == firstFromData.CursorKey(c.OrderBy.Field).String() {
pi.HasPrev = true
}
@@ -97,7 +98,7 @@ func NewPage[T Paginable](data []T, c *Cursor) *Page[T] {
edges = edges[1:]
}
if c.Key != nil && *c.Key == firstFromData.CursorKey() {
if c.Key != nil && c.Key.String() == firstFromData.CursorKey(c.OrderBy.Field).String() {
pi.HasNext = true
}
@@ -109,7 +110,8 @@ func NewPage[T Paginable](data []T, c *Cursor) *Page[T] {
}
return &Page[T]{
Info: pi,
Data: edges,
Info: pi,
Cursor: c,
Data: edges,
}
}