Skip to content

feat(database): add simplePaginate() to SelectQueryBuilder - #2250

Merged
xHeaven merged 5 commits into
tempestphp:3.xfrom
Lanser0614:feat/simple-paginate
Aug 15, 2026
Merged

feat(database): add simplePaginate() to SelectQueryBuilder#2250
xHeaven merged 5 commits into
tempestphp:3.xfrom
Lanser0614:feat/simple-paginate

Conversation

@Lanser0614

Copy link
Copy Markdown
Contributor

Summary

Adds simple pagination without executing an additional COUNT(*) query.

query(Book::class)
    ->select()
    ->simplePaginate(itemsPerPage: 20, currentPage: 2);

The query requests one additional item:

SELECT ...
LIMIT 21 OFFSET 20

If the additional item exists, it is removed from the returned data and hasNext is set to true.

Changes

  • Add SelectQueryBuilder::simplePaginate().
  • Add database-independent SimplePaginator.
  • Add SimplePaginatedData without synthetic totalItems or totalPages.
  • Expose navigation metadata such as hasNext, hasPrevious, nextPage, and previousPage.
  • Support map(), array serialization, and JSON serialization.
  • Validate itemsPerPage and currentPage.
  • Ensure the public paginate() API never returns more than itemsPerPage items.
  • Document out-of-range page behavior and the trade-offs of offset pagination.

Tests

Added unit and integration coverage for:

  • exactly itemsPerPage results;
  • an additional result used to detect the next page;
  • input larger than itemsPerPage + 1;
  • empty and out-of-range pages;
  • second-page offset calculation;
  • invalid arguments;
  • map(), toArray(), and JSON serialization;
  • SelectQueryBuilder::simplePaginate();
  • execution of a single SELECT query without COUNT(*).

Local verification:

  • PHPUnit: 51 tests, 159 assertions
  • Mago formatter and lint
  • PHPStan

Notes

This is still offset-based pagination. It avoids the potentially expensive count query, but large offsets may remain costly, and concurrent inserts or deletes can shift results between pages. Cursor/keyset pagination remains preferable for very large or frequently changing datasets.

@Lanser0614 Lanser0614 changed the title Add simplePaginate() to SelectQueryBuilder feat(database): add simplePaginate() to SelectQueryBuilder Aug 10, 2026
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown

Benchmark Results

Comparison of feat/simple-paginate against 3.x (2ed234eb062b540ca10dbd9ca8f37a06de08901f).

Open to see the benchmark results
Benchmark Set Mem. Peak Time Variability
ContainerBench(benchRegisterSingletonInstance) - 6.087mb 0.00% 1.772μs +5.24% ±2.70% +9.03%

Generated by phpbench against commit dab7493

@Lanser0614

Copy link
Copy Markdown
Contributor Author

@brendt @innocenzi What is the average review time for a pull request ?

Comment thread packages/support/src/Paginator/SimplePaginator.php Outdated
Comment thread packages/support/src/Paginator/SimplePaginator.php Outdated
@xHeaven xHeaven linked an issue Aug 12, 2026 that may be closed by this pull request
@xHeaven
xHeaven merged commit a31bbcd into tempestphp:3.x Aug 15, 2026
78 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add simplePaginate() to SelectQueryBuilder

3 participants