GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Database::getReadPreference()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/**
4
 * This file is part of the PHPMongo package.
5
 *
6
 * (c) Dmytro Sokil <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sokil\Mongo;
13
14
use Sokil\Mongo\Collection\Definition;
15
16
class Database
17
{
18
    /**
19
     *
20
     * @var \Sokil\Mongo\Client
21
     */
22
    private $client;
23
24
    /**
25
     * @var \MongoDB
26
     */
27
    private $database;
28
29
    /**
30
     * @var string
31
     */
32
    private $databaseName;
33
34
    /**
35
     * @var array map collection name to class
36
     */
37
    private $mapping = array();
38
39
    /**
40
     * @var array map regexp pattern of collection name to class
41
     */
42
    private $regexpMapping = array();
43
44
    /**
45
     * @var array pool of initialised collections
46
     */
47
    private $collectionPool = array();
48
49
    /**
50
     *
51
     * @var bool is collection pool enabled
52
     */
53
    private $collectionPoolEnabled = true;
54
55
    /**
56
     * @param Client $client
57
     * @param \MongoDB|string $database
58
     */
59
    public function __construct(Client $client, $database)
60
    {
61
        $this->client = $client;
62
63
        if ($database instanceof \MongoDB) {
64
            $this->database = $database;
65
            $this->databaseName = $database->__toString();
66
        } else {
67
            $this->databaseName = $database;
68
        }
69
    }
70
71
    /**
72
     *
73
     * @param string $username
74
     * @param string $password
75
     */
76
    public function authenticate($username, $password)
77
    {
78
        $this->getMongoDB()->authenticate($username, $password);
79
    }
80
81
    public function logout()
82
    {
83
        $this->executeCommand(array(
84
            'logout' => 1,
85
        ));
86
    }
87
88
    public function __get($name)
89
    {
90
        return $this->getCollection($name);
91
    }
92
93
    /**
94
     * @return string get name of database
95
     */
96
    public function getName()
97
    {
98
        return $this->databaseName;
99
    }
100
101
    /**
102
     *
103
     * @return \MongoDB
104
     */
105
    public function getMongoDB()
106
    {
107
        if (empty($this->database)) {
108
            $this->database = $this
109
                ->client
110
                ->getMongoClient()
111
                ->selectDB($this->databaseName);
112
        }
113
114
        return $this->database;
115
    }
116
117
    /**
118
     *
119
     * @return \Sokil\Mongo\Client
120
     */
121
    public function getClient()
122
    {
123
        return $this->client;
124
    }
125
126
    public function disableCollectionPool()
127
    {
128
        $this->collectionPoolEnabled = false;
129
        return $this;
130
    }
131
132
    public function enableCollectionPool()
133
    {
134
        $this->collectionPoolEnabled = true;
135
        return $this;
136
    }
137
138
    public function isCollectionPoolEnabled()
139
    {
140
        return $this->collectionPoolEnabled;
141
    }
142
143
    public function clearCollectionPool()
144
    {
145
        $this->collectionPool = array();
146
        return $this;
147
    }
148
149
    public function isCollectionPoolEmpty()
150
    {
151
        return !$this->collectionPool;
152
    }
153
154
    /**
155
     * Reset specified mapping
156
     *
157
     * @return \Sokil\Mongo\Client
158
     */
159
    public function resetMapping()
160
    {
161
        $this->mapping = array();
162
163
        return $this;
164
    }
165
166
    /**
167
     * Map collection name to class
168
     *
169
     * @param string|array                  $name               collection name or array like
170
     *                                                          [collectionName => collectionClass, ...]
171
     * @param string|array|Definition|null  $classDefinition    if $name is string, then full class name or array
172
     *                                                          with parameters, else omitted
173
     * @return \Sokil\Mongo\Client
174
     */
175
    public function map($name, $classDefinition = null)
176
    {
177
        // map collection to class
178
        if ($classDefinition) {
179
            return $this->defineCollection($name, $classDefinition);
0 ignored issues
show
Bug introduced by
It seems like $name defined by parameter $name on line 175 can also be of type array; however, Sokil\Mongo\Database::defineCollection() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
180
        }
181
182
        // map collections to classes
183
        if (is_array($name)) {
184
            foreach ($name as $collectionName => $classDefinition) {
185
                $this->defineCollection($collectionName, $classDefinition);
186
            }
187
            return $this;
188
        }
189
190
        // define class prefix
191
        // deprecated: use class definition
192
        $this->defineCollection('*', array(
193
            'class' => $name,
194
        ));
195
196
        return $this;
197
    }
198
199
    /**
200
     * Define collection through array or Definition instance
201
     *
202
     * @param string                    $name       collection name
203
     * @param Definition|array|string   $definition collection definition
204
     * @return Database
205
     */
206
    private function defineCollection($name, $definition)
207
    {
208
        // prepare definition object
209
        if (false === ($definition instanceof Definition)) {
210
            if (is_string($definition)) {
211
                $definition = new Definition(array('class' => $definition));
212
            } elseif (is_array($definition)) {
213
                $definition = new Definition($definition);
214
            } else {
215
                throw new Exception(sprintf('Wrong definition passed for collection %s', $name));
216
            }
217
        }
218
219
        // set definition
220
        if ('/' !== substr($name, 0, 1)) {
221
            $this->mapping[$name] = $definition;
222
        } else {
223
            $this->regexpMapping[$name] = $definition;
224
        }
225
226
        return $this;
227
    }
228
229
    /**
230
     * Get class name mapped to collection
231
     *
232
     * @param string        $name               name of collection
233
     * @param array         $defaultDefinition  definition used when no definition found for defined class
234
     * @throws Exception
235
     * @return string|array                     name of class or array of class definition
236
     */
237
    private function getCollectionDefinition($name, array $defaultDefinition = null)
238
    {
239
        if (isset($this->mapping[$name])) {
240
            $classDefinition = $this->mapping[$name];
241
        } elseif ($this->regexpMapping) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->regexpMapping of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
242
            foreach ($this->regexpMapping as $collectionNamePattern => $regexpMappingClassDefinition) {
243
                if (preg_match($collectionNamePattern, $name, $matches)) {
244
                    $classDefinition = clone $regexpMappingClassDefinition;
245
                    $classDefinition->setOption('regexp', $matches);
246
                    break;
247
                }
248
            }
249
        }
250
251
        // mapping not configured - use default
252
        if (!isset($classDefinition)) {
253
            if (!empty($this->mapping['*'])) {
254
                $classDefinition = clone $this->mapping['*'];
255
                $collectionClass = $classDefinition->getClass()
256
                    . '\\'
257
                    . implode('\\', array_map('ucfirst', explode('.', $name)));
258
                $classDefinition->setClass($collectionClass);
259
            } else {
260
                $classDefinition = new Definition();
261
                if ($defaultDefinition) {
262
                    $classDefinition->merge($defaultDefinition);
263
                }
264
            }
265
        }
266
267
        // check if class exists
268
        if (!class_exists($classDefinition->getClass())) {
269
            throw new Exception(
270
                'Class ' . $classDefinition->getClass() . ' not found while map collection name to class'
271
            );
272
        }
273
274
        return $classDefinition;
275
    }
276
277
    /**
278
     * Create collection
279
     *
280
     * @param string $name name of collection
281
     * @param array|null $options array of options
282
     * @return \Sokil\Mongo\Collection
283
     * @throws \Sokil\Mongo\Exception
284
     */
285
    public function createCollection($name, array $options = null)
286
    {
287
        $classDefinition = $this->getCollectionDefinition($name);
288
        
289
        if (!empty($options)) {
290
            $classDefinition->merge($options);
0 ignored issues
show
Bug introduced by
The method merge cannot be called on $classDefinition (of type string|array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
291
        }
292
293
        $mongoCollection = $this->getMongoDB()->createCollection(
294
            $name,
295
            $classDefinition->getMongoCollectionOptions()
0 ignored issues
show
Bug introduced by
The method getMongoCollectionOptions cannot be called on $classDefinition (of type string|array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
296
        );
297
298
        // create collection
299
        $className = $classDefinition->getClass();
0 ignored issues
show
Bug introduced by
The method getClass cannot be called on $classDefinition (of type string|array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
300
        return new $className(
301
            $this,
302
            $mongoCollection,
303
            $classDefinition
304
        );
305
    }
306
307
    /**
308
     *
309
     * @param string $name name of collection
310
     * @param int $maxElements The maximum number of elements to store in the collection.
311
     * @param int $size Size in bytes.
312
     * @return \Sokil\Mongo\Collection
313
     * @throws Exception
314
     */
315
    public function createCappedCollection($name, $maxElements, $size)
316
    {
317
        $options = array(
318
            'capped'    => true,
319
            'size'      => (int) $size,
320
            'max'       => (int) $maxElements,
321
        );
322
323
        if (!$options['size'] && !$options['max']) {
324
            throw new Exception('Size or number of elements must be defined');
325
        }
326
327
        return $this->createCollection($name, $options);
328
    }
329
330
    /**
331
     *
332
     * @param string $name name of collection
333
     * @return \Sokil\Mongo\Collection
334
     * @throws \Sokil\Mongo\Exception
335
     */
336 View Code Duplication
    public function getCollection($name)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
337
    {
338
        // return from pool
339
        if ($this->collectionPoolEnabled && isset($this->collectionPool[$name])) {
340
            return $this->collectionPool[$name];
341
        }
342
343
        // no object in pool - init new
344
        $classDefinition = $this->getCollectionDefinition($name);
345
        $className = $classDefinition->getClass();
0 ignored issues
show
Bug introduced by
The method getClass cannot be called on $classDefinition (of type string|array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
346
347
        // create collection class
348
        $collection = new $className($this, $name, $classDefinition);
349
        if (!$collection instanceof Collection) {
350
            throw new Exception('Must be instance of \Sokil\Mongo\Collection');
351
        }
352
353
        // store to pool
354
        if ($this->collectionPoolEnabled) {
355
            $this->collectionPool[$name] = $collection;
356
        }
357
358
        // return
359
        return $collection;
360
    }
361
362
    /**
363
     * Get Document instance by it's reference
364
     *
365
     * @param array $ref reference to document
366
     * @param bool  $useDocumentPool try to get document from pool or fetch document from database
367
     *
368
     * @return Document|null
369
     */
370 View Code Duplication
    public function getDocumentByReference(array $ref, $useDocumentPool = true)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
371
    {
372
        $documentArray = $this->getMongoDB()->getDBRef($ref);
373
        if (null === $documentArray) {
374
            return null;
375
        }
376
377
        return $this->getCollection($ref['$ref'])->hydrate($documentArray, $useDocumentPool);
378
    }
379
380
    /**
381
     * Get instance of GridFS
382
     *
383
     * @param string $name prefix of files and chunks collection
384
     * @return \Sokil\Mongo\GridFS
385
     * @throws \Sokil\Mongo\Exception
386
     */
387 View Code Duplication
    public function getGridFS($name = 'fs')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
388
    {
389
        // return from pool
390
        if ($this->collectionPoolEnabled && isset($this->collectionPool[$name])) {
391
            return $this->collectionPool[$name];
392
        }
393
394
        // no object in pool - init new
395
        $classDefinition = $this->getCollectionDefinition($name, array('gridfs' => true));
396
        $className = $classDefinition->getClass();
0 ignored issues
show
Bug introduced by
The method getClass cannot be called on $classDefinition (of type string|array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
397
398
        // create collection class
399
        $collection = new $className($this, $name, $classDefinition);
400
        if (!$collection instanceof \Sokil\Mongo\GridFS) {
401
            throw new Exception('Must be instance of \Sokil\Mongo\GridFS');
402
        }
403
404
        // store to pool
405
        if ($this->collectionPoolEnabled) {
406
            $this->collectionPool[$name] = $collection;
407
        }
408
409
        // return
410
        return $collection;
411
    }
412
413
    /**
414
     *
415
     * @param string $channel name of channel
416
     * @return \Sokil\Mongo\Queue
417
     */
418
    public function getQueue($channel)
419
    {
420
        return new Queue($this, $channel);
421
    }
422
423
    /**
424
     * Get cache
425
     *
426
     * @param string $namespace name of collection to be created in database
427
     *
428
     * @return Cache
429
     */
430
    public function getCache($namespace)
431
    {
432
        return new Cache($this, $namespace);
433
    }
434
435
    public function readPrimaryOnly()
436
    {
437
        $this->getMongoDB()->setReadPreference(\MongoClient::RP_PRIMARY);
438
        return $this;
439
    }
440
441
    public function readPrimaryPreferred(array $tags = null)
442
    {
443
        $this->getMongoDB()->setReadPreference(\MongoClient::RP_PRIMARY_PREFERRED, $tags);
444
        return $this;
445
    }
446
447
    public function readSecondaryOnly(array $tags = null)
448
    {
449
        $this->getMongoDB()->setReadPreference(\MongoClient::RP_SECONDARY, $tags);
450
        return $this;
451
    }
452
453
    public function readSecondaryPreferred(array $tags = null)
454
    {
455
        $this->getMongoDB()->setReadPreference(\MongoClient::RP_SECONDARY_PREFERRED, $tags);
456
        return $this;
457
    }
458
459
    public function readNearest(array $tags = null)
460
    {
461
        $this->getMongoDB()->setReadPreference(\MongoClient::RP_NEAREST, $tags);
462
        return $this;
463
    }
464
465
    public function getReadPreference()
466
    {
467
        return $this->getMongoDB()->getReadPreference();
468
    }
469
470
    /**
471
     * Define write concern.
472
     * May be used only if mongo extension version >=1.5
473
     *
474
     * @param string|integer $w write concern
475
     * @param int $timeout timeout in milliseconds
476
     * @return \Sokil\Mongo\Database
477
     * @throws \Sokil\Mongo\Exception
478
     */
479
    public function setWriteConcern($w, $timeout = 10000)
480
    {
481
        if (!$this->getMongoDB()->setWriteConcern($w, (int) $timeout)) {
482
            throw new Exception('Error setting write concern');
483
        }
484
485
        return $this;
486
    }
487
488
    /**
489
     * Define unacknowledged write concern.
490
     * May be used only if mongo extension version >=1.5
491
     *
492
     * @param int $timeout timeout in milliseconds
493
     * @return \Sokil\Mongo\Database
494
     */
495
    public function setUnacknowledgedWriteConcern($timeout = 10000)
496
    {
497
        $this->setWriteConcern(0, (int) $timeout);
498
        return $this;
499
    }
500
501
    /**
502
     * Define majority write concern.
503
     * May be used only if mongo extension version >=1.5
504
     *
505
     * @param int $timeout timeout in milliseconds
506
     * @return \Sokil\Mongo\Database
507
     */
508
    public function setMajorityWriteConcern($timeout = 10000)
509
    {
510
        $this->setWriteConcern('majority', (int) $timeout);
511
        return $this;
512
    }
513
514
    /**
515
     * Get current write concern
516
     * May be used only if mongo extension version >=1.5
517
     *
518
     * @return mixed
519
     */
520
    public function getWriteConcern()
521
    {
522
        return $this->getMongoDB()->getWriteConcern();
523
    }
524
525
    /**
526
     * Execute Mongo command
527
     *
528
     * @param array $command
529
     * @param array $options
530
     * @return array
531
     */
532
    public function executeCommand(array $command, array $options = array())
533
    {
534
        return $this->getMongoDB()->command($command, $options);
535
    }
536
537
    public function executeJS($code, array $args = array())
538
    {
539
        $response = $this->getMongoDB()->execute($code, $args);
540
        if ($response['ok'] == 1.0) {
541
            return $response['retval'];
542
        } else {
543
            throw new Exception('Error #' . $response['code'] . ': ' . $response['errmsg'], $response['code']);
544
        }
545
    }
546
547
    public function stats()
548
    {
549
        return $this->executeCommand(array(
550
            'dbstats' => 1,
551
        ));
552
    }
553
554
    public function getLastError()
555
    {
556
        return $this->getMongoDB()->lastError();
557
    }
558
559
    public function getProfilerParams()
560
    {
561
        return $this->executeCommand(array(
562
            'profile'   => -1,
563
        ));
564
    }
565
566
    public function getProfilerLevel()
567
    {
568
        $params = $this->getProfilerParams();
569
        return $params['was'];
570
    }
571
572
    public function getProfilerSlowMs()
573
    {
574
        $params = $this->getProfilerParams();
575
        return $params['slowms'];
576
    }
577
578
    public function disableProfiler()
579
    {
580
        return $this->executeCommand(array(
581
            'profile'   => 0,
582
        ));
583
    }
584
585
    public function profileSlowQueries($slowms = 100)
586
    {
587
        return $this->executeCommand(array(
588
            'profile'   => 1,
589
            'slowms'    => (int) $slowms
590
        ));
591
    }
592
593
    public function profileAllQueries($slowms = null)
594
    {
595
        $command = array(
596
            'profile'   => 2,
597
        );
598
599
        if ($slowms) {
600
            $command['slowms'] = (int) $slowms;
601
        }
602
603
        return $this->executeCommand($command);
604
    }
605
606
    /**
607
     *
608
     * @return \Sokil\Mongo\Cursor
609
     */
610
    public function findProfilerRows()
611
    {
612
        return $this
613
            ->getCollection('system.profile')
614
            ->find()
615
            ->asArray();
616
    }
617
}
618