Completed
Push — master ( 1f43e8...488daa )
by Hung
01:54
created

ResultSetBase::getCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
namespace Foolz\SphinxQL\Drivers;
3
4
use Foolz\SphinxQL\Exception\ResultSetException;
5
use \Foolz\SphinxQL\Drivers\Mysqli\ResultSetAdapter;
6
7
abstract class ResultSetBase implements ResultSetInterface
8
{
9
    /**
10
     * @var int
11
     */
12
    protected $num_rows = 0;
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 int
26
     */
27
    protected $affected_rows = 0; // leave to 0 so SELECT etc. will be coherent
28
29
    /**
30
     * @var array
31
     */
32
    protected $fields;
33
34
    /**
35
     * @var null|array
36
     */
37
    protected $stored;
38
39
    /**
40
     * @var null|array
41
     */
42
    protected $fetched;
43
44
    /**
45
     * @var null|\Foolz\SphinxQL\Drivers\ResultSetAdapterInterface
46
     */
47
    protected $adapter;
48
49
    /**
50
     * Checks that a row actually exists
51
     *
52
     * @param int $num The number of the row to check on
53
     * @return bool True if the row exists
54
     */
55
    public function hasRow($num)
56
    {
57
        return $num >= 0 && $num < $this->num_rows;
58
    }
59
60
    /**
61
     * Checks that a next row exists
62
     *
63
     * @return bool True if there's another row with a higher index
64
     */
65
    public function hasNextRow()
66
    {
67
        return $this->cursor + 1 < $this->num_rows;
68
    }
69
70
    /**
71
     * Returns the number of rows affected by the query
72
     * This will be 0 for SELECT and any query not editing rows
73
     *
74
     * @return int
75
     */
76
    public function getAffectedRows()
77
    {
78
        return $this->affected_rows;
79
    }
80
81
    /**
82
     * (PHP 5 &gt;= 5.0.0)<br/>
83
     * Whether a offset exists
84
     * @link http://php.net/manual/en/arrayaccess.offsetexists.php
85
     * @param mixed $offset <p>
86
     * An offset to check for.
87
     * </p>
88
     * @return boolean true on success or false on failure.
89
     * </p>
90
     * <p>
91
     * The return value will be casted to boolean if non-boolean was returned.
92
     */
93
    public function offsetExists($offset)
94
    {
95
        return $this->hasRow($offset);
96
    }
97
98
    /**
99
     * (PHP 5 &gt;= 5.0.0)<br/>
100
     * Offset to retrieve
101
     * @link http://php.net/manual/en/arrayaccess.offsetget.php
102
     * @param mixed $offset <p>
103
     * The offset to retrieve.
104
     * </p>
105
     * @return mixed Can return all value types.
106
     */
107
    public function offsetGet($offset)
108
    {
109
        return $this->toRow($offset)->fetchAssoc();
110
    }
111
112
    /**
113
     * (PHP 5 &gt;= 5.0.0)<br/>
114
     * Offset to set
115
     * @link http://php.net/manual/en/arrayaccess.offsetset.php
116
     * @param mixed $offset <p>
117
     * The offset to assign the value to.
118
     * </p>
119
     * @param mixed $value <p>
120
     * The value to set.
121
     * </p>
122
     * @return void
123
     *
124
     * @codeCoverageIgnore
125
     */
126
    public function offsetSet($offset, $value)
127
    {
128
        throw new \BadMethodCallException('Not implemented');
129
    }
130
131
    /**
132
     * (PHP 5 &gt;= 5.0.0)<br/>
133
     * Offset to unset
134
     * @link http://php.net/manual/en/arrayaccess.offsetunset.php
135
     * @param mixed $offset <p>
136
     * The offset to unset.
137
     * </p>
138
     * @return void
139
     *
140
     * @codeCoverageIgnore
141
     */
142
    public function offsetUnset($offset)
143
    {
144
        throw new \BadMethodCallException('Not implemented');
145
    }
146
147
    /**
148
     * (PHP 5 &gt;= 5.0.0)<br/>
149
     * Return the current element
150
     * @link http://php.net/manual/en/iterator.current.php
151
     * @return mixed Can return any type.
152
     */
153
    public function current()
154
    {
155
        $row = $this->fetched;
156
        unset($this->fetched);
157
        return $row;
158
    }
159
160
    /**
161
     * (PHP 5 &gt;= 5.0.0)<br/>
162
     * Move forward to next element
163
     * @link http://php.net/manual/en/iterator.next.php
164
     * @return void Any returned value is ignored.
165
     */
166
    public function next()
167
    {
168
        $this->fetched = $this->fetch(ResultSetAdapter::FETCH_ASSOC);
169
    }
170
171
    /**
172
     * (PHP 5 &gt;= 5.0.0)<br/>
173
     * Return the key of the current element
174
     * @link http://php.net/manual/en/iterator.key.php
175
     * @return mixed scalar on success, or null on failure.
176
     */
177
    public function key()
178
    {
179
        return (int)$this->cursor;
180
    }
181
182
    /**
183
     * (PHP 5 &gt;= 5.0.0)<br/>
184
     * Checks if current position is valid
185
     * @link http://php.net/manual/en/iterator.valid.php
186
     * @return boolean The return value will be casted to boolean and then evaluated.
187
     * Returns true on success or false on failure.
188
     */
189
    public function valid()
190
    {
191
        if ($this->stored !== null) {
192
            return $this->hasRow($this->cursor);
193
        }
194
195
        return $this->adapter->valid();
196
    }
197
198
    /**
199
     * (PHP 5 &gt;= 5.0.0)<br/>
200
     * Rewind the Iterator to the first element
201
     * @link http://php.net/manual/en/iterator.rewind.php
202
     * @return void Any returned value is ignored.
203
     */
204
    public function rewind()
205
    {
206
        if ($this->stored === null) {
207
            $this->adapter->rewind();
208
        }
209
210
        $this->next_cursor = 0;
211
212
        $this->fetched = $this->fetch(ResultSetAdapter::FETCH_ASSOC);
213
    }
214
215
    /**
216
     * Returns the number of rows in the result set
217
     * @inheritdoc
218
     */
219
    public function count()
220
    {
221
        return $this->num_rows;
222
    }
223
224
    protected function init()
225
    {
226
        if ($this->adapter->isDml()) {
227
            $this->affected_rows = $this->adapter->getAffectedRows();
228
        } else {
229
            $this->num_rows = $this->adapter->getNumRows();
230
            $this->fields = $this->adapter->getFields();
231
        }
232
    }
233
234
    /**
235
     * @param array $numeric_array
236
     * @return array
237
     */
238
    protected function makeAssoc($numeric_array)
239
    {
240
        $assoc_array = array();
241
        foreach ($numeric_array as $col_key => $col_value) {
242
            $assoc_array[$this->fields[$col_key]->name] = $col_value;
243
        }
244
245
        return $assoc_array;
246
    }
247
248
    /**
249
     * @param ResultSetAdapter::FETCH_ASSOC|ResultSetAdapter::FETCH_NUM $fetch_type
0 ignored issues
show
Documentation introduced by
The doc-type ResultSetAdapter::FETCH_...ltSetAdapter::FETCH_NUM could not be parsed: Unknown type name "ResultSetAdapter::FETCH_ASSOC" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
250
     * @return array|bool|null
251
     */
252
    protected function fetchFromStore($fetch_type)
253
    {
254
        if ($this->stored === null) {
255
            return false;
256
        }
257
258
        $row = isset($this->stored[$this->cursor]) ? $this->stored[$this->cursor] : null;
259
260
        if ($row !== null) {
261
            $row = $fetch_type == ResultSetAdapter::FETCH_ASSOC ? $this->makeAssoc($row) : $row;
262
        }
263
264
        return $row;
265
    }
266
267
    /**
268
     * @param ResultSetAdapter::FETCH_ASSOC|ResultSetAdapter::FETCH_NUM $fetch_type
0 ignored issues
show
Documentation introduced by
The doc-type ResultSetAdapter::FETCH_...ltSetAdapter::FETCH_NUM could not be parsed: Unknown type name "ResultSetAdapter::FETCH_ASSOC" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
269
     * @return array|bool
270
     */
271
    protected function fetchAllFromStore($fetch_type)
272
    {
273
        if ($this->stored === null) {
274
            return false;
275
        }
276
277
        $result_from_store = array();
278
279
        $this->cursor = $this->next_cursor;
280
        while ($row = $this->fetchFromStore($fetch_type)) {
281
            $result_from_store[] = $row;
282
            $this->cursor = ++$this->next_cursor;
283
        }
284
285
        return $result_from_store;
286
    }
287
288
    /**
289
     * @param ResultSetAdapter::FETCH_ASSOC|ResultSetAdapter::FETCH_NUM $fetch_type
0 ignored issues
show
Documentation introduced by
The doc-type ResultSetAdapter::FETCH_...ltSetAdapter::FETCH_NUM could not be parsed: Unknown type name "ResultSetAdapter::FETCH_ASSOC" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
290
     * @return array
291
     */
292
    protected function fetchAll($fetch_type)
293
    {
294
        $fetch_all_result = $this->fetchAllFromStore($fetch_type);
295
296
        if ($fetch_all_result === false) {
297
            $fetch_all_result = $this->adapter->fetchAll($fetch_type);
298
        }
299
300
        $this->cursor = $this->num_rows;
301
        $this->next_cursor = $this->cursor + 1;
302
303
        return $fetch_all_result;
304
    }
305
306
    /**
307
     * Store all the data in this object and free the driver object
308
     *
309
     * @return static $this
310
     */
311
    public function store()
312
    {
313
        if ($this->stored !== null) {
314
            return $this;
315
        }
316
317
        if ($this->adapter->isDml()) {
318
            $this->stored = $this->affected_rows;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->affected_rows of type integer is incompatible with the declared type null|array of property $stored.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
319
        } else {
320
            $this->stored = $this->adapter->store();
321
        }
322
323
        return $this;
324
    }
325
326
    /**
327
     * Returns the array as in version 0.9.x
328
     *
329
     * @return array|int|mixed
330
     * @deprecated Commodity method for simple transition to version 1.0.0
331
     */
332
    public function getStored()
333
    {
334
        $this->store();
335
        if ($this->adapter->isDml()) {
336
            return $this->getAffectedRows();
337
        }
338
339
        return $this->fetchAllAssoc();
340
    }
341
342
    /**
343
     * Moves the cursor to the selected row
344
     *
345
     * @param int $num The number of the row to move the cursor to
346
     * @return static
347
     * @throws ResultSetException If the row does not exist
348
     */
349
    public function toRow($num)
350
    {
351
        if (!$this->hasRow($num)) {
352
            throw new ResultSetException('The row does not exist.');
353
        }
354
355
        $this->cursor = $num;
356
        $this->next_cursor = $num;
357
358
        if ($this->stored === null) {
359
            $this->adapter->toRow($this->cursor);
360
        }
361
362
        return $this;
363
    }
364
365
    /**
366
     * Moves the cursor to the next row
367
     *
368
     * @return static $this
369
     * @throws ResultSetException If the next row does not exist
370
     */
371
    public function toNextRow()
372
    {
373
        $this->toRow(++$this->cursor);
374
        return $this;
375
    }
376
377
    /**
378
     * Fetches all the rows as an array of associative arrays
379
     *
380
     * @return array
381
     */
382
    public function fetchAllAssoc()
383
    {
384
        return $this->fetchAll(ResultSetAdapter::FETCH_ASSOC);
385
    }
386
387
    /**
388
     * Fetches all the rows as an array of indexed arrays
389
     *
390
     * @return array
391
     */
392
    public function fetchAllNum()
393
    {
394
        return $this->fetchAll(ResultSetAdapter::FETCH_NUM);
395
    }
396
397
    /**
398
     * Fetches a row as an associative array
399
     *
400
     * @return array
401
     */
402
    public function fetchAssoc()
403
    {
404
        return $this->fetch(ResultSetAdapter::FETCH_ASSOC);
405
    }
406
407
    /**
408
     * Fetches a row as an indexed array
409
     *
410
     * @return array|null
411
     */
412
    public function fetchNum()
413
    {
414
        return $this->fetch(ResultSetAdapter::FETCH_NUM);
415
    }
416
417
    /**
418
     * @param ResultSetAdapter::FETCH_ASSOC|ResultSetAdapter::FETCH_NUM $fetch_type
0 ignored issues
show
Documentation introduced by
The doc-type ResultSetAdapter::FETCH_...ltSetAdapter::FETCH_NUM could not be parsed: Unknown type name "ResultSetAdapter::FETCH_ASSOC" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
419
     * @return array|null
420
     */
421
    protected function fetch($fetch_type)
422
    {
423
        $this->cursor = $this->next_cursor;
424
425
        $row = $this->fetchFromStore($fetch_type);
426
427
        if ($row === false) {
428
            $row = $this->adapter->fetch($fetch_type);
429
        }
430
431
        $this->next_cursor++;
432
433
        return $row;
434
    }
435
436
    /**
437
     * Frees the memory from the result
438
     * Call it after you're done with a result set
439
     *
440
     * @return static
441
     */
442
    public function freeResult()
443
    {
444
        $this->adapter->freeResult();
445
        return $this;
446
    }
447
}
448