Differences Between: [Versions 310 and 311] [Versions 311 and 401] [Versions 39 and 311]
1 <?php 2 /* 3 * Copyright 2015-2017 MongoDB, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 namespace MongoDB; 19 20 use Iterator; 21 use MongoDB\Driver\Cursor; 22 use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; 23 use MongoDB\Driver\Manager; 24 use MongoDB\Driver\ReadConcern; 25 use MongoDB\Driver\ReadPreference; 26 use MongoDB\Driver\WriteConcern; 27 use MongoDB\Exception\InvalidArgumentException; 28 use MongoDB\Exception\UnexpectedValueException; 29 use MongoDB\Exception\UnsupportedException; 30 use MongoDB\GridFS\Bucket; 31 use MongoDB\Model\BSONArray; 32 use MongoDB\Model\BSONDocument; 33 use MongoDB\Model\CollectionInfoIterator; 34 use MongoDB\Operation\Aggregate; 35 use MongoDB\Operation\CreateCollection; 36 use MongoDB\Operation\DatabaseCommand; 37 use MongoDB\Operation\DropCollection; 38 use MongoDB\Operation\DropDatabase; 39 use MongoDB\Operation\ListCollectionNames; 40 use MongoDB\Operation\ListCollections; 41 use MongoDB\Operation\ModifyCollection; 42 use MongoDB\Operation\Watch; 43 use Traversable; 44 use function is_array; 45 use function strlen; 46 47 class Database 48 { 49 /** @var array */ 50 private static $defaultTypeMap = [ 51 'array' => BSONArray::class, 52 'document' => BSONDocument::class, 53 'root' => BSONDocument::class, 54 ]; 55 56 /** @var integer */ 57 private static $wireVersionForReadConcern = 4; 58 59 /** @var integer */ 60 private static $wireVersionForWritableCommandWriteConcern = 5; 61 62 /** @var integer */ 63 private static $wireVersionForReadConcernWithWriteStage = 8; 64 65 /** @var string */ 66 private $databaseName; 67 68 /** @var Manager */ 69 private $manager; 70 71 /** @var ReadConcern */ 72 private $readConcern; 73 74 /** @var ReadPreference */ 75 private $readPreference; 76 77 /** @var array */ 78 private $typeMap; 79 80 /** @var WriteConcern */ 81 private $writeConcern; 82 83 /** 84 * Constructs new Database instance. 85 * 86 * This class provides methods for database-specific operations and serves 87 * as a gateway for accessing collections. 88 * 89 * Supported options: 90 * 91 * * readConcern (MongoDB\Driver\ReadConcern): The default read concern to 92 * use for database operations and selected collections. Defaults to the 93 * Manager's read concern. 94 * 95 * * readPreference (MongoDB\Driver\ReadPreference): The default read 96 * preference to use for database operations and selected collections. 97 * Defaults to the Manager's read preference. 98 * 99 * * typeMap (array): Default type map for cursors and BSON documents. 100 * 101 * * writeConcern (MongoDB\Driver\WriteConcern): The default write concern 102 * to use for database operations and selected collections. Defaults to 103 * the Manager's write concern. 104 * 105 * @param Manager $manager Manager instance from the driver 106 * @param string $databaseName Database name 107 * @param array $options Database options 108 * @throws InvalidArgumentException for parameter/option parsing errors 109 */ 110 public function __construct(Manager $manager, $databaseName, array $options = []) 111 { 112 if (strlen($databaseName) < 1) { 113 throw new InvalidArgumentException('$databaseName is invalid: ' . $databaseName); 114 } 115 116 if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) { 117 throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], ReadConcern::class); 118 } 119 120 if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) { 121 throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class); 122 } 123 124 if (isset($options['typeMap']) && ! is_array($options['typeMap'])) { 125 throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array'); 126 } 127 128 if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) { 129 throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class); 130 } 131 132 $this->manager = $manager; 133 $this->databaseName = (string) $databaseName; 134 $this->readConcern = $options['readConcern'] ?? $this->manager->getReadConcern(); 135 $this->readPreference = $options['readPreference'] ?? $this->manager->getReadPreference(); 136 $this->typeMap = $options['typeMap'] ?? self::$defaultTypeMap; 137 $this->writeConcern = $options['writeConcern'] ?? $this->manager->getWriteConcern(); 138 } 139 140 /** 141 * Return internal properties for debugging purposes. 142 * 143 * @see http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo 144 * @return array 145 */ 146 public function __debugInfo() 147 { 148 return [ 149 'databaseName' => $this->databaseName, 150 'manager' => $this->manager, 151 'readConcern' => $this->readConcern, 152 'readPreference' => $this->readPreference, 153 'typeMap' => $this->typeMap, 154 'writeConcern' => $this->writeConcern, 155 ]; 156 } 157 158 /** 159 * Select a collection within this database. 160 * 161 * Note: collections whose names contain special characters (e.g. ".") may 162 * be selected with complex syntax (e.g. $database->{"system.profile"}) or 163 * {@link selectCollection()}. 164 * 165 * @see http://php.net/oop5.overloading#object.get 166 * @see http://php.net/types.string#language.types.string.parsing.complex 167 * @param string $collectionName Name of the collection to select 168 * @return Collection 169 */ 170 public function __get($collectionName) 171 { 172 return $this->selectCollection($collectionName); 173 } 174 175 /** 176 * Return the database name. 177 * 178 * @return string 179 */ 180 public function __toString() 181 { 182 return $this->databaseName; 183 } 184 185 /** 186 * Runs an aggregation framework pipeline on the database for pipeline 187 * stages that do not require an underlying collection, such as $currentOp 188 * and $listLocalSessions. Requires MongoDB >= 3.6 189 * 190 * @see Aggregate::__construct() for supported options 191 * @param array $pipeline List of pipeline operations 192 * @param array $options Command options 193 * @return Traversable 194 * @throws UnexpectedValueException if the command response was malformed 195 * @throws UnsupportedException if options are not supported by the selected server 196 * @throws InvalidArgumentException for parameter/option parsing errors 197 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 198 */ 199 public function aggregate(array $pipeline, array $options = []) 200 { 201 $hasWriteStage = is_last_pipeline_operator_write($pipeline); 202 203 if (! isset($options['readPreference']) && ! is_in_transaction($options)) { 204 $options['readPreference'] = $this->readPreference; 205 } 206 207 if ($hasWriteStage) { 208 $options['readPreference'] = new ReadPreference(ReadPreference::RP_PRIMARY); 209 } 210 211 $server = select_server($this->manager, $options); 212 213 /* MongoDB 4.2 and later supports a read concern when an $out stage is 214 * being used, but earlier versions do not. 215 * 216 * A read concern is also not compatible with transactions. 217 */ 218 if (! isset($options['readConcern']) && 219 server_supports_feature($server, self::$wireVersionForReadConcern) && 220 ! is_in_transaction($options) && 221 ( ! $hasWriteStage || server_supports_feature($server, self::$wireVersionForReadConcernWithWriteStage)) 222 ) { 223 $options['readConcern'] = $this->readConcern; 224 } 225 226 if (! isset($options['typeMap'])) { 227 $options['typeMap'] = $this->typeMap; 228 } 229 230 if ($hasWriteStage && 231 ! isset($options['writeConcern']) && 232 server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && 233 ! is_in_transaction($options)) { 234 $options['writeConcern'] = $this->writeConcern; 235 } 236 237 $operation = new Aggregate($this->databaseName, null, $pipeline, $options); 238 239 return $operation->execute($server); 240 } 241 242 /** 243 * Execute a command on this database. 244 * 245 * @see DatabaseCommand::__construct() for supported options 246 * @param array|object $command Command document 247 * @param array $options Options for command execution 248 * @return Cursor 249 * @throws InvalidArgumentException for parameter/option parsing errors 250 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 251 */ 252 public function command($command, array $options = []) 253 { 254 if (! isset($options['typeMap'])) { 255 $options['typeMap'] = $this->typeMap; 256 } 257 258 $operation = new DatabaseCommand($this->databaseName, $command, $options); 259 $server = select_server($this->manager, $options); 260 261 return $operation->execute($server); 262 } 263 264 /** 265 * Create a new collection explicitly. 266 * 267 * @see CreateCollection::__construct() for supported options 268 * @param string $collectionName 269 * @param array $options 270 * @return array|object Command result document 271 * @throws UnsupportedException if options are not supported by the selected server 272 * @throws InvalidArgumentException for parameter/option parsing errors 273 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 274 */ 275 public function createCollection($collectionName, array $options = []) 276 { 277 if (! isset($options['typeMap'])) { 278 $options['typeMap'] = $this->typeMap; 279 } 280 281 $server = select_server($this->manager, $options); 282 283 if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) { 284 $options['writeConcern'] = $this->writeConcern; 285 } 286 287 $operation = new CreateCollection($this->databaseName, $collectionName, $options); 288 289 return $operation->execute($server); 290 } 291 292 /** 293 * Drop this database. 294 * 295 * @see DropDatabase::__construct() for supported options 296 * @param array $options Additional options 297 * @return array|object Command result document 298 * @throws UnsupportedException if options are unsupported on the selected server 299 * @throws InvalidArgumentException for parameter/option parsing errors 300 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 301 */ 302 public function drop(array $options = []) 303 { 304 if (! isset($options['typeMap'])) { 305 $options['typeMap'] = $this->typeMap; 306 } 307 308 $server = select_server($this->manager, $options); 309 310 if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) { 311 $options['writeConcern'] = $this->writeConcern; 312 } 313 314 $operation = new DropDatabase($this->databaseName, $options); 315 316 return $operation->execute($server); 317 } 318 319 /** 320 * Drop a collection within this database. 321 * 322 * @see DropCollection::__construct() for supported options 323 * @param string $collectionName Collection name 324 * @param array $options Additional options 325 * @return array|object Command result document 326 * @throws UnsupportedException if options are unsupported on the selected server 327 * @throws InvalidArgumentException for parameter/option parsing errors 328 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 329 */ 330 public function dropCollection($collectionName, array $options = []) 331 { 332 if (! isset($options['typeMap'])) { 333 $options['typeMap'] = $this->typeMap; 334 } 335 336 $server = select_server($this->manager, $options); 337 338 if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) { 339 $options['writeConcern'] = $this->writeConcern; 340 } 341 342 $operation = new DropCollection($this->databaseName, $collectionName, $options); 343 344 return $operation->execute($server); 345 } 346 347 /** 348 * Returns the database name. 349 * 350 * @return string 351 */ 352 public function getDatabaseName() 353 { 354 return $this->databaseName; 355 } 356 357 /** 358 * Return the Manager. 359 * 360 * @return Manager 361 */ 362 public function getManager() 363 { 364 return $this->manager; 365 } 366 367 /** 368 * Return the read concern for this database. 369 * 370 * @see http://php.net/manual/en/mongodb-driver-readconcern.isdefault.php 371 * @return ReadConcern 372 */ 373 public function getReadConcern() 374 { 375 return $this->readConcern; 376 } 377 378 /** 379 * Return the read preference for this database. 380 * 381 * @return ReadPreference 382 */ 383 public function getReadPreference() 384 { 385 return $this->readPreference; 386 } 387 388 /** 389 * Return the type map for this database. 390 * 391 * @return array 392 */ 393 public function getTypeMap() 394 { 395 return $this->typeMap; 396 } 397 398 /** 399 * Return the write concern for this database. 400 * 401 * @see http://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php 402 * @return WriteConcern 403 */ 404 public function getWriteConcern() 405 { 406 return $this->writeConcern; 407 } 408 409 /** 410 * Returns the names of all collections in this database 411 * 412 * @see ListCollectionNames::__construct() for supported options 413 * @throws InvalidArgumentException for parameter/option parsing errors 414 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 415 */ 416 public function listCollectionNames(array $options = []) : Iterator 417 { 418 $operation = new ListCollectionNames($this->databaseName, $options); 419 $server = select_server($this->manager, $options); 420 421 return $operation->execute($server); 422 } 423 424 /** 425 * Returns information for all collections in this database. 426 * 427 * @see ListCollections::__construct() for supported options 428 * @param array $options 429 * @return CollectionInfoIterator 430 * @throws InvalidArgumentException for parameter/option parsing errors 431 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 432 */ 433 public function listCollections(array $options = []) 434 { 435 $operation = new ListCollections($this->databaseName, $options); 436 $server = select_server($this->manager, $options); 437 438 return $operation->execute($server); 439 } 440 441 /** 442 * Modifies a collection or view. 443 * 444 * @see ModifyCollection::__construct() for supported options 445 * @param string $collectionName Collection or view to modify 446 * @param array $collectionOptions Collection or view options to assign 447 * @param array $options Command options 448 * @return array|object 449 * @throws InvalidArgumentException for parameter/option parsing errors 450 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 451 */ 452 public function modifyCollection($collectionName, array $collectionOptions, array $options = []) 453 { 454 if (! isset($options['typeMap'])) { 455 $options['typeMap'] = $this->typeMap; 456 } 457 458 $server = select_server($this->manager, $options); 459 460 if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) { 461 $options['writeConcern'] = $this->writeConcern; 462 } 463 464 $operation = new ModifyCollection($this->databaseName, $collectionName, $collectionOptions, $options); 465 466 return $operation->execute($server); 467 } 468 469 /** 470 * Select a collection within this database. 471 * 472 * @see Collection::__construct() for supported options 473 * @param string $collectionName Name of the collection to select 474 * @param array $options Collection constructor options 475 * @return Collection 476 * @throws InvalidArgumentException for parameter/option parsing errors 477 */ 478 public function selectCollection($collectionName, array $options = []) 479 { 480 $options += [ 481 'readConcern' => $this->readConcern, 482 'readPreference' => $this->readPreference, 483 'typeMap' => $this->typeMap, 484 'writeConcern' => $this->writeConcern, 485 ]; 486 487 return new Collection($this->manager, $this->databaseName, $collectionName, $options); 488 } 489 490 /** 491 * Select a GridFS bucket within this database. 492 * 493 * @see Bucket::__construct() for supported options 494 * @param array $options Bucket constructor options 495 * @return Bucket 496 * @throws InvalidArgumentException for parameter/option parsing errors 497 */ 498 public function selectGridFSBucket(array $options = []) 499 { 500 $options += [ 501 'readConcern' => $this->readConcern, 502 'readPreference' => $this->readPreference, 503 'typeMap' => $this->typeMap, 504 'writeConcern' => $this->writeConcern, 505 ]; 506 507 return new Bucket($this->manager, $this->databaseName, $options); 508 } 509 510 /** 511 * Create a change stream for watching changes to the database. 512 * 513 * @see Watch::__construct() for supported options 514 * @param array $pipeline List of pipeline operations 515 * @param array $options Command options 516 * @return ChangeStream 517 * @throws InvalidArgumentException for parameter/option parsing errors 518 */ 519 public function watch(array $pipeline = [], array $options = []) 520 { 521 if (! isset($options['readPreference']) && ! is_in_transaction($options)) { 522 $options['readPreference'] = $this->readPreference; 523 } 524 525 $server = select_server($this->manager, $options); 526 527 if (! isset($options['readConcern']) && server_supports_feature($server, self::$wireVersionForReadConcern) && ! is_in_transaction($options)) { 528 $options['readConcern'] = $this->readConcern; 529 } 530 531 if (! isset($options['typeMap'])) { 532 $options['typeMap'] = $this->typeMap; 533 } 534 535 $operation = new Watch($this->manager, $this->databaseName, null, $pipeline, $options); 536 537 return $operation->execute($server); 538 } 539 540 /** 541 * Get a clone of this database with different options. 542 * 543 * @see Database::__construct() for supported options 544 * @param array $options Database constructor options 545 * @return Database 546 * @throws InvalidArgumentException for parameter/option parsing errors 547 */ 548 public function withOptions(array $options = []) 549 { 550 $options += [ 551 'readConcern' => $this->readConcern, 552 'readPreference' => $this->readPreference, 553 'typeMap' => $this->typeMap, 554 'writeConcern' => $this->writeConcern, 555 ]; 556 557 return new Database($this->manager, $this->databaseName, $options); 558 } 559 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body