Completed
Pull Request — master (#12)
by
unknown
02:39
created

MongoCursor::getCursorInfo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 12
rs 9.4286
nc 1
cc 1
eloc 9
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 MongoDB\Driver\Cursor;
18
use MongoDB\Driver\ReadPreference;
19
use MongoDB\Operation\Find;
20
21
/**
22
 * Result object for database query.
23
 * @link http://www.php.net/manual/en/class.mongocursor.php
24
 */
25
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...
26
{
27
    /**
28
     * @var bool
29
     */
30
    public static $slaveOkay = false;
31
32
    /**
33
     * @var int
34
     */
35
    public static $timeout = 30000;
36
37
    /**
38
     * @var array
39
     */
40
    protected $optionNames = [
41
        'allowPartialResults',
42
        'batchSize',
43
        'cursorType',
44
        'limit',
45
        'maxTimeMS',
46
        'modifiers',
47
        'noCursorTimeout',
48
        'projection',
49
        'readPreference',
50
        'skip',
51
        'sort',
52
    ];
53
54
    /**
55
     * @var array
56
     */
57
    protected $projection;
58
59
    /**
60
     * @var array
61
     */
62
    protected $query;
63
64
    protected $allowPartialResults;
65
    protected $awaitData;
66
    protected $flags = 0;
67
    protected $hint;
68
    protected $limit;
69
    protected $maxTimeMS;
70
    protected $noCursorTimeout;
71
    protected $options = [];
72
    protected $skip;
73
    protected $snapshot;
74
    protected $sort;
75
    protected $tailable;
76
77
    /**
78
     * Create a new cursor
79
     * @link http://www.php.net/manual/en/mongocursor.construct.php
80
     * @param MongoClient $connection Database connection.
81
     * @param string $ns Full name of database and collection.
82
     * @param array $query Database query.
83
     * @param array $fields Fields to return.
84
     */
85
    public function __construct(MongoClient $connection, $ns, array $query = array(), array $fields = array())
86
    {
87
        parent::__construct($connection, $ns);
88
89
        $this->query = $query;
90
        $this->projection = $fields;
91
    }
92
93
    /**
94
     * Adds a top-level key/value pair to a query
95
     * @link http://www.php.net/manual/en/mongocursor.addoption.php
96
     * @param string $key Fieldname to add.
97
     * @param mixed $value Value to add.
98
     * @throws MongoCursorException
99
     * @return MongoCursor Returns this cursor
100
     */
101
    public function addOption($key, $value)
102
    {
103
        $this->errorIfOpened();
104
        $this->options[$key] = $value;
105
106
        return $this;
107
    }
108
109
    /**
110
     * (PECL mongo &gt;= 1.2.11)<br/>
111
     * Sets whether this cursor will wait for a while for a tailable cursor to return more data
112
     * @param bool $wait [optional] <p>If the cursor should wait for more data to become available.</p>
113
     * @return MongoCursor Returns this cursor.
114
     */
115
    public function awaitData($wait = true)
116
    {
117
        $this->errorIfOpened();
118
        $this->awaitData = $wait;
119
120
        return $this;
121
    }
122
123
124
    /**
125
     * Counts the number of results for this query
126
     * @link http://www.php.net/manual/en/mongocursor.count.php
127
     * @param bool $foundOnly Send cursor limit and skip information to the count function, if applicable.
128
     * @return int The number of documents returned by this cursor's query.
129
     */
130
    public function count($foundOnly = false)
131
    {
132
        if ($foundOnly && $this->cursor !== null) {
133
            return iterator_count($this->ensureIterator());
134
        }
135
136
        $optionNames = ['hint', 'maxTimeMS'];
137
        if ($foundOnly) {
138
            $optionNames = array_merge($optionNames, ['limit', 'skip']);
139
        }
140
141
        $options = $this->getOptions($optionNames) + $this->options;
142
143
        $count = $this->collection->count($this->query, $options);
144
        return $count;
145
    }
146
147
    /**
148
     * Execute the query
149
     * @link http://www.php.net/manual/en/mongocursor.doquery.php
150
     * @throws MongoConnectionException if it cannot reach the database.
151
     * @return void
152
     */
153
    protected function doQuery()
154
    {
155
        $options = $this->getOptions() + $this->options;
156
157
        $this->cursor = $this->collection->find($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...
158
    }
159
160
    /**
161
     * Return an explanation of the query, often useful for optimization and debugging
162
     * @link http://www.php.net/manual/en/mongocursor.explain.php
163
     * @return array Returns an explanation of the query.
164
     */
165
    public function explain()
166
    {
167
        $this->notImplemented();
168
    }
169
170
    /**
171
     * Sets the fields for a query
172
     * @link http://www.php.net/manual/en/mongocursor.fields.php
173
     * @param array $f Fields to return (or not return).
174
     * @throws MongoCursorException
175
     * @return MongoCursor
176
     */
177
    public function fields(array $f)
178
    {
179
        $this->errorIfOpened();
180
        $this->projection = $f;
181
182
        return $this;
183
    }
184
185
    /**
186
     * Return the next object to which this cursor points, and advance the cursor
187
     * @link http://www.php.net/manual/en/mongocursor.getnext.php
188
     * @throws MongoConnectionException
189
     * @throws MongoCursorTimeoutException
190
     * @return array Returns the next object
191
     */
192
    public function getNext()
193
    {
194
        $this->next();
195
196
        return $this->current();
197
    }
198
199
    /**
200
     * Checks if there are any more elements in this cursor
201
     * @link http://www.php.net/manual/en/mongocursor.hasnext.php
202
     * @throws MongoConnectionException
203
     * @throws MongoCursorTimeoutException
204
     * @return bool Returns true if there is another element
205
     */
206
    public function hasNext()
207
    {
208
        $this->errorIfOpened();
209
        $this->notImplemented();
210
    }
211
212
    /**
213
     * Gives the database a hint about the query
214
     * @link http://www.php.net/manual/en/mongocursor.hint.php
215
     * @param array|string $keyPattern Indexes to use for the query.
216
     * @throws MongoCursorException
217
     * @return MongoCursor Returns this cursor
218
     */
219
    public function hint($keyPattern)
220
    {
221
        $this->errorIfOpened();
222
        $this->hint = $keyPattern;
223
224
        return $this;
225
    }
226
227
    /**
228
     * Sets whether this cursor will timeout
229
     * @link http://www.php.net/manual/en/mongocursor.immortal.php
230
     * @param bool $liveForever If the cursor should be immortal.
231
     * @throws MongoCursorException
232
     * @return MongoCursor Returns this cursor
233
     */
234
    public function immortal($liveForever = true)
235
    {
236
        $this->errorIfOpened();
237
        $this->noCursorTimeout = $liveForever;
238
239
        return $this;
240
    }
241
242
    /**
243
     * Limits the number of results returned
244
     * @link http://www.php.net/manual/en/mongocursor.limit.php
245
     * @param int $num The number of results to return.
246
     * @throws MongoCursorException
247
     * @return MongoCursor Returns this cursor
248
     */
249
    public function limit($num)
250
    {
251
        $this->errorIfOpened();
252
        $this->limit = $num;
253
254
        return $this;
255
    }
256
257
    /**
258
     * @param int $ms
259
     * @return $this
260
     * @throws MongoCursorException
261
     */
262
    public function maxTimeMS($ms)
263
    {
264
        $this->errorIfOpened();
265
        $this->maxTimeMS = $ms;
266
267
        return $this;
268
    }
269
270
    /**
271
     * @link http://www.php.net/manual/en/mongocursor.partial.php
272
     * @param bool $okay [optional] <p>If receiving partial results is okay.</p>
273
     * @return MongoCursor Returns this cursor.
274
     */
275
    public function partial($okay = true)
276
    {
277
        $this->allowPartialResults = $okay;
278
279
        return $this;
280
    }
281
282
    /**
283
     * Clears the cursor
284
     * @link http://www.php.net/manual/en/mongocursor.reset.php
285
     * @return void
286
     */
287
    public function reset()
288
    {
289
        parent::reset();
290
    }
291
292
    /**
293
     * @link http://www.php.net/manual/en/mongocursor.setflag.php
294
     * @param int $flag
295
     * @param bool $set
296
     * @return MongoCursor
297
     */
298
    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...
299
    {
300
        $this->notImplemented();
301
    }
302
303
    /**
304
     * Skips a number of results
305
     * @link http://www.php.net/manual/en/mongocursor.skip.php
306
     * @param int $num The number of results to skip.
307
     * @throws MongoCursorException
308
     * @return MongoCursor Returns this cursor
309
     */
310
    public function skip($num)
311
    {
312
        $this->errorIfOpened();
313
        $this->skip = $num;
314
315
        return $this;
316
    }
317
318
    /**
319
     * Sets whether this query can be done on a slave
320
     * This method will override the static class variable slaveOkay.
321
     * @link http://www.php.net/manual/en/mongocursor.slaveOkay.php
322
     * @param boolean $okay If it is okay to query the slave.
323
     * @throws MongoCursorException
324
     * @return MongoCursor Returns this cursor
325
     */
326
    public function slaveOkay($okay = true)
327
    {
328
        $this->errorIfOpened();
329
        static::$slaveOkay = $okay;
330
331
        $readPreferenceArray = $this->getReadPreference();
332
        $readPreferenceArray['type'] = $okay ? \MongoClient::RP_SECONDARY_PREFERRED : \MongoClient::RP_PRIMARY;
333
334
        $this->setReadPreferenceFromArray($readPreferenceArray);
335
    }
336
337
    /**
338
     * Use snapshot mode for the query
339
     * @link http://www.php.net/manual/en/mongocursor.snapshot.php
340
     * @throws MongoCursorException
341
     * @return MongoCursor Returns this cursor
342
     */
343
    public function snapshot()
344
    {
345
        $this->errorIfOpened();
346
        $this->snapshot = true;
347
348
        return $this;
349
    }
350
351
    /**
352
     * Sorts the results by given fields
353
     * @link http://www.php.net/manual/en/mongocursor.sort.php
354
     * @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
355
     * @throws MongoCursorException
356
     * @return MongoCursor Returns the same cursor that this method was called on
357
     */
358
    public function sort(array $fields)
359
    {
360
        $this->errorIfOpened();
361
        $this->sort = $fields;
362
363
        return $this;
364
    }
365
366
    /**
367
     * Sets whether this cursor will be left open after fetching the last results
368
     * @link http://www.php.net/manual/en/mongocursor.tailable.php
369
     * @param bool $tail If the cursor should be tailable.
370
     * @return MongoCursor Returns this cursor
371
     */
372
    public function tailable($tail = true)
373
    {
374
        $this->errorIfOpened();
375
        $this->tailable = $tail;
376
377
        return $this;
378
    }
379
380
    /**
381
     * @return int|null
382
     */
383
    protected function convertCursorType()
384
    {
385
        if (! $this->tailable) {
386
            return null;
387
        }
388
389
        return $this->awaitData ? Find::TAILABLE_AWAIT : Find::TAILABLE;
390
    }
391
392
    protected function convertModifiers()
393
    {
394
        $modifiers = array_key_exists('modifiers', $this->options) ? $this->options['modifiers'] : [];
395
396
        foreach (['hint', 'snapshot'] as $modifier) {
397
            if ($this->$modifier === null) {
398
                continue;
399
            }
400
401
            $modifiers['$' . $modifier] = $this->$modifier;
402
        }
403
404
        return $modifiers;
405
    }
406
407
    /**
408
     * @return Cursor
409
     */
410
    protected function ensureCursor()
411
    {
412
        if ($this->cursor === null) {
413
            $this->doQuery();
414
        }
415
416
        return $this->cursor;
417
    }
418
419
    /**
420
     * @return array
421
     */
422
    protected function getCursorInfo()
423
    {
424
        return [
425
            'ns' => $this->ns,
426
            'limit' => $this->limit,
427
            'batchSize' => $this->batchSize,
428
            'skip' => $this->skip,
429
            'flags' => $this->flags,
430
            'query' => $this->query,
431
            'fields' => $this->projection,
432
        ];
433
    }
434
}
435