Completed
Pull Request — master (#20)
by
unknown
02:57
created

MongoDB::checkDatabaseName()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 20
rs 8.8571
cc 6
eloc 11
nc 6
nop 1
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\Helper;
17
use Alcaeus\MongoDbAdapter\TypeConverter;
18
use Alcaeus\MongoDbAdapter\ExceptionConverter;
19
use MongoDB\Model\CollectionInfo;
20
21
/**
22
 * Instances of this class are used to interact with a database.
23
 * @link http://www.php.net/manual/en/class.mongodb.php
24
 */
25
class MongoDB
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
    use Helper\ReadPreference;
28
    use Helper\SlaveOkay;
29
    use Helper\WriteConcern;
30
31
    const PROFILING_OFF = 0;
32
    const PROFILING_SLOW = 1;
33
    const PROFILING_ON = 2;
34
35
    /**
36
     * @var MongoClient
37
     */
38
    protected $connection;
39
40
    /**
41
     * @var \MongoDB\Database
42
     */
43
    protected $db;
44
45
    /**
46
     * @var string
47
     */
48
    protected $name;
49
50
    /**
51
     * Creates a new database
52
     *
53
     * This method is not meant to be called directly. The preferred way to create an instance of MongoDB is through {@see Mongo::__get()} or {@see Mongo::selectDB()}.
54
     * @link http://www.php.net/manual/en/mongodb.construct.php
55
     * @param MongoClient $conn Database connection.
56
     * @param string $name Database name.
57
     * @throws Exception
58
     * @return MongoDB Returns the database.
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
59
     */
60
    public function __construct(MongoClient $conn, $name)
61
    {
62
        $this->checkDatabaseName($name);
63
        $this->connection = $conn;
64
        $this->name = $name;
65
66
        $this->setReadPreferenceFromArray($conn->getReadPreference());
67
        $this->setWriteConcernFromArray($conn->getWriteConcern());
68
69
        $this->createDatabaseObject();
70
    }
71
72
    /**
73
     * @return \MongoDB\Database
74
     * @internal This method is not part of the ext-mongo API
75
     */
76
    public function getDb()
77
    {
78
        return $this->db;
79
    }
80
81
    /**
82
     * The name of this database
83
     *
84
     * @link http://www.php.net/manual/en/mongodb.--tostring.php
85
     * @return string Returns this database's name.
86
     */
87
    public function __toString()
88
    {
89
        return $this->name;
90
    }
91
92
    /**
93
     * Gets a collection
94
     *
95
     * @link http://www.php.net/manual/en/mongodb.get.php
96
     * @param string $name The name of the collection.
97
     * @return MongoCollection
98
     */
99
    public function __get($name)
100
    {
101
        // Handle w and wtimeout properties that replicate data stored in $readPreference
102
        if ($name === 'w' || $name === 'wtimeout') {
103
            return $this->getWriteConcern()[$name];
104
        }
105
106
        return $this->selectCollection($name);
107
    }
108
109
    /**
110
     * @param string $name
111
     * @param mixed $value
112
     */
113 View Code Duplication
    public function __set($name, $value)
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...
114
    {
115
        if ($name === 'w' || $name === 'wtimeout') {
116
            $this->setWriteConcernFromArray([$name => $value] + $this->getWriteConcern());
117
            $this->createDatabaseObject();
118
        }
119
    }
120
121
    /**
122
     * Returns information about collections in this database
123
     *
124
     * @link http://www.php.net/manual/en/mongodb.getcollectioninfo.php
125
     * @param array $options An array of options for listing the collections.
126
     * @return array
127
     */
128
    public function getCollectionInfo(array $options = [])
129
    {
130
        // The includeSystemCollections option is no longer supported
131
        if (isset($options['includeSystemCollections'])) {
132
            unset($options['includeSystemCollections']);
133
        }
134
135
        try {
136
            $collections = $this->db->listCollections($options);
137
        } 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...
138
            throw new \MongoExecutionTimeoutException($e->getMessage(), $e->getCode(), $e);
139
        } 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...
140
            ExceptionConverter::toLegacy($e);
141
        }
142
143
        $getCollectionInfo = function (CollectionInfo $collectionInfo) {
144
            return [
145
                'name' => $collectionInfo->getName(),
146
                'options' => $collectionInfo->getOptions(),
147
            ];
148
        };
149
150
        return array_map($getCollectionInfo, iterator_to_array($collections));
151
    }
152
153
    /**
154
     * Get all collections from this database
155
     *
156
     * @link http://www.php.net/manual/en/mongodb.getcollectionnames.php
157
     * @param array $options An array of options for listing the collections.
158
     * @return array Returns the names of the all the collections in the database as an array
159
     */
160
    public function getCollectionNames(array $options = [])
161
    {
162
        // The includeSystemCollections option is no longer supported
163
        if (isset($options['includeSystemCollections'])) {
164
            unset($options['includeSystemCollections']);
165
        }
166
167
        try {
168
            $collections = $this->db->listCollections($options);
169
        } 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...
170
            throw new \MongoExecutionTimeoutException($e->getMessage(), $e->getCode(), $e);
171
        } 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...
172
            ExceptionConverter::toLegacy($e);
173
        }
174
175
        $getCollectionName = function (CollectionInfo $collectionInfo) {
176
            return $collectionInfo->getName();
177
        };
178
179
        return array_map($getCollectionName, iterator_to_array($collections));
180
    }
181
182
    /**
183
     * @return MongoClient
184
     * @internal This method is not part of the ext-mongo API
185
     */
186
    public function getConnection()
187
    {
188
        return $this->connection;
189
    }
190
191
    /**
192
     * Fetches toolkit for dealing with files stored in this database
193
     *
194
     * @link http://www.php.net/manual/en/mongodb.getgridfs.php
195
     * @param string $prefix The prefix for the files and chunks collections.
196
     * @return MongoGridFS Returns a new gridfs object for this database.
197
     */
198
    public function getGridFS($prefix = "fs")
199
    {
200
        return new \MongoGridFS($this, $prefix, $prefix);
201
    }
202
203
    /**
204
     * Gets this database's profiling level
205
     *
206
     * @link http://www.php.net/manual/en/mongodb.getprofilinglevel.php
207
     * @return int Returns the profiling level.
208
     */
209
    public function getProfilingLevel()
210
    {
211
        $result = $this->command(['profile' => -1]);
212
213
        return ($result['ok'] && isset($result['was'])) ? $result['was'] : 0;
214
    }
215
216
    /**
217
     * Sets this database's profiling level
218
     *
219
     * @link http://www.php.net/manual/en/mongodb.setprofilinglevel.php
220
     * @param int $level Profiling level.
221
     * @return int Returns the previous profiling level.
222
     */
223
    public function setProfilingLevel($level)
224
    {
225
        $result = $this->command(['profile' => $level]);
226
227
        return ($result['ok'] && isset($result['was'])) ? $result['was'] : 0;
228
    }
229
230
    /**
231
     * Drops this database
232
     *
233
     * @link http://www.php.net/manual/en/mongodb.drop.php
234
     * @return array Returns the database response.
235
     */
236
    public function drop()
237
    {
238
        return TypeConverter::toLegacy($this->db->drop());
239
    }
240
241
    /**
242
     * Repairs and compacts this database
243
     *
244
     * @link http://www.php.net/manual/en/mongodb.repair.php
245
     * @param bool $preserve_cloned_files [optional] <p>If cloned files should be kept if the repair fails.</p>
246
     * @param bool $backup_original_files [optional] <p>If original files should be backed up.</p>
247
     * @return array <p>Returns db response.</p>
248
     */
249
    public function repair($preserve_cloned_files = FALSE, $backup_original_files = FALSE)
0 ignored issues
show
Unused Code introduced by
The parameter $preserve_cloned_files 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 $backup_original_files 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...
250
    {
251
        $this->notImplemented();
252
    }
253
254
    /**
255
     * Gets a collection
256
     *
257
     * @link http://www.php.net/manual/en/mongodb.selectcollection.php
258
     * @param string $name <b>The collection name.</b>
259
     * @throws Exception if the collection name is invalid.
260
     * @return MongoCollection Returns a new collection object.
261
     */
262
    public function selectCollection($name)
263
    {
264
        return new MongoCollection($this, $name);
265
    }
266
267
    /**
268
     * Creates a collection
269
     *
270
     * @link http://www.php.net/manual/en/mongodb.createcollection.php
271
     * @param string $name The name of the collection.
272
     * @param array $options
273
     * @return MongoCollection Returns a collection object representing the new collection.
274
     */
275
    public function createCollection($name, $options)
276
    {
277
        try {
278
            $this->db->createCollection($name, $options);
279
        } 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...
280
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by MongoDB::createCollection of type MongoCollection.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
281
        }
282
283
        return $this->selectCollection($name);
284
    }
285
286
    /**
287
     * Drops a collection
288
     *
289
     * @link http://www.php.net/manual/en/mongodb.dropcollection.php
290
     * @param MongoCollection|string $coll MongoCollection or name of collection to drop.
291
     * @return array Returns the database response.
292
     *
293
     * @deprecated Use MongoCollection::drop() instead.
294
     */
295
    public function dropCollection($coll)
296
    {
297
        if ($coll instanceof MongoCollection) {
298
            $coll = $coll->getName();
299
        }
300
301
        return TypeConverter::toLegacy($this->db->dropCollection((string) $coll));
302
    }
303
304
    /**
305
     * Get a list of collections in this database
306
     *
307
     * @link http://www.php.net/manual/en/mongodb.listcollections.php
308
     * @param array $options
309
     * @return MongoCollection[] Returns a list of MongoCollections.
310
     */
311
    public function listCollections(array $options = [])
312
    {
313
        return array_map([$this, 'selectCollection'], $this->getCollectionNames($options));
314
    }
315
316
    /**
317
     * Creates a database reference
318
     *
319
     * @link http://www.php.net/manual/en/mongodb.createdbref.php
320
     * @param string $collection The collection to which the database reference will point.
321
     * @param mixed $document_or_id
322
     * @return array Returns a database reference array.
323
     */
324 View Code Duplication
    public function createDBRef($collection, $document_or_id)
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...
325
    {
326
        if ($document_or_id instanceof \MongoId) {
327
            $id = $document_or_id;
328
        } elseif (is_object($document_or_id)) {
329
            if (! isset($document_or_id->_id)) {
330
                return null;
331
            }
332
333
            $id = $document_or_id->_id;
334
        } elseif (is_array($document_or_id)) {
335
            if (! isset($document_or_id['_id'])) {
336
                return null;
337
            }
338
339
            $id = $document_or_id['_id'];
340
        } else {
341
            $id = $document_or_id;
342
        }
343
344
        return MongoDBRef::create($collection, $id, $this->name);
345
    }
346
347
348
    /**
349
     * Fetches the document pointed to by a database reference
350
     *
351
     * @link http://www.php.net/manual/en/mongodb.getdbref.php
352
     * @param array $ref A database reference.
353
     * @return array Returns the document pointed to by the reference.
354
     */
355
    public function getDBRef(array $ref)
356
    {
357
        return MongoDBRef::get($this, $ref);
358
    }
359
360
    /**
361
     * Runs JavaScript code on the database server.
362
     *
363
     * @link http://www.php.net/manual/en/mongodb.execute.php
364
     * @param MongoCode|string $code Code to execute.
365
     * @param array $args [optional] Arguments to be passed to code.
366
     * @return array Returns the result of the evaluation.
367
     */
368
    public function execute($code, array $args = [])
369
    {
370
        return $this->command(['eval' => $code, 'args' => $args]);
371
    }
372
373
    /**
374
     * Execute a database command
375
     *
376
     * @link http://www.php.net/manual/en/mongodb.command.php
377
     * @param array $data The query to send.
378
     * @param array $options
379
     * @return array Returns database response.
380
     */
381
    public function command(array $data, $options = [], &$hash = null)
0 ignored issues
show
Unused Code introduced by
The parameter $options 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 $hash 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...
382
    {
383
        try {
384
            $cursor = new \MongoCommandCursor($this->connection, $this->name, $data);
385
            $cursor->setReadPreference($this->getReadPreference());
0 ignored issues
show
Documentation introduced by
$this->getReadPreference() is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
386
387
            return iterator_to_array($cursor)[0];
388
        } 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...
389
            throw new MongoCursorTimeoutException($e->getMessage(), $e->getCode(), $e);
390
        } catch (\MongoDB\Driver\Exception\RuntimeException $e) {
0 ignored issues
show
Bug introduced by
The class MongoDB\Driver\Exception\RuntimeException 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...
391
            return [
392
                'ok' => 0,
393
                'errmsg' => $e->getMessage(),
394
                'code' => $e->getCode(),
395
            ];
396
        } catch (\MongoDB\Driver\Exception\Excepiton $e) {
0 ignored issues
show
Bug introduced by
The class MongoDB\Driver\Exception\Excepiton 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...
397
            ExceptionConverter::toLegacy($e);
398
        }
399
    }
400
401
    /**
402
     * Check if there was an error on the most recent db operation performed
403
     *
404
     * @link http://www.php.net/manual/en/mongodb.lasterror.php
405
     * @return array Returns the error, if there was one.
406
     */
407
    public function lastError()
408
    {
409
        return $this->command(array('getLastError' => 1));
410
    }
411
412
    /**
413
     * Checks for the last error thrown during a database operation
414
     *
415
     * @link http://www.php.net/manual/en/mongodb.preverror.php
416
     * @return array Returns the error and the number of operations ago it occurred.
417
     */
418
    public function prevError()
419
    {
420
        return $this->command(array('getPrevError' => 1));
421
    }
422
423
    /**
424
     * Clears any flagged errors on the database
425
     *
426
     * @link http://www.php.net/manual/en/mongodb.reseterror.php
427
     * @return array Returns the database response.
428
     */
429
    public function resetError()
430
    {
431
        return $this->command(array('resetError' => 1));
432
    }
433
434
    /**
435
     * Creates a database error
436
     *
437
     * @link http://www.php.net/manual/en/mongodb.forceerror.php
438
     * @return boolean Returns the database response.
439
     */
440
    public function forceError()
441
    {
442
        return $this->command(array('forceerror' => 1));
443
    }
444
445
    /**
446
     * Log in to this database
447
     *
448
     * @link http://www.php.net/manual/en/mongodb.authenticate.php
449
     * @param string $username The username.
450
     * @param string $password The password (in plaintext).
451
     * @return array Returns database response. If the login was successful, it will return 1.
452
     *
453
     * @deprecated This method is not implemented, supply authentication credentials through the connection string instead.
454
     */
455
    public function authenticate($username, $password)
0 ignored issues
show
Unused Code introduced by
The parameter $username 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 $password 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...
456
    {
457
        throw new \Exception('The MongoDB::authenticate method is not supported. Please supply authentication credentials through the connection string');
458
    }
459
460
    /**
461
     * {@inheritdoc}
462
     */
463
    public function setReadPreference($readPreference, $tags = null)
464
    {
465
        $result = $this->setReadPreferenceFromParameters($readPreference, $tags);
466
        $this->createDatabaseObject();
467
468
        return $result;
469
    }
470
471
    /**
472
     * {@inheritdoc}
473
     */
474
    public function setWriteConcern($wstring, $wtimeout = 0)
475
    {
476
        $result = $this->setWriteConcernFromParameters($wstring, $wtimeout);
477
        $this->createDatabaseObject();
478
479
        return $result;
480
    }
481
482
    protected function notImplemented()
483
    {
484
        throw new \Exception('Not implemented');
485
    }
486
487
    /**
488
     * @return \MongoDB\Database
489
     */
490 View Code Duplication
    private function createDatabaseObject()
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...
491
    {
492
        $options = [
493
            'readPreference' => $this->readPreference,
494
            'writeConcern' => $this->writeConcern,
495
        ];
496
497
        if ($this->db === null) {
498
            $this->db = $this->connection->getClient()->selectDatabase($this->name, $options);
499
        } else {
500
            $this->db = $this->db->withOptions($options);
501
        }
502
    }
503
504
    private function checkDatabaseName($name)
505
    {
506
        if (empty($name)) {
507
            throw new \Exception('Database name cannot be empty');
508
        }
509
        if (strlen($name) >= 64) {
510
            throw new \Exception('Database name cannot exceed 63 characters');
511
        }
512
        if (strpos($name, chr(0)) !== false) {
513
            throw new \Exception('Database name cannot contain null bytes');
514
        }
515
516
        $invalidCharacters = ['.', '$', '/', ' ', '\\'];
517
        foreach ($invalidCharacters as $char) {
518
            if (strchr($name, $char) !== false) {
519
                throw new \Exception('Database name contains invalid characters');
520
            }
521
        }
522
523
    }
524
}
525