Skip to content

Commit

Permalink
feat(PageableInterface): add $start parameter to getPages() met…
Browse files Browse the repository at this point in the history
…hod to ease batch resuming. (#97)
  • Loading branch information
priyadi authored Jun 22, 2024
1 parent 2d2c614 commit 7518d35
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 30 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* fix(`PagerItem`): `withPageNumber` should return static
* build: update php-cs-fixer
* feat(`QueryBuilderAdapter`): add `indexBy` parameter
* feat(`PageableInterface`): add `$start` parameter to `getPages()` method to
ease batch resuming.

# 0.11.2

Expand Down
4 changes: 3 additions & 1 deletion packages/rekapager-contracts/src/PageableInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@ public function getLastPage(): ?PageInterface;
/**
* Gets an iterable of all pages in the pageable object.
*
* @param object|null $start The identifier of the starting page. If null,
* it will start from the first page.
* @return \Traversable<PageInterface<TKey,T>>
*/
public function getPages(): \Traversable;
public function getPages(?object $start = null): \Traversable;

/**
* Gets the number of items per page. The actual items in the page may be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,21 @@

namespace Rekalogika\Contracts\Rekapager\Trait;

trait TotalPagesTrait
use Rekalogika\Contracts\Rekapager\PageInterface;

/**
* @template TKey of array-key
* @template-covariant T
*/
trait PageableTrait
{
/**
* @return PageInterface<TKey,T>
*/
abstract public function getFirstPage(): PageInterface;

abstract public function getPageByIdentifier(object $pageIdentifier): PageInterface;

/**
* @return int<1,max>
*/
Expand All @@ -41,4 +54,22 @@ public function getTotalPages(): ?int

return $result;
}

/**
* @return \Traversable<PageInterface<TKey,T>>
*/
public function getPages(?object $start = null): \Traversable
{
if ($start === null) {
$page = $this->getFirstPage();
} else {
$page = $this->getPageByIdentifier($start);
}

while ($page !== null) {
yield $page;

$page = $page->getNextPage();
}
}
}
18 changes: 5 additions & 13 deletions packages/rekapager-keyset-pagination/src/KeysetPageable.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
use Rekalogika\Contracts\Rekapager\Exception\InvalidArgumentException;
use Rekalogika\Contracts\Rekapager\PageableInterface;
use Rekalogika\Contracts\Rekapager\PageInterface;
use Rekalogika\Contracts\Rekapager\Trait\TotalPagesTrait;
use Rekalogika\Contracts\Rekapager\Trait\PageableTrait;
use Rekalogika\Rekapager\Keyset\Contracts\BoundaryType;
use Rekalogika\Rekapager\Keyset\Contracts\KeysetPageIdentifier;
use Rekalogika\Rekapager\Keyset\Internal\KeysetPage;
Expand All @@ -28,7 +28,10 @@
*/
final class KeysetPageable implements PageableInterface
{
use TotalPagesTrait;
/**
* @use PageableTrait<TKey,T>
*/
use PageableTrait;

/**
* @var int<0,max>|null
Expand Down Expand Up @@ -64,17 +67,6 @@ public function getItemsPerPage(): int
return $this->itemsPerPage;
}

public function getPages(): \Traversable
{
$page = $this->getFirstPage();

while ($page !== null) {
yield $page;

$page = $page->getNextPage();
}
}

/**
* @return PageInterface<TKey,T>
*/
Expand Down
18 changes: 5 additions & 13 deletions packages/rekapager-offset-pagination/src/OffsetPageable.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
use Rekalogika\Contracts\Rekapager\Exception\InvalidArgumentException;
use Rekalogika\Contracts\Rekapager\PageableInterface;
use Rekalogika\Contracts\Rekapager\PageInterface;
use Rekalogika\Contracts\Rekapager\Trait\TotalPagesTrait;
use Rekalogika\Contracts\Rekapager\Trait\PageableTrait;
use Rekalogika\Rekapager\Offset\Contracts\PageNumber;
use Rekalogika\Rekapager\Offset\Internal\NullOffsetPage;
use Rekalogika\Rekapager\Offset\Internal\OffsetPage;
Expand All @@ -28,7 +28,10 @@
*/
final class OffsetPageable implements PageableInterface
{
use TotalPagesTrait;
/**
* @use PageableTrait<TKey,T>
*/
use PageableTrait;

/**
* @var int<0,max>|null
Expand Down Expand Up @@ -67,17 +70,6 @@ public function getItemsPerPage(): int
return $this->itemsPerPage;
}

public function getPages(): \Traversable
{
$page = $this->getFirstPage();

while ($page !== null) {
yield $page;

$page = $page->getNextPage();
}
}

public function getFirstPage(): PageInterface
{
return $this->getPageByIdentifier(new PageNumber(1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ public function getPageIdentifierClass(): string
return $this->pageable->getPageIdentifierClass();
}

public function getPages(): \Traversable
public function getPages(?object $start = null): \Traversable
{
return $this->pageable->getPages();
return $this->pageable->getPages($start);
}

public function getFirstPage(): PageInterface
Expand Down
42 changes: 42 additions & 0 deletions tests/src/IntegrationTests/Pageable/BatchTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,46 @@ public function testBatch(string $pageableGeneratorClass): void
static::assertSame(21, $pagesCount);
static::assertCount(1003, $ids);
}

#[DataProviderExternal(PageableGeneratorProvider::class, 'all')]
public function testBatchResuming(string $pageableGeneratorClass): void
{
$pageable = $this->createPageableFromGenerator($pageableGeneratorClass);

$itemsCount = 0;
$pagesCount = 0;
$ids = [];

$currentIdentifier = null;

foreach ($pageable->withItemsPerPage(50)->getPages() as $page) {
$currentIdentifier = $page->getPageIdentifier();

if ($pagesCount === 5) {
break;
}

/** @var Post $post */
foreach ($page as $post) {
$ids[$post->getId()] = true;
$itemsCount++;
}
$pagesCount++;
}

foreach ($pageable->withItemsPerPage(50)->getPages($currentIdentifier) as $page) {
$currentIdentifier = $page->getPageIdentifier();

/** @var Post $post */
foreach ($page as $post) {
$ids[$post->getId()] = true;
$itemsCount++;
}
$pagesCount++;
}

static::assertSame(1003, $itemsCount);
static::assertSame(21, $pagesCount);
static::assertCount(1003, $ids);
}
}

0 comments on commit 7518d35

Please sign in to comment.