Completed
Pull Request — master (#20)
by
unknown
05:09 queued 26s
created

MongoCursor::reset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 4
rs 10
nc 1
cc 1
eloc 2
nop 0
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 */
15
16
use Alcaeus\MongoDbAdapter\AbstractCursor;
17
use Alcaeus\MongoDbAdapter\TypeConverter;
18
use Alcaeus\MongoDbAdapter\ExceptionConverter;
19
use MongoDB\Driver\Cursor;
20
use MongoDB\Driver\ReadPreference;
21
use MongoDB\Operation\Find;
22
23
/**
24
 * Result object for database query.
25
 * @link http://www.php.net/manual/en/class.mongocursor.php
26
 */
27
class MongoCursor extends AbstractCursor implements Iterator
1 ignored issue
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
28
{
29
    /**
30
     * @var bool
31
     */
32
    public static $slaveOkay = false;
33
34
    /**
35
     * @var int
36
     */
37
    public static $timeout = 30000;
38
39
    /**
40
     * @var array
41
     */
42
    protected $optionNames = [
43
        'allowPartialResults',
44
        'batchSize',
45
        'cursorType',
46
        'limit',
47
        'maxTimeMS',
48
        'modifiers',
49
        'noCursorTimeout',
50
        'projection',
51
        'readPreference',
52
        'skip',
53
        'sort',
54
    ];
55
56
    /**
57
     * @var array
58
     */
59
    protected $projection;
60
61
    /**
62
     * @var array
63
     */
64
    protected $query;
65
66
    protected $allowPartialResults;
67
    protected $awaitData;
68
    protected $flags = 0;
69
    protected $hint;
70
    protected $limit;
71
    protected $maxTimeMS;
72
    protected $noCursorTimeout;
73
    protected $options = [];
74
    protected $skip;
75
    protected $snapshot;
76
    protected $sort;
77
    protected $tailable;
78
79
    /**
80
     * Create a new cursor
81
     * @link http://www.php.net/manual/en/mongocursor.construct.php
82
     * @param MongoClient $connection Database connection.
83
     * @param string $ns Full name of database and collection.
84
     * @param array $query Database query.
85
     * @param array $fields Fields to return.
86
     */
87
    public function __construct(MongoClient $connection, $ns, array $query = array(), array $fields = array())
88
    {
89
        parent::__construct($connection, $ns);
90
91
        $this->query = $query;
92
        $this->projection = $fields;
93
    }
94
95
    /**
96
     * Adds a top-level key/value pair to a query
97
     * @link http://www.php.net/manual/en/mongocursor.addoption.php
98
     * @param string $key Fieldname to add.
99
     * @param mixed $value Value to add.
100
     * @throws MongoCursorException
101
     * @return MongoCursor Returns this cursor
102
     */
103
    public function addOption($key, $value)
104
    {
105
        $this->errorIfOpened();
106
        $this->options[$key] = $value;
107
108
        return $this;
109
    }
110
111
    /**
112
     * (PECL mongo &gt;= 1.2.11)<br/>
113
     * Sets whether this cursor will wait for a while for a tailable cursor to return more data
114
     * @param bool $wait [optional] <p>If the cursor should wait for more data to become available.</p>
115
     * @return MongoCursor Returns this cursor.
116
     */
117
    public function awaitData($wait = true)
118
    {
119
        $this->errorIfOpened();
120
        $this->awaitData = $wait;
121
122
        return $this;
123
    }
124
125
126
    /**
127
     * Counts the number of results for this query
128
     * @link http://www.php.net/manual/en/mongocursor.count.php
129
     * @param bool $foundOnly Send cursor limit and skip information to the count function, if applicable.
130
     * @return int The number of documents returned by this cursor's query.
131
     */
132
    public function count($foundOnly = false)
133
    {
134
        if ($foundOnly && $this->cursor !== null) {
135
            return iterator_count($this->ensureIterator());
136
        }
137
138
        $optionNames = ['hint', 'maxTimeMS'];
139
        if ($foundOnly) {
140
            $optionNames = array_merge($optionNames, ['limit', 'skip']);
141
        }
142
143
        $options = $this->getOptions($optionNames) + $this->options;
144
        try {
145
            $count = $this->collection->count(TypeConverter::fromLegacy($this->query), $options);
146
        } catch (\MongoDB\Driver\Exception\ExecutionTimeoutException $e) {
1 ignored issue
show
Bug introduced by
The class MongoDB\Driver\Exception\ExecutionTimeoutException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
147
            throw new MongoCursorTimeoutException($e->getMessage(), $e->getCode(), $e);
148
        } catch (\MongoDB\Driver\Exception\Exception $e) {
1 ignored issue
show
Bug introduced by
The class MongoDB\Driver\Exception\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
149
            ExceptionConverter::toLegacy($e);
150
        }
151
152
        return $count;
153
    }
154
155
    /**
156
     * Execute the query
157
     * @link http://www.php.net/manual/en/mongocursor.doquery.php
158
     * @throws MongoConnectionException if it cannot reach the database.
159
     * @return void
160
     */
161
    protected function doQuery()
162
    {
163
        $options = $this->getOptions() + $this->options;
164
165
        try {
166
            $this->cursor = $this->collection->find(TypeConverter::fromLegacy($this->query), $options);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->collection->find(...this->query), $options) of type object<MongoDB\Operation\Cursor> is incompatible with the declared type object<MongoDB\Driver\Cursor> of property $cursor.

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...
167
        } catch (\MongoDB\Driver\Exception\ExecutionTimeoutException $e) {
1 ignored issue
show
Bug introduced by
The class MongoDB\Driver\Exception\ExecutionTimeoutException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
168
            throw new MongoCursorTimeoutException($e->getMessage(), $e->getCode(), $e);
169
        } catch (\MongoDB\Driver\Exception\Exception $e) {
1 ignored issue
show
Bug introduced by
The class MongoDB\Driver\Exception\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
170
            ExceptionConverter::toLegacy($e);
171
        }
172
    }
173
174
    /**
175
     * Return an explanation of the query, often useful for optimization and debugging
176
     * @link http://www.php.net/manual/en/mongocursor.explain.php
177
     * @return array Returns an explanation of the query.
178
     */
179
    public function explain()
180
    {
181
        $this->notImplemented();
182
    }
183
184
    /**
185
     * Sets the fields for a query
186
     * @link http://www.php.net/manual/en/mongocursor.fields.php
187
     * @param array $f Fields to return (or not return).
188
     * @throws MongoCursorException
189
     * @return MongoCursor
190
     */
191
    public function fields(array $f)
192
    {
193
        $this->errorIfOpened();
194
        $this->projection = $f;
195
196
        return $this;
197
    }
198
199
    /**
200
     * Return the next object to which this cursor points, and advance the cursor
201
     * @link http://www.php.net/manual/en/mongocursor.getnext.php
202
     * @throws MongoConnectionException
203
     * @throws MongoCursorTimeoutException
204
     * @return array Returns the next object
205
     */
206
    public function getNext()
207
    {
208
        $this->next();
209
210
        return $this->current();
211
    }
212
213
    /**
214
     * Checks if there are any more elements in this cursor
215
     * @link http://www.php.net/manual/en/mongocursor.hasnext.php
216
     * @throws MongoConnectionException
217
     * @throws MongoCursorTimeoutException
218
     * @return bool Returns true if there is another element
219
     */
220
    public function hasNext()
221
    {
222
        $this->errorIfOpened();
223
        $this->notImplemented();
224
    }
225
226
    /**
227
     * Gives the database a hint about the query
228
     * @link http://www.php.net/manual/en/mongocursor.hint.php
229
     * @param array|string $keyPattern Indexes to use for the query.
230
     * @throws MongoCursorException
231
     * @return MongoCursor Returns this cursor
232
     */
233
    public function hint($keyPattern)
234
    {
235
        $this->errorIfOpened();
236
        $this->hint = $keyPattern;
237
238
        return $this;
239
    }
240
241
    /**
242
     * Sets whether this cursor will timeout
243
     * @link http://www.php.net/manual/en/mongocursor.immortal.php
244
     * @param bool $liveForever If the cursor should be immortal.
245
     * @throws MongoCursorException
246
     * @return MongoCursor Returns this cursor
247
     */
248
    public function immortal($liveForever = true)
249
    {
250
        $this->errorIfOpened();
251
        $this->noCursorTimeout = $liveForever;
252
253
        return $this;
254
    }
255
256
    /**
257
     * Limits the number of results returned
258
     * @link http://www.php.net/manual/en/mongocursor.limit.php
259
     * @param int $num The number of results to return.
260
     * @throws MongoCursorException
261
     * @return MongoCursor Returns this cursor
262
     */
263
    public function limit($num)
264
    {
265
        $this->errorIfOpened();
266
        $this->limit = $num;
267
268
        return $this;
269
    }
270
271
    /**
272
     * @param int $ms
273
     * @return $this
274
     * @throws MongoCursorException
275
     */
276
    public function maxTimeMS($ms)
277
    {
278
        $this->errorIfOpened();
279
        $this->maxTimeMS = $ms;
280
281
        return $this;
282
    }
283
284
    /**
285
     * @link http://www.php.net/manual/en/mongocursor.partial.php
286
     * @param bool $okay [optional] <p>If receiving partial results is okay.</p>
287
     * @return MongoCursor Returns this cursor.
288
     */
289
    public function partial($okay = true)
290
    {
291
        $this->allowPartialResults = $okay;
292
293
        return $this;
294
    }
295
296
    /**
297
     * Clears the cursor
298
     * @link http://www.php.net/manual/en/mongocursor.reset.php
299
     * @return void
300
     */
301
    public function reset()
302
    {
303
        parent::reset();
304
    }
305
306
    /**
307
     * @link http://www.php.net/manual/en/mongocursor.setflag.php
308
     * @param int $flag
309
     * @param bool $set
310
     * @return MongoCursor
311
     */
312
    public function setFlag($flag, $set = true)
0 ignored issues
show
Unused Code introduced by
The parameter $flag is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $set is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
313
    {
314
        $this->notImplemented();
315
    }
316
317
    /**
318
     * Skips a number of results
319
     * @link http://www.php.net/manual/en/mongocursor.skip.php
320
     * @param int $num The number of results to skip.
321
     * @throws MongoCursorException
322
     * @return MongoCursor Returns this cursor
323
     */
324
    public function skip($num)
325
    {
326
        $this->errorIfOpened();
327
        $this->skip = $num;
328
329
        return $this;
330
    }
331
332
    /**
333
     * Sets whether this query can be done on a slave
334
     * This method will override the static class variable slaveOkay.
335
     * @link http://www.php.net/manual/en/mongocursor.slaveOkay.php
336
     * @param boolean $okay If it is okay to query the slave.
337
     * @throws MongoCursorException
338
     * @return MongoCursor Returns this cursor
339
     */
340
    public function slaveOkay($okay = true)
341
    {
342
        $this->errorIfOpened();
343
344
        $this->setReadPreferenceFromSlaveOkay($okay);
345
346
        return $this;
347
    }
348
349
    /**
350
     * Use snapshot mode for the query
351
     * @link http://www.php.net/manual/en/mongocursor.snapshot.php
352
     * @throws MongoCursorException
353
     * @return MongoCursor Returns this cursor
354
     */
355
    public function snapshot()
356
    {
357
        $this->errorIfOpened();
358
        $this->snapshot = true;
359
360
        return $this;
361
    }
362
363
    /**
364
     * Sorts the results by given fields
365
     * @link http://www.php.net/manual/en/mongocursor.sort.php
366
     * @param array $fields An array of fields by which to sort. Each element in the array has as key the field name, and as value either 1 for ascending sort, or -1 for descending sort
367
     * @throws MongoCursorException
368
     * @return MongoCursor Returns the same cursor that this method was called on
369
     */
370
    public function sort(array $fields)
371
    {
372
        $this->errorIfOpened();
373
        $this->sort = $fields;
374
375
        return $this;
376
    }
377
378
    /**
379
     * Sets whether this cursor will be left open after fetching the last results
380
     * @link http://www.php.net/manual/en/mongocursor.tailable.php
381
     * @param bool $tail If the cursor should be tailable.
382
     * @return MongoCursor Returns this cursor
383
     */
384
    public function tailable($tail = true)
385
    {
386
        $this->errorIfOpened();
387
        $this->tailable = $tail;
388
389
        return $this;
390
    }
391
392
    /**
393
     * @return int|null
394
     */
395
    protected function convertCursorType()
396
    {
397
        if (! $this->tailable) {
398
            return null;
399
        }
400
401
        return $this->awaitData ? Find::TAILABLE_AWAIT : Find::TAILABLE;
402
    }
403
404
    protected function convertModifiers()
405
    {
406
        $modifiers = array_key_exists('modifiers', $this->options) ? $this->options['modifiers'] : [];
407
408
        foreach (['hint', 'snapshot'] as $modifier) {
409
            if ($this->$modifier === null) {
410
                continue;
411
            }
412
413
            $modifiers['$' . $modifier] = $this->$modifier;
414
        }
415
416
        return $modifiers;
417
    }
418
419
    /**
420
     * @return Cursor
421
     */
422
    protected function ensureCursor()
423
    {
424
        if ($this->cursor === null) {
425
            $this->doQuery();
426
        }
427
428
        return $this->cursor;
429
    }
430
431
    /**
432
     * @return array
433
     */
434
    protected function getCursorInfo()
435
    {
436
        return [
437
            'ns' => $this->ns,
438
            'limit' => $this->limit,
439
            'batchSize' => $this->batchSize,
440
            'skip' => $this->skip,
441
            'flags' => $this->flags,
442
            'query' => $this->query,
443
            'fields' => $this->projection,
444
        ];
445
    }
446
}
447