Passed
Pull Request — master (#17)
by
unknown
01:52
created

OffsetDataReader::withOffset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 1
eloc 3
c 1
b 1
f 0
nc 1
nop 1
dl 0
loc 5
ccs 0
cts 5
cp 0
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Cycle\DataReader;
6
7
use Countable;
8
use Cycle\ORM\Select;
9
use InvalidArgumentException;
10
use Spiral\Database\Query\QueryInterface;
11
use Spiral\Database\Query\SelectQuery;
12
use Spiral\Pagination\PaginableInterface;
13
use Yiisoft\Data\Reader\CountableDataInterface;
14
use Yiisoft\Data\Reader\DataReaderInterface;
15
use Yiisoft\Data\Reader\OffsetableDataInterface;
16
use Yiisoft\Yii\Cycle\DataReader\Cache\CachedCount;
17
use Yiisoft\Yii\Cycle\DataReader\Cache\CachedCollection;
18
19
final class OffsetDataReader implements DataReaderInterface, OffsetableDataInterface, CountableDataInterface
20
{
21
    /** @var QueryInterface|Select */
22
    private $query;
23
    private ?int $limit = null;
24
    private ?int $offset = null;
25
    private CachedCount $countCache;
26
    private CachedCollection $itemsCache;
27
28
    /**
29
     * @param Select|SelectQuery $query
30
     */
31
    public function __construct($query)
32
    {
33
        if (!$query instanceof Countable) {
0 ignored issues
show
introduced by
$query is always a sub-type of Countable.
Loading history...
34
            throw new InvalidArgumentException(sprintf('Query should implement %s interface', Countable::class));
35
        }
36
        if (!$query instanceof PaginableInterface) {
0 ignored issues
show
introduced by
$query is always a sub-type of Spiral\Pagination\PaginableInterface.
Loading history...
37
            throw new InvalidArgumentException(
38
                sprintf('Query should implement %s interface', PaginableInterface::class)
39
            );
40
        }
41
        $this->query = clone $query;
42
        $this->countCache = new CachedCount($this->query);
43
        $this->itemsCache = new CachedCollection();
44
    }
45
    public function withLimit(int $limit): self
46
    {
47
        $clone = clone $this;
48
        $clone->setLimit($limit);
49
        return $clone;
50
    }
51
    public function withOffset(int $offset): self
52
    {
53
        $clone = clone $this;
54
        $clone->setOffset($offset);
55
        return $clone;
56
    }
57
    public function count(): int
58
    {
59
        return $this->countCache->getCount();
60
    }
61
    public function read(): iterable
62
    {
63
        if ($this->itemsCache->getCollection() !== null) {
64
            return $this->itemsCache->getCollection();
65
        }
66
        $newQuery = clone $this->query;
67
        if ($this->offset !== null) {
68
            $newQuery->offset($this->offset);
0 ignored issues
show
Bug introduced by
The method offset() does not exist on Spiral\Database\Query\QueryInterface. It seems like you code against a sub-type of Spiral\Database\Query\QueryInterface such as Spiral\Database\Query\SelectQuery. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

68
            $newQuery->/** @scrutinizer ignore-call */ 
69
                       offset($this->offset);
Loading history...
69
        }
70
        if ($this->limit !== null) {
71
            $newQuery->limit($this->limit);
0 ignored issues
show
Bug introduced by
The method limit() does not exist on Spiral\Database\Query\QueryInterface. It seems like you code against a sub-type of Spiral\Database\Query\QueryInterface such as Spiral\Database\Query\SelectQuery. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

71
            $newQuery->/** @scrutinizer ignore-call */ 
72
                       limit($this->limit);
Loading history...
72
        }
73
        $this->itemsCache->setCollection($newQuery->fetchAll());
0 ignored issues
show
Bug introduced by
The method fetchAll() does not exist on Spiral\Database\Query\QueryInterface. It seems like you code against a sub-type of Spiral\Database\Query\QueryInterface such as Spiral\Database\Query\SelectQuery. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

73
        $this->itemsCache->setCollection($newQuery->/** @scrutinizer ignore-call */ fetchAll());
Loading history...
74
        return $this->itemsCache->getCollection();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->itemsCache->getCollection() returns the type null which is incompatible with the type-hinted return iterable.
Loading history...
Bug introduced by
Are you sure the usage of $this->itemsCache->getCollection() targeting Yiisoft\Yii\Cycle\DataRe...ection::getCollection() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
75
    }
76
77
    private function setLimit(?int $limit): void
78
    {
79
        if ($this->limit !== $limit) {
80
            $this->limit = $limit;
81
            $this->itemsCache = new CachedCollection();
82
        }
83
    }
84
    private function setOffset(?int $offset): void
85
    {
86
        if ($this->offset !== $offset) {
87
            $this->offset = $offset;
88
            $this->itemsCache = new CachedCollection();
89
        }
90
    }
91
}
92