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