diff options
Diffstat (limited to 'vendor/ipl/orm/src/ResultSet.php')
-rw-r--r-- | vendor/ipl/orm/src/ResultSet.php | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/vendor/ipl/orm/src/ResultSet.php b/vendor/ipl/orm/src/ResultSet.php new file mode 100644 index 0000000..05117a5 --- /dev/null +++ b/vendor/ipl/orm/src/ResultSet.php @@ -0,0 +1,146 @@ +<?php + +namespace ipl\Orm; + +use ArrayIterator; +use Iterator; +use Traversable; + +class ResultSet implements Iterator +{ + protected $cache; + + /** @var bool Whether cache is disabled */ + protected $isCacheDisabled = false; + + protected $generator; + + protected $limit; + + protected $position; + + public function __construct(Traversable $traversable, $limit = null) + { + $this->cache = new ArrayIterator(); + $this->generator = $this->yieldTraversable($traversable); + $this->limit = $limit; + } + + /** + * Create a new result set from the given query + * + * @param Query $query + * + * @return static + */ + public static function fromQuery(Query $query) + { + return new static($query->yieldResults(), $query->getLimit()); + } + + /** + * Do not cache query result + * + * ResultSet instance can only be iterated once + * + * @return $this + */ + public function disableCache() + { + $this->isCacheDisabled = true; + + return $this; + } + + public function hasMore() + { + return $this->generator->valid(); + } + + public function hasResult() + { + return $this->generator->valid(); + } + + #[\ReturnTypeWillChange] + public function current() + { + if ($this->position === null) { + $this->advance(); + } + + return $this->isCacheDisabled ? $this->generator->current() : $this->cache->current(); + } + + public function next(): void + { + if (! $this->isCacheDisabled) { + $this->cache->next(); + } + + if ($this->isCacheDisabled || ! $this->cache->valid()) { + $this->generator->next(); + $this->advance(); + } else { + $this->position += 1; + } + } + + public function key(): int + { + if ($this->position === null) { + $this->advance(); + } + + return $this->isCacheDisabled ? $this->generator->key() : $this->cache->key(); + } + + public function valid(): bool + { + if ($this->limit !== null && $this->position === $this->limit) { + return false; + } + + return $this->cache->valid() || $this->generator->valid(); + } + + public function rewind(): void + { + if (! $this->isCacheDisabled) { + $this->cache->rewind(); + } + + if ($this->position === null) { + $this->advance(); + } else { + $this->position = 0; + } + } + + protected function advance() + { + if (! $this->generator->valid()) { + return; + } + + if (! $this->isCacheDisabled) { + $this->cache[$this->generator->key()] = $this->generator->current(); + + // Only required on PHP 5.6, 7+ does it automatically + $this->cache->seek($this->generator->key()); + } + + if ($this->position === null) { + $this->position = 0; + } else { + $this->position += 1; + } + } + + protected function yieldTraversable(Traversable $traversable) + { + foreach ($traversable as $key => $value) { + yield $key => $value; + } + } +} |