Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 25 additions & 13 deletions offset/paginator.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,27 +131,39 @@ func buildOrderBy(args *paging.PageArgs) []paging.Sort {
// buildOffsetPageInfo creates PageInfo for offset-based pagination.
// It calculates page boundaries and provides functions to query pagination state.
//
// The endOffset calculation ensures the last page cursor points to the start
// of the final complete page of results.
// StartCursor and EndCursor point to the first and last items on the current page,
// not the first or last page of the entire dataset.
func buildOffsetPageInfo(
pageSize int,
totalCount int64,
currentOffset int,
) paging.PageInfo {
count := int(totalCount)
endOffset := count - (count % pageSize)

if endOffset == count {
endOffset = count - pageSize
}
if endOffset < 0 {
endOffset = 0
}

return paging.PageInfo{
TotalCount: func() (*int, error) { return &count, nil },
StartCursor: func() (*string, error) { return EncodeCursor(0), nil },
EndCursor: func() (*string, error) { return EncodeCursor(endOffset), nil },
TotalCount: func() (*int, error) { return &count, nil },
StartCursor: func() (*string, error) {
if count == 0 {
return nil, nil
}
// Cursor of the first item on current page
return EncodeCursor(currentOffset + 1), nil
},
EndCursor: func() (*string, error) {
if count == 0 {
return nil, nil
}
// Calculate the offset of the last item on this page
lastItemOffset := currentOffset + pageSize - 1
if lastItemOffset >= count {
lastItemOffset = count - 1
}
if lastItemOffset < currentOffset {
return nil, nil
}
// Cursor encodes position after the item (lastItemOffset + 1)
return EncodeCursor(lastItemOffset + 1), nil
},
HasNextPage: func() (bool, error) { return (currentOffset + pageSize) < count, nil },
HasPreviousPage: func() (bool, error) { return currentOffset > 0, nil },
}
Expand Down
8 changes: 6 additions & 2 deletions offset/paginator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,15 @@ var _ = Describe("Paginator", func() {
hasPreviousPage, _ := page.PageInfo.HasPreviousPage()
Expect(hasPreviousPage).To(Equal(true))

// StartCursor should point to first item on current page (offset 20)
// Cursor encoding is offset + 1, so cursor = 21
startCursor, _ := page.PageInfo.StartCursor()
Expect(startCursor).To(Equal(offset.EncodeCursor(0)))
Expect(startCursor).To(Equal(offset.EncodeCursor(21)))

// EndCursor should point to last item on current page (offset 29)
// Cursor encoding is offset + 1, so cursor = 30
endCursor, _ := page.PageInfo.EndCursor()
Expect(endCursor).To(Equal(offset.EncodeCursor(90)))
Expect(endCursor).To(Equal(offset.EncodeCursor(30)))
})
})

Expand Down
Loading