Completed
Push — master ( d6fc27...dc9f7f )
by Hung
19s
created

MultiResultSetBase::getNext()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 10
nc 6
nop 0
1
<?php
2
namespace Foolz\SphinxQL\Drivers;
3
4
use Foolz\SphinxQL\Exception\DatabaseException;
5
6
abstract class MultiResultSetBase implements MultiResultSetInterface
7
{
8
    /**
9
     * @var null|array
10
     */
11
    public $stored = null;
12
13
    /**
14
     * @var int
15
     */
16
    public $cursor = 0;
17
18
    /**
19
     * @var int
20
     */
21
    protected $next_cursor = 0;
22
23
    /**
24
     * @var \Foolz\SphinxQL\Drivers\ResultSetInterface|null
25
     */
26
    protected $rowSet = null;
27
28
    /**
29
     * @var \Foolz\SphinxQL\Drivers\MultiResultSetAdapterInterface|null
30
     */
31
    protected $adapter = null;
32
33
    /**
34
     * @var bool
35
     */
36
    protected $valid = true;
37
38
    public function getStored()
39
    {
40
        $this->store();
41
        return $this->stored;
42
    }
43
44
    /**
45
     * (PHP 5 &gt;= 5.0.0)<br/>
46
     * Whether a offset exists
47
     * @link http://php.net/manual/en/arrayaccess.offsetexists.php
48
     * @param mixed $offset <p>
49
     * An offset to check for.
50
     * </p>
51
     * @return boolean true on success or false on failure.
52
     * </p>
53
     * <p>
54
     * The return value will be casted to boolean if non-boolean was returned.
55
     */
56
    public function offsetExists($offset)
57
    {
58
        $this->store();
59
        return $this->storedValid($offset);
60
    }
61
62
    /**
63
     * (PHP 5 &gt;= 5.0.0)<br/>
64
     * Offset to retrieve
65
     * @link http://php.net/manual/en/arrayaccess.offsetget.php
66
     * @param mixed $offset <p>
67
     * The offset to retrieve.
68
     * </p>
69
     * @return mixed Can return all value types.
70
     */
71
    public function offsetGet($offset)
72
    {
73
        $this->store();
74
        return $this->stored[$offset];
75
    }
76
77
    /**
78
     * (PHP 5 &gt;= 5.0.0)<br/>
79
     * Offset to set
80
     * @link http://php.net/manual/en/arrayaccess.offsetset.php
81
     * @param mixed $offset <p>
82
     * The offset to assign the value to.
83
     * </p>
84
     * @param mixed $value <p>
85
     * The value to set.
86
     * </p>
87
     * @return void
88
     *
89
     * @codeCoverageIgnore
90
     */
91
    public function offsetSet($offset, $value)
92
    {
93
        throw new \BadMethodCallException('Not implemented');
94
    }
95
96
    /**
97
     * (PHP 5 &gt;= 5.0.0)<br/>
98
     * Offset to unset
99
     * @link http://php.net/manual/en/arrayaccess.offsetunset.php
100
     * @param mixed $offset <p>
101
     * The offset to unset.
102
     * </p>
103
     * @return void
104
     *
105
     * @codeCoverageIgnore
106
     */
107
    public function offsetUnset($offset)
108
    {
109
        throw new \BadMethodCallException('Not implemented');
110
    }
111
112
    /**
113
     * (PHP 5 &gt;= 5.0.0)<br/>
114
     * Move forward to next element
115
     * @link http://php.net/manual/en/iterator.next.php
116
     * @return void Any returned value is ignored.
117
     */
118
    public function next()
119
    {
120
        $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 object<Foolz\SphinxQL\Dr...esultSetInterface>|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...
121
    }
122
123
    /**
124
     * (PHP 5 &gt;= 5.0.0)<br/>
125
     * Return the key of the current element
126
     * @link http://php.net/manual/en/iterator.key.php
127
     * @return mixed scalar on success, or null on failure.
128
     */
129
    public function key()
130
    {
131
        return (int)$this->cursor;
132
    }
133
134
    /**
135
     * (PHP 5 &gt;= 5.0.0)<br/>
136
     * Rewind the Iterator to the first element
137
     * @link http://php.net/manual/en/iterator.rewind.php
138
     * @return void Any returned value is ignored.
139
     */
140
    public function rewind()
141
    {
142
        // we actually can't roll this back unless it was stored first
143
        $this->cursor = 0;
144
        $this->next_cursor = 0;
145
        $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 object<Foolz\SphinxQL\Dr...esultSetInterface>|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...
146
    }
147
148
    /**
149
     * (PHP 5 &gt;= 5.1.0)<br/>
150
     * Count elements of an object
151
     * @link http://php.net/manual/en/countable.count.php
152
     * @return int The custom count as an integer.
153
     * </p>
154
     * <p>
155
     * The return value is cast to an integer.
156
     */
157
    public function count()
158
    {
159
        $this->store();
160
        return count($this->stored);
161
    }
162
163
    /**
164
     * (PHP 5 &gt;= 5.0.0)<br/>
165
     * Checks if current position is valid
166
     * @link http://php.net/manual/en/iterator.valid.php
167
     * @return boolean The return value will be casted to boolean and then evaluated.
168
     * Returns true on success or false on failure.
169
     */
170
    public function valid()
171
    {
172
        if ($this->stored !== null) {
173
            return $this->storedValid();
174
        }
175
176
        return $this->adapter->valid();
177
    }
178
179
    /**
180
     * (PHP 5 &gt;= 5.0.0)<br/>
181
     * Return the current element
182
     * @link http://php.net/manual/en/iterator.current.php
183
     * @return mixed Can return any type.
184
     */
185
    public function current()
186
    {
187
        $rowSet = $this->rowSet;
188
        unset($this->rowSet);
189
        return $rowSet;
190
    }
191
192
    /**
193
     * @param null|int $cursor
194
     * @return bool
195
     */
196
    protected function storedValid($cursor = null)
197
    {
198
        $cursor = (!is_null($cursor) ? $cursor : $this->cursor);
199
        return $cursor >= 0 && $cursor < count($this->stored);
200
    }
201
202
    /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
203
     * @return \Foolz\SphinxQL\Drivers\ResultSetInterface|false
204
     */
205
    public function getNext()
206
    {
207
        $this->cursor = $this->next_cursor;
208
209
        if ($this->stored !== null) {
210
            $resultSet = !$this->storedValid() ? false : $this->stored[$this->cursor];
211
        } else {
212
            if ($this->next_cursor > 0) {
213
                $this->adapter->getNext();
214
            }
215
216
            $resultSet = !$this->adapter->valid() ? false : $this->adapter->current();
217
        }
218
219
        $this->next_cursor++;
220
221
        return $resultSet;
222
    }
223
224
    /**
225
     * @return $this
226
     * @throws DatabaseException
227
     */
228
    public function store()
229
    {
230
        if ($this->stored !== null) {
231
            return $this;
232
        }
233
234
        // don't let users mix storage and driver cursors
235
        if ($this->next_cursor > 0) {
236
            throw new DatabaseException('The MultiResultSet is using the driver cursors, store() can\'t fetch all the data');
237
        }
238
239
        $store = array();
240
        while ($set = $this->getNext()) {
241
            // this relies on stored being null!
242
            $store[] = $set->store();
243
        }
244
245
        $this->cursor = 0;
246
        $this->next_cursor = 0;
247
248
        // if we write the array straight to $this->stored it won't be null anymore and functions relying on null will break
249
        $this->stored = $store;
250
251
        return $this;
252
    }
253
}
254