MultiResultSet::offsetGet()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Foolz\SphinxQL\Drivers;
4
5
use Foolz\SphinxQL\Exception\DatabaseException;
6
7
class MultiResultSet implements MultiResultSetInterface
8
{
9
    /**
10
     * @var null|array
11
     */
12
    protected $stored;
13
14
    /**
15
     * @var int
16
     */
17
    protected $cursor = 0;
18
19
    /**
20
     * @var int
21
     */
22
    protected $next_cursor = 0;
23
24
    /**
25
     * @var ResultSetInterface|null
26
     */
27
    protected $rowSet;
28
29
    /**
30
     * @var MultiResultSetAdapterInterface
31
     */
32
    protected $adapter;
33
34
    /**
35
     * @var bool
36
     */
37
    protected $valid = true;
38
39
    /**
40
     * @param MultiResultSetAdapterInterface $adapter
41
     */
42
    public function __construct(MultiResultSetAdapterInterface $adapter)
43
    {
44
        $this->adapter = $adapter;
45
    }
46
47
    /**
48
     * @inheritdoc
49
     * @throws DatabaseException
50
     */
51
    public function getStored()
52
    {
53
        $this->store();
54
55
        return $this->stored;
56
    }
57
58
    /**
59
     * @inheritdoc
60
     * @throws DatabaseException
61
     */
62
    #[\ReturnTypeWillChange]
63
    public function offsetExists($offset)
64
    {
65
        $this->store();
66
67
        return $this->storedValid($offset);
68
    }
69
70
    /**
71
     * @inheritdoc
72
     * @throws DatabaseException
73
     */
74
    #[\ReturnTypeWillChange]
75
    public function offsetGet($offset)
76
    {
77
        $this->store();
78
79
        return $this->stored[$offset];
80
    }
81
82
    /**
83
     * @inheritdoc
84
     * @codeCoverageIgnore
85
     */
86
    #[\ReturnTypeWillChange]
87
    public function offsetSet($offset, $value)
88
    {
89
        throw new \BadMethodCallException('Not implemented');
90
    }
91
92
    /**
93
     * @inheritdoc
94
     * @codeCoverageIgnore
95
     */
96
    #[\ReturnTypeWillChange]
97
    public function offsetUnset($offset)
98
    {
99
        throw new \BadMethodCallException('Not implemented');
100
    }
101
102
    /**
103
     * @inheritdoc
104
     */
105
    #[\ReturnTypeWillChange]
106
    public function next()
107
    {
108
        $this->rowSet = $this->getNext();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getNext() can also be of type false. However, the property $rowSet is declared as type Foolz\SphinxQL\Drivers\ResultSetInterface|null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
109
    }
110
111
    /**
112
     * @inheritdoc
113
     */
114
    #[\ReturnTypeWillChange]
115
    public function key()
116
    {
117
        return (int)$this->cursor;
118
    }
119
120
    /**
121
     * @inheritdoc
122
     */
123
    #[\ReturnTypeWillChange]
124
    public function rewind()
125
    {
126
        // we actually can't roll this back unless it was stored first
127
        $this->cursor = 0;
128
        $this->next_cursor = 0;
129
        $this->rowSet = $this->getNext();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getNext() can also be of type false. However, the property $rowSet is declared as type Foolz\SphinxQL\Drivers\ResultSetInterface|null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
130
    }
131
132
    /**
133
     * @inheritdoc
134
     * @throws DatabaseException
135
     */
136
    #[\ReturnTypeWillChange]
137
    public function count()
138
    {
139
        $this->store();
140
141
        return count($this->stored);
0 ignored issues
show
Bug introduced by
It seems like $this->stored can also be of type null; however, parameter $value of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

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

141
        return count(/** @scrutinizer ignore-type */ $this->stored);
Loading history...
142
    }
143
144
    /**
145
     * @inheritdoc
146
     */
147
    #[\ReturnTypeWillChange]
148
    public function valid()
149
    {
150
        if ($this->stored !== null) {
151
            return $this->storedValid();
152
        }
153
154
        return $this->adapter->valid();
155
    }
156
157
    /**
158
     * @inheritdoc
159
     */
160
    #[\ReturnTypeWillChange]
161
    public function current()
162
    {
163
        $rowSet = $this->rowSet;
164
        unset($this->rowSet);
165
166
        return $rowSet;
167
    }
168
169
    /**
170
     * @param null|int $cursor
171
     *
172
     * @return bool
173
     */
174
    protected function storedValid($cursor = null)
175
    {
176
        $cursor = (!is_null($cursor) ? $cursor : $this->cursor);
177
178
        return $cursor >= 0 && $cursor < count($this->stored);
0 ignored issues
show
Bug introduced by
It seems like $this->stored can also be of type null; however, parameter $value of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

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

178
        return $cursor >= 0 && $cursor < count(/** @scrutinizer ignore-type */ $this->stored);
Loading history...
179
    }
180
181
    /**
182
     * @inheritdoc
183
     */
184
    public function getNext()
185
    {
186
        $this->cursor = $this->next_cursor;
187
188
        if ($this->stored !== null) {
189
            $resultSet = !$this->storedValid() ? false : $this->stored[$this->cursor];
190
        } else {
191
            if ($this->next_cursor > 0) {
192
                $this->adapter->getNext();
193
            }
194
195
            $resultSet = !$this->adapter->valid() ? false : $this->adapter->current();
196
        }
197
198
        $this->next_cursor++;
199
200
        return $resultSet;
201
    }
202
203
    /**
204
     * @inheritdoc
205
     */
206
    public function store()
207
    {
208
        if ($this->stored !== null) {
209
            return $this;
210
        }
211
212
        // don't let users mix storage and driver cursors
213
        if ($this->next_cursor > 0) {
214
            throw new DatabaseException('The MultiResultSet is using the driver cursors, store() can\'t fetch all the data');
215
        }
216
217
        $store = array();
218
        while ($set = $this->getNext()) {
219
            // this relies on stored being null!
220
            $store[] = $set->store();
221
        }
222
223
        $this->cursor = 0;
224
        $this->next_cursor = 0;
225
226
        // if we write the array straight to $this->stored it won't be null anymore and functions relying on null will break
227
        $this->stored = $store;
228
229
        return $this;
230
    }
231
}
232