Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add paging functionality to ResultSet #136

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
87 changes: 82 additions & 5 deletions src/ResultSet.php
Original file line number Diff line number Diff line change
@@ -1,47 +1,108 @@
<?php

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:__construct\(\) has parameter \$limit with no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:hasMore\(\) has no return type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:hasResult\(\) has no return type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:yieldTraversable\(\) has no return type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$cache has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$generator has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$limit has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$position has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:__construct\(\) has parameter \$limit with no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:hasMore\(\) has no return type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:hasResult\(\) has no return type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:yieldTraversable\(\) has no return type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$cache has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$generator has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$limit has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$position has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:__construct\(\) has parameter \$limit with no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:hasMore\(\) has no return type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:hasResult\(\) has no return type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:yieldTraversable\(\) has no return type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$cache has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$generator has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$limit has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$position has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:__construct\(\) has parameter \$limit with no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:hasMore\(\) has no return type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:hasResult\(\) has no return type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Ignored error pattern #^Method ipl\\Orm\\ResultSet\:\:yieldTraversable\(\) has no return type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$cache has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$generator has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$limit has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

Check failure on line 1 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Ignored error pattern #^Property ipl\\Orm\\ResultSet\:\:\$position has no type specified\.$# in path /home/runner/work/ipl-orm/ipl-orm/src/ResultSet.php was not matched in reported errors.

namespace ipl\Orm;

use ArrayIterator;
use BadMethodCallException;
use Generator;
use Iterator;
use Traversable;

/**
* Dataset containing database rows
*/
class ResultSet implements Iterator
{
/** @var ArrayIterator */
protected $cache;

Check failure on line 17 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Property ipl\Orm\ResultSet::$cache with generic class ArrayIterator does not specify its types: TKey, TValue

Check failure on line 17 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Property ipl\Orm\ResultSet::$cache with generic class ArrayIterator does not specify its types: TKey, TValue

Check failure on line 17 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Property ipl\Orm\ResultSet::$cache with generic class ArrayIterator does not specify its types: TKey, TValue

Check failure on line 17 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Property ipl\Orm\ResultSet::$cache with generic class ArrayIterator does not specify its types: TKey, TValue

/** @var bool Whether cache is disabled */
protected $isCacheDisabled = false;

/** @var Generator */
protected $generator;

/** @var ?int */
protected $limit;

/** @var ?int */
protected $position;

public function __construct(Traversable $traversable, $limit = null)
/** @var ?int */
protected $offset;

/** @var ?int */
protected $pageSize;

/**
* Construct the {@see self::class class} object
ncosta-ic marked this conversation as resolved.
Show resolved Hide resolved
*
* @param Traversable $traversable
* @param ?int $limit
* @param ?int $offset
*/
public function __construct(Traversable $traversable, $limit = null, $offset = null)
{
$this->cache = new ArrayIterator();
$this->generator = $this->yieldTraversable($traversable);
$this->limit = $limit;
$this->offset = $offset;
}

/**
* Get the current page number
*
* Returns the current page, calculated by the {@see self::$position position}, {@see self::$offset offset}
* and the {@see self::$pageSize page size}
*
* @return int page
* @throws BadMethodCallException if no {@see self::$pageSize page size} has been provided
*/
public function getCurrentPage(): int
{
if ($this->pageSize) {
$offset = $this->offset ?: 0;
if ($this->position && ($this->position + $offset) > $this->pageSize) {
// we are not on the first page anymore, calculating proper page
return intval(floor(($this->position + $offset) / $this->pageSize));
ncosta-ic marked this conversation as resolved.
Show resolved Hide resolved
}

// still on the first page
return 1;
}

throw new BadMethodCallException("The 'pageSize' property has not been set. Cannot calculate pages.");
}

/**
* Set the amount of entries a page should contain (needed for pagination)
*
* @param ?int $size entries per page
* @return $this
*/
public function setPageSize(?int $size)
{
$this->pageSize = $size;

return $this;
}

/**
* Create a new result set from the given query
* Create a new result set from the given {@see Query query}
*
* @param Query $query
*
* @return static
ncosta-ic marked this conversation as resolved.
Show resolved Hide resolved
*/
public static function fromQuery(Query $query)
{
return new static($query->yieldResults(), $query->getLimit());
return new static($query->yieldResults(), $query->getLimit(), $query->getOffset());
}

/**
* Do not cache query result
*
* ResultSet instance can only be iterated once
* {@see self::class class} instance can only be iterated once
ncosta-ic marked this conversation as resolved.
Show resolved Hide resolved
*
* @return $this
ncosta-ic marked this conversation as resolved.
Show resolved Hide resolved
*/
Expand All @@ -52,11 +113,21 @@
return $this;
}

/**
* Check if dataset has more entries
*
* @return bool
*/
public function hasMore()
{
return $this->generator->valid();
}

/**
* Check if dataset has a result
*
* @return bool
*/
public function hasResult()
{
return $this->generator->valid();
Expand Down Expand Up @@ -86,13 +157,13 @@
}
}

public function key(): int
public function key(): ?int
ncosta-ic marked this conversation as resolved.
Show resolved Hide resolved
ncosta-ic marked this conversation as resolved.
Show resolved Hide resolved
{
if ($this->position === null) {
$this->advance();
}

return $this->isCacheDisabled ? $this->generator->key() : $this->cache->key();

Check failure on line 166 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.2 on ubuntu-latest

Method ipl\Orm\ResultSet::key() should return int|null but returns mixed.

Check failure on line 166 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.3 on ubuntu-latest

Method ipl\Orm\ResultSet::key() should return int|null but returns mixed.

Check failure on line 166 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.1 on ubuntu-latest

Method ipl\Orm\ResultSet::key() should return int|null but returns mixed.

Check failure on line 166 in src/ResultSet.php

View workflow job for this annotation

GitHub Actions / phpstan / Static analysis with phpstan and php 8.0 on ubuntu-latest

Method ipl\Orm\ResultSet::key() should return int|null but returns mixed.
}

public function valid(): bool
Expand Down Expand Up @@ -137,6 +208,12 @@
}
}

/**
* Yield entry from dataset
*
* @param Traversable $traversable
* @return Generator
ncosta-ic marked this conversation as resolved.
Show resolved Hide resolved
*/
protected function yieldTraversable(Traversable $traversable)
{
foreach ($traversable as $key => $value) {
Expand Down
Loading