Skip to content

Add simplePaginate() to SelectQueryBuilder #2245

Description

@Lanser0614

Description

Tempest currently provides length-aware pagination through SelectQueryBuilder::paginate().

This implementation performs an additional count query to calculate:

  • the total number of items;
  • the total number of pages;
  • the page range.

For large tables or complex queries, the count query may be expensive or unnecessary when the application only needs to know whether another page exists.

It would be useful to provide a simple pagination method, similar to Laravel's simplePaginate(), that avoids the count query.

Proposed API

$pagination = query(Book::class)->select()->simplePaginate(
    itemsPerPage: 20,
    currentPage: 1,
);

The implementation could request one additional record:

$itemsPerPage + 1

The extra record would be used to determine whether the next page exists and would then be removed from the returned data.

Proposed result type

Since simple pagination cannot provide totalItems or totalPages, it may be cleaner to return a separate result type:

/**
 * @template T
 */
final class SimplePaginatedData
{
    /**
     * @param array<T> $data
     */
    public function __construct(
        public array $data,
        public int $currentPage,
        public int $itemsPerPage,
        public int $offset,
        public int $limit,
        public bool $hasNext,
        public bool $hasPrevious,
        public ?int $nextPage,
        public ?int $previousPage,
    ) {}
}

This would keep the existing PaginatedData contract strict instead of making fields such as totalItems and totalPages nullable.

Benefits

  • avoids an additional count query;
  • improves performance for large or complex datasets;
  • works well for APIs and infinite scrolling;
  • preserves the existing length-aware pagination behavior;
  • keeps simple and length-aware pagination as separate contracts.

I would be interested in implementing this as a first contribution if this direction fits Tempest's API design.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions