From 0552779650f0c00e92ee9780182bcf55a2ea9211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Mon, 16 Sep 2024 16:35:29 +0200 Subject: [PATCH 1/6] PHPLIB-1218 Remove deprecated fields from GridFS files (#1398) --- UPGRADE-2.0.md | 28 +++++++++++ composer.json | 1 - src/GridFS/Bucket.php | 34 ++----------- src/GridFS/WritableStream.php | 50 +------------------ tests/GridFS/BucketFunctionalTest.php | 38 ++------------ tests/GridFS/WritableStreamFunctionalTest.php | 28 ----------- tests/UnifiedSpecTests/Context.php | 6 +-- tests/UnifiedSpecTests/UnifiedSpecTest.php | 4 ++ tests/UnifiedSpecTests/Util.php | 4 +- 9 files changed, 42 insertions(+), 151 deletions(-) create mode 100644 UPGRADE-2.0.md diff --git a/UPGRADE-2.0.md b/UPGRADE-2.0.md new file mode 100644 index 000000000..3f012f6d2 --- /dev/null +++ b/UPGRADE-2.0.md @@ -0,0 +1,28 @@ +UPGRADE FROM 1.x to 2.0 +======================== + +GridFS +------ + + * The `md5` is no longer calculated when a file is uploaded to GridFS. + Applications that require a file digest should implement it outside GridFS + and store in metadata. + + ```php + $hash = hash_file('sha256', $filename); + $bucket->openUploadStream($fileId, ['metadata' => ['hash' => $hash]]); + ``` + + * The fields `contentType` and `aliases` are no longer stored in the `files` + collection. Applications that require this information should store it in + metadata. + + **Before:** + ```php + $bucket->openUploadStream($fileId, ['contentType' => 'image/png']); + ``` + + **After:** + ```php + $bucket->openUploadStream($fileId, ['metadata' => ['contentType' => 'image/png']]); + ``` diff --git a/composer.json b/composer.json index a856f4e84..fd6362af2 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,6 @@ ], "require": { "php": "^8.1", - "ext-hash": "*", "ext-json": "*", "ext-mongodb": "^1.20.0", "composer-runtime-api": "^2.0", diff --git a/src/GridFS/Bucket.php b/src/GridFS/Bucket.php index 56a4e26e2..04324df09 100644 --- a/src/GridFS/Bucket.php +++ b/src/GridFS/Bucket.php @@ -45,7 +45,6 @@ use function get_resource_type; use function in_array; use function is_array; -use function is_bool; use function is_integer; use function is_object; use function is_resource; @@ -59,11 +58,8 @@ use function stream_copy_to_stream; use function stream_get_meta_data; use function stream_get_wrappers; -use function trigger_error; use function urlencode; -use const E_USER_DEPRECATED; - /** * Bucket provides a public API for interacting with the GridFS files and chunks * collections. @@ -88,8 +84,6 @@ class Bucket private string $bucketName; - private bool $disableMD5; - private int $chunkSizeBytes; private ReadConcern $readConcern; @@ -111,9 +105,6 @@ class Bucket * * chunkSizeBytes (integer): The chunk size in bytes. Defaults to * 261120 (i.e. 255 KiB). * - * * disableMD5 (boolean): When true, no MD5 sum will be generated for - * each stored file. Defaults to "false". - * * * readConcern (MongoDB\Driver\ReadConcern): Read concern. * * * readPreference (MongoDB\Driver\ReadPreference): Read preference. @@ -129,14 +120,9 @@ class Bucket */ public function __construct(private Manager $manager, private string $databaseName, array $options = []) { - if (isset($options['disableMD5']) && $options['disableMD5'] === false) { - @trigger_error('Setting GridFS "disableMD5" option to "false" is deprecated since mongodb/mongodb 1.18 and will not be supported in version 2.0.', E_USER_DEPRECATED); - } - $options += [ 'bucketName' => self::DEFAULT_BUCKET_NAME, 'chunkSizeBytes' => self::DEFAULT_CHUNK_SIZE_BYTES, - 'disableMD5' => false, ]; if (! is_string($options['bucketName'])) { @@ -155,10 +141,6 @@ public function __construct(private Manager $manager, private string $databaseNa throw InvalidArgumentException::invalidType('"codec" option', $options['codec'], DocumentCodec::class); } - if (! is_bool($options['disableMD5'])) { - throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean'); - } - if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) { throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], ReadConcern::class); } @@ -182,7 +164,6 @@ public function __construct(private Manager $manager, private string $databaseNa $this->bucketName = $options['bucketName']; $this->chunkSizeBytes = $options['chunkSizeBytes']; $this->codec = $options['codec'] ?? null; - $this->disableMD5 = $options['disableMD5']; $this->readConcern = $options['readConcern'] ?? $this->manager->getReadConcern(); $this->readPreference = $options['readPreference'] ?? $this->manager->getReadPreference(); $this->typeMap = $options['typeMap'] ?? self::DEFAULT_TYPE_MAP; @@ -211,7 +192,6 @@ public function __debugInfo() 'bucketName' => $this->bucketName, 'codec' => $this->codec, 'databaseName' => $this->databaseName, - 'disableMD5' => $this->disableMD5, 'manager' => $this->manager, 'chunkSizeBytes' => $this->chunkSizeBytes, 'readConcern' => $this->readConcern, @@ -565,9 +545,6 @@ public function openDownloadStreamByName(string $filename, array $options = []) * * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the * bucket's chunk size. * - * * disableMD5 (boolean): When true, no MD5 sum will be generated for - * the stored file. Defaults to "false". - * * * metadata (document): User data for the "metadata" field of the files * collection document. * @@ -579,7 +556,6 @@ public function openUploadStream(string $filename, array $options = []) { $options += [ 'chunkSizeBytes' => $this->chunkSizeBytes, - 'disableMD5' => $this->disableMD5, ]; $path = $this->createPathForUpload(); @@ -658,9 +634,6 @@ public function rename(mixed $id, string $newFilename) * * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the * bucket's chunk size. * - * * disableMD5 (boolean): When true, no MD5 sum will be generated for - * the stored file. Defaults to "false". - * * * metadata (document): User data for the "metadata" field of the files * collection document. * @@ -792,9 +765,9 @@ private function registerStreamWrapper(): void * * @see StreamWrapper::setContextResolver() * - * @param string $path The full url provided to fopen(). It contains the filename. - * gridfs://database_name/collection_name.files/file_name - * @param array{revision?: int, chunkSizeBytes?: int, disableMD5?: bool} $context The options provided to fopen() + * @param string $path The full url provided to fopen(). It contains the filename. + * gridfs://database_name/collection_name.files/file_name + * @param array{revision?: int, chunkSizeBytes?: int} $context The options provided to fopen() * * @return array{collectionWrapper: CollectionWrapper, file: object}|array{collectionWrapper: CollectionWrapper, filename: string, options: array} * @@ -825,7 +798,6 @@ private function resolveStreamContext(string $path, string $mode, array $context 'filename' => $filename, 'options' => $context + [ 'chunkSizeBytes' => $this->chunkSizeBytes, - 'disableMD5' => $this->disableMD5, ], ]; } diff --git a/src/GridFS/WritableStream.php b/src/GridFS/WritableStream.php index 65b35de90..093a10a7c 100644 --- a/src/GridFS/WritableStream.php +++ b/src/GridFS/WritableStream.php @@ -17,7 +17,6 @@ namespace MongoDB\GridFS; -use HashContext; use MongoDB\BSON\Binary; use MongoDB\BSON\ObjectId; use MongoDB\BSON\UTCDateTime; @@ -25,14 +24,8 @@ use MongoDB\Exception\InvalidArgumentException; use function array_intersect_key; -use function hash_final; -use function hash_init; -use function hash_update; -use function is_bool; use function is_integer; -use function is_string; use function MongoDB\is_document; -use function MongoDB\is_string_array; use function sprintf; use function strlen; use function substr; @@ -52,12 +45,8 @@ class WritableStream private int $chunkSize; - private bool $disableMD5; - private array $file; - private ?HashContext $hashCtx = null; - private bool $isClosed = false; private int $length = 0; @@ -69,19 +58,9 @@ class WritableStream * * * _id (mixed): File document identifier. Defaults to a new ObjectId. * - * * aliases (array of strings): DEPRECATED An array of aliases. - * Applications wishing to store aliases should add an aliases field to - * the metadata document instead. - * * * chunkSizeBytes (integer): The chunk size in bytes. Defaults to * 261120 (i.e. 255 KiB). * - * * disableMD5 (boolean): When true, no MD5 sum will be generated. - * Defaults to "false". - * - * * contentType (string): DEPRECATED content type to be stored with the - * file. This information should now be added to the metadata. - * * * metadata (document): User data for the "metadata" field of the files * collection document. * @@ -95,13 +74,8 @@ public function __construct(private CollectionWrapper $collectionWrapper, string $options += [ '_id' => new ObjectId(), 'chunkSizeBytes' => self::DEFAULT_CHUNK_SIZE_BYTES, - 'disableMD5' => false, ]; - if (isset($options['aliases']) && ! is_string_array($options['aliases'])) { - throw InvalidArgumentException::invalidType('"aliases" option', $options['aliases'], 'array of strings'); - } - if (! is_integer($options['chunkSizeBytes'])) { throw InvalidArgumentException::invalidType('"chunkSizeBytes" option', $options['chunkSizeBytes'], 'integer'); } @@ -110,32 +84,18 @@ public function __construct(private CollectionWrapper $collectionWrapper, string throw new InvalidArgumentException(sprintf('Expected "chunkSizeBytes" option to be >= 1, %d given', $options['chunkSizeBytes'])); } - if (! is_bool($options['disableMD5'])) { - throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean'); - } - - if (isset($options['contentType']) && ! is_string($options['contentType'])) { - throw InvalidArgumentException::invalidType('"contentType" option', $options['contentType'], 'string'); - } - if (isset($options['metadata']) && ! is_document($options['metadata'])) { throw InvalidArgumentException::expectedDocumentType('"metadata" option', $options['metadata']); } $this->chunkSize = $options['chunkSizeBytes']; - $this->disableMD5 = $options['disableMD5']; - - if (! $this->disableMD5) { - $this->hashCtx = hash_init('md5'); - } - $this->file = [ '_id' => $options['_id'], 'chunkSize' => $this->chunkSize, 'filename' => $filename, 'length' => null, 'uploadDate' => null, - ] + array_intersect_key($options, ['aliases' => 1, 'contentType' => 1, 'metadata' => 1]); + ] + array_intersect_key($options, ['metadata' => 1]); } /** @@ -248,10 +208,6 @@ private function fileCollectionInsert(): void $this->file['length'] = $this->length; $this->file['uploadDate'] = new UTCDateTime(); - if (! $this->disableMD5 && $this->hashCtx) { - $this->file['md5'] = hash_final($this->hashCtx); - } - try { $this->collectionWrapper->insertFile($this->file); } catch (DriverRuntimeException $e) { @@ -276,10 +232,6 @@ private function insertChunkFromBuffer(): void 'data' => new Binary($data), ]; - if (! $this->disableMD5 && $this->hashCtx) { - hash_update($this->hashCtx, $data); - } - try { $this->collectionWrapper->insertChunk($chunk); } catch (DriverRuntimeException $e) { diff --git a/tests/GridFS/BucketFunctionalTest.php b/tests/GridFS/BucketFunctionalTest.php index 2f2d126d4..23b2baff9 100644 --- a/tests/GridFS/BucketFunctionalTest.php +++ b/tests/GridFS/BucketFunctionalTest.php @@ -60,7 +60,6 @@ public function testValidConstructorOptions(): void 'readConcern' => new ReadConcern(ReadConcern::LOCAL), 'readPreference' => new ReadPreference(ReadPreference::PRIMARY), 'writeConcern' => new WriteConcern(WriteConcern::MAJORITY, 1000), - 'disableMD5' => true, ]); } @@ -77,7 +76,6 @@ public static function provideInvalidConstructorOptions() 'bucketName' => self::getInvalidStringValues(true), 'chunkSizeBytes' => self::getInvalidIntegerValues(true), 'codec' => self::getInvalidDocumentCodecValues(), - 'disableMD5' => self::getInvalidBooleanValues(true), 'readConcern' => self::getInvalidReadConcernValues(), 'readPreference' => self::getInvalidReadPreferenceValues(), 'typeMap' => self::getInvalidArrayValues(), @@ -762,46 +760,16 @@ public function testUploadingAnEmptyFile(): void [ 'projection' => [ 'length' => 1, - 'md5' => 1, '_id' => 0, ], ], ); - $expected = [ - 'length' => 0, - 'md5' => 'd41d8cd98f00b204e9800998ecf8427e', - ]; + $expected = ['length' => 0]; $this->assertSameDocument($expected, $fileDocument); } - public function testDisableMD5(): void - { - $options = ['disableMD5' => true]; - $id = $this->bucket->uploadFromStream('filename', self::createStream('data'), $options); - - $fileDocument = $this->filesCollection->findOne( - ['_id' => $id], - ); - - $this->assertArrayNotHasKey('md5', $fileDocument); - } - - public function testDisableMD5OptionInConstructor(): void - { - $options = ['disableMD5' => true]; - - $this->bucket = new Bucket($this->manager, $this->getDatabaseName(), $options); - $id = $this->bucket->uploadFromStream('filename', self::createStream('data')); - - $fileDocument = $this->filesCollection->findOne( - ['_id' => $id], - ); - - $this->assertArrayNotHasKey('md5', $fileDocument); - } - public function testUploadingFirstFileCreatesIndexes(): void { $this->bucket->uploadFromStream('filename', self::createStream('foo')); @@ -863,7 +831,7 @@ public function testDanglingOpenWritableStream(): void $client = MongoDB\Tests\FunctionalTestCase::createTestClient(); $database = $client->selectDatabase(getenv('MONGODB_DATABASE') ?: 'phplib_test'); $gridfs = $database->selectGridFSBucket(); - $stream = $gridfs->openUploadStream('hello.txt', ['disableMD5' => true]); + $stream = $gridfs->openUploadStream('hello.txt'); fwrite($stream, 'Hello MongoDB!'); PHP; @@ -970,7 +938,7 @@ public function testResolveStreamContextForWrite(): void $this->assertArrayHasKey('filename', $context); $this->assertSame('filename', $context['filename']); $this->assertArrayHasKey('options', $context); - $this->assertSame(['chunkSizeBytes' => 261120, 'disableMD5' => false], $context['options']); + $this->assertSame(['chunkSizeBytes' => 261120], $context['options']); } /** diff --git a/tests/GridFS/WritableStreamFunctionalTest.php b/tests/GridFS/WritableStreamFunctionalTest.php index a46741fae..fd5abf421 100644 --- a/tests/GridFS/WritableStreamFunctionalTest.php +++ b/tests/GridFS/WritableStreamFunctionalTest.php @@ -43,7 +43,6 @@ public static function provideInvalidConstructorOptions() { return self::createOptionDataProvider([ 'chunkSizeBytes' => self::getInvalidIntegerValues(true), - 'disableMD5' => self::getInvalidBooleanValues(true), 'metadata' => self::getInvalidDocumentValues(), ]); } @@ -70,31 +69,4 @@ public function testWriteBytesAlwaysUpdatesFileSize(): void $stream->close(); $this->assertSame(1536, $stream->getSize()); } - - /** @dataProvider provideInputDataAndExpectedMD5 */ - public function testWriteBytesCalculatesMD5($input, $expectedMD5): void - { - $stream = new WritableStream($this->collectionWrapper, 'filename'); - $stream->writeBytes($input); - $stream->close(); - - $fileDocument = $this->filesCollection->findOne( - ['_id' => $stream->getFile()->_id], - ['projection' => ['md5' => 1, '_id' => 0]], - ); - - $this->assertSameDocument(['md5' => $expectedMD5], $fileDocument); - } - - public static function provideInputDataAndExpectedMD5() - { - return [ - ['', 'd41d8cd98f00b204e9800998ecf8427e'], - ['foobar', '3858f62230ac3c915f300c664312c63f'], - [str_repeat('foobar', 43520), '88ff0e5fcb0acb27947d736b5d69cb73'], - [str_repeat('foobar', 43521), '8ff86511c95a06a611842ceb555d8454'], - [str_repeat('foobar', 87040), '45bfa1a9ec36728ee7338d15c5a30c13'], - [str_repeat('foobar', 87041), '95e78f624f8e745bcfd2d11691fa601e'], - ]; - } } diff --git a/tests/UnifiedSpecTests/Context.php b/tests/UnifiedSpecTests/Context.php index 56f68adc0..a06e7cb89 100644 --- a/tests/UnifiedSpecTests/Context.php +++ b/tests/UnifiedSpecTests/Context.php @@ -497,7 +497,7 @@ private static function prepareCollectionOrDatabaseOptions(array $options): arra private static function prepareBucketOptions(array $options): array { - Util::assertHasOnlyKeys($options, ['bucketName', 'chunkSizeBytes', 'disableMD5', 'readConcern', 'readPreference', 'writeConcern']); + Util::assertHasOnlyKeys($options, ['bucketName', 'chunkSizeBytes', 'readConcern', 'readPreference', 'writeConcern']); if (array_key_exists('bucketName', $options)) { assertIsString($options['bucketName']); @@ -507,10 +507,6 @@ private static function prepareBucketOptions(array $options): array assertIsInt($options['chunkSizeBytes']); } - if (array_key_exists('disableMD5', $options)) { - assertIsBool($options['disableMD5']); - } - return Util::prepareCommonOptions($options); } diff --git a/tests/UnifiedSpecTests/UnifiedSpecTest.php b/tests/UnifiedSpecTests/UnifiedSpecTest.php index 6b6031948..6500e59d7 100644 --- a/tests/UnifiedSpecTests/UnifiedSpecTest.php +++ b/tests/UnifiedSpecTests/UnifiedSpecTest.php @@ -187,6 +187,10 @@ class UnifiedSpecTest extends FunctionalTestCase 'crud/db-aggregate-write-readPreference: Database-level aggregate with $out omits read preference for pre-5.0 server' => 'PHPLIB-1458', 'crud/db-aggregate-write-readPreference: Database-level aggregate with $merge includes read preference for 5.0+ server' => 'PHPLIB-1458', 'crud/db-aggregate-write-readPreference: Database-level aggregate with $merge omits read preference for pre-5.0 server' => 'PHPLIB-1458', + // GridFS deprecated fields are removed + 'gridfs/gridfs-upload-disableMD5: upload when length is 0 sans MD5' => 'Deprecated fields are removed', + 'gridfs/gridfs-upload-disableMD5: upload when length is 1 sans MD5' => 'Deprecated fields are removed', + 'gridfs/gridfs-upload: upload when contentType is provided' => 'Deprecated fields are removed', ]; /** diff --git a/tests/UnifiedSpecTests/Util.php b/tests/UnifiedSpecTests/Util.php index 4f2fb22f1..d817d61d3 100644 --- a/tests/UnifiedSpecTests/Util.php +++ b/tests/UnifiedSpecTests/Util.php @@ -134,8 +134,8 @@ final class Util 'delete' => ['id'], 'downloadByName' => ['filename', 'revision'], 'download' => ['id'], - 'uploadWithId' => ['id', 'filename', 'source', 'chunkSizeBytes', 'disableMD5', 'contentType', 'metadata'], - 'upload' => ['filename', 'source', 'chunkSizeBytes', 'disableMD5', 'contentType', 'metadata'], + 'uploadWithId' => ['id', 'filename', 'source', 'chunkSizeBytes', 'metadata'], + 'upload' => ['filename', 'source', 'chunkSizeBytes', 'metadata'], ], ]; From 368954a273f8a7b8b2b02a60a5e9010a469b4539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 17 Sep 2024 09:06:08 +0200 Subject: [PATCH 2/6] PHPLIB-953 Make internal classes and Operation classes final (#1392) * PHPLIB-953 Make internal classes final * Make all Operation classes final * Add UPGRADE-2.0 --- UPGRADE-2.0.md | 2 ++ src/Command/ListCollections.php | 2 +- src/Command/ListDatabases.php | 2 +- src/GridFS/CollectionWrapper.php | 2 +- src/GridFS/ReadableStream.php | 2 +- src/GridFS/StreamWrapper.php | 4 ++-- src/GridFS/WritableStream.php | 2 +- src/Model/CachingIterator.php | 2 +- src/Model/CallbackIterator.php | 2 +- src/Model/ChangeStreamIterator.php | 2 +- src/Model/CollectionInfoCommandIterator.php | 2 +- src/Model/DatabaseInfoLegacyIterator.php | 2 +- src/Model/IndexInfoIteratorIterator.php | 2 +- src/Model/IndexInput.php | 2 +- src/Model/SearchIndexInput.php | 2 +- src/Operation/Aggregate.php | 2 +- src/Operation/BulkWrite.php | 2 +- src/Operation/Count.php | 2 +- src/Operation/CountDocuments.php | 2 +- src/Operation/CreateCollection.php | 2 +- src/Operation/CreateEncryptedCollection.php | 2 +- src/Operation/CreateIndexes.php | 2 +- src/Operation/CreateSearchIndexes.php | 2 +- src/Operation/DatabaseCommand.php | 2 +- src/Operation/Delete.php | 2 +- src/Operation/DeleteMany.php | 2 +- src/Operation/DeleteOne.php | 2 +- src/Operation/Distinct.php | 2 +- src/Operation/DropCollection.php | 2 +- src/Operation/DropDatabase.php | 2 +- src/Operation/DropEncryptedCollection.php | 2 +- src/Operation/DropIndexes.php | 2 +- src/Operation/DropSearchIndex.php | 2 +- src/Operation/EstimatedDocumentCount.php | 2 +- src/Operation/Explain.php | 2 +- src/Operation/Find.php | 2 +- src/Operation/FindAndModify.php | 2 +- src/Operation/FindOne.php | 2 +- src/Operation/FindOneAndDelete.php | 2 +- src/Operation/FindOneAndReplace.php | 2 +- src/Operation/FindOneAndUpdate.php | 2 +- src/Operation/InsertMany.php | 2 +- src/Operation/InsertOne.php | 2 +- src/Operation/ListCollectionNames.php | 2 +- src/Operation/ListCollections.php | 2 +- src/Operation/ListDatabaseNames.php | 2 +- src/Operation/ListDatabases.php | 2 +- src/Operation/ListIndexes.php | 2 +- src/Operation/ListSearchIndexes.php | 2 +- src/Operation/MapReduce.php | 2 +- src/Operation/ModifyCollection.php | 2 +- src/Operation/RenameCollection.php | 2 +- src/Operation/ReplaceOne.php | 2 +- src/Operation/Update.php | 2 +- src/Operation/UpdateMany.php | 2 +- src/Operation/UpdateOne.php | 2 +- src/Operation/UpdateSearchIndex.php | 2 +- src/Operation/Watch.php | 2 +- src/Operation/WithTransaction.php | 2 +- 59 files changed, 61 insertions(+), 59 deletions(-) diff --git a/UPGRADE-2.0.md b/UPGRADE-2.0.md index 3f012f6d2..15af9de1c 100644 --- a/UPGRADE-2.0.md +++ b/UPGRADE-2.0.md @@ -1,6 +1,8 @@ UPGRADE FROM 1.x to 2.0 ======================== + * Classes in the namespace `MongoDB\Operation\` are `final`. + GridFS ------ diff --git a/src/Command/ListCollections.php b/src/Command/ListCollections.php index 454e145f3..f2fb2410f 100644 --- a/src/Command/ListCollections.php +++ b/src/Command/ListCollections.php @@ -36,7 +36,7 @@ * @internal * @see https://mongodb.com/docs/manual/reference/command/listCollections/ */ -class ListCollections implements Executable +final class ListCollections implements Executable { /** * Constructs a listCollections command. diff --git a/src/Command/ListDatabases.php b/src/Command/ListDatabases.php index 5386559db..7ceeb4206 100644 --- a/src/Command/ListDatabases.php +++ b/src/Command/ListDatabases.php @@ -37,7 +37,7 @@ * @internal * @see https://mongodb.com/docs/manual/reference/command/listDatabases/ */ -class ListDatabases implements Executable +final class ListDatabases implements Executable { /** * Constructs a listDatabases command. diff --git a/src/GridFS/CollectionWrapper.php b/src/GridFS/CollectionWrapper.php index 0c6b9b96c..a28185cb0 100644 --- a/src/GridFS/CollectionWrapper.php +++ b/src/GridFS/CollectionWrapper.php @@ -39,7 +39,7 @@ * * @internal */ -class CollectionWrapper +final class CollectionWrapper { private Collection $chunksCollection; diff --git a/src/GridFS/ReadableStream.php b/src/GridFS/ReadableStream.php index 980e3e19f..c8441d18c 100644 --- a/src/GridFS/ReadableStream.php +++ b/src/GridFS/ReadableStream.php @@ -38,7 +38,7 @@ * * @internal */ -class ReadableStream +final class ReadableStream { private ?string $buffer = null; diff --git a/src/GridFS/StreamWrapper.php b/src/GridFS/StreamWrapper.php index cc1d89fc9..302a63385 100644 --- a/src/GridFS/StreamWrapper.php +++ b/src/GridFS/StreamWrapper.php @@ -49,7 +49,7 @@ * @see Bucket::openDownloadStream() * @psalm-type ContextOptions = array{collectionWrapper: CollectionWrapper, file: object}|array{collectionWrapper: CollectionWrapper, filename: string, options: array} */ -class StreamWrapper +final class StreamWrapper { /** @var resource|null Stream context (set by PHP) */ public $context; @@ -89,7 +89,7 @@ public static function register(string $protocol = 'gridfs'): void stream_wrapper_unregister($protocol); } - stream_wrapper_register($protocol, static::class, STREAM_IS_URL); + stream_wrapper_register($protocol, self::class, STREAM_IS_URL); } /** diff --git a/src/GridFS/WritableStream.php b/src/GridFS/WritableStream.php index 093a10a7c..e7a4e0e63 100644 --- a/src/GridFS/WritableStream.php +++ b/src/GridFS/WritableStream.php @@ -35,7 +35,7 @@ * * @internal */ -class WritableStream +final class WritableStream { private const DEFAULT_CHUNK_SIZE_BYTES = 261120; diff --git a/src/Model/CachingIterator.php b/src/Model/CachingIterator.php index 15ba7ca1a..2f4fcb29f 100644 --- a/src/Model/CachingIterator.php +++ b/src/Model/CachingIterator.php @@ -40,7 +40,7 @@ * @template TValue * @template-implements Iterator */ -class CachingIterator implements Countable, Iterator +final class CachingIterator implements Countable, Iterator { private const FIELD_KEY = 0; private const FIELD_VALUE = 1; diff --git a/src/Model/CallbackIterator.php b/src/Model/CallbackIterator.php index ea429ccbc..cf7e60fa5 100644 --- a/src/Model/CallbackIterator.php +++ b/src/Model/CallbackIterator.php @@ -34,7 +34,7 @@ * @template TCallbackValue * @template-implements Iterator */ -class CallbackIterator implements Iterator +final class CallbackIterator implements Iterator { /** @var callable(TValue, TKey): TCallbackValue */ private $callback; diff --git a/src/Model/ChangeStreamIterator.php b/src/Model/ChangeStreamIterator.php index aa635dda9..721c59734 100644 --- a/src/Model/ChangeStreamIterator.php +++ b/src/Model/ChangeStreamIterator.php @@ -51,7 +51,7 @@ * @template TValue of array|object * @template-extends IteratorIterator&Iterator> */ -class ChangeStreamIterator extends IteratorIterator implements CommandSubscriber +final class ChangeStreamIterator extends IteratorIterator implements CommandSubscriber { private int $batchPosition = 0; diff --git a/src/Model/CollectionInfoCommandIterator.php b/src/Model/CollectionInfoCommandIterator.php index 14ef39a02..3a87db65b 100644 --- a/src/Model/CollectionInfoCommandIterator.php +++ b/src/Model/CollectionInfoCommandIterator.php @@ -32,7 +32,7 @@ * @see https://mongodb.com/docs/manual/reference/command/listCollections/ * @template-extends IteratorIterator> */ -class CollectionInfoCommandIterator extends IteratorIterator implements CollectionInfoIterator +final class CollectionInfoCommandIterator extends IteratorIterator implements CollectionInfoIterator { /** @param Traversable $iterator */ public function __construct(Traversable $iterator, private ?string $databaseName = null) diff --git a/src/Model/DatabaseInfoLegacyIterator.php b/src/Model/DatabaseInfoLegacyIterator.php index da657acec..07aacd6a3 100644 --- a/src/Model/DatabaseInfoLegacyIterator.php +++ b/src/Model/DatabaseInfoLegacyIterator.php @@ -32,7 +32,7 @@ * @see \MongoDB\Client::listDatabases() * @see https://mongodb.com/docs/manual/reference/command/listDatabases/ */ -class DatabaseInfoLegacyIterator implements DatabaseInfoIterator +final class DatabaseInfoLegacyIterator implements DatabaseInfoIterator { public function __construct(private array $databases) { diff --git a/src/Model/IndexInfoIteratorIterator.php b/src/Model/IndexInfoIteratorIterator.php index a2fa85d6f..871a6ba4b 100644 --- a/src/Model/IndexInfoIteratorIterator.php +++ b/src/Model/IndexInfoIteratorIterator.php @@ -36,7 +36,7 @@ * @see https://mongodb.com/docs/manual/reference/system-collections/ * @template-extends IteratorIterator> */ -class IndexInfoIteratorIterator extends IteratorIterator implements IndexInfoIterator +final class IndexInfoIteratorIterator extends IteratorIterator implements IndexInfoIterator { /** @param Traversable $iterator */ public function __construct(Traversable $iterator, private ?string $ns = null) diff --git a/src/Model/IndexInput.php b/src/Model/IndexInput.php index 657c2b6da..133451eeb 100644 --- a/src/Model/IndexInput.php +++ b/src/Model/IndexInput.php @@ -38,7 +38,7 @@ * @see https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst * @see https://mongodb.com/docs/manual/reference/method/db.collection.createIndex/ */ -class IndexInput implements Serializable +final class IndexInput implements Serializable { /** * @param array $index Index specification diff --git a/src/Model/SearchIndexInput.php b/src/Model/SearchIndexInput.php index bad880a7f..b27f4f3be 100644 --- a/src/Model/SearchIndexInput.php +++ b/src/Model/SearchIndexInput.php @@ -34,7 +34,7 @@ * @see https://github.com/mongodb/specifications/blob/master/source/index-management/index-management.rst#search-indexes * @see https://mongodb.com/docs/manual/reference/method/db.collection.createSearchIndex/ */ -class SearchIndexInput implements Serializable +final class SearchIndexInput implements Serializable { /** * @param array{definition: array|object, name?: string, type?: string} $index Search index specification diff --git a/src/Operation/Aggregate.php b/src/Operation/Aggregate.php index 00d408c18..495d741a9 100644 --- a/src/Operation/Aggregate.php +++ b/src/Operation/Aggregate.php @@ -49,7 +49,7 @@ * @see \MongoDB\Collection::aggregate() * @see https://mongodb.com/docs/manual/reference/command/aggregate/ */ -class Aggregate implements Executable, Explainable +final class Aggregate implements Executable, Explainable { private bool $isWrite; diff --git a/src/Operation/BulkWrite.php b/src/Operation/BulkWrite.php index 6da8a68b3..d9eb43376 100644 --- a/src/Operation/BulkWrite.php +++ b/src/Operation/BulkWrite.php @@ -46,7 +46,7 @@ * * @see \MongoDB\Collection::bulkWrite() */ -class BulkWrite implements Executable +final class BulkWrite implements Executable { public const DELETE_MANY = 'deleteMany'; public const DELETE_ONE = 'deleteOne'; diff --git a/src/Operation/Count.php b/src/Operation/Count.php index b29aa826a..6a42a5c15 100644 --- a/src/Operation/Count.php +++ b/src/Operation/Count.php @@ -41,7 +41,7 @@ * @see \MongoDB\Collection::count() * @see https://mongodb.com/docs/manual/reference/command/count/ */ -class Count implements Executable, Explainable +final class Count implements Executable, Explainable { /** * Constructs a count command. diff --git a/src/Operation/CountDocuments.php b/src/Operation/CountDocuments.php index 5d6502fca..449399a5a 100644 --- a/src/Operation/CountDocuments.php +++ b/src/Operation/CountDocuments.php @@ -37,7 +37,7 @@ * @see \MongoDB\Collection::countDocuments() * @see https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst#countdocuments */ -class CountDocuments implements Executable +final class CountDocuments implements Executable { private array $aggregateOptions; diff --git a/src/Operation/CreateCollection.php b/src/Operation/CreateCollection.php index 3292e6fa7..e5406315e 100644 --- a/src/Operation/CreateCollection.php +++ b/src/Operation/CreateCollection.php @@ -41,7 +41,7 @@ * @see \MongoDB\Database::createCollection() * @see https://mongodb.com/docs/manual/reference/command/create/ */ -class CreateCollection implements Executable +final class CreateCollection implements Executable { public const USE_POWER_OF_2_SIZES = 1; public const NO_PADDING = 2; diff --git a/src/Operation/CreateEncryptedCollection.php b/src/Operation/CreateEncryptedCollection.php index a5cde6514..9c7d120d8 100644 --- a/src/Operation/CreateEncryptedCollection.php +++ b/src/Operation/CreateEncryptedCollection.php @@ -48,7 +48,7 @@ * @see https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/client-side-encryption.rst#create-encrypted-collection-helper * @see https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/manage-collections/ */ -class CreateEncryptedCollection implements Executable +final class CreateEncryptedCollection implements Executable { private const WIRE_VERSION_FOR_QUERYABLE_ENCRYPTION_V2 = 21; diff --git a/src/Operation/CreateIndexes.php b/src/Operation/CreateIndexes.php index 396cc8163..637e99cbd 100644 --- a/src/Operation/CreateIndexes.php +++ b/src/Operation/CreateIndexes.php @@ -41,7 +41,7 @@ * @see \MongoDB\Collection::createIndexes() * @see https://mongodb.com/docs/manual/reference/command/createIndexes/ */ -class CreateIndexes implements Executable +final class CreateIndexes implements Executable { private const WIRE_VERSION_FOR_COMMIT_QUORUM = 9; diff --git a/src/Operation/CreateSearchIndexes.php b/src/Operation/CreateSearchIndexes.php index fd27b043c..b96ca0f41 100644 --- a/src/Operation/CreateSearchIndexes.php +++ b/src/Operation/CreateSearchIndexes.php @@ -37,7 +37,7 @@ * @see \MongoDB\Collection::createSearchIndexes() * @see https://mongodb.com/docs/manual/reference/command/createSearchIndexes/ */ -class CreateSearchIndexes implements Executable +final class CreateSearchIndexes implements Executable { private array $indexes = []; diff --git a/src/Operation/DatabaseCommand.php b/src/Operation/DatabaseCommand.php index 4ae8214f1..bf02a6430 100644 --- a/src/Operation/DatabaseCommand.php +++ b/src/Operation/DatabaseCommand.php @@ -32,7 +32,7 @@ * * @see \MongoDB\Database::command() */ -class DatabaseCommand implements Executable +final class DatabaseCommand implements Executable { private Command $command; diff --git a/src/Operation/Delete.php b/src/Operation/Delete.php index 477cade91..09e39a922 100644 --- a/src/Operation/Delete.php +++ b/src/Operation/Delete.php @@ -42,7 +42,7 @@ * @internal * @see https://mongodb.com/docs/manual/reference/command/delete/ */ -class Delete implements Executable, Explainable +final class Delete implements Executable, Explainable { private const WIRE_VERSION_FOR_HINT = 9; diff --git a/src/Operation/DeleteMany.php b/src/Operation/DeleteMany.php index 20ca38d1d..2d85727a8 100644 --- a/src/Operation/DeleteMany.php +++ b/src/Operation/DeleteMany.php @@ -29,7 +29,7 @@ * @see \MongoDB\Collection::deleteOne() * @see https://mongodb.com/docs/manual/reference/command/delete/ */ -class DeleteMany implements Executable, Explainable +final class DeleteMany implements Executable, Explainable { private Delete $delete; diff --git a/src/Operation/DeleteOne.php b/src/Operation/DeleteOne.php index 1aaad5d27..c9460a916 100644 --- a/src/Operation/DeleteOne.php +++ b/src/Operation/DeleteOne.php @@ -29,7 +29,7 @@ * @see \MongoDB\Collection::deleteOne() * @see https://mongodb.com/docs/manual/reference/command/delete/ */ -class DeleteOne implements Executable, Explainable +final class DeleteOne implements Executable, Explainable { private Delete $delete; diff --git a/src/Operation/Distinct.php b/src/Operation/Distinct.php index 1483012f3..e69adabac 100644 --- a/src/Operation/Distinct.php +++ b/src/Operation/Distinct.php @@ -40,7 +40,7 @@ * @see \MongoDB\Collection::distinct() * @see https://mongodb.com/docs/manual/reference/command/distinct/ */ -class Distinct implements Executable, Explainable +final class Distinct implements Executable, Explainable { /** * Constructs a distinct command. diff --git a/src/Operation/DropCollection.php b/src/Operation/DropCollection.php index a467a7391..3384bd998 100644 --- a/src/Operation/DropCollection.php +++ b/src/Operation/DropCollection.php @@ -36,7 +36,7 @@ * @see \MongoDB\Database::dropCollection() * @see https://mongodb.com/docs/manual/reference/command/drop/ */ -class DropCollection implements Executable +final class DropCollection implements Executable { private const ERROR_CODE_NAMESPACE_NOT_FOUND = 26; diff --git a/src/Operation/DropDatabase.php b/src/Operation/DropDatabase.php index 15cb0c34e..cb1563612 100644 --- a/src/Operation/DropDatabase.php +++ b/src/Operation/DropDatabase.php @@ -34,7 +34,7 @@ * @see \MongoDB\Database::drop() * @see https://mongodb.com/docs/manual/reference/command/dropDatabase/ */ -class DropDatabase implements Executable +final class DropDatabase implements Executable { /** * Constructs a dropDatabase command. diff --git a/src/Operation/DropEncryptedCollection.php b/src/Operation/DropEncryptedCollection.php index 491a8e9eb..1d90f89f4 100644 --- a/src/Operation/DropEncryptedCollection.php +++ b/src/Operation/DropEncryptedCollection.php @@ -37,7 +37,7 @@ * @see https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/client-side-encryption.rst#drop-collection-helper * @see https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/manage-collections/ */ -class DropEncryptedCollection implements Executable +final class DropEncryptedCollection implements Executable { private DropCollection $dropCollection; diff --git a/src/Operation/DropIndexes.php b/src/Operation/DropIndexes.php index c5302e250..69cc8ce4c 100644 --- a/src/Operation/DropIndexes.php +++ b/src/Operation/DropIndexes.php @@ -35,7 +35,7 @@ * @see \MongoDB\Collection::dropIndexes() * @see https://mongodb.com/docs/manual/reference/command/dropIndexes/ */ -class DropIndexes implements Executable +final class DropIndexes implements Executable { /** * Constructs a dropIndexes command. diff --git a/src/Operation/DropSearchIndex.php b/src/Operation/DropSearchIndex.php index 42fc58baa..73b9c6e17 100644 --- a/src/Operation/DropSearchIndex.php +++ b/src/Operation/DropSearchIndex.php @@ -30,7 +30,7 @@ * @see \MongoDB\Collection::dropSearchIndexes() * @see https://mongodb.com/docs/manual/reference/command/dropSearchIndexes/ */ -class DropSearchIndex implements Executable +final class DropSearchIndex implements Executable { private const ERROR_CODE_NAMESPACE_NOT_FOUND = 26; diff --git a/src/Operation/EstimatedDocumentCount.php b/src/Operation/EstimatedDocumentCount.php index e3c240c78..3a6ce256b 100644 --- a/src/Operation/EstimatedDocumentCount.php +++ b/src/Operation/EstimatedDocumentCount.php @@ -35,7 +35,7 @@ * @see \MongoDB\Collection::estimatedDocumentCount() * @see https://mongodb.com/docs/manual/reference/command/count/ */ -class EstimatedDocumentCount implements Executable, Explainable +final class EstimatedDocumentCount implements Executable, Explainable { private array $options; diff --git a/src/Operation/Explain.php b/src/Operation/Explain.php index 1c132b2f5..a6e14303f 100644 --- a/src/Operation/Explain.php +++ b/src/Operation/Explain.php @@ -35,7 +35,7 @@ * @see \MongoDB\Collection::explain() * @see https://mongodb.com/docs/manual/reference/command/explain/ */ -class Explain implements Executable +final class Explain implements Executable { public const VERBOSITY_ALL_PLANS = 'allPlansExecution'; public const VERBOSITY_EXEC_STATS = 'executionStats'; diff --git a/src/Operation/Find.php b/src/Operation/Find.php index 13944a682..f391faea5 100644 --- a/src/Operation/Find.php +++ b/src/Operation/Find.php @@ -48,7 +48,7 @@ * @see https://mongodb.com/docs/manual/tutorial/query-documents/ * @see https://mongodb.com/docs/manual/reference/operator/query-modifier/ */ -class Find implements Executable, Explainable +final class Find implements Executable, Explainable { public const NON_TAILABLE = 1; public const TAILABLE = 2; diff --git a/src/Operation/FindAndModify.php b/src/Operation/FindAndModify.php index e67413b6c..07abfe80e 100644 --- a/src/Operation/FindAndModify.php +++ b/src/Operation/FindAndModify.php @@ -51,7 +51,7 @@ * @internal * @see https://mongodb.com/docs/manual/reference/command/findAndModify/ */ -class FindAndModify implements Executable, Explainable +final class FindAndModify implements Executable, Explainable { private const WIRE_VERSION_FOR_HINT = 9; diff --git a/src/Operation/FindOne.php b/src/Operation/FindOne.php index 6fdff0a29..0670d97c6 100644 --- a/src/Operation/FindOne.php +++ b/src/Operation/FindOne.php @@ -31,7 +31,7 @@ * @see https://mongodb.com/docs/manual/tutorial/query-documents/ * @see https://mongodb.com/docs/manual/reference/operator/query-modifier/ */ -class FindOne implements Executable, Explainable +final class FindOne implements Executable, Explainable { private Find $find; diff --git a/src/Operation/FindOneAndDelete.php b/src/Operation/FindOneAndDelete.php index ae5148872..68be63e23 100644 --- a/src/Operation/FindOneAndDelete.php +++ b/src/Operation/FindOneAndDelete.php @@ -30,7 +30,7 @@ * @see \MongoDB\Collection::findOneAndDelete() * @see https://mongodb.com/docs/manual/reference/command/findAndModify/ */ -class FindOneAndDelete implements Executable, Explainable +final class FindOneAndDelete implements Executable, Explainable { private FindAndModify $findAndModify; diff --git a/src/Operation/FindOneAndReplace.php b/src/Operation/FindOneAndReplace.php index 6f4409406..21a34fc77 100644 --- a/src/Operation/FindOneAndReplace.php +++ b/src/Operation/FindOneAndReplace.php @@ -35,7 +35,7 @@ * @see \MongoDB\Collection::findOneAndReplace() * @see https://mongodb.com/docs/manual/reference/command/findAndModify/ */ -class FindOneAndReplace implements Executable, Explainable +final class FindOneAndReplace implements Executable, Explainable { public const RETURN_DOCUMENT_BEFORE = 1; public const RETURN_DOCUMENT_AFTER = 2; diff --git a/src/Operation/FindOneAndUpdate.php b/src/Operation/FindOneAndUpdate.php index 0fbe127d0..f44cc4421 100644 --- a/src/Operation/FindOneAndUpdate.php +++ b/src/Operation/FindOneAndUpdate.php @@ -34,7 +34,7 @@ * @see \MongoDB\Collection::findOneAndUpdate() * @see https://mongodb.com/docs/manual/reference/command/findAndModify/ */ -class FindOneAndUpdate implements Executable, Explainable +final class FindOneAndUpdate implements Executable, Explainable { public const RETURN_DOCUMENT_BEFORE = 1; public const RETURN_DOCUMENT_AFTER = 2; diff --git a/src/Operation/InsertMany.php b/src/Operation/InsertMany.php index 01640da2f..8f99fc771 100644 --- a/src/Operation/InsertMany.php +++ b/src/Operation/InsertMany.php @@ -38,7 +38,7 @@ * @see \MongoDB\Collection::insertMany() * @see https://mongodb.com/docs/manual/reference/command/insert/ */ -class InsertMany implements Executable +final class InsertMany implements Executable { /** @var list */ private array $documents; diff --git a/src/Operation/InsertOne.php b/src/Operation/InsertOne.php index 8626364f8..95d49c129 100644 --- a/src/Operation/InsertOne.php +++ b/src/Operation/InsertOne.php @@ -36,7 +36,7 @@ * @see \MongoDB\Collection::insertOne() * @see https://mongodb.com/docs/manual/reference/command/insert/ */ -class InsertOne implements Executable +final class InsertOne implements Executable { private array|object $document; diff --git a/src/Operation/ListCollectionNames.php b/src/Operation/ListCollectionNames.php index f2124c4d4..fefa464af 100644 --- a/src/Operation/ListCollectionNames.php +++ b/src/Operation/ListCollectionNames.php @@ -30,7 +30,7 @@ * @see \MongoDB\Database::listCollectionNames() * @see https://mongodb.com/docs/manual/reference/command/listCollections/ */ -class ListCollectionNames implements Executable +final class ListCollectionNames implements Executable { private ListCollectionsCommand $listCollections; diff --git a/src/Operation/ListCollections.php b/src/Operation/ListCollections.php index 340c11017..bc76d8a58 100644 --- a/src/Operation/ListCollections.php +++ b/src/Operation/ListCollections.php @@ -30,7 +30,7 @@ * @see \MongoDB\Database::listCollections() * @see https://mongodb.com/docs/manual/reference/command/listCollections/ */ -class ListCollections implements Executable +final class ListCollections implements Executable { private ListCollectionsCommand $listCollections; diff --git a/src/Operation/ListDatabaseNames.php b/src/Operation/ListDatabaseNames.php index 7b6a529b4..0c6ee5437 100644 --- a/src/Operation/ListDatabaseNames.php +++ b/src/Operation/ListDatabaseNames.php @@ -33,7 +33,7 @@ * @see \MongoDB\Client::listDatabaseNames() * @see https://mongodb.com/docs/manual/reference/command/listDatabases/#mongodb-dbcommand-dbcmd.listDatabases */ -class ListDatabaseNames implements Executable +final class ListDatabaseNames implements Executable { private ListDatabasesCommand $listDatabases; diff --git a/src/Operation/ListDatabases.php b/src/Operation/ListDatabases.php index ee90cca65..b5e505d23 100644 --- a/src/Operation/ListDatabases.php +++ b/src/Operation/ListDatabases.php @@ -31,7 +31,7 @@ * @see \MongoDB\Client::listDatabases() * @see https://mongodb.com/docs/manual/reference/command/listDatabases/#mongodb-dbcommand-dbcmd.listDatabases` */ -class ListDatabases implements Executable +final class ListDatabases implements Executable { private ListDatabasesCommand $listDatabases; diff --git a/src/Operation/ListIndexes.php b/src/Operation/ListIndexes.php index 384a5f498..350731697 100644 --- a/src/Operation/ListIndexes.php +++ b/src/Operation/ListIndexes.php @@ -36,7 +36,7 @@ * @see \MongoDB\Collection::listIndexes() * @see https://mongodb.com/docs/manual/reference/command/listIndexes/ */ -class ListIndexes implements Executable +final class ListIndexes implements Executable { private const ERROR_CODE_DATABASE_NOT_FOUND = 60; private const ERROR_CODE_NAMESPACE_NOT_FOUND = 26; diff --git a/src/Operation/ListSearchIndexes.php b/src/Operation/ListSearchIndexes.php index 2dbb3688b..8a3850968 100644 --- a/src/Operation/ListSearchIndexes.php +++ b/src/Operation/ListSearchIndexes.php @@ -35,7 +35,7 @@ * @see \MongoDB\Collection::listSearchIndexes() * @see https://mongodb.com/docs/manual/reference/command/listSearchIndexes/ */ -class ListSearchIndexes implements Executable +final class ListSearchIndexes implements Executable { private array $listSearchIndexesOptions; private array $aggregateOptions; diff --git a/src/Operation/MapReduce.php b/src/Operation/MapReduce.php index faf91019c..dcb1be4c6 100644 --- a/src/Operation/MapReduce.php +++ b/src/Operation/MapReduce.php @@ -54,7 +54,7 @@ * @see https://mongodb.com/docs/manual/reference/command/mapReduce/ * @psalm-import-type MapReduceCallable from MapReduceResult */ -class MapReduce implements Executable +final class MapReduce implements Executable { private array|object|string $out; diff --git a/src/Operation/ModifyCollection.php b/src/Operation/ModifyCollection.php index 53eaa9e09..dd707cd2d 100644 --- a/src/Operation/ModifyCollection.php +++ b/src/Operation/ModifyCollection.php @@ -33,7 +33,7 @@ * @see \MongoDB\Database::modifyCollection() * @see https://mongodb.com/docs/manual/reference/command/collMod/ */ -class ModifyCollection implements Executable +final class ModifyCollection implements Executable { /** * Constructs a collMod command. diff --git a/src/Operation/RenameCollection.php b/src/Operation/RenameCollection.php index 5b69cce41..d90c9815b 100644 --- a/src/Operation/RenameCollection.php +++ b/src/Operation/RenameCollection.php @@ -36,7 +36,7 @@ * @see \MongoDB\Database::renameCollection() * @see https://mongodb.com/docs/manual/reference/command/renameCollection/ */ -class RenameCollection implements Executable +final class RenameCollection implements Executable { private string $fromNamespace; diff --git a/src/Operation/ReplaceOne.php b/src/Operation/ReplaceOne.php index 32bf5a06d..47277e058 100644 --- a/src/Operation/ReplaceOne.php +++ b/src/Operation/ReplaceOne.php @@ -34,7 +34,7 @@ * @see \MongoDB\Collection::replaceOne() * @see https://mongodb.com/docs/manual/reference/command/update/ */ -class ReplaceOne implements Executable +final class ReplaceOne implements Executable { private Update $update; diff --git a/src/Operation/Update.php b/src/Operation/Update.php index 0b47b1cc1..1eb0bc9da 100644 --- a/src/Operation/Update.php +++ b/src/Operation/Update.php @@ -45,7 +45,7 @@ * @internal * @see https://mongodb.com/docs/manual/reference/command/update/ */ -class Update implements Executable, Explainable +final class Update implements Executable, Explainable { private const WIRE_VERSION_FOR_HINT = 8; diff --git a/src/Operation/UpdateMany.php b/src/Operation/UpdateMany.php index e61731622..a0f204837 100644 --- a/src/Operation/UpdateMany.php +++ b/src/Operation/UpdateMany.php @@ -32,7 +32,7 @@ * @see \MongoDB\Collection::updateMany() * @see https://mongodb.com/docs/manual/reference/command/update/ */ -class UpdateMany implements Executable, Explainable +final class UpdateMany implements Executable, Explainable { private Update $update; diff --git a/src/Operation/UpdateOne.php b/src/Operation/UpdateOne.php index 40d71addf..ac0f20720 100644 --- a/src/Operation/UpdateOne.php +++ b/src/Operation/UpdateOne.php @@ -32,7 +32,7 @@ * @see \MongoDB\Collection::updateOne() * @see https://mongodb.com/docs/manual/reference/command/update/ */ -class UpdateOne implements Executable, Explainable +final class UpdateOne implements Executable, Explainable { private Update $update; diff --git a/src/Operation/UpdateSearchIndex.php b/src/Operation/UpdateSearchIndex.php index 31d86ca8e..9aff80662 100644 --- a/src/Operation/UpdateSearchIndex.php +++ b/src/Operation/UpdateSearchIndex.php @@ -31,7 +31,7 @@ * @see \MongoDB\Collection::updateSearchIndexes() * @see https://mongodb.com/docs/manual/reference/command/updateSearchIndexes/ */ -class UpdateSearchIndex implements Executable +final class UpdateSearchIndex implements Executable { private object $definition; diff --git a/src/Operation/Watch.php b/src/Operation/Watch.php index 09f8b659b..5880b1b2a 100644 --- a/src/Operation/Watch.php +++ b/src/Operation/Watch.php @@ -57,7 +57,7 @@ * @see \MongoDB\Collection::watch() * @see https://mongodb.com/docs/manual/changeStreams/ */ -class Watch implements Executable, /* @internal */ CommandSubscriber +final class Watch implements Executable, /* @internal */ CommandSubscriber { public const FULL_DOCUMENT_DEFAULT = 'default'; public const FULL_DOCUMENT_UPDATE_LOOKUP = 'updateLookup'; diff --git a/src/Operation/WithTransaction.php b/src/Operation/WithTransaction.php index f0b5b0ec7..760825946 100644 --- a/src/Operation/WithTransaction.php +++ b/src/Operation/WithTransaction.php @@ -11,7 +11,7 @@ use function time; /** @internal */ -class WithTransaction +final class WithTransaction { /** @var callable */ private $callback; From dac8b8fc09946e5d31b8fc555b579c31495f5091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Wed, 18 Sep 2024 12:04:40 +0200 Subject: [PATCH 3/6] Revert "Add final annotations to non-internal Operation classes (#1410)" This reverts commit 89fb97ad230985d82d903306f63cae81122acf4f. --- src/Operation/Aggregate.php | 2 -- src/Operation/BulkWrite.php | 2 -- src/Operation/Count.php | 2 -- src/Operation/CountDocuments.php | 2 -- src/Operation/CreateCollection.php | 2 -- src/Operation/CreateIndexes.php | 2 -- src/Operation/CreateSearchIndexes.php | 2 -- src/Operation/DatabaseCommand.php | 2 -- src/Operation/DeleteMany.php | 2 -- src/Operation/DeleteOne.php | 2 -- src/Operation/Distinct.php | 2 -- src/Operation/DropCollection.php | 2 -- src/Operation/DropDatabase.php | 2 -- src/Operation/DropIndexes.php | 2 -- src/Operation/DropSearchIndex.php | 2 -- src/Operation/EstimatedDocumentCount.php | 2 -- src/Operation/Explain.php | 2 -- src/Operation/Find.php | 2 -- src/Operation/FindOne.php | 2 -- src/Operation/FindOneAndDelete.php | 2 -- src/Operation/FindOneAndReplace.php | 2 -- src/Operation/FindOneAndUpdate.php | 2 -- src/Operation/InsertMany.php | 2 -- src/Operation/InsertOne.php | 2 -- src/Operation/ListCollectionNames.php | 2 -- src/Operation/ListCollections.php | 2 -- src/Operation/ListDatabaseNames.php | 2 -- src/Operation/ListDatabases.php | 4 +--- src/Operation/ListIndexes.php | 2 -- src/Operation/ListSearchIndexes.php | 2 -- src/Operation/MapReduce.php | 2 -- src/Operation/ModifyCollection.php | 2 -- src/Operation/RenameCollection.php | 2 -- src/Operation/ReplaceOne.php | 2 -- src/Operation/UpdateMany.php | 2 -- src/Operation/UpdateOne.php | 2 -- src/Operation/UpdateSearchIndex.php | 2 -- src/Operation/Watch.php | 2 -- 38 files changed, 1 insertion(+), 77 deletions(-) diff --git a/src/Operation/Aggregate.php b/src/Operation/Aggregate.php index 3543fc73c..00d408c18 100644 --- a/src/Operation/Aggregate.php +++ b/src/Operation/Aggregate.php @@ -48,8 +48,6 @@ * * @see \MongoDB\Collection::aggregate() * @see https://mongodb.com/docs/manual/reference/command/aggregate/ - * - * @final extending this class will not be supported in v2.0.0 */ class Aggregate implements Executable, Explainable { diff --git a/src/Operation/BulkWrite.php b/src/Operation/BulkWrite.php index a5367bf2c..6da8a68b3 100644 --- a/src/Operation/BulkWrite.php +++ b/src/Operation/BulkWrite.php @@ -45,8 +45,6 @@ * Operation for executing multiple write operations. * * @see \MongoDB\Collection::bulkWrite() - * - * @final extending this class will not be supported in v2.0.0 */ class BulkWrite implements Executable { diff --git a/src/Operation/Count.php b/src/Operation/Count.php index 9f9225942..b29aa826a 100644 --- a/src/Operation/Count.php +++ b/src/Operation/Count.php @@ -40,8 +40,6 @@ * * @see \MongoDB\Collection::count() * @see https://mongodb.com/docs/manual/reference/command/count/ - * - * @final extending this class will not be supported in v2.0.0 */ class Count implements Executable, Explainable { diff --git a/src/Operation/CountDocuments.php b/src/Operation/CountDocuments.php index 954ea7466..5d6502fca 100644 --- a/src/Operation/CountDocuments.php +++ b/src/Operation/CountDocuments.php @@ -36,8 +36,6 @@ * * @see \MongoDB\Collection::countDocuments() * @see https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst#countdocuments - * - * @final extending this class will not be supported in v2.0.0 */ class CountDocuments implements Executable { diff --git a/src/Operation/CreateCollection.php b/src/Operation/CreateCollection.php index 3f4cc881a..3292e6fa7 100644 --- a/src/Operation/CreateCollection.php +++ b/src/Operation/CreateCollection.php @@ -40,8 +40,6 @@ * * @see \MongoDB\Database::createCollection() * @see https://mongodb.com/docs/manual/reference/command/create/ - * - * @final extending this class will not be supported in v2.0.0 */ class CreateCollection implements Executable { diff --git a/src/Operation/CreateIndexes.php b/src/Operation/CreateIndexes.php index e2ac08813..396cc8163 100644 --- a/src/Operation/CreateIndexes.php +++ b/src/Operation/CreateIndexes.php @@ -40,8 +40,6 @@ * @see \MongoDB\Collection::createIndex() * @see \MongoDB\Collection::createIndexes() * @see https://mongodb.com/docs/manual/reference/command/createIndexes/ - * - * @final extending this class will not be supported in v2.0.0 */ class CreateIndexes implements Executable { diff --git a/src/Operation/CreateSearchIndexes.php b/src/Operation/CreateSearchIndexes.php index d5be61116..fd27b043c 100644 --- a/src/Operation/CreateSearchIndexes.php +++ b/src/Operation/CreateSearchIndexes.php @@ -36,8 +36,6 @@ * @see \MongoDB\Collection::createSearchIndex() * @see \MongoDB\Collection::createSearchIndexes() * @see https://mongodb.com/docs/manual/reference/command/createSearchIndexes/ - * - * @final extending this class will not be supported in v2.0.0 */ class CreateSearchIndexes implements Executable { diff --git a/src/Operation/DatabaseCommand.php b/src/Operation/DatabaseCommand.php index 7ea406baa..4ae8214f1 100644 --- a/src/Operation/DatabaseCommand.php +++ b/src/Operation/DatabaseCommand.php @@ -31,8 +31,6 @@ * Operation for executing a database command. * * @see \MongoDB\Database::command() - * - * @final extending this class will not be supported in v2.0.0 */ class DatabaseCommand implements Executable { diff --git a/src/Operation/DeleteMany.php b/src/Operation/DeleteMany.php index d6d443b32..20ca38d1d 100644 --- a/src/Operation/DeleteMany.php +++ b/src/Operation/DeleteMany.php @@ -28,8 +28,6 @@ * * @see \MongoDB\Collection::deleteOne() * @see https://mongodb.com/docs/manual/reference/command/delete/ - * - * @final extending this class will not be supported in v2.0.0 */ class DeleteMany implements Executable, Explainable { diff --git a/src/Operation/DeleteOne.php b/src/Operation/DeleteOne.php index 8bbdb45ce..1aaad5d27 100644 --- a/src/Operation/DeleteOne.php +++ b/src/Operation/DeleteOne.php @@ -28,8 +28,6 @@ * * @see \MongoDB\Collection::deleteOne() * @see https://mongodb.com/docs/manual/reference/command/delete/ - * - * @final extending this class will not be supported in v2.0.0 */ class DeleteOne implements Executable, Explainable { diff --git a/src/Operation/Distinct.php b/src/Operation/Distinct.php index 171a18269..1483012f3 100644 --- a/src/Operation/Distinct.php +++ b/src/Operation/Distinct.php @@ -39,8 +39,6 @@ * * @see \MongoDB\Collection::distinct() * @see https://mongodb.com/docs/manual/reference/command/distinct/ - * - * @final extending this class will not be supported in v2.0.0 */ class Distinct implements Executable, Explainable { diff --git a/src/Operation/DropCollection.php b/src/Operation/DropCollection.php index d19859de1..a467a7391 100644 --- a/src/Operation/DropCollection.php +++ b/src/Operation/DropCollection.php @@ -35,8 +35,6 @@ * @see \MongoDB\Collection::drop() * @see \MongoDB\Database::dropCollection() * @see https://mongodb.com/docs/manual/reference/command/drop/ - * - * @final extending this class will not be supported in v2.0.0 */ class DropCollection implements Executable { diff --git a/src/Operation/DropDatabase.php b/src/Operation/DropDatabase.php index 290887900..15cb0c34e 100644 --- a/src/Operation/DropDatabase.php +++ b/src/Operation/DropDatabase.php @@ -33,8 +33,6 @@ * @see \MongoDB\Client::dropDatabase() * @see \MongoDB\Database::drop() * @see https://mongodb.com/docs/manual/reference/command/dropDatabase/ - * - * @final extending this class will not be supported in v2.0.0 */ class DropDatabase implements Executable { diff --git a/src/Operation/DropIndexes.php b/src/Operation/DropIndexes.php index 8fde88b4d..c5302e250 100644 --- a/src/Operation/DropIndexes.php +++ b/src/Operation/DropIndexes.php @@ -34,8 +34,6 @@ * * @see \MongoDB\Collection::dropIndexes() * @see https://mongodb.com/docs/manual/reference/command/dropIndexes/ - * - * @final extending this class will not be supported in v2.0.0 */ class DropIndexes implements Executable { diff --git a/src/Operation/DropSearchIndex.php b/src/Operation/DropSearchIndex.php index e65adee6a..42fc58baa 100644 --- a/src/Operation/DropSearchIndex.php +++ b/src/Operation/DropSearchIndex.php @@ -29,8 +29,6 @@ * * @see \MongoDB\Collection::dropSearchIndexes() * @see https://mongodb.com/docs/manual/reference/command/dropSearchIndexes/ - * - * @final extending this class will not be supported in v2.0.0 */ class DropSearchIndex implements Executable { diff --git a/src/Operation/EstimatedDocumentCount.php b/src/Operation/EstimatedDocumentCount.php index db876c71c..e3c240c78 100644 --- a/src/Operation/EstimatedDocumentCount.php +++ b/src/Operation/EstimatedDocumentCount.php @@ -34,8 +34,6 @@ * * @see \MongoDB\Collection::estimatedDocumentCount() * @see https://mongodb.com/docs/manual/reference/command/count/ - * - * @final extending this class will not be supported in v2.0.0 */ class EstimatedDocumentCount implements Executable, Explainable { diff --git a/src/Operation/Explain.php b/src/Operation/Explain.php index ea4572fa6..1c132b2f5 100644 --- a/src/Operation/Explain.php +++ b/src/Operation/Explain.php @@ -34,8 +34,6 @@ * * @see \MongoDB\Collection::explain() * @see https://mongodb.com/docs/manual/reference/command/explain/ - * - * @final extending this class will not be supported in v2.0.0 */ class Explain implements Executable { diff --git a/src/Operation/Find.php b/src/Operation/Find.php index 1d2dfb388..13944a682 100644 --- a/src/Operation/Find.php +++ b/src/Operation/Find.php @@ -47,8 +47,6 @@ * @see \MongoDB\Collection::find() * @see https://mongodb.com/docs/manual/tutorial/query-documents/ * @see https://mongodb.com/docs/manual/reference/operator/query-modifier/ - * - * @final extending this class will not be supported in v2.0.0 */ class Find implements Executable, Explainable { diff --git a/src/Operation/FindOne.php b/src/Operation/FindOne.php index 161d01dd0..6fdff0a29 100644 --- a/src/Operation/FindOne.php +++ b/src/Operation/FindOne.php @@ -30,8 +30,6 @@ * @see \MongoDB\Collection::findOne() * @see https://mongodb.com/docs/manual/tutorial/query-documents/ * @see https://mongodb.com/docs/manual/reference/operator/query-modifier/ - * - * @final extending this class will not be supported in v2.0.0 */ class FindOne implements Executable, Explainable { diff --git a/src/Operation/FindOneAndDelete.php b/src/Operation/FindOneAndDelete.php index a560ee4c6..ae5148872 100644 --- a/src/Operation/FindOneAndDelete.php +++ b/src/Operation/FindOneAndDelete.php @@ -29,8 +29,6 @@ * * @see \MongoDB\Collection::findOneAndDelete() * @see https://mongodb.com/docs/manual/reference/command/findAndModify/ - * - * @final extending this class will not be supported in v2.0.0 */ class FindOneAndDelete implements Executable, Explainable { diff --git a/src/Operation/FindOneAndReplace.php b/src/Operation/FindOneAndReplace.php index dfd761305..6f4409406 100644 --- a/src/Operation/FindOneAndReplace.php +++ b/src/Operation/FindOneAndReplace.php @@ -34,8 +34,6 @@ * * @see \MongoDB\Collection::findOneAndReplace() * @see https://mongodb.com/docs/manual/reference/command/findAndModify/ - * - * @final extending this class will not be supported in v2.0.0 */ class FindOneAndReplace implements Executable, Explainable { diff --git a/src/Operation/FindOneAndUpdate.php b/src/Operation/FindOneAndUpdate.php index 3566c9822..0fbe127d0 100644 --- a/src/Operation/FindOneAndUpdate.php +++ b/src/Operation/FindOneAndUpdate.php @@ -33,8 +33,6 @@ * * @see \MongoDB\Collection::findOneAndUpdate() * @see https://mongodb.com/docs/manual/reference/command/findAndModify/ - * - * @final extending this class will not be supported in v2.0.0 */ class FindOneAndUpdate implements Executable, Explainable { diff --git a/src/Operation/InsertMany.php b/src/Operation/InsertMany.php index 5e227cbc2..01640da2f 100644 --- a/src/Operation/InsertMany.php +++ b/src/Operation/InsertMany.php @@ -37,8 +37,6 @@ * * @see \MongoDB\Collection::insertMany() * @see https://mongodb.com/docs/manual/reference/command/insert/ - * - * @final extending this class will not be supported in v2.0.0 */ class InsertMany implements Executable { diff --git a/src/Operation/InsertOne.php b/src/Operation/InsertOne.php index 6d8f58cd8..8626364f8 100644 --- a/src/Operation/InsertOne.php +++ b/src/Operation/InsertOne.php @@ -35,8 +35,6 @@ * * @see \MongoDB\Collection::insertOne() * @see https://mongodb.com/docs/manual/reference/command/insert/ - * - * @final extending this class will not be supported in v2.0.0 */ class InsertOne implements Executable { diff --git a/src/Operation/ListCollectionNames.php b/src/Operation/ListCollectionNames.php index fe0ea12c6..f2124c4d4 100644 --- a/src/Operation/ListCollectionNames.php +++ b/src/Operation/ListCollectionNames.php @@ -29,8 +29,6 @@ * * @see \MongoDB\Database::listCollectionNames() * @see https://mongodb.com/docs/manual/reference/command/listCollections/ - * - * @final extending this class will not be supported in v2.0.0 */ class ListCollectionNames implements Executable { diff --git a/src/Operation/ListCollections.php b/src/Operation/ListCollections.php index 29b53df7c..340c11017 100644 --- a/src/Operation/ListCollections.php +++ b/src/Operation/ListCollections.php @@ -29,8 +29,6 @@ * * @see \MongoDB\Database::listCollections() * @see https://mongodb.com/docs/manual/reference/command/listCollections/ - * - * @final extending this class will not be supported in v2.0.0 */ class ListCollections implements Executable { diff --git a/src/Operation/ListDatabaseNames.php b/src/Operation/ListDatabaseNames.php index f7301c169..7b6a529b4 100644 --- a/src/Operation/ListDatabaseNames.php +++ b/src/Operation/ListDatabaseNames.php @@ -32,8 +32,6 @@ * * @see \MongoDB\Client::listDatabaseNames() * @see https://mongodb.com/docs/manual/reference/command/listDatabases/#mongodb-dbcommand-dbcmd.listDatabases - * - * @final extending this class will not be supported in v2.0.0 */ class ListDatabaseNames implements Executable { diff --git a/src/Operation/ListDatabases.php b/src/Operation/ListDatabases.php index 2e7e36b22..ee90cca65 100644 --- a/src/Operation/ListDatabases.php +++ b/src/Operation/ListDatabases.php @@ -29,9 +29,7 @@ * Operation for the ListDatabases command. * * @see \MongoDB\Client::listDatabases() - * @see https://mongodb.com/docs/manual/reference/command/listDatabases/#mongodb-dbcommand-dbcmd.listDatabases - * - * @final extending this class will not be supported in v2.0.0 + * @see https://mongodb.com/docs/manual/reference/command/listDatabases/#mongodb-dbcommand-dbcmd.listDatabases` */ class ListDatabases implements Executable { diff --git a/src/Operation/ListIndexes.php b/src/Operation/ListIndexes.php index 351b88bac..384a5f498 100644 --- a/src/Operation/ListIndexes.php +++ b/src/Operation/ListIndexes.php @@ -35,8 +35,6 @@ * * @see \MongoDB\Collection::listIndexes() * @see https://mongodb.com/docs/manual/reference/command/listIndexes/ - * - * @final extending this class will not be supported in v2.0.0 */ class ListIndexes implements Executable { diff --git a/src/Operation/ListSearchIndexes.php b/src/Operation/ListSearchIndexes.php index e685da5c2..2dbb3688b 100644 --- a/src/Operation/ListSearchIndexes.php +++ b/src/Operation/ListSearchIndexes.php @@ -34,8 +34,6 @@ * * @see \MongoDB\Collection::listSearchIndexes() * @see https://mongodb.com/docs/manual/reference/command/listSearchIndexes/ - * - * @final extending this class will not be supported in v2.0.0 */ class ListSearchIndexes implements Executable { diff --git a/src/Operation/MapReduce.php b/src/Operation/MapReduce.php index a62dd2f86..faf91019c 100644 --- a/src/Operation/MapReduce.php +++ b/src/Operation/MapReduce.php @@ -53,8 +53,6 @@ * @see \MongoDB\Collection::mapReduce() * @see https://mongodb.com/docs/manual/reference/command/mapReduce/ * @psalm-import-type MapReduceCallable from MapReduceResult - * - * @final extending this class will not be supported in v2.0.0 */ class MapReduce implements Executable { diff --git a/src/Operation/ModifyCollection.php b/src/Operation/ModifyCollection.php index f8d0c721d..53eaa9e09 100644 --- a/src/Operation/ModifyCollection.php +++ b/src/Operation/ModifyCollection.php @@ -32,8 +32,6 @@ * * @see \MongoDB\Database::modifyCollection() * @see https://mongodb.com/docs/manual/reference/command/collMod/ - * - * @final extending this class will not be supported in v2.0.0 */ class ModifyCollection implements Executable { diff --git a/src/Operation/RenameCollection.php b/src/Operation/RenameCollection.php index 245231a13..5b69cce41 100644 --- a/src/Operation/RenameCollection.php +++ b/src/Operation/RenameCollection.php @@ -35,8 +35,6 @@ * @see \MongoDB\Collection::rename() * @see \MongoDB\Database::renameCollection() * @see https://mongodb.com/docs/manual/reference/command/renameCollection/ - * - * @final extending this class will not be supported in v2.0.0 */ class RenameCollection implements Executable { diff --git a/src/Operation/ReplaceOne.php b/src/Operation/ReplaceOne.php index 3cec99ff0..32bf5a06d 100644 --- a/src/Operation/ReplaceOne.php +++ b/src/Operation/ReplaceOne.php @@ -33,8 +33,6 @@ * * @see \MongoDB\Collection::replaceOne() * @see https://mongodb.com/docs/manual/reference/command/update/ - * - * @final extending this class will not be supported in v2.0.0 */ class ReplaceOne implements Executable { diff --git a/src/Operation/UpdateMany.php b/src/Operation/UpdateMany.php index f600d46e6..e61731622 100644 --- a/src/Operation/UpdateMany.php +++ b/src/Operation/UpdateMany.php @@ -31,8 +31,6 @@ * * @see \MongoDB\Collection::updateMany() * @see https://mongodb.com/docs/manual/reference/command/update/ - * - * @final extending this class will not be supported in v2.0.0 */ class UpdateMany implements Executable, Explainable { diff --git a/src/Operation/UpdateOne.php b/src/Operation/UpdateOne.php index 17bc4a554..40d71addf 100644 --- a/src/Operation/UpdateOne.php +++ b/src/Operation/UpdateOne.php @@ -31,8 +31,6 @@ * * @see \MongoDB\Collection::updateOne() * @see https://mongodb.com/docs/manual/reference/command/update/ - * - * @final extending this class will not be supported in v2.0.0 */ class UpdateOne implements Executable, Explainable { diff --git a/src/Operation/UpdateSearchIndex.php b/src/Operation/UpdateSearchIndex.php index effb4a942..31d86ca8e 100644 --- a/src/Operation/UpdateSearchIndex.php +++ b/src/Operation/UpdateSearchIndex.php @@ -30,8 +30,6 @@ * * @see \MongoDB\Collection::updateSearchIndexes() * @see https://mongodb.com/docs/manual/reference/command/updateSearchIndexes/ - * - * @final extending this class will not be supported in v2.0.0 */ class UpdateSearchIndex implements Executable { diff --git a/src/Operation/Watch.php b/src/Operation/Watch.php index 7e192b298..d06d31bf4 100644 --- a/src/Operation/Watch.php +++ b/src/Operation/Watch.php @@ -56,8 +56,6 @@ * * @see \MongoDB\Collection::watch() * @see https://mongodb.com/docs/manual/changeStreams/ - * - * @final extending this class will not be supported in v2.0.0 */ class Watch implements Executable, /* @internal */ CommandSubscriber { From 081e9daf44ba4824d7f49850f6babc4ffbfb9d74 Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Mon, 23 Sep 2024 16:17:13 +0200 Subject: [PATCH 4/6] PHPLIB-797: Remove unused methods in UnsupportedException (#1436) * PHPLIB-797: Remove unused methods in UnsupportedException * Mark remaining methods as internal * Add upgrade note * Mark other exception factories as internal --- UPGRADE-2.0.md | 15 ++++ src/Exception/BadMethodCallException.php | 2 + src/Exception/InvalidArgumentException.php | 3 + src/Exception/ResumeTokenException.php | 2 + src/Exception/UnsupportedException.php | 70 ++----------------- src/GridFS/Exception/CorruptFileException.php | 5 ++ .../Exception/FileNotFoundException.php | 3 + src/GridFS/Exception/StreamException.php | 7 +- 8 files changed, 40 insertions(+), 67 deletions(-) diff --git a/UPGRADE-2.0.md b/UPGRADE-2.0.md index 15af9de1c..2c131e24c 100644 --- a/UPGRADE-2.0.md +++ b/UPGRADE-2.0.md @@ -28,3 +28,18 @@ GridFS ```php $bucket->openUploadStream($fileId, ['metadata' => ['contentType' => 'image/png']]); ``` + +UnsupportedException method removals +------------------------------------ + +The following methods have been removed from the +`MongoDB\Exception\UnsupportedException` class: + * `allowDiskUseNotSupported` + * `arrayFiltersNotSupported` + * `collationNotSupported` + * `explainNotSupported` + * `readConcernNotSupported` + * `writeConcernNotSupported` + +The remaining methods have been marked as internal and may be removed in a +future minor version. Only the class itself is covered by the BC promise. diff --git a/src/Exception/BadMethodCallException.php b/src/Exception/BadMethodCallException.php index e1070982a..4595bb9d1 100644 --- a/src/Exception/BadMethodCallException.php +++ b/src/Exception/BadMethodCallException.php @@ -28,6 +28,7 @@ class BadMethodCallException extends BaseBadMethodCallException implements Excep * * @param string $class Class name * @return self + * @internal */ public static function classIsImmutable(string $class) { @@ -39,6 +40,7 @@ public static function classIsImmutable(string $class) * * @param string $method Method name * @return self + * @internal */ public static function unacknowledgedWriteResultAccess(string $method) { diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php index 115f6a5c7..8a1b81ec2 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Exception/InvalidArgumentException.php @@ -29,6 +29,7 @@ class InvalidArgumentException extends DriverInvalidArgumentException implements Exception { + /** @internal */ public static function cannotCombineCodecAndTypeMap(): self { return new self('Cannot provide both "codec" and "typeMap" options'); @@ -39,6 +40,7 @@ public static function cannotCombineCodecAndTypeMap(): self * * @param string $name Name of the argument or option * @param mixed $value Actual value (used to derive the type) + * @internal */ public static function expectedDocumentType(string $name, mixed $value): self { @@ -52,6 +54,7 @@ public static function expectedDocumentType(string $name, mixed $value): self * @param mixed $value Actual value (used to derive the type) * @param string|list $expectedType Expected type as a string or an array containing one or more strings * @return self + * @internal */ public static function invalidType(string $name, mixed $value, string|array $expectedType) { diff --git a/src/Exception/ResumeTokenException.php b/src/Exception/ResumeTokenException.php index fc8808271..a73249cf9 100644 --- a/src/Exception/ResumeTokenException.php +++ b/src/Exception/ResumeTokenException.php @@ -27,6 +27,7 @@ class ResumeTokenException extends RuntimeException * * @param mixed $value Actual value (used to derive the type) * @return self + * @internal */ public static function invalidType(mixed $value) { @@ -37,6 +38,7 @@ public static function invalidType(mixed $value) * Thrown when a resume token is not found in a change document. * * @return self + * @internal */ public static function notFound() { diff --git a/src/Exception/UnsupportedException.php b/src/Exception/UnsupportedException.php index 2bf910a09..2ad501051 100644 --- a/src/Exception/UnsupportedException.php +++ b/src/Exception/UnsupportedException.php @@ -19,107 +19,45 @@ class UnsupportedException extends RuntimeException { - /** - * Thrown when a command's allowDiskUse option is not supported by a server. - * - * @return self - */ - public static function allowDiskUseNotSupported() - { - return new self('The "allowDiskUse" option is not supported by the server executing this operation'); - } - - /** - * Thrown when array filters are not supported by a server. - * - * @deprecated 1.12 - * @todo Remove this in 2.0 (see: PHPLIB-797) - * - * @return self - */ - public static function arrayFiltersNotSupported() - { - return new self('Array filters are not supported by the server executing this operation'); - } - - /** - * Thrown when collations are not supported by a server. - * - * @deprecated 1.12 - * @todo Remove this in 2.0 (see: PHPLIB-797) - * - * @return self - */ - public static function collationNotSupported() - { - return new self('Collations are not supported by the server executing this operation'); - } - /** * Thrown when the commitQuorum option for createIndexes is not supported * by a server. * * @return self + * @internal */ public static function commitQuorumNotSupported() { return new self('The "commitQuorum" option is not supported by the server executing this operation'); } - /** - * Thrown when explain is not supported by a server. - * - * @return self - */ - public static function explainNotSupported() - { - return new self('Explain is not supported by the server executing this operation'); - } - /** * Thrown when a command's hint option is not supported by a server. * * @return self + * @internal */ public static function hintNotSupported() { return new self('Hint is not supported by the server executing this operation'); } - /** - * Thrown when a command's readConcern option is not supported by a server. - * - * @return self - */ - public static function readConcernNotSupported() - { - return new self('Read concern is not supported by the server executing this command'); - } - /** * Thrown when a readConcern is used with a read operation in a transaction. * * @return self + * @internal */ public static function readConcernNotSupportedInTransaction() { return new self('The "readConcern" option cannot be specified within a transaction. Instead, specify it when starting the transaction.'); } - /** - * Thrown when a command's writeConcern option is not supported by a server. - * - * @return self - */ - public static function writeConcernNotSupported() - { - return new self('Write concern is not supported by the server executing this command'); - } - /** * Thrown when a writeConcern is used with a write operation in a transaction. * * @return self + * @internal */ public static function writeConcernNotSupportedInTransaction() { diff --git a/src/GridFS/Exception/CorruptFileException.php b/src/GridFS/Exception/CorruptFileException.php index db1622908..34f89a6c0 100644 --- a/src/GridFS/Exception/CorruptFileException.php +++ b/src/GridFS/Exception/CorruptFileException.php @@ -25,6 +25,8 @@ class CorruptFileException extends RuntimeException { /** * Thrown when a chunk doesn't contain valid data. + * + * @internal */ public static function invalidChunkData(int $chunkIndex): self { @@ -36,6 +38,7 @@ public static function invalidChunkData(int $chunkIndex): self * * @param integer $expectedIndex Expected index number * @return self + * @internal */ public static function missingChunk(int $expectedIndex) { @@ -48,6 +51,7 @@ public static function missingChunk(int $expectedIndex) * @param integer $index Actual index number (i.e. "n" field) * @param integer $expectedIndex Expected index number * @return self + * @internal */ public static function unexpectedIndex(int $index, int $expectedIndex) { @@ -60,6 +64,7 @@ public static function unexpectedIndex(int $index, int $expectedIndex) * @param integer $size Actual size (i.e. "data" field length) * @param integer $expectedSize Expected size * @return self + * @internal */ public static function unexpectedSize(int $size, int $expectedSize) { diff --git a/src/GridFS/Exception/FileNotFoundException.php b/src/GridFS/Exception/FileNotFoundException.php index 99c6d854a..21b8871ca 100644 --- a/src/GridFS/Exception/FileNotFoundException.php +++ b/src/GridFS/Exception/FileNotFoundException.php @@ -29,6 +29,7 @@ class FileNotFoundException extends RuntimeException * * @param string $filename Filename * @return self + * @internal */ public static function byFilename(string $filename) { @@ -42,6 +43,7 @@ public static function byFilename(string $filename) * @param integer $revision Revision * @param string $namespace Namespace for the files collection * @return self + * @internal */ public static function byFilenameAndRevision(string $filename, int $revision, string $namespace) { @@ -54,6 +56,7 @@ public static function byFilenameAndRevision(string $filename, int $revision, st * @param mixed $id File ID * @param string $namespace Namespace for the files collection * @return self + * @internal */ public static function byId(mixed $id, string $namespace) { diff --git a/src/GridFS/Exception/StreamException.php b/src/GridFS/Exception/StreamException.php index 880182588..3fd75ca8c 100644 --- a/src/GridFS/Exception/StreamException.php +++ b/src/GridFS/Exception/StreamException.php @@ -13,6 +13,7 @@ class StreamException extends RuntimeException /** * @param resource $source * @param resource $destination + * @internal */ public static function downloadFromFilenameFailed(string $filename, $source, $destination): self { @@ -25,6 +26,7 @@ public static function downloadFromFilenameFailed(string $filename, $source, $de /** * @param resource $source * @param resource $destination + * @internal */ public static function downloadFromIdFailed(mixed $id, $source, $destination): self { @@ -35,7 +37,10 @@ public static function downloadFromIdFailed(mixed $id, $source, $destination): s return new self(sprintf('Downloading file from "%s" to "%s" failed. GridFS identifier: "%s"', $sourceMetadata['uri'], $destinationMetadata['uri'], $idString)); } - /** @param resource $source */ + /** + * @param resource $source + * @internal + */ public static function uploadFailed(string $filename, $source, string $destinationUri): self { $sourceMetadata = stream_get_meta_data($source); From 5dda098ee48c2be5d485968ff6fda2a6f74df15e Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Tue, 24 Sep 2024 09:47:06 +0200 Subject: [PATCH 5/6] PHPLIB-954: Add return types to all methods (#1391) * Test with PHPC 2.0 Squashed commit of the following: commit bc37a4b83e86edba06f97148d9a1b4a194623097 Author: Andreas Braun Date: Thu Sep 19 13:32:18 2024 +0200 TMP: Use branch reporting 2.0 version for testing commit 938c4cd5be825b605a01e1f3129a2e233c62ac1b Author: Andreas Braun Date: Wed Sep 18 10:49:01 2024 +0200 Update CI config to test with ext-mongodb 2.0 commit 23b11eca50d9edafbc9179885298b0c35fe2ff86 Author: Andreas Braun Date: Wed Sep 18 10:47:33 2024 +0200 Require ext-mongodb 2.0 * Remove compatibility layer for CursorId deprecation Squashed commit of the following: commit b06bffe0196134a6d75baa25b01cb8a2a893964d Author: Andreas Braun Date: Thu Sep 19 12:56:07 2024 +0200 Update psalm baseline commit bb4bb563d2cb2844148db187990e05b9dc568220 Author: Andreas Braun Date: Thu Sep 19 12:55:52 2024 +0200 Remove CursorInterface::getId compatibility layer commit 00fa5e44898bad13c13608524319a59da6e968c3 Author: Andreas Braun Date: Thu Sep 19 12:55:32 2024 +0200 Add temporary stubs for cursor classes in 2.x * PHPLIB-954: Add return types to all methods * PHPLIB-1114: Replace Cursor types with CursorInterface * Add upgrade note --- .../generated/build/build-extension.yml | 36 +++--- .../templates/build/build-extension.yml | 12 +- .github/workflows/coding-standards.yml | 4 +- .github/workflows/generator.yml | 4 +- .github/workflows/static-analysis.yml | 4 +- .github/workflows/tests.yml | 4 +- UPGRADE-2.0.md | 1 + composer.json | 2 +- phpcs.xml.dist | 8 -- psalm-baseline.xml | 98 ++++++++++----- psalm.xml.dist | 2 + src/BulkWriteResult.php | 26 ++-- src/ChangeStream.php | 66 ++-------- src/Client.php | 49 +++----- src/Codec/DecodeIfSupported.php | 10 +- src/Codec/Decoder.php | 6 +- src/Codec/EncodeIfSupported.php | 10 +- src/Codec/Encoder.php | 6 +- src/Collection.php | 116 ++++++------------ src/Database.php | 67 ++++------ src/DeleteResult.php | 7 +- src/Exception/BadMethodCallException.php | 6 +- src/Exception/InvalidArgumentException.php | 3 +- src/Exception/ResumeTokenException.php | 6 +- src/Exception/UnsupportedException.php | 12 +- src/Exception/UnsupportedValueException.php | 3 +- src/GridFS/Bucket.php | 67 +++------- src/GridFS/CollectionWrapper.php | 10 +- src/GridFS/Exception/CorruptFileException.php | 9 +- .../Exception/FileNotFoundException.php | 9 +- src/GridFS/ReadableStream.php | 4 +- src/GridFS/StreamWrapper.php | 3 +- src/InsertManyResult.php | 11 +- src/InsertOneResult.php | 11 +- src/MapReduceResult.php | 16 +-- src/Model/BSONArray.php | 15 +-- src/Model/BSONDocument.php | 15 +-- src/Model/BSONIterator.php | 34 ++--- src/Model/CachingIterator.php | 13 +- src/Model/CallbackIterator.php | 7 +- src/Model/ChangeStreamIterator.php | 46 ++----- src/Model/CodecCursor.php | 35 +----- src/Model/CollectionInfo.php | 38 ++---- src/Model/CollectionInfoIterator.php | 6 +- src/Model/DatabaseInfo.php | 32 ++--- src/Model/DatabaseInfoIterator.php | 6 +- src/Model/IndexInfo.php | 60 +++------ src/Model/IndexInfoIterator.php | 6 +- src/Operation/Aggregate.php | 10 +- src/Operation/BulkWrite.php | 3 +- src/Operation/Count.php | 6 +- src/Operation/CountDocuments.php | 3 +- src/Operation/CreateCollection.php | 2 +- src/Operation/CreateEncryptedCollection.php | 2 +- src/Operation/CreateIndexes.php | 2 +- src/Operation/DatabaseCommand.php | 5 +- src/Operation/Delete.php | 6 +- src/Operation/DeleteMany.php | 6 +- src/Operation/DeleteOne.php | 6 +- src/Operation/Distinct.php | 6 +- src/Operation/DropCollection.php | 2 +- src/Operation/DropDatabase.php | 2 +- src/Operation/DropEncryptedCollection.php | 2 +- src/Operation/DropIndexes.php | 2 +- src/Operation/EstimatedDocumentCount.php | 6 +- src/Operation/Executable.php | 3 +- src/Operation/Explain.php | 3 +- src/Operation/Explainable.php | 4 +- src/Operation/Find.php | 7 +- src/Operation/FindAndModify.php | 6 +- src/Operation/FindOne.php | 6 +- src/Operation/FindOneAndDelete.php | 6 +- src/Operation/FindOneAndReplace.php | 9 +- src/Operation/FindOneAndUpdate.php | 6 +- src/Operation/InsertMany.php | 3 +- src/Operation/InsertOne.php | 6 +- src/Operation/ListCollections.php | 3 +- src/Operation/ListDatabases.php | 3 +- src/Operation/ListIndexes.php | 3 +- src/Operation/MapReduce.php | 3 +- src/Operation/ModifyCollection.php | 2 +- src/Operation/RenameCollection.php | 2 +- src/Operation/ReplaceOne.php | 6 +- src/Operation/Update.php | 6 +- src/Operation/UpdateMany.php | 6 +- src/Operation/UpdateOne.php | 6 +- src/Operation/Watch.php | 11 +- src/UpdateResult.php | 16 +-- src/functions.php | 12 +- stubs/Driver/Cursor.stub.php | 59 +++++++++ stubs/Driver/CursorInterface.stub.php | 33 +++++ tests/Model/CodecCursorFunctionalTest.php | 65 +--------- tests/Operation/WatchFunctionalTest.php | 6 +- 93 files changed, 515 insertions(+), 878 deletions(-) create mode 100644 stubs/Driver/Cursor.stub.php create mode 100644 stubs/Driver/CursorInterface.stub.php diff --git a/.evergreen/config/generated/build/build-extension.yml b/.evergreen/config/generated/build/build-extension.yml index c16586063..02033b002 100644 --- a/.evergreen/config/generated/build/build-extension.yml +++ b/.evergreen/config/generated/build/build-extension.yml @@ -7,11 +7,11 @@ tasks: vars: PHP_VERSION: "8.3" - func: "compile extension" - # TODO: remove once 1.20.0 is released + # TODO: remove once 2.0.0 is released vars: - EXTENSION_BRANCH: "v1.20" + EXTENSION_BRANCH: "v2.x" - func: "upload extension" - # TODO: re-enable once 1.20.0 is released + # TODO: re-enable once 2.0.0 is released # - name: "build-php-8.3-lowest" # tags: ["build", "php8.3", "lowest", "pr", "tag"] # commands: @@ -20,7 +20,7 @@ tasks: # PHP_VERSION: "8.3" # - func: "compile extension" # vars: -# EXTENSION_VERSION: "1.20.0" +# EXTENSION_VERSION: "2.0.0" # - func: "upload extension" # - name: "build-php-8.3-next-stable" # tags: ["build", "php8.3", "next-stable", "pr", "tag"] @@ -30,7 +30,7 @@ tasks: # PHP_VERSION: "8.3" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "v1.20.0" +# EXTENSION_BRANCH: "v2.0" # - func: "upload extension" # - name: "build-php-8.3-next-minor" # tags: ["build", "php8.3", "next-minor"] @@ -40,7 +40,7 @@ tasks: # PHP_VERSION: "8.3" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "master" +# EXTENSION_BRANCH: "v2.x" # - func: "upload extension" - name: "build-php-8.2" tags: ["build", "php8.2", "stable", "pr", "tag"] @@ -49,11 +49,11 @@ tasks: vars: PHP_VERSION: "8.2" - func: "compile extension" - # TODO: remove once 1.20.0 is released + # TODO: remove once 2.0.0 is released vars: - EXTENSION_BRANCH: "v1.20" + EXTENSION_BRANCH: "v2.x" - func: "upload extension" - # TODO: re-enable once 1.20.0 is released + # TODO: re-enable once 2.0.0 is released # - name: "build-php-8.2-lowest" # tags: ["build", "php8.2", "lowest", "pr", "tag"] # commands: @@ -62,7 +62,7 @@ tasks: # PHP_VERSION: "8.2" # - func: "compile extension" # vars: -# EXTENSION_VERSION: "1.20.0" +# EXTENSION_VERSION: "2.0.0" # - func: "upload extension" # - name: "build-php-8.2-next-stable" # tags: ["build", "php8.2", "next-stable", "pr", "tag"] @@ -72,7 +72,7 @@ tasks: # PHP_VERSION: "8.2" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "v1.20.0" +# EXTENSION_BRANCH: "v2.0" # - func: "upload extension" # - name: "build-php-8.2-next-minor" # tags: ["build", "php8.2", "next-minor"] @@ -82,7 +82,7 @@ tasks: # PHP_VERSION: "8.2" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "master" +# EXTENSION_BRANCH: "v2.x" # - func: "upload extension" - name: "build-php-8.1" tags: ["build", "php8.1", "stable", "pr", "tag"] @@ -91,11 +91,11 @@ tasks: vars: PHP_VERSION: "8.1" - func: "compile extension" - # TODO: remove once 1.20.0 is released + # TODO: remove once 2.0.0 is released vars: - EXTENSION_BRANCH: "v1.20" + EXTENSION_BRANCH: "v2.x" - func: "upload extension" - # TODO: re-enable once 1.20.0 is released + # TODO: re-enable once 2.0.0 is released # - name: "build-php-8.1-lowest" # tags: ["build", "php8.1", "lowest", "pr", "tag"] # commands: @@ -104,7 +104,7 @@ tasks: # PHP_VERSION: "8.1" # - func: "compile extension" # vars: -# EXTENSION_VERSION: "1.20.0" +# EXTENSION_VERSION: "2.0.0" # - func: "upload extension" # - name: "build-php-8.1-next-stable" # tags: ["build", "php8.1", "next-stable", "pr", "tag"] @@ -114,7 +114,7 @@ tasks: # PHP_VERSION: "8.1" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "v1.20.0" +# EXTENSION_BRANCH: "v2.0" # - func: "upload extension" # - name: "build-php-8.1-next-minor" # tags: ["build", "php8.1", "next-minor"] @@ -124,5 +124,5 @@ tasks: # PHP_VERSION: "8.1" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "master" +# EXTENSION_BRANCH: "v2.x" # - func: "upload extension" diff --git a/.evergreen/config/templates/build/build-extension.yml b/.evergreen/config/templates/build/build-extension.yml index ecd1fffdd..1599967ab 100644 --- a/.evergreen/config/templates/build/build-extension.yml +++ b/.evergreen/config/templates/build/build-extension.yml @@ -5,11 +5,11 @@ vars: PHP_VERSION: "%phpVersion%" - func: "compile extension" - # TODO: remove once 1.20.0 is released + # TODO: remove once 2.0.0 is released vars: - EXTENSION_BRANCH: "v1.20" + EXTENSION_BRANCH: "v2.x" - func: "upload extension" - # TODO: re-enable once 1.20.0 is released + # TODO: re-enable once 2.0.0 is released # - name: "build-php-%phpVersion%-lowest" # tags: ["build", "php%phpVersion%", "lowest", "pr", "tag"] # commands: @@ -18,7 +18,7 @@ # PHP_VERSION: "%phpVersion%" # - func: "compile extension" # vars: -# EXTENSION_VERSION: "1.20.0" +# EXTENSION_VERSION: "2.0.0" # - func: "upload extension" # - name: "build-php-%phpVersion%-next-stable" # tags: ["build", "php%phpVersion%", "next-stable", "pr", "tag"] @@ -28,7 +28,7 @@ # PHP_VERSION: "%phpVersion%" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "v1.20.0" +# EXTENSION_BRANCH: "v2.0" # - func: "upload extension" # - name: "build-php-%phpVersion%-next-minor" # tags: ["build", "php%phpVersion%", "next-minor"] @@ -38,5 +38,5 @@ # PHP_VERSION: "%phpVersion%" # - func: "compile extension" # vars: -# EXTENSION_BRANCH: "master" +# EXTENSION_BRANCH: "v2.x" # - func: "upload extension" diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 5dbb7dd71..b03f7779f 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -13,9 +13,9 @@ on: env: PHP_VERSION: "8.2" - # TODO: change to "stable" once 1.20.0 is released + # TODO: change to "stable" once 2.0.0 is released # DRIVER_VERSION: "stable" - DRIVER_VERSION: "mongodb/mongo-php-driver@v1.20" + DRIVER_VERSION: "mongodb/mongo-php-driver@v2.x" jobs: phpcs: diff --git a/.github/workflows/generator.yml b/.github/workflows/generator.yml index 2427a41eb..711befabd 100644 --- a/.github/workflows/generator.yml +++ b/.github/workflows/generator.yml @@ -13,9 +13,9 @@ on: env: PHP_VERSION: "8.2" - # TODO: change to "stable" once 1.20.0 is released + # TODO: change to "stable" once 2.0.0 is released # DRIVER_VERSION: "stable" - DRIVER_VERSION: "mongodb/mongo-php-driver@v1.20" + DRIVER_VERSION: "mongodb/mongo-php-driver@v2.x" jobs: psalm: diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index ebb60cabf..82919098f 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -19,9 +19,9 @@ on: env: PHP_VERSION: "8.2" - # TODO: change to "stable" once 1.20.0 is released + # TODO: change to "stable" once 2.0.0 is released # DRIVER_VERSION: "stable" - DRIVER_VERSION: "mongodb/mongo-php-driver@v1.20" + DRIVER_VERSION: "mongodb/mongo-php-driver@v2.x" jobs: psalm: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 803eb476d..29d36194f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,9 +12,9 @@ on: - "feature/*" env: - # TODO: change to "stable" once 1.20.0 is released + # TODO: change to "stable" once 2.0.0 is released # DRIVER_VERSION: "stable" - DRIVER_VERSION: "mongodb/mongo-php-driver@v1.20" + DRIVER_VERSION: "mongodb/mongo-php-driver@v2.x" jobs: phpunit: diff --git a/UPGRADE-2.0.md b/UPGRADE-2.0.md index 2c131e24c..8dabbdd59 100644 --- a/UPGRADE-2.0.md +++ b/UPGRADE-2.0.md @@ -2,6 +2,7 @@ UPGRADE FROM 1.x to 2.0 ======================== * Classes in the namespace `MongoDB\Operation\` are `final`. + * All methods in interfaces and classes now define a return type. GridFS ------ diff --git a/composer.json b/composer.json index d9d0516b4..95b96ddb8 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "require": { "php": "^8.1", "ext-json": "*", - "ext-mongodb": "^1.20.0", + "ext-mongodb": "^2.0", "composer-runtime-api": "^2.0", "psr/log": "^1.1.4|^2|^3", "symfony/polyfill-php80": "^1.27", diff --git a/phpcs.xml.dist b/phpcs.xml.dist index de542ac64..3c2b9441b 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -133,14 +133,6 @@ - - - - - src - - - diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 039b43007..5ea414eb3 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -5,11 +5,7 @@ name]]> - - - - @@ -23,6 +19,9 @@ + + + @@ -184,11 +183,14 @@ - - - + + + + + ]]> + @@ -196,6 +198,9 @@ + + ]]> + @@ -227,10 +232,19 @@ + + + + + ]]> + + + ]]> + @@ -257,10 +271,19 @@ + + + + + ]]> + + + ]]> + @@ -324,6 +347,7 @@ getArrayCopy()]]> + getArrayCopy()]]> @@ -331,6 +355,7 @@ + @@ -339,6 +364,15 @@ + + + + + ]]> + + + ]]> + cursor->nextBatch]]> @@ -354,11 +388,6 @@ current()]]> - - - - - @@ -724,18 +753,6 @@ value ?? null) : null]]> - - - - - - - - - - - - @@ -786,14 +803,26 @@ - - listCollections->execute($server), $this->databaseName)]]> - + + + + + ]]> + + + ]]> + - - listDatabases->execute($server))]]> - + + + + + ]]> + + + ]]> + @@ -801,10 +830,19 @@ databaseName . '.' . $this->collectionName)]]> + + + + + ]]> + + + ]]> + diff --git a/psalm.xml.dist b/psalm.xml.dist index 83d825d51..d9640583b 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -21,6 +21,8 @@ + + diff --git a/src/BulkWriteResult.php b/src/BulkWriteResult.php index 4fb556e0b..548acc9a7 100644 --- a/src/BulkWriteResult.php +++ b/src/BulkWriteResult.php @@ -38,10 +38,9 @@ public function __construct(private WriteResult $writeResult, private array $ins * This method should only be called if the write was acknowledged. * * @see BulkWriteResult::isAcknowledged() - * @return integer|null * @throws BadMethodCallException if the write result is unacknowledged */ - public function getDeletedCount() + public function getDeletedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getDeletedCount(); @@ -56,10 +55,9 @@ public function getDeletedCount() * This method should only be called if the write was acknowledged. * * @see BulkWriteResult::isAcknowledged() - * @return integer|null * @throws BadMethodCallException if the write result is unacknowledged */ - public function getInsertedCount() + public function getInsertedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getInsertedCount(); @@ -76,10 +74,8 @@ public function getInsertedCount() * the driver did not generate an ID), the index will contain its "_id" * field value. Any driver-generated ID will be a MongoDB\BSON\ObjectId * instance. - * - * @return array */ - public function getInsertedIds() + public function getInsertedIds(): array { return $this->insertedIds; } @@ -90,10 +86,9 @@ public function getInsertedIds() * This method should only be called if the write was acknowledged. * * @see BulkWriteResult::isAcknowledged() - * @return integer|null * @throws BadMethodCallException if the write result is unacknowledged */ - public function getMatchedCount() + public function getMatchedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getMatchedCount(); @@ -111,10 +106,9 @@ public function getMatchedCount() * This method should only be called if the write was acknowledged. * * @see BulkWriteResult::isAcknowledged() - * @return integer|null * @throws BadMethodCallException if the write result is unacknowledged */ - public function getModifiedCount() + public function getModifiedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getModifiedCount(); @@ -129,10 +123,9 @@ public function getModifiedCount() * This method should only be called if the write was acknowledged. * * @see BulkWriteResult::isAcknowledged() - * @return integer|null * @throws BadMethodCallException if the write result is unacknowledged */ - public function getUpsertedCount() + public function getUpsertedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getUpsertedCount(); @@ -152,10 +145,9 @@ public function getUpsertedCount() * This method should only be called if the write was acknowledged. * * @see BulkWriteResult::isAcknowledged() - * @return array * @throws BadMethodCallException if the write result is unacknowledged */ - public function getUpsertedIds() + public function getUpsertedIds(): array { if ($this->isAcknowledged) { return $this->writeResult->getUpsertedIds(); @@ -169,10 +161,8 @@ public function getUpsertedIds() * * If the update was not acknowledged, other fields from the WriteResult * (e.g. matchedCount) will be undefined. - * - * @return boolean */ - public function isAcknowledged() + public function isAcknowledged(): bool { return $this->isAcknowledged; } diff --git a/src/ChangeStream.php b/src/ChangeStream.php index 55f25b031..a1a732666 100644 --- a/src/ChangeStream.php +++ b/src/ChangeStream.php @@ -21,22 +21,16 @@ use MongoDB\BSON\Document; use MongoDB\BSON\Int64; use MongoDB\Codec\DocumentCodec; -use MongoDB\Driver\CursorId; use MongoDB\Driver\Exception\ConnectionException; use MongoDB\Driver\Exception\RuntimeException; use MongoDB\Driver\Exception\ServerException; use MongoDB\Exception\BadMethodCallException; use MongoDB\Exception\ResumeTokenException; use MongoDB\Model\ChangeStreamIterator; -use ReturnTypeWillChange; use function assert; use function call_user_func; use function in_array; -use function sprintf; -use function trigger_error; - -use const E_USER_DEPRECATED; /** * Iterator for a change stream. @@ -88,12 +82,8 @@ class ChangeStream implements Iterator */ private bool $hasAdvanced = false; - /** - * @see https://php.net/iterator.current - * @return array|object|null - */ - #[ReturnTypeWillChange] - public function current() + /** @see https://php.net/iterator.current */ + public function current(): array|object|null { $value = $this->iterator->current(); @@ -106,26 +96,9 @@ public function current() return $this->codec->decode($value); } - /** - * @return CursorId|Int64 - * @psalm-return ($asInt64 is true ? Int64 : CursorId) - */ - #[ReturnTypeWillChange] - public function getCursorId(bool $asInt64 = false) + public function getCursorId(): Int64 { - if (! $asInt64) { - @trigger_error( - sprintf( - 'The method "%s" will no longer return a "%s" instance in the future. Pass "true" as argument to change to the new behavior and receive a "%s" instance instead.', - __METHOD__, - CursorId::class, - Int64::class, - ), - E_USER_DEPRECATED, - ); - } - - return $this->iterator->getInnerIterator()->getId($asInt64); + return $this->iterator->getInnerIterator()->getId(); } /** @@ -134,20 +107,14 @@ public function getCursorId(bool $asInt64 = false) * Null may be returned if no change documents have been iterated and the * server did not include a postBatchResumeToken in its aggregate or getMore * command response. - * - * @return array|object|null */ - public function getResumeToken() + public function getResumeToken(): array|object|null { return $this->iterator->getResumeToken(); } - /** - * @see https://php.net/iterator.key - * @return int|null - */ - #[ReturnTypeWillChange] - public function key() + /** @see https://php.net/iterator.key */ + public function key(): ?int { if ($this->valid()) { return $this->key; @@ -158,11 +125,9 @@ public function key() /** * @see https://php.net/iterator.next - * @return void * @throws ResumeTokenException */ - #[ReturnTypeWillChange] - public function next() + public function next(): void { try { $this->iterator->next(); @@ -174,11 +139,9 @@ public function next() /** * @see https://php.net/iterator.rewind - * @return void * @throws ResumeTokenException */ - #[ReturnTypeWillChange] - public function rewind() + public function rewind(): void { try { $this->iterator->rewind(); @@ -191,12 +154,8 @@ public function rewind() } } - /** - * @see https://php.net/iterator.valid - * @return boolean - */ - #[ReturnTypeWillChange] - public function valid() + /** @see https://php.net/iterator.valid */ + public function valid(): bool { return $this->iterator->valid(); } @@ -255,7 +214,8 @@ private function onIteration(bool $incrementKey): void * have been received in the last response. Therefore, we can unset the * resumeCallable. This will free any reference to Watch as well as the * only reference to any implicit session created therein. */ - if ((string) $this->getCursorId(true) === '0') { + // Use a type-unsafe comparison to compare with Int64 instances + if ($this->getCursorId() == 0) { $this->resumeCallable = null; } diff --git a/src/Client.php b/src/Client.php index 5ed76a0e0..00a1a6ed3 100644 --- a/src/Client.php +++ b/src/Client.php @@ -39,6 +39,7 @@ use MongoDB\Model\BSONArray; use MongoDB\Model\BSONDocument; use MongoDB\Model\DatabaseInfo; +use MongoDB\Model\DatabaseInfoIterator; use MongoDB\Operation\DropDatabase; use MongoDB\Operation\ListDatabaseNames; use MongoDB\Operation\ListDatabases; @@ -143,9 +144,8 @@ public function __construct(?string $uri = null, array $uriOptions = [], array $ * Return internal properties for debugging purposes. * * @see https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo - * @return array */ - public function __debugInfo() + public function __debugInfo(): array { return [ 'manager' => $this->manager, @@ -166,19 +166,16 @@ public function __debugInfo() * @see https://php.net/oop5.overloading#object.get * @see https://php.net/types.string#language.types.string.parsing.complex * @param string $databaseName Name of the database to select - * @return Database */ - public function __get(string $databaseName) + public function __get(string $databaseName): Database { return $this->selectDatabase($databaseName); } /** * Return the connection string (i.e. URI). - * - * @return string */ - public function __toString() + public function __toString(): string { return $this->uri; } @@ -197,10 +194,8 @@ final public function addSubscriber(Subscriber $subscriber): void * Returns a ClientEncryption instance for explicit encryption and decryption * * @param array $options Encryption options - * - * @return ClientEncryption */ - public function createClientEncryption(array $options) + public function createClientEncryption(array $options): ClientEncryption { if (isset($options['keyVaultClient'])) { if ($options['keyVaultClient'] instanceof self) { @@ -224,7 +219,7 @@ public function createClientEncryption(array $options) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function dropDatabase(string $databaseName, array $options = []) + public function dropDatabase(string $databaseName, array $options = []): array|object { if (! isset($options['typeMap'])) { $options['typeMap'] = $this->typeMap; @@ -243,10 +238,8 @@ public function dropDatabase(string $databaseName, array $options = []) /** * Return the Manager. - * - * @return Manager */ - public function getManager() + public function getManager(): Manager { return $this->manager; } @@ -255,29 +248,24 @@ public function getManager() * Return the read concern for this client. * * @see https://php.net/manual/en/mongodb-driver-readconcern.isdefault.php - * @return ReadConcern */ - public function getReadConcern() + public function getReadConcern(): ReadConcern { return $this->readConcern; } /** * Return the read preference for this client. - * - * @return ReadPreference */ - public function getReadPreference() + public function getReadPreference(): ReadPreference { return $this->readPreference; } /** * Return the type map for this client. - * - * @return array */ - public function getTypeMap() + public function getTypeMap(): array { return $this->typeMap; } @@ -286,9 +274,8 @@ public function getTypeMap() * Return the write concern for this client. * * @see https://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php - * @return WriteConcern */ - public function getWriteConcern() + public function getWriteConcern(): WriteConcern { return $this->writeConcern; } @@ -318,7 +305,7 @@ public function listDatabaseNames(array $options = []): Iterator * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function listDatabases(array $options = []) + public function listDatabases(array $options = []): DatabaseInfoIterator { $operation = new ListDatabases($options); $server = select_server($this->manager, $options); @@ -343,10 +330,9 @@ final public function removeSubscriber(Subscriber $subscriber): void * @param string $databaseName Name of the database containing the collection * @param string $collectionName Name of the collection to select * @param array $options Collection constructor options - * @return Collection * @throws InvalidArgumentException for parameter/option parsing errors */ - public function selectCollection(string $databaseName, string $collectionName, array $options = []) + public function selectCollection(string $databaseName, string $collectionName, array $options = []): Collection { $options += ['typeMap' => $this->typeMap, 'builderEncoder' => $this->builderEncoder]; @@ -359,10 +345,9 @@ public function selectCollection(string $databaseName, string $collectionName, a * @see Database::__construct() for supported options * @param string $databaseName Name of the database to select * @param array $options Database constructor options - * @return Database * @throws InvalidArgumentException for parameter/option parsing errors */ - public function selectDatabase(string $databaseName, array $options = []) + public function selectDatabase(string $databaseName, array $options = []): Database { $options += ['typeMap' => $this->typeMap, 'builderEncoder' => $this->builderEncoder]; @@ -374,9 +359,8 @@ public function selectDatabase(string $databaseName, array $options = []) * * @see https://php.net/manual/en/mongodb-driver-manager.startsession.php * @param array $options Session options - * @return Session */ - public function startSession(array $options = []) + public function startSession(array $options = []): Session { return $this->manager->startSession($options); } @@ -387,10 +371,9 @@ public function startSession(array $options = []) * @see Watch::__construct() for supported options * @param array $pipeline Aggregation pipeline * @param array $options Command options - * @return ChangeStream * @throws InvalidArgumentException for parameter/option parsing errors */ - public function watch(array $pipeline = [], array $options = []) + public function watch(array $pipeline = [], array $options = []): ChangeStream { if (is_builder_pipeline($pipeline)) { $pipeline = new Pipeline(...$pipeline); diff --git a/src/Codec/DecodeIfSupported.php b/src/Codec/DecodeIfSupported.php index 7fd768011..ea8dde15c 100644 --- a/src/Codec/DecodeIfSupported.php +++ b/src/Codec/DecodeIfSupported.php @@ -30,17 +30,13 @@ abstract public function canDecode(mixed $value): bool; /** * @psalm-param BSONType $value - * @return mixed * @psalm-return NativeType * @throws UnsupportedValueException if the decoder does not support the value */ - abstract public function decode(mixed $value); + abstract public function decode(mixed $value): mixed; - /** - * @return mixed - * @psalm-return ($value is BSONType ? NativeType : $value) - */ - public function decodeIfSupported(mixed $value) + /** @psalm-return ($value is BSONType ? NativeType : $value) */ + public function decodeIfSupported(mixed $value): mixed { return $this->canDecode($value) ? $this->decode($value) : $value; } diff --git a/src/Codec/Decoder.php b/src/Codec/Decoder.php index 432fb2dd7..37ff9b263 100644 --- a/src/Codec/Decoder.php +++ b/src/Codec/Decoder.php @@ -37,11 +37,10 @@ public function canDecode(mixed $value): bool; * should throw an exception. * * @psalm-param BSONType $value - * @return mixed * @psalm-return NativeType * @throws UnsupportedValueException if the decoder does not support the value */ - public function decode(mixed $value); + public function decode(mixed $value): mixed; /** * Decodes a given value if supported, otherwise returns the value as-is. @@ -49,8 +48,7 @@ public function decode(mixed $value); * The DecodeIfSupported trait provides a default implementation of this * method. * - * @return mixed * @psalm-return ($value is BSONType ? NativeType : $value) */ - public function decodeIfSupported(mixed $value); + public function decodeIfSupported(mixed $value): mixed; } diff --git a/src/Codec/EncodeIfSupported.php b/src/Codec/EncodeIfSupported.php index 33823cfd6..2ce1fcf53 100644 --- a/src/Codec/EncodeIfSupported.php +++ b/src/Codec/EncodeIfSupported.php @@ -30,17 +30,13 @@ abstract public function canEncode(mixed $value): bool; /** * @psalm-param NativeType $value - * @return mixed * @psalm-return BSONType * @throws UnsupportedValueException if the encoder does not support the value */ - abstract public function encode(mixed $value); + abstract public function encode(mixed $value): mixed; - /** - * @return mixed - * @psalm-return ($value is NativeType ? BSONType : $value) - */ - public function encodeIfSupported(mixed $value) + /** @psalm-return ($value is NativeType ? BSONType : $value) */ + public function encodeIfSupported(mixed $value): mixed { return $this->canEncode($value) ? $this->encode($value) : $value; } diff --git a/src/Codec/Encoder.php b/src/Codec/Encoder.php index 0cd0d58cb..c8ee0917b 100644 --- a/src/Codec/Encoder.php +++ b/src/Codec/Encoder.php @@ -37,11 +37,10 @@ public function canEncode(mixed $value): bool; * should throw an exception. * * @psalm-param NativeType $value - * @return mixed * @psalm-return BSONType * @throws UnsupportedValueException if the encoder does not support the value */ - public function encode(mixed $value); + public function encode(mixed $value): mixed; /** * Encodes a given value if supported, otherwise returns the value as-is. @@ -49,8 +48,7 @@ public function encode(mixed $value); * The EncodeIfSupported trait provides a default implementation of this * method. * - * @return mixed * @psalm-return ($value is NativeType ? BSONType : $value) */ - public function encodeIfSupported(mixed $value); + public function encodeIfSupported(mixed $value): mixed; } diff --git a/src/Collection.php b/src/Collection.php index ab82cca5d..2c659f5db 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -38,6 +38,7 @@ use MongoDB\Model\BSONArray; use MongoDB\Model\BSONDocument; use MongoDB\Model\IndexInfo; +use MongoDB\Model\IndexInfoIterator; use MongoDB\Operation\Aggregate; use MongoDB\Operation\BulkWrite; use MongoDB\Operation\Count; @@ -181,9 +182,8 @@ public function __construct(private Manager $manager, private string $databaseNa * Return internal properties for debugging purposes. * * @see https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo - * @return array */ - public function __debugInfo() + public function __debugInfo(): array { return [ 'builderEncoder' => $this->builderEncoder, @@ -202,9 +202,8 @@ public function __debugInfo() * Return the collection namespace (e.g. "db.collection"). * * @see https://mongodb.com/docs/manual/core/databases-and-collections/ - * @return string */ - public function __toString() + public function __toString(): string { return $this->databaseName . '.' . $this->collectionName; } @@ -215,13 +214,12 @@ public function __toString() * @see Aggregate::__construct() for supported options * @param array $pipeline Aggregation pipeline * @param array $options Command options - * @return CursorInterface&Iterator * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function aggregate(array $pipeline, array $options = []) + public function aggregate(array $pipeline, array $options = []): CursorInterface { if (is_builder_pipeline($pipeline)) { $pipeline = new Pipeline(...$pipeline); @@ -261,12 +259,11 @@ public function aggregate(array $pipeline, array $options = []) * @see BulkWrite::__construct() for supported options * @param array[] $operations List of write operations * @param array $options Command options - * @return BulkWriteResult * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function bulkWrite(array $operations, array $options = []) + public function bulkWrite(array $operations, array $options = []): BulkWriteResult { $options = $this->inheritBuilderEncoder($options); $options = $this->inheritWriteOptions($options); @@ -283,7 +280,6 @@ public function bulkWrite(array $operations, array $options = []) * @see Count::__construct() for supported options * @param array|object $filter Query by which to filter documents * @param array $options Command options - * @return integer * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors @@ -291,7 +287,7 @@ public function bulkWrite(array $operations, array $options = []) * * @deprecated 1.4 */ - public function count(array|object $filter = [], array $options = []) + public function count(array|object $filter = [], array $options = []): int { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); @@ -307,13 +303,12 @@ public function count(array|object $filter = [], array $options = []) * @see CountDocuments::__construct() for supported options * @param array|object $filter Query by which to filter documents * @param array $options Command options - * @return integer * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function countDocuments(array|object $filter = [], array $options = []) + public function countDocuments(array|object $filter = [], array $options = []): int { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); @@ -336,7 +331,7 @@ public function countDocuments(array|object $filter = [], array $options = []) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function createIndex(array|object $key, array $options = []) + public function createIndex(array|object $key, array $options = []): string { $operationOptionKeys = ['comment' => 1, 'commitQuorum' => 1, 'maxTimeMS' => 1, 'session' => 1, 'writeConcern' => 1]; $indexOptions = array_diff_key($options, $operationOptionKeys); @@ -372,7 +367,7 @@ public function createIndex(array|object $key, array $options = []) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function createIndexes(array $indexes, array $options = []) + public function createIndexes(array $indexes, array $options = []): array { $options = $this->inheritWriteOptions($options); @@ -446,12 +441,11 @@ public function createSearchIndexes(array $indexes, array $options = []): array * @see https://mongodb.com/docs/manual/reference/command/delete/ * @param array|object $filter Query by which to delete documents * @param array $options Command options - * @return DeleteResult * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function deleteMany(array|object $filter, array $options = []) + public function deleteMany(array|object $filter, array $options = []): DeleteResult { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); @@ -468,12 +462,11 @@ public function deleteMany(array|object $filter, array $options = []) * @see https://mongodb.com/docs/manual/reference/command/delete/ * @param array|object $filter Query by which to delete documents * @param array $options Command options - * @return DeleteResult * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function deleteOne(array|object $filter, array $options = []) + public function deleteOne(array|object $filter, array $options = []): DeleteResult { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); @@ -490,13 +483,12 @@ public function deleteOne(array|object $filter, array $options = []) * @param string $fieldName Field for which to return distinct values * @param array|object $filter Query by which to filter documents * @param array $options Command options - * @return array * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function distinct(string $fieldName, array|object $filter = [], array $options = []) + public function distinct(string $fieldName, array|object $filter = [], array $options = []): array { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); @@ -517,7 +509,7 @@ public function distinct(string $fieldName, array|object $filter = [], array $op * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function drop(array $options = []) + public function drop(array $options = []): array|object { $options = $this->inheritWriteOptions($options); $options = $this->inheritTypeMap($options); @@ -547,7 +539,7 @@ public function drop(array $options = []) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function dropIndex(string|IndexInfo $indexName, array $options = []) + public function dropIndex(string|IndexInfo $indexName, array $options = []): array|object { $indexName = (string) $indexName; @@ -573,7 +565,7 @@ public function dropIndex(string|IndexInfo $indexName, array $options = []) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function dropIndexes(array $options = []) + public function dropIndexes(array $options = []): array|object { $options = $this->inheritWriteOptions($options); $options = $this->inheritTypeMap($options); @@ -606,13 +598,12 @@ public function dropSearchIndex(string $name, array $options = []): void * * @see EstimatedDocumentCount::__construct() for supported options * @param array $options Command options - * @return integer * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function estimatedDocumentCount(array $options = []) + public function estimatedDocumentCount(array $options = []): int { $options = $this->inheritReadOptions($options); @@ -628,12 +619,11 @@ public function estimatedDocumentCount(array $options = []) * @see https://mongodb.com/docs/manual/reference/command/explain/ * @param Explainable $explainable Command on which to run explain * @param array $options Additional options - * @return array|object * @throws UnsupportedException if explainable or options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function explain(Explainable $explainable, array $options = []) + public function explain(Explainable $explainable, array $options = []): array|object { $options = $this->inheritReadPreference($options); $options = $this->inheritTypeMap($options); @@ -650,12 +640,11 @@ public function explain(Explainable $explainable, array $options = []) * @see https://mongodb.com/docs/manual/crud/#read-operations * @param array|object $filter Query by which to filter documents * @param array $options Additional options - * @return CursorInterface&Iterator * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function find(array|object $filter = [], array $options = []) + public function find(array|object $filter = [], array $options = []): CursorInterface { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); @@ -673,12 +662,11 @@ public function find(array|object $filter = [], array $options = []) * @see https://mongodb.com/docs/manual/crud/#read-operations * @param array|object $filter Query by which to filter documents * @param array $options Additional options - * @return array|object|null * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function findOne(array|object $filter = [], array $options = []) + public function findOne(array|object $filter = [], array $options = []): array|object|null { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritReadOptions($options); @@ -698,13 +686,12 @@ public function findOne(array|object $filter = [], array $options = []) * @see https://mongodb.com/docs/manual/reference/command/findAndModify/ * @param array|object $filter Query by which to filter documents * @param array $options Command options - * @return array|object|null * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function findOneAndDelete(array|object $filter, array $options = []) + public function findOneAndDelete(array|object $filter, array $options = []): array|object|null { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); @@ -729,13 +716,12 @@ public function findOneAndDelete(array|object $filter, array $options = []) * @param array|object $filter Query by which to filter documents * @param array|object $replacement Replacement document * @param array $options Command options - * @return array|object|null * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function findOneAndReplace(array|object $filter, array|object $replacement, array $options = []) + public function findOneAndReplace(array|object $filter, array|object $replacement, array $options = []): array|object|null { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); @@ -760,13 +746,12 @@ public function findOneAndReplace(array|object $filter, array|object $replacemen * @param array|object $filter Query by which to filter documents * @param array|object $update Update to apply to the matched document * @param array $options Command options - * @return array|object|null * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function findOneAndUpdate(array|object $filter, array|object $update, array $options = []) + public function findOneAndUpdate(array|object $filter, array|object $update, array $options = []): array|object|null { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); @@ -779,30 +764,24 @@ public function findOneAndUpdate(array|object $filter, array|object $update, arr /** * Return the collection name. - * - * @return string */ - public function getCollectionName() + public function getCollectionName(): string { return $this->collectionName; } /** * Return the database name. - * - * @return string */ - public function getDatabaseName() + public function getDatabaseName(): string { return $this->databaseName; } /** * Return the Manager. - * - * @return Manager */ - public function getManager() + public function getManager(): Manager { return $this->manager; } @@ -811,9 +790,8 @@ public function getManager() * Return the collection namespace. * * @see https://mongodb.com/docs/manual/reference/glossary/#term-namespace - * @return string */ - public function getNamespace() + public function getNamespace(): string { return $this->databaseName . '.' . $this->collectionName; } @@ -822,29 +800,24 @@ public function getNamespace() * Return the read concern for this collection. * * @see https://php.net/manual/en/mongodb-driver-readconcern.isdefault.php - * @return ReadConcern */ - public function getReadConcern() + public function getReadConcern(): ReadConcern { return $this->readConcern; } /** * Return the read preference for this collection. - * - * @return ReadPreference */ - public function getReadPreference() + public function getReadPreference(): ReadPreference { return $this->readPreference; } /** * Return the type map for this collection. - * - * @return array */ - public function getTypeMap() + public function getTypeMap(): array { return $this->typeMap; } @@ -853,9 +826,8 @@ public function getTypeMap() * Return the write concern for this collection. * * @see https://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php - * @return WriteConcern */ - public function getWriteConcern() + public function getWriteConcern(): WriteConcern { return $this->writeConcern; } @@ -867,11 +839,10 @@ public function getWriteConcern() * @see https://mongodb.com/docs/manual/reference/command/insert/ * @param list $documents The documents to insert * @param array $options Command options - * @return InsertManyResult * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function insertMany(array $documents, array $options = []) + public function insertMany(array $documents, array $options = []): InsertManyResult { $options = $this->inheritWriteOptions($options); $options = $this->inheritCodec($options); @@ -888,11 +859,10 @@ public function insertMany(array $documents, array $options = []) * @see https://mongodb.com/docs/manual/reference/command/insert/ * @param array|object $document The document to insert * @param array $options Command options - * @return InsertOneResult * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function insertOne(array|object $document, array $options = []) + public function insertOne(array|object $document, array $options = []): InsertOneResult { $options = $this->inheritWriteOptions($options); $options = $this->inheritCodec($options); @@ -910,7 +880,7 @@ public function insertOne(array|object $document, array $options = []) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function listIndexes(array $options = []) + public function listIndexes(array $options = []): IndexInfoIterator { $operation = new ListIndexes($this->databaseName, $this->collectionName, $options); @@ -944,13 +914,12 @@ public function listSearchIndexes(array $options = []): Iterator * @param JavascriptInterface $reduce Reduce function * @param string|array|object $out Output specification * @param array $options Command options - * @return MapReduceResult * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) * @throws UnexpectedValueException if the command response was malformed */ - public function mapReduce(JavascriptInterface $map, JavascriptInterface $reduce, string|array|object $out, array $options = []) + public function mapReduce(JavascriptInterface $map, JavascriptInterface $reduce, string|array|object $out, array $options = []): MapReduceResult { $hasOutputCollection = ! is_mapreduce_output_inline($out); @@ -988,7 +957,7 @@ public function mapReduce(JavascriptInterface $map, JavascriptInterface $reduce, * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function rename(string $toCollectionName, ?string $toDatabaseName = null, array $options = []) + public function rename(string $toCollectionName, ?string $toDatabaseName = null, array $options = []): array|object { if (! isset($toDatabaseName)) { $toDatabaseName = $this->databaseName; @@ -1010,12 +979,11 @@ public function rename(string $toCollectionName, ?string $toDatabaseName = null, * @param array|object $filter Query by which to filter documents * @param array|object $replacement Replacement document * @param array $options Command options - * @return UpdateResult * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function replaceOne(array|object $filter, array|object $replacement, array $options = []) + public function replaceOne(array|object $filter, array|object $replacement, array $options = []): UpdateResult { $filter = $this->builderEncoder->encodeIfSupported($filter); $options = $this->inheritWriteOptions($options); @@ -1034,12 +1002,11 @@ public function replaceOne(array|object $filter, array|object $replacement, arra * @param array|object $filter Query by which to filter documents * @param array|object $update Update to apply to the matched documents * @param array $options Command options - * @return UpdateResult * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function updateMany(array|object $filter, array|object $update, array $options = []) + public function updateMany(array|object $filter, array|object $update, array $options = []): UpdateResult { $filter = $this->builderEncoder->encodeIfSupported($filter); $update = $this->builderEncoder->encodeIfSupported($update); @@ -1058,12 +1025,11 @@ public function updateMany(array|object $filter, array|object $update, array $op * @param array|object $filter Query by which to filter documents * @param array|object $update Update to apply to the matched document * @param array $options Command options - * @return UpdateResult * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function updateOne(array|object $filter, array|object $update, array $options = []) + public function updateOne(array|object $filter, array|object $update, array $options = []): UpdateResult { $filter = $this->builderEncoder->encodeIfSupported($filter); $update = $this->builderEncoder->encodeIfSupported($update); @@ -1099,10 +1065,9 @@ public function updateSearchIndex(string $name, array|object $definition, array * @see Watch::__construct() for supported options * @param array $pipeline Aggregation pipeline * @param array $options Command options - * @return ChangeStream * @throws InvalidArgumentException for parameter/option parsing errors */ - public function watch(array $pipeline = [], array $options = []) + public function watch(array $pipeline = [], array $options = []): ChangeStream { if (is_builder_pipeline($pipeline)) { $pipeline = new Pipeline(...$pipeline); @@ -1123,10 +1088,9 @@ public function watch(array $pipeline = [], array $options = []) * * @see Collection::__construct() for supported options * @param array $options Collection constructor options - * @return Collection * @throws InvalidArgumentException for parameter/option parsing errors */ - public function withOptions(array $options = []) + public function withOptions(array $options = []): Collection { $options += [ 'builderEncoder' => $this->builderEncoder, diff --git a/src/Database.php b/src/Database.php index 4d15637a4..e8e256c49 100644 --- a/src/Database.php +++ b/src/Database.php @@ -24,7 +24,7 @@ use MongoDB\Builder\Pipeline; use MongoDB\Codec\Encoder; use MongoDB\Driver\ClientEncryption; -use MongoDB\Driver\Cursor; +use MongoDB\Driver\CursorInterface; use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; use MongoDB\Driver\Manager; use MongoDB\Driver\ReadConcern; @@ -38,6 +38,7 @@ use MongoDB\Model\BSONArray; use MongoDB\Model\BSONDocument; use MongoDB\Model\CollectionInfo; +use MongoDB\Model\CollectionInfoIterator; use MongoDB\Operation\Aggregate; use MongoDB\Operation\CreateCollection; use MongoDB\Operation\CreateEncryptedCollection; @@ -52,7 +53,6 @@ use MongoDB\Operation\Watch; use stdClass; use Throwable; -use Traversable; use function is_array; use function strlen; @@ -145,9 +145,8 @@ public function __construct(private Manager $manager, private string $databaseNa * Return internal properties for debugging purposes. * * @see https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo - * @return array */ - public function __debugInfo() + public function __debugInfo(): array { return [ 'builderEncoder' => $this->builderEncoder, @@ -170,19 +169,16 @@ public function __debugInfo() * @see https://php.net/oop5.overloading#object.get * @see https://php.net/types.string#language.types.string.parsing.complex * @param string $collectionName Name of the collection to select - * @return Collection */ - public function __get(string $collectionName) + public function __get(string $collectionName): Collection { return $this->selectCollection($collectionName); } /** * Return the database name. - * - * @return string */ - public function __toString() + public function __toString(): string { return $this->databaseName; } @@ -195,13 +191,12 @@ public function __toString() * @see Aggregate::__construct() for supported options * @param array $pipeline Aggregation pipeline * @param array $options Command options - * @return Traversable * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function aggregate(array $pipeline, array $options = []) + public function aggregate(array $pipeline, array $options = []): CursorInterface { if (is_builder_pipeline($pipeline)) { $pipeline = new Pipeline(...$pipeline); @@ -251,11 +246,10 @@ public function aggregate(array $pipeline, array $options = []) * @see DatabaseCommand::__construct() for supported options * @param array|object $command Command document * @param array $options Options for command execution - * @return Cursor * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function command(array|object $command, array $options = []) + public function command(array|object $command, array $options = []): CursorInterface { if (! isset($options['typeMap'])) { $options['typeMap'] = $this->typeMap; @@ -282,7 +276,7 @@ public function command(array|object $command, array $options = []) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function createCollection(string $collectionName, array $options = []) + public function createCollection(string $collectionName, array $options = []): array|object { if (! isset($options['typeMap'])) { $options['typeMap'] = $this->typeMap; @@ -358,7 +352,7 @@ public function createEncryptedCollection(string $collectionName, ClientEncrypti * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function drop(array $options = []) + public function drop(array $options = []): array|object { if (! isset($options['typeMap'])) { $options['typeMap'] = $this->typeMap; @@ -386,7 +380,7 @@ public function drop(array $options = []) * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function dropCollection(string $collectionName, array $options = []) + public function dropCollection(string $collectionName, array $options = []): array|object { if (! isset($options['typeMap'])) { $options['typeMap'] = $this->typeMap; @@ -412,20 +406,16 @@ public function dropCollection(string $collectionName, array $options = []) /** * Returns the database name. - * - * @return string */ - public function getDatabaseName() + public function getDatabaseName(): string { return $this->databaseName; } /** * Return the Manager. - * - * @return Manager */ - public function getManager() + public function getManager(): Manager { return $this->manager; } @@ -434,29 +424,24 @@ public function getManager() * Return the read concern for this database. * * @see https://php.net/manual/en/mongodb-driver-readconcern.isdefault.php - * @return ReadConcern */ - public function getReadConcern() + public function getReadConcern(): ReadConcern { return $this->readConcern; } /** * Return the read preference for this database. - * - * @return ReadPreference */ - public function getReadPreference() + public function getReadPreference(): ReadPreference { return $this->readPreference; } /** * Return the type map for this database. - * - * @return array */ - public function getTypeMap() + public function getTypeMap(): array { return $this->typeMap; } @@ -465,9 +450,8 @@ public function getTypeMap() * Return the write concern for this database. * * @see https://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php - * @return WriteConcern */ - public function getWriteConcern() + public function getWriteConcern(): WriteConcern { return $this->writeConcern; } @@ -495,7 +479,7 @@ public function listCollectionNames(array $options = []): Iterator * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function listCollections(array $options = []) + public function listCollections(array $options = []): CollectionInfoIterator { $operation = new ListCollections($this->databaseName, $options); $server = select_server($this->manager, $options); @@ -510,11 +494,10 @@ public function listCollections(array $options = []) * @param string $collectionName Collection or view to modify * @param array $collectionOptions Collection or view options to assign * @param array $options Command options - * @return array|object * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function modifyCollection(string $collectionName, array $collectionOptions, array $options = []) + public function modifyCollection(string $collectionName, array $collectionOptions, array $options = []): array|object { if (! isset($options['typeMap'])) { $options['typeMap'] = $this->typeMap; @@ -544,7 +527,7 @@ public function modifyCollection(string $collectionName, array $collectionOption * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function renameCollection(string $fromCollectionName, string $toCollectionName, ?string $toDatabaseName = null, array $options = []) + public function renameCollection(string $fromCollectionName, string $toCollectionName, ?string $toDatabaseName = null, array $options = []): array|object { if (! isset($toDatabaseName)) { $toDatabaseName = $this->databaseName; @@ -571,10 +554,9 @@ public function renameCollection(string $fromCollectionName, string $toCollectio * @see Collection::__construct() for supported options * @param string $collectionName Name of the collection to select * @param array $options Collection constructor options - * @return Collection * @throws InvalidArgumentException for parameter/option parsing errors */ - public function selectCollection(string $collectionName, array $options = []) + public function selectCollection(string $collectionName, array $options = []): Collection { $options += [ 'builderEncoder' => $this->builderEncoder, @@ -592,10 +574,9 @@ public function selectCollection(string $collectionName, array $options = []) * * @see Bucket::__construct() for supported options * @param array $options Bucket constructor options - * @return Bucket * @throws InvalidArgumentException for parameter/option parsing errors */ - public function selectGridFSBucket(array $options = []) + public function selectGridFSBucket(array $options = []): Bucket { $options += [ 'readConcern' => $this->readConcern, @@ -613,10 +594,9 @@ public function selectGridFSBucket(array $options = []) * @see Watch::__construct() for supported options * @param array $pipeline Aggregation pipeline * @param array $options Command options - * @return ChangeStream * @throws InvalidArgumentException for parameter/option parsing errors */ - public function watch(array $pipeline = [], array $options = []) + public function watch(array $pipeline = [], array $options = []): ChangeStream { if (is_builder_pipeline($pipeline)) { $pipeline = new Pipeline(...$pipeline); @@ -648,10 +628,9 @@ public function watch(array $pipeline = [], array $options = []) * * @see Database::__construct() for supported options * @param array $options Database constructor options - * @return Database * @throws InvalidArgumentException for parameter/option parsing errors */ - public function withOptions(array $options = []) + public function withOptions(array $options = []): Database { $options += [ 'readConcern' => $this->readConcern, diff --git a/src/DeleteResult.php b/src/DeleteResult.php index 56f3f072d..b58d3650d 100644 --- a/src/DeleteResult.php +++ b/src/DeleteResult.php @@ -38,10 +38,9 @@ public function __construct(private WriteResult $writeResult) * This method should only be called if the write was acknowledged. * * @see DeleteResult::isAcknowledged() - * @return integer|null * @throws BadMethodCallException if the write result is unacknowledged */ - public function getDeletedCount() + public function getDeletedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getDeletedCount(); @@ -55,10 +54,8 @@ public function getDeletedCount() * * If the delete was not acknowledged, other fields from the WriteResult * (e.g. deletedCount) will be undefined. - * - * @return boolean */ - public function isAcknowledged() + public function isAcknowledged(): bool { return $this->isAcknowledged; } diff --git a/src/Exception/BadMethodCallException.php b/src/Exception/BadMethodCallException.php index 4595bb9d1..e165b95ac 100644 --- a/src/Exception/BadMethodCallException.php +++ b/src/Exception/BadMethodCallException.php @@ -27,10 +27,9 @@ class BadMethodCallException extends BaseBadMethodCallException implements Excep * Thrown when a mutable method is invoked on an immutable object. * * @param string $class Class name - * @return self * @internal */ - public static function classIsImmutable(string $class) + public static function classIsImmutable(string $class): self { return new self(sprintf('%s is immutable', $class)); } @@ -39,10 +38,9 @@ public static function classIsImmutable(string $class) * Thrown when accessing a result field on an unacknowledged write result. * * @param string $method Method name - * @return self * @internal */ - public static function unacknowledgedWriteResultAccess(string $method) + public static function unacknowledgedWriteResultAccess(string $method): self { return new self(sprintf('%s should not be called for an unacknowledged write result', $method)); } diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php index 8a1b81ec2..2a9bc30b9 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Exception/InvalidArgumentException.php @@ -53,10 +53,9 @@ public static function expectedDocumentType(string $name, mixed $value): self * @param string $name Name of the argument or option * @param mixed $value Actual value (used to derive the type) * @param string|list $expectedType Expected type as a string or an array containing one or more strings - * @return self * @internal */ - public static function invalidType(string $name, mixed $value, string|array $expectedType) + public static function invalidType(string $name, mixed $value, string|array $expectedType): self { if (is_array($expectedType)) { $expectedType = self::expectedTypesToString($expectedType); diff --git a/src/Exception/ResumeTokenException.php b/src/Exception/ResumeTokenException.php index a73249cf9..9117f700d 100644 --- a/src/Exception/ResumeTokenException.php +++ b/src/Exception/ResumeTokenException.php @@ -26,10 +26,9 @@ class ResumeTokenException extends RuntimeException * Thrown when a resume token has an invalid type. * * @param mixed $value Actual value (used to derive the type) - * @return self * @internal */ - public static function invalidType(mixed $value) + public static function invalidType(mixed $value): self { return new self(sprintf('Expected resume token to have type "array or object" but found "%s"', get_debug_type($value))); } @@ -37,10 +36,9 @@ public static function invalidType(mixed $value) /** * Thrown when a resume token is not found in a change document. * - * @return self * @internal */ - public static function notFound() + public static function notFound(): self { return new self('Resume token not found in change document'); } diff --git a/src/Exception/UnsupportedException.php b/src/Exception/UnsupportedException.php index 2ad501051..1a5273715 100644 --- a/src/Exception/UnsupportedException.php +++ b/src/Exception/UnsupportedException.php @@ -23,10 +23,9 @@ class UnsupportedException extends RuntimeException * Thrown when the commitQuorum option for createIndexes is not supported * by a server. * - * @return self * @internal */ - public static function commitQuorumNotSupported() + public static function commitQuorumNotSupported(): self { return new self('The "commitQuorum" option is not supported by the server executing this operation'); } @@ -34,10 +33,9 @@ public static function commitQuorumNotSupported() /** * Thrown when a command's hint option is not supported by a server. * - * @return self * @internal */ - public static function hintNotSupported() + public static function hintNotSupported(): self { return new self('Hint is not supported by the server executing this operation'); } @@ -45,10 +43,9 @@ public static function hintNotSupported() /** * Thrown when a readConcern is used with a read operation in a transaction. * - * @return self * @internal */ - public static function readConcernNotSupportedInTransaction() + public static function readConcernNotSupportedInTransaction(): self { return new self('The "readConcern" option cannot be specified within a transaction. Instead, specify it when starting the transaction.'); } @@ -56,10 +53,9 @@ public static function readConcernNotSupportedInTransaction() /** * Thrown when a writeConcern is used with a write operation in a transaction. * - * @return self * @internal */ - public static function writeConcernNotSupportedInTransaction() + public static function writeConcernNotSupportedInTransaction(): self { return new self('The "writeConcern" option cannot be specified within a transaction. Instead, specify it when starting the transaction.'); } diff --git a/src/Exception/UnsupportedValueException.php b/src/Exception/UnsupportedValueException.php index d744baa13..62e089e5e 100644 --- a/src/Exception/UnsupportedValueException.php +++ b/src/Exception/UnsupportedValueException.php @@ -24,8 +24,7 @@ class UnsupportedValueException extends InvalidArgumentException implements Exception { - /** @return mixed */ - public function getValue() + public function getValue(): mixed { return $this->value; } diff --git a/src/GridFS/Bucket.php b/src/GridFS/Bucket.php index 04324df09..e054450cf 100644 --- a/src/GridFS/Bucket.php +++ b/src/GridFS/Bucket.php @@ -17,7 +17,6 @@ namespace MongoDB\GridFS; -use Iterator; use MongoDB\BSON\Document; use MongoDB\Codec\DocumentCodec; use MongoDB\Collection; @@ -184,9 +183,8 @@ public function __construct(private Manager $manager, private string $databaseNa * Return internal properties for debugging purposes. * * @see https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo - * @return array */ - public function __debugInfo() + public function __debugInfo(): array { return [ 'bucketName' => $this->bucketName, @@ -208,11 +206,10 @@ public function __debugInfo() * attempt to delete orphaned chunks. * * @param mixed $id File ID - * @return void * @throws FileNotFoundException if no file could be selected * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function delete(mixed $id) + public function delete(mixed $id): void { $file = $this->collectionWrapper->findFileById($id); $this->collectionWrapper->deleteFileAndChunksById($id); @@ -227,13 +224,12 @@ public function delete(mixed $id) * * @param mixed $id File ID * @param resource $destination Writable Stream - * @return void * @throws FileNotFoundException if no file could be selected * @throws InvalidArgumentException if $destination is not a stream * @throws StreamException if the file could not be uploaded * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function downloadToStream(mixed $id, $destination) + public function downloadToStream(mixed $id, $destination): void { if (! is_resource($destination) || get_resource_type($destination) != 'stream') { throw InvalidArgumentException::invalidType('$destination', $destination, 'resource'); @@ -267,13 +263,12 @@ public function downloadToStream(mixed $id, $destination) * @param string $filename Filename * @param resource $destination Writable Stream * @param array $options Download options - * @return void * @throws FileNotFoundException if no file could be selected * @throws InvalidArgumentException if $destination is not a stream * @throws StreamException if the file could not be uploaded * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function downloadToStreamByName(string $filename, $destination, array $options = []) + public function downloadToStreamByName(string $filename, $destination, array $options = []): void { if (! is_resource($destination) || get_resource_type($destination) != 'stream') { throw InvalidArgumentException::invalidType('$destination', $destination, 'resource'); @@ -289,10 +284,9 @@ public function downloadToStreamByName(string $filename, $destination, array $op * Drops the files and chunks collections associated with this GridFS * bucket. * - * @return void * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function drop() + public function drop(): void { $this->collectionWrapper->dropCollections(); } @@ -304,12 +298,11 @@ public function drop() * @see Find::__construct() for supported options * @param array|object $filter Query by which to filter documents * @param array $options Additional options - * @return CursorInterface&Iterator * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function find(array|object $filter = [], array $options = []) + public function find(array|object $filter = [], array $options = []): CursorInterface { if ($this->codec && ! array_key_exists('codec', $options)) { $options['codec'] = $this->codec; @@ -325,12 +318,11 @@ public function find(array|object $filter = [], array $options = []) * @see FindOne::__construct() for supported options * @param array|object $filter Query by which to filter documents * @param array $options Additional options - * @return array|object|null * @throws UnsupportedException if options are not supported by the selected server * @throws InvalidArgumentException for parameter/option parsing errors * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function findOne(array|object $filter = [], array $options = []) + public function findOne(array|object $filter = [], array $options = []): array|object|null { if ($this->codec && ! array_key_exists('codec', $options)) { $options['codec'] = $this->codec; @@ -341,40 +333,32 @@ public function findOne(array|object $filter = [], array $options = []) /** * Return the bucket name. - * - * @return string */ - public function getBucketName() + public function getBucketName(): string { return $this->bucketName; } /** * Return the chunks collection. - * - * @return Collection */ - public function getChunksCollection() + public function getChunksCollection(): Collection { return $this->collectionWrapper->getChunksCollection(); } /** * Return the chunk size in bytes. - * - * @return integer */ - public function getChunkSizeBytes() + public function getChunkSizeBytes(): int { return $this->chunkSizeBytes; } /** * Return the database name. - * - * @return string */ - public function getDatabaseName() + public function getDatabaseName(): string { return $this->databaseName; } @@ -383,11 +367,10 @@ public function getDatabaseName() * Gets the file document of the GridFS file associated with a stream. * * @param resource $stream GridFS stream - * @return array|object * @throws InvalidArgumentException if $stream is not a GridFS stream * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function getFileDocumentForStream($stream) + public function getFileDocumentForStream($stream): array|object { $file = $this->getRawFileDocumentForStream($stream); @@ -403,12 +386,11 @@ public function getFileDocumentForStream($stream) * Gets the file document's ID of the GridFS file associated with a stream. * * @param resource $stream GridFS stream - * @return mixed * @throws CorruptFileException if the file "_id" field does not exist * @throws InvalidArgumentException if $stream is not a GridFS stream * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function getFileIdForStream($stream) + public function getFileIdForStream($stream): mixed { $file = $this->getRawFileDocumentForStream($stream); @@ -428,10 +410,8 @@ public function getFileIdForStream($stream) /** * Return the files collection. - * - * @return Collection */ - public function getFilesCollection() + public function getFilesCollection(): Collection { return $this->collectionWrapper->getFilesCollection(); } @@ -440,29 +420,24 @@ public function getFilesCollection() * Return the read concern for this GridFS bucket. * * @see https://php.net/manual/en/mongodb-driver-readconcern.isdefault.php - * @return ReadConcern */ - public function getReadConcern() + public function getReadConcern(): ReadConcern { return $this->readConcern; } /** * Return the read preference for this GridFS bucket. - * - * @return ReadPreference */ - public function getReadPreference() + public function getReadPreference(): ReadPreference { return $this->readPreference; } /** * Return the type map for this GridFS bucket. - * - * @return array */ - public function getTypeMap() + public function getTypeMap(): array { return $this->typeMap; } @@ -471,9 +446,8 @@ public function getTypeMap() * Return the write concern for this GridFS bucket. * * @see https://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php - * @return WriteConcern */ - public function getWriteConcern() + public function getWriteConcern(): WriteConcern { return $this->writeConcern; } @@ -598,11 +572,10 @@ public function registerGlobalStreamWrapperAlias(string $alias): void * * @param mixed $id File ID * @param string $newFilename New filename - * @return void * @throws FileNotFoundException if no file could be selected * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function rename(mixed $id, string $newFilename) + public function rename(mixed $id, string $newFilename): void { $updateResult = $this->collectionWrapper->updateFilenameForId($id, $newFilename); @@ -645,7 +618,7 @@ public function rename(mixed $id, string $newFilename) * @throws StreamException if the file could not be uploaded * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function uploadFromStream(string $filename, $source, array $options = []) + public function uploadFromStream(string $filename, $source, array $options = []): mixed { if (! is_resource($source) || get_resource_type($source) != 'stream') { throw InvalidArgumentException::invalidType('$source', $source, 'resource'); diff --git a/src/GridFS/CollectionWrapper.php b/src/GridFS/CollectionWrapper.php index a28185cb0..30923ccde 100644 --- a/src/GridFS/CollectionWrapper.php +++ b/src/GridFS/CollectionWrapper.php @@ -18,7 +18,6 @@ namespace MongoDB\GridFS; use ArrayIterator; -use Iterator; use MongoDB\Collection; use MongoDB\Driver\CursorInterface; use MongoDB\Driver\Manager; @@ -117,9 +116,8 @@ public function dropCollections(): void * * @param mixed $id File ID * @param integer $fromChunk Starting chunk (inclusive) - * @return CursorInterface&Iterator */ - public function findChunksByFileId(mixed $id, int $fromChunk = 0) + public function findChunksByFileId(mixed $id, int $fromChunk = 0): CursorInterface { return $this->chunksCollection->find( [ @@ -194,9 +192,8 @@ public function findFileById(mixed $id): ?object * @see Find::__construct() for supported options * @param array|object $filter Query by which to filter documents * @param array $options Additional options - * @return CursorInterface&Iterator */ - public function findFiles(array|object $filter, array $options = []) + public function findFiles(array|object $filter, array $options = []): CursorInterface { return $this->filesCollection->find($filter, $options); } @@ -206,9 +203,8 @@ public function findFiles(array|object $filter, array $options = []) * * @param array|object $filter Query by which to filter documents * @param array $options Additional options - * @return array|object|null */ - public function findOneFile(array|object $filter, array $options = []) + public function findOneFile(array|object $filter, array $options = []): array|object|null { return $this->filesCollection->findOne($filter, $options); } diff --git a/src/GridFS/Exception/CorruptFileException.php b/src/GridFS/Exception/CorruptFileException.php index 34f89a6c0..b9feef87d 100644 --- a/src/GridFS/Exception/CorruptFileException.php +++ b/src/GridFS/Exception/CorruptFileException.php @@ -37,10 +37,9 @@ public static function invalidChunkData(int $chunkIndex): self * Thrown when a chunk is not found for an expected index. * * @param integer $expectedIndex Expected index number - * @return self * @internal */ - public static function missingChunk(int $expectedIndex) + public static function missingChunk(int $expectedIndex): self { return new self(sprintf('Chunk not found for index "%d"', $expectedIndex)); } @@ -50,10 +49,9 @@ public static function missingChunk(int $expectedIndex) * * @param integer $index Actual index number (i.e. "n" field) * @param integer $expectedIndex Expected index number - * @return self * @internal */ - public static function unexpectedIndex(int $index, int $expectedIndex) + public static function unexpectedIndex(int $index, int $expectedIndex): self { return new self(sprintf('Expected chunk to have index "%d" but found "%d"', $expectedIndex, $index)); } @@ -63,10 +61,9 @@ public static function unexpectedIndex(int $index, int $expectedIndex) * * @param integer $size Actual size (i.e. "data" field length) * @param integer $expectedSize Expected size - * @return self * @internal */ - public static function unexpectedSize(int $size, int $expectedSize) + public static function unexpectedSize(int $size, int $expectedSize): self { return new self(sprintf('Expected chunk to have size "%d" but found "%d"', $expectedSize, $size)); } diff --git a/src/GridFS/Exception/FileNotFoundException.php b/src/GridFS/Exception/FileNotFoundException.php index 21b8871ca..4cf153c08 100644 --- a/src/GridFS/Exception/FileNotFoundException.php +++ b/src/GridFS/Exception/FileNotFoundException.php @@ -28,10 +28,9 @@ class FileNotFoundException extends RuntimeException * Thrown when a file cannot be found by its filename. * * @param string $filename Filename - * @return self * @internal */ - public static function byFilename(string $filename) + public static function byFilename(string $filename): self { return new self(sprintf('File with name "%s" not found', $filename)); } @@ -42,10 +41,9 @@ public static function byFilename(string $filename) * @param string $filename Filename * @param integer $revision Revision * @param string $namespace Namespace for the files collection - * @return self * @internal */ - public static function byFilenameAndRevision(string $filename, int $revision, string $namespace) + public static function byFilenameAndRevision(string $filename, int $revision, string $namespace): self { return new self(sprintf('File with name "%s" and revision "%d" not found in "%s"', $filename, $revision, $namespace)); } @@ -55,10 +53,9 @@ public static function byFilenameAndRevision(string $filename, int $revision, st * * @param mixed $id File ID * @param string $namespace Namespace for the files collection - * @return self * @internal */ - public static function byId(mixed $id, string $namespace) + public static function byId(mixed $id, string $namespace): self { $json = Document::fromPHP(['_id' => $id])->toRelaxedExtendedJSON(); diff --git a/src/GridFS/ReadableStream.php b/src/GridFS/ReadableStream.php index c8441d18c..4e9b1ec72 100644 --- a/src/GridFS/ReadableStream.php +++ b/src/GridFS/ReadableStream.php @@ -17,7 +17,6 @@ namespace MongoDB\GridFS; -use Iterator; use MongoDB\BSON\Binary; use MongoDB\Driver\CursorInterface; use MongoDB\Exception\InvalidArgumentException; @@ -48,8 +47,7 @@ final class ReadableStream private int $chunkOffset = 0; - /** @var (CursorInterface&Iterator)|null */ - private ?Iterator $chunksIterator = null; + private ?CursorInterface $chunksIterator = null; private int $expectedLastChunkSize = 0; diff --git a/src/GridFS/StreamWrapper.php b/src/GridFS/StreamWrapper.php index 302a63385..e4f57fa85 100644 --- a/src/GridFS/StreamWrapper.php +++ b/src/GridFS/StreamWrapper.php @@ -315,8 +315,7 @@ public function unlink(string $path): bool return true; } - /** @return false|array */ - public function url_stat(string $path, int $flags) + public function url_stat(string $path, int $flags): false|array { assert($this->stream === null); diff --git a/src/InsertManyResult.php b/src/InsertManyResult.php index 6ad2a9595..3d2176e58 100644 --- a/src/InsertManyResult.php +++ b/src/InsertManyResult.php @@ -38,10 +38,9 @@ public function __construct(private WriteResult $writeResult, private array $ins * This method should only be called if the write was acknowledged. * * @see InsertManyResult::isAcknowledged() - * @return integer|null * @throws BadMethodCallException if the write result is unacknowledged */ - public function getInsertedCount() + public function getInsertedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getInsertedCount(); @@ -58,10 +57,8 @@ public function getInsertedCount() * the driver did not generate an ID), the index will contain its "_id" * field value. Any driver-generated ID will be a MongoDB\BSON\ObjectId * instance. - * - * @return array */ - public function getInsertedIds() + public function getInsertedIds(): array { return $this->insertedIds; } @@ -71,10 +68,8 @@ public function getInsertedIds() * * If the insert was not acknowledged, other fields from the WriteResult * (e.g. insertedCount) will be undefined. - * - * @return boolean */ - public function isAcknowledged() + public function isAcknowledged(): bool { return $this->writeResult->isAcknowledged(); } diff --git a/src/InsertOneResult.php b/src/InsertOneResult.php index 9c72775c8..8e3d4b3ab 100644 --- a/src/InsertOneResult.php +++ b/src/InsertOneResult.php @@ -38,10 +38,9 @@ public function __construct(private WriteResult $writeResult, private mixed $ins * This method should only be called if the write was acknowledged. * * @see InsertOneResult::isAcknowledged() - * @return integer|null * @throws BadMethodCallException if the write result is unacknowledged */ - public function getInsertedCount() + public function getInsertedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getInsertedCount(); @@ -56,10 +55,8 @@ public function getInsertedCount() * If the document had an ID prior to inserting (i.e. the driver did not * need to generate an ID), this will contain its "_id". Any * driver-generated ID will be a MongoDB\BSON\ObjectId instance. - * - * @return mixed */ - public function getInsertedId() + public function getInsertedId(): mixed { return $this->insertedId; } @@ -73,10 +70,8 @@ public function getInsertedId() * If the insert was not acknowledged, other fields from the WriteResult * (e.g. insertedCount) will be undefined and their getter methods should * not be invoked. - * - * @return boolean */ - public function isAcknowledged() + public function isAcknowledged(): bool { return $this->writeResult->isAcknowledged(); } diff --git a/src/MapReduceResult.php b/src/MapReduceResult.php index 00a75116a..dbe0e1dda 100644 --- a/src/MapReduceResult.php +++ b/src/MapReduceResult.php @@ -18,7 +18,6 @@ namespace MongoDB; use IteratorAggregate; -use ReturnTypeWillChange; use stdClass; use Traversable; @@ -52,20 +51,16 @@ class MapReduceResult implements IteratorAggregate /** * Returns various count statistics from the mapReduce command. - * - * @return array */ - public function getCounts() + public function getCounts(): array { return $this->counts; } /** * Return the command execution time in milliseconds. - * - * @return integer */ - public function getExecutionTimeMS() + public function getExecutionTimeMS(): int { return $this->executionTimeMS; } @@ -76,8 +71,7 @@ public function getExecutionTimeMS() * @see https://php.net/iteratoraggregate.getiterator * @return Traversable */ - #[ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return call_user_func($this->getIterator); } @@ -87,10 +81,8 @@ public function getIterator() * * Note: timing statistics are only available if the mapReduce command's * "verbose" option was true; otherwise, an empty array will be returned. - * - * @return array */ - public function getTiming() + public function getTiming(): array { return $this->timing; } diff --git a/src/Model/BSONArray.php b/src/Model/BSONArray.php index f055f4cb7..040350ce4 100644 --- a/src/Model/BSONArray.php +++ b/src/Model/BSONArray.php @@ -21,7 +21,6 @@ use JsonSerializable; use MongoDB\BSON\Serializable; use MongoDB\BSON\Unserializable; -use ReturnTypeWillChange; use function array_values; use function MongoDB\recursive_copy; @@ -51,9 +50,8 @@ public function __clone() * * @see https://php.net/oop5.magic#object.set-state * @see https://php.net/var-export - * @return self */ - public static function __set_state(array $properties) + public static function __set_state(array $properties): self { $array = new self(); $array->exchangeArray($properties); @@ -68,10 +66,8 @@ public static function __set_state(array $properties) * as a BSON array. * * @see https://php.net/mongodb-bson-serializable.bsonserialize - * @return array */ - #[ReturnTypeWillChange] - public function bsonSerialize() + public function bsonSerialize(): array { return array_values($this->getArrayCopy()); } @@ -82,8 +78,7 @@ public function bsonSerialize() * @see https://php.net/mongodb-bson-unserializable.bsonunserialize * @param array $data Array data */ - #[ReturnTypeWillChange] - public function bsonUnserialize(array $data) + public function bsonUnserialize(array $data): void { parent::__construct($data); } @@ -95,10 +90,8 @@ public function bsonUnserialize(array $data) * as a JSON array. * * @see https://php.net/jsonserializable.jsonserialize - * @return array */ - #[ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return array_values($this->getArrayCopy()); } diff --git a/src/Model/BSONDocument.php b/src/Model/BSONDocument.php index b9a9c0d80..5df92c0be 100644 --- a/src/Model/BSONDocument.php +++ b/src/Model/BSONDocument.php @@ -22,7 +22,6 @@ use JsonSerializable; use MongoDB\BSON\Serializable; use MongoDB\BSON\Unserializable; -use ReturnTypeWillChange; use stdClass; use function MongoDB\recursive_copy; @@ -65,9 +64,8 @@ public function __construct(array $input = [], int $flags = ArrayObject::ARRAY_A * * @see https://php.net/oop5.magic#object.set-state * @see https://php.net/var-export - * @return self */ - public static function __set_state(array $properties) + public static function __set_state(array $properties): self { $document = new self(); $document->exchangeArray($properties); @@ -79,10 +77,8 @@ public static function __set_state(array $properties) * Serialize the document to BSON. * * @see https://php.net/mongodb-bson-serializable.bsonserialize - * @return stdClass */ - #[ReturnTypeWillChange] - public function bsonSerialize() + public function bsonSerialize(): stdClass { return (object) $this->getArrayCopy(); } @@ -93,8 +89,7 @@ public function bsonSerialize() * @see https://php.net/mongodb-bson-unserializable.bsonunserialize * @param array $data Array data */ - #[ReturnTypeWillChange] - public function bsonUnserialize(array $data) + public function bsonUnserialize(array $data): void { parent::__construct($data, ArrayObject::ARRAY_AS_PROPS); } @@ -103,10 +98,8 @@ public function bsonUnserialize(array $data) * Serialize the array to JSON. * * @see https://php.net/jsonserializable.jsonserialize - * @return object */ - #[ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): stdClass { return (object) $this->getArrayCopy(); } diff --git a/src/Model/BSONIterator.php b/src/Model/BSONIterator.php index 2ca257c7f..e90901173 100644 --- a/src/Model/BSONIterator.php +++ b/src/Model/BSONIterator.php @@ -21,7 +21,6 @@ use MongoDB\BSON\Document; use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\UnexpectedValueException; -use ReturnTypeWillChange; use function assert; use function is_array; @@ -50,44 +49,28 @@ class BSONIterator implements Iterator private int $position = 0; - /** - * @see https://php.net/iterator.current - * @return mixed - */ - #[ReturnTypeWillChange] - public function current() + /** @see https://php.net/iterator.current */ + public function current(): mixed { return $this->current; } - /** - * @see https://php.net/iterator.key - * @return int - */ - #[ReturnTypeWillChange] - public function key() + /** @see https://php.net/iterator.key */ + public function key(): int { return $this->key; } - /** - * @see https://php.net/iterator.next - * @return void - */ - #[ReturnTypeWillChange] - public function next() + /** @see https://php.net/iterator.next */ + public function next(): void { $this->key++; $this->current = null; $this->advance(); } - /** - * @see https://php.net/iterator.rewind - * @return void - */ - #[ReturnTypeWillChange] - public function rewind() + /** @see https://php.net/iterator.rewind */ + public function rewind(): void { $this->key = 0; $this->position = 0; @@ -96,7 +79,6 @@ public function rewind() } /** @see https://php.net/iterator.valid */ - #[ReturnTypeWillChange] public function valid(): bool { return $this->current !== null; diff --git a/src/Model/CachingIterator.php b/src/Model/CachingIterator.php index 2f4fcb29f..64c61708f 100644 --- a/src/Model/CachingIterator.php +++ b/src/Model/CachingIterator.php @@ -20,7 +20,6 @@ use Countable; use Iterator; use IteratorIterator; -use ReturnTypeWillChange; use Traversable; use function count; @@ -79,12 +78,8 @@ public function count(): int return count($this->items); } - /** - * @see https://php.net/iterator.current - * @return mixed - */ - #[ReturnTypeWillChange] - public function current() + /** @see https://php.net/iterator.current */ + public function current(): mixed { $currentItem = current($this->items); @@ -93,11 +88,9 @@ public function current() /** * @see https://php.net/iterator.key - * @return mixed * @psalm-return TKey|null */ - #[ReturnTypeWillChange] - public function key() + public function key(): mixed { $currentItem = current($this->items); diff --git a/src/Model/CallbackIterator.php b/src/Model/CallbackIterator.php index cf7e60fa5..161224925 100644 --- a/src/Model/CallbackIterator.php +++ b/src/Model/CallbackIterator.php @@ -19,7 +19,6 @@ use Iterator; use IteratorIterator; -use ReturnTypeWillChange; use Traversable; use function call_user_func; @@ -56,8 +55,7 @@ public function __construct(Traversable $traversable, callable $callback) * @see https://php.net/iterator.current * @return TCallbackValue */ - #[ReturnTypeWillChange] - public function current() + public function current(): mixed { return call_user_func($this->callback, $this->iterator->current(), $this->iterator->key()); } @@ -66,8 +64,7 @@ public function current() * @see https://php.net/iterator.key * @return TKey */ - #[ReturnTypeWillChange] - public function key() + public function key(): mixed { return $this->iterator->key(); } diff --git a/src/Model/ChangeStreamIterator.php b/src/Model/ChangeStreamIterator.php index 721c59734..4a4f36b51 100644 --- a/src/Model/ChangeStreamIterator.php +++ b/src/Model/ChangeStreamIterator.php @@ -17,7 +17,6 @@ namespace MongoDB\Model; -use Iterator; use IteratorIterator; use MongoDB\BSON\Document; use MongoDB\BSON\Serializable; @@ -30,7 +29,6 @@ use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\ResumeTokenException; use MongoDB\Exception\UnexpectedValueException; -use ReturnTypeWillChange; use function assert; use function count; @@ -49,7 +47,7 @@ * * @internal * @template TValue of array|object - * @template-extends IteratorIterator&Iterator> + * @template-extends IteratorIterator> */ final class ChangeStreamIterator extends IteratorIterator implements CommandSubscriber { @@ -67,28 +65,25 @@ final class ChangeStreamIterator extends IteratorIterator implements CommandSubs /** * @see https://php.net/iteratoriterator.current - * @return array|object|null * @psalm-return TValue|null */ - #[ReturnTypeWillChange] - public function current() + public function current(): array|object|null { return $this->valid() ? parent::current() : null; } /** - * Necessary to let psalm know that we're always expecting a cursor as inner - * iterator. This could be side-stepped due to the class not being final, - * but it's very much an invalid use-case. This method can be dropped in 2.0 - * once the class is final. + * This method is necessary as psalm does not properly set the return type + * of IteratorIterator::getInnerIterator to the templated iterator * - * @return CursorInterface&Iterator + * @see https://github.com/vimeo/psalm/pull/11100. + * + * @return CursorInterface */ - final public function getInnerIterator(): Iterator + public function getInnerIterator(): CursorInterface { $cursor = parent::getInnerIterator(); assert($cursor instanceof CursorInterface); - assert($cursor instanceof Iterator); return $cursor; } @@ -99,10 +94,8 @@ final public function getInnerIterator(): Iterator * Null may be returned if no change documents have been iterated and the * server did not include a postBatchResumeToken in its aggregate or getMore * command response. - * - * @return array|object|null */ - public function getResumeToken() + public function getResumeToken(): array|object|null { return $this->resumeToken; } @@ -115,12 +108,8 @@ public function getServer(): Server return $this->server; } - /** - * @see https://php.net/iteratoriterator.key - * @return int|null - */ - #[ReturnTypeWillChange] - public function key() + /** @see https://php.net/iteratoriterator.key */ + public function key(): ?int { return $this->valid() ? parent::key() : null; } @@ -173,18 +162,10 @@ public function valid(): bool /** * @internal - * @psalm-param CursorInterface&Iterator $cursor + * @psalm-param CursorInterface $cursor */ public function __construct(CursorInterface $cursor, int $firstBatchSize, array|object|null $initialResumeToken, private ?object $postBatchResumeToken = null) { - if (! $cursor instanceof Iterator) { - throw InvalidArgumentException::invalidType( - '$cursor', - $cursor, - CursorInterface::class . '&' . Iterator::class, - ); - } - if (isset($initialResumeToken) && ! is_document($initialResumeToken)) { throw InvalidArgumentException::expectedDocumentType('$initialResumeToken', $initialResumeToken); } @@ -238,11 +219,10 @@ final public function commandSucceeded(CommandSucceededEvent $event): void * Extracts the resume token (i.e. "_id" field) from a change document. * * @param array|object $document Change document - * @return array|object * @throws InvalidArgumentException * @throws ResumeTokenException if the resume token is not found or invalid */ - private function extractResumeToken(array|object $document) + private function extractResumeToken(array|object $document): array|object { if (! is_document($document)) { throw InvalidArgumentException::expectedDocumentType('$document', $document); diff --git a/src/Model/CodecCursor.php b/src/Model/CodecCursor.php index 642f3c3c1..d7a3776b2 100644 --- a/src/Model/CodecCursor.php +++ b/src/Model/CodecCursor.php @@ -17,30 +17,24 @@ namespace MongoDB\Model; -use Iterator; use MongoDB\BSON\Document; use MongoDB\BSON\Int64; use MongoDB\Codec\DocumentCodec; -use MongoDB\Driver\Cursor; -use MongoDB\Driver\CursorId; use MongoDB\Driver\CursorInterface; use MongoDB\Driver\Server; -use ReturnTypeWillChange; use function assert; use function iterator_to_array; use function sprintf; use function trigger_error; -use const E_USER_DEPRECATED; use const E_USER_WARNING; /** * @template TValue of object - * @template-implements CursorInterface - * @template-implements Iterator + * @template-implements CursorInterface */ -class CodecCursor implements CursorInterface, Iterator +class CodecCursor implements CursorInterface { private const TYPEMAP = ['root' => 'bson']; @@ -64,33 +58,16 @@ public function current(): ?object * @param DocumentCodec $codec * @return self */ - public static function fromCursor(Cursor $cursor, DocumentCodec $codec): self + public static function fromCursor(CursorInterface $cursor, DocumentCodec $codec): self { $cursor->setTypeMap(self::TYPEMAP); return new self($cursor, $codec); } - /** - * @return CursorId|Int64 - * @psalm-return ($asInt64 is true ? Int64 : CursorId) - */ - #[ReturnTypeWillChange] - public function getId(bool $asInt64 = false) + public function getId(): Int64 { - if (! $asInt64) { - @trigger_error( - sprintf( - 'The method "%s" will no longer return a "%s" instance in the future. Pass "true" as argument to change to the new behavior and receive a "%s" instance instead.', - __METHOD__, - CursorId::class, - Int64::class, - ), - E_USER_DEPRECATED, - ); - } - - return $this->cursor->getId($asInt64); + return $this->cursor->getId(); } public function getServer(): Server @@ -138,7 +115,7 @@ public function valid(): bool } /** @param DocumentCodec $codec */ - private function __construct(private Cursor $cursor, private DocumentCodec $codec) + private function __construct(private CursorInterface $cursor, private DocumentCodec $codec) { } } diff --git a/src/Model/CollectionInfo.php b/src/Model/CollectionInfo.php index 2850a4be4..717e19d84 100644 --- a/src/Model/CollectionInfo.php +++ b/src/Model/CollectionInfo.php @@ -19,7 +19,6 @@ use ArrayAccess; use MongoDB\Exception\BadMethodCallException; -use ReturnTypeWillChange; use function array_key_exists; @@ -45,9 +44,8 @@ public function __construct(private array $info) * Return the collection info as an array. * * @see https://php.net/oop5.magic#language.oop5.magic.debuginfo - * @return array */ - public function __debugInfo() + public function __debugInfo(): array { return $this->info; } @@ -56,10 +54,8 @@ public function __debugInfo() * Return the maximum number of documents to keep in the capped collection. * * @deprecated 1.0 Deprecated in favor of using getOptions - * - * @return integer|null */ - public function getCappedMax() + public function getCappedMax(): ?int { /* The MongoDB server might return this number as an integer or float */ return isset($this->info['options']['max']) ? (integer) $this->info['options']['max'] : null; @@ -69,10 +65,8 @@ public function getCappedMax() * Return the maximum size (in bytes) of the capped collection. * * @deprecated 1.0 Deprecated in favor of using getOptions - * - * @return integer|null */ - public function getCappedSize() + public function getCappedSize(): ?int { /* The MongoDB server might return this number as an integer or float */ return isset($this->info['options']['size']) ? (integer) $this->info['options']['size'] : null; @@ -100,9 +94,8 @@ public function getInfo(): array * Return the collection name. * * @see https://mongodb.com/docs/manual/reference/command/listCollections/#output - * @return string */ - public function getName() + public function getName(): string { return (string) $this->info['name']; } @@ -111,9 +104,8 @@ public function getName() * Return the collection options. * * @see https://mongodb.com/docs/manual/reference/command/listCollections/#output - * @return array */ - public function getOptions() + public function getOptions(): array { return (array) ($this->info['options'] ?? []); } @@ -132,10 +124,8 @@ public function getType(): string * Return whether the collection is a capped collection. * * @deprecated 1.0 Deprecated in favor of using getOptions - * - * @return boolean */ - public function isCapped() + public function isCapped(): bool { return ! empty($this->info['options']['capped']); } @@ -144,11 +134,9 @@ public function isCapped() * Check whether a field exists in the collection information. * * @see https://php.net/arrayaccess.offsetexists - * @return boolean * @psalm-param array-key $offset */ - #[ReturnTypeWillChange] - public function offsetExists(mixed $offset) + public function offsetExists(mixed $offset): bool { return array_key_exists($offset, $this->info); } @@ -157,11 +145,9 @@ public function offsetExists(mixed $offset) * Return the field's value from the collection information. * * @see https://php.net/arrayaccess.offsetget - * @return mixed * @psalm-param array-key $offset */ - #[ReturnTypeWillChange] - public function offsetGet(mixed $offset) + public function offsetGet(mixed $offset): mixed { return $this->info[$offset]; } @@ -171,10 +157,8 @@ public function offsetGet(mixed $offset) * * @see https://php.net/arrayaccess.offsetset * @throws BadMethodCallException - * @return void */ - #[ReturnTypeWillChange] - public function offsetSet(mixed $offset, mixed $value) + public function offsetSet(mixed $offset, mixed $value): void { throw BadMethodCallException::classIsImmutable(self::class); } @@ -184,10 +168,8 @@ public function offsetSet(mixed $offset, mixed $value) * * @see https://php.net/arrayaccess.offsetunset * @throws BadMethodCallException - * @return void */ - #[ReturnTypeWillChange] - public function offsetUnset(mixed $offset) + public function offsetUnset(mixed $offset): void { throw BadMethodCallException::classIsImmutable(self::class); } diff --git a/src/Model/CollectionInfoIterator.php b/src/Model/CollectionInfoIterator.php index e7ebf4984..6ce22c551 100644 --- a/src/Model/CollectionInfoIterator.php +++ b/src/Model/CollectionInfoIterator.php @@ -18,7 +18,6 @@ namespace MongoDB\Model; use Iterator; -use ReturnTypeWillChange; /** * CollectionInfoIterator interface. @@ -33,9 +32,6 @@ interface CollectionInfoIterator extends Iterator { /** * Return the current element as a CollectionInfo instance. - * - * @return CollectionInfo */ - #[ReturnTypeWillChange] - public function current(); + public function current(): CollectionInfo; } diff --git a/src/Model/DatabaseInfo.php b/src/Model/DatabaseInfo.php index 2803532f8..2a9d01204 100644 --- a/src/Model/DatabaseInfo.php +++ b/src/Model/DatabaseInfo.php @@ -19,7 +19,6 @@ use ArrayAccess; use MongoDB\Exception\BadMethodCallException; -use ReturnTypeWillChange; use function array_key_exists; @@ -44,29 +43,24 @@ public function __construct(private array $info) * Return the database info as an array. * * @see https://php.net/oop5.magic#language.oop5.magic.debuginfo - * @return array */ - public function __debugInfo() + public function __debugInfo(): array { return $this->info; } /** * Return the database name. - * - * @return string */ - public function getName() + public function getName(): string { return (string) $this->info['name']; } /** * Return the databases size on disk (in bytes). - * - * @return integer */ - public function getSizeOnDisk() + public function getSizeOnDisk(): int { /* The MongoDB server might return this number as an integer or float */ return (integer) $this->info['sizeOnDisk']; @@ -74,10 +68,8 @@ public function getSizeOnDisk() /** * Return whether the database is empty. - * - * @return boolean */ - public function isEmpty() + public function isEmpty(): bool { return (boolean) $this->info['empty']; } @@ -86,11 +78,9 @@ public function isEmpty() * Check whether a field exists in the database information. * * @see https://php.net/arrayaccess.offsetexists - * @return boolean * @psalm-param array-key $offset */ - #[ReturnTypeWillChange] - public function offsetExists(mixed $offset) + public function offsetExists(mixed $offset): bool { return array_key_exists($offset, $this->info); } @@ -99,11 +89,9 @@ public function offsetExists(mixed $offset) * Return the field's value from the database information. * * @see https://php.net/arrayaccess.offsetget - * @return mixed * @psalm-param array-key $offset */ - #[ReturnTypeWillChange] - public function offsetGet(mixed $offset) + public function offsetGet(mixed $offset): mixed { return $this->info[$offset]; } @@ -113,10 +101,8 @@ public function offsetGet(mixed $offset) * * @see https://php.net/arrayaccess.offsetset * @throws BadMethodCallException - * @return void */ - #[ReturnTypeWillChange] - public function offsetSet(mixed $offset, mixed $value) + public function offsetSet(mixed $offset, mixed $value): void { throw BadMethodCallException::classIsImmutable(self::class); } @@ -126,10 +112,8 @@ public function offsetSet(mixed $offset, mixed $value) * * @see https://php.net/arrayaccess.offsetunset * @throws BadMethodCallException - * @return void */ - #[ReturnTypeWillChange] - public function offsetUnset(mixed $offset) + public function offsetUnset(mixed $offset): void { throw BadMethodCallException::classIsImmutable(self::class); } diff --git a/src/Model/DatabaseInfoIterator.php b/src/Model/DatabaseInfoIterator.php index 72199bd32..fc00fb79b 100644 --- a/src/Model/DatabaseInfoIterator.php +++ b/src/Model/DatabaseInfoIterator.php @@ -18,7 +18,6 @@ namespace MongoDB\Model; use Iterator; -use ReturnTypeWillChange; /** * DatabaseInfoIterator interface. @@ -33,9 +32,6 @@ interface DatabaseInfoIterator extends Iterator { /** * Return the current element as a DatabaseInfo instance. - * - * @return DatabaseInfo */ - #[ReturnTypeWillChange] - public function current(); + public function current(): DatabaseInfo; } diff --git a/src/Model/IndexInfo.php b/src/Model/IndexInfo.php index 53b7b63f0..360b27327 100644 --- a/src/Model/IndexInfo.php +++ b/src/Model/IndexInfo.php @@ -19,7 +19,6 @@ use ArrayAccess; use MongoDB\Exception\BadMethodCallException; -use ReturnTypeWillChange; use function array_key_exists; use function array_search; @@ -53,39 +52,32 @@ public function __construct(private array $info) * Return the collection info as an array. * * @see https://php.net/oop5.magic#language.oop5.magic.debuginfo - * @return array */ - public function __debugInfo() + public function __debugInfo(): array { return $this->info; } /** * Return the index name to allow casting IndexInfo to string. - * - * @return string */ - public function __toString() + public function __toString(): string { return $this->getName(); } /** * Return the index key. - * - * @return array */ - public function getKey() + public function getKey(): array { return (array) $this->info['key']; } /** * Return the index name. - * - * @return string */ - public function getName() + public function getName(): string { return (string) $this->info['name']; } @@ -94,10 +86,8 @@ public function getName() * Return the index namespace (e.g. "db.collection"). * * @deprecated - * - * @return string */ - public function getNamespace() + public function getNamespace(): string { @trigger_error('MongoDB 4.4 drops support for the namespace in indexes, the method "IndexInfo::getNamespace()" will be removed in a future release', E_USER_DEPRECATED); @@ -106,20 +96,16 @@ public function getNamespace() /** * Return the index version. - * - * @return integer */ - public function getVersion() + public function getVersion(): int { return (integer) $this->info['v']; } /** * Return whether or not this index is of type 2dsphere. - * - * @return boolean */ - public function is2dSphere() + public function is2dSphere(): bool { return array_search('2dsphere', $this->getKey(), true) !== false; } @@ -127,10 +113,9 @@ public function is2dSphere() /** * Return whether or not this index is of type geoHaystack. * - * @return boolean * @deprecated Since 1.16: MongoDB 5.0 removes support for geoHaystack indexes. */ - public function isGeoHaystack() + public function isGeoHaystack(): bool { @trigger_error('MongoDB 5.0 removes support for "geoHaystack" indexes, the method "IndexInfo::isGeoHaystack()" will be removed in a future release', E_USER_DEPRECATED); @@ -141,19 +126,16 @@ public function isGeoHaystack() * Return whether this is a sparse index. * * @see https://mongodb.com/docs/manual/core/index-sparse/ - * @return boolean */ - public function isSparse() + public function isSparse(): bool { return ! empty($this->info['sparse']); } /** * Return whether or not this index is of type text. - * - * @return boolean */ - public function isText() + public function isText(): bool { return array_search('text', $this->getKey(), true) !== false; } @@ -162,9 +144,8 @@ public function isText() * Return whether this is a TTL index. * * @see https://mongodb.com/docs/manual/core/index-ttl/ - * @return boolean */ - public function isTtl() + public function isTtl(): bool { return array_key_exists('expireAfterSeconds', $this->info); } @@ -173,9 +154,8 @@ public function isTtl() * Return whether this is a unique index. * * @see https://mongodb.com/docs/manual/core/index-unique/ - * @return boolean */ - public function isUnique() + public function isUnique(): bool { return ! empty($this->info['unique']); } @@ -184,11 +164,9 @@ public function isUnique() * Check whether a field exists in the index information. * * @see https://php.net/arrayaccess.offsetexists - * @return boolean * @psalm-param array-key $offset */ - #[ReturnTypeWillChange] - public function offsetExists(mixed $offset) + public function offsetExists(mixed $offset): bool { return array_key_exists($offset, $this->info); } @@ -202,11 +180,9 @@ public function offsetExists(mixed $offset) * * @see https://php.net/arrayaccess.offsetget * @see https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst#getting-full-index-information - * @return mixed * @psalm-param array-key $offset */ - #[ReturnTypeWillChange] - public function offsetGet(mixed $offset) + public function offsetGet(mixed $offset): mixed { return $this->info[$offset]; } @@ -216,10 +192,8 @@ public function offsetGet(mixed $offset) * * @see https://php.net/arrayaccess.offsetset * @throws BadMethodCallException - * @return void */ - #[ReturnTypeWillChange] - public function offsetSet(mixed $offset, mixed $value) + public function offsetSet(mixed $offset, mixed $value): void { throw BadMethodCallException::classIsImmutable(self::class); } @@ -229,10 +203,8 @@ public function offsetSet(mixed $offset, mixed $value) * * @see https://php.net/arrayaccess.offsetunset * @throws BadMethodCallException - * @return void */ - #[ReturnTypeWillChange] - public function offsetUnset(mixed $offset) + public function offsetUnset(mixed $offset): void { throw BadMethodCallException::classIsImmutable(self::class); } diff --git a/src/Model/IndexInfoIterator.php b/src/Model/IndexInfoIterator.php index b7929c20f..f52e8dbfa 100644 --- a/src/Model/IndexInfoIterator.php +++ b/src/Model/IndexInfoIterator.php @@ -18,7 +18,6 @@ namespace MongoDB\Model; use Iterator; -use ReturnTypeWillChange; /** * IndexInfoIterator interface. @@ -33,9 +32,6 @@ interface IndexInfoIterator extends Iterator { /** * Return the current element as a IndexInfo instance. - * - * @return IndexInfo */ - #[ReturnTypeWillChange] - public function current(); + public function current(): IndexInfo; } diff --git a/src/Operation/Aggregate.php b/src/Operation/Aggregate.php index 495d741a9..b7f109589 100644 --- a/src/Operation/Aggregate.php +++ b/src/Operation/Aggregate.php @@ -17,10 +17,8 @@ namespace MongoDB\Operation; -use Iterator; use MongoDB\Codec\DocumentCodec; use MongoDB\Driver\Command; -use MongoDB\Driver\Cursor; use MongoDB\Driver\CursorInterface; use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; use MongoDB\Driver\ReadConcern; @@ -215,12 +213,11 @@ public function __construct(private string $databaseName, private ?string $colle * Execute the operation. * * @see Executable::execute() - * @return CursorInterface&Iterator * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if read concern or write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): CursorInterface { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction) { @@ -255,9 +252,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { $cmd = $this->createCommandDocument(); @@ -320,7 +316,7 @@ private function createCommandOptions(): array * @see https://php.net/manual/en/mongodb-driver-server.executereadcommand.php * @see https://php.net/manual/en/mongodb-driver-server.executereadwritecommand.php */ - private function executeCommand(Server $server, Command $command): Cursor + private function executeCommand(Server $server, Command $command): CursorInterface { $options = []; diff --git a/src/Operation/BulkWrite.php b/src/Operation/BulkWrite.php index d9eb43376..178ff1847 100644 --- a/src/Operation/BulkWrite.php +++ b/src/Operation/BulkWrite.php @@ -186,11 +186,10 @@ public function __construct(private string $databaseName, private string $collec * Execute the operation. * * @see Executable::execute() - * @return BulkWriteResult * @throws UnsupportedException if write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): BulkWriteResult { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['writeConcern'])) { diff --git a/src/Operation/Count.php b/src/Operation/Count.php index 6a42a5c15..df91214bd 100644 --- a/src/Operation/Count.php +++ b/src/Operation/Count.php @@ -125,12 +125,11 @@ public function __construct(private string $databaseName, private string $collec * Execute the operation. * * @see Executable::execute() - * @return integer * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if read concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): int { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['readConcern'])) { @@ -152,9 +151,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { $cmd = $this->createCommandDocument(); diff --git a/src/Operation/CountDocuments.php b/src/Operation/CountDocuments.php index 449399a5a..4badaaf3b 100644 --- a/src/Operation/CountDocuments.php +++ b/src/Operation/CountDocuments.php @@ -104,12 +104,11 @@ public function __construct(private string $databaseName, private string $collec * Execute the operation. * * @see Executable::execute() - * @return integer * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if collation or read concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): int { $cursor = $this->aggregate->execute($server); diff --git a/src/Operation/CreateCollection.php b/src/Operation/CreateCollection.php index e5406315e..2182aec58 100644 --- a/src/Operation/CreateCollection.php +++ b/src/Operation/CreateCollection.php @@ -243,7 +243,7 @@ public function __construct(private string $databaseName, private string $collec * @return array|object Command result document * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions()); diff --git a/src/Operation/CreateEncryptedCollection.php b/src/Operation/CreateEncryptedCollection.php index 9c7d120d8..fec5f2d18 100644 --- a/src/Operation/CreateEncryptedCollection.php +++ b/src/Operation/CreateEncryptedCollection.php @@ -160,7 +160,7 @@ public function createDataKeys(ClientEncryption $clientEncryption, string $kmsPr * @throws DriverRuntimeException for other driver errors (e.g. connection errors) * @throws UnsupportedException if the server does not support Queryable Encryption */ - public function execute(Server $server) + public function execute(Server $server): array|object { if (! server_supports_feature($server, self::WIRE_VERSION_FOR_QUERYABLE_ENCRYPTION_V2)) { throw new UnsupportedException('Driver support of Queryable Encryption is incompatible with server. Upgrade server to use Queryable Encryption.'); diff --git a/src/Operation/CreateIndexes.php b/src/Operation/CreateIndexes.php index 637e99cbd..0b164c48c 100644 --- a/src/Operation/CreateIndexes.php +++ b/src/Operation/CreateIndexes.php @@ -121,7 +121,7 @@ public function __construct(private string $databaseName, private string $collec * @throws UnsupportedException if write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['writeConcern'])) { diff --git a/src/Operation/DatabaseCommand.php b/src/Operation/DatabaseCommand.php index bf02a6430..97cb7a500 100644 --- a/src/Operation/DatabaseCommand.php +++ b/src/Operation/DatabaseCommand.php @@ -18,7 +18,7 @@ namespace MongoDB\Operation; use MongoDB\Driver\Command; -use MongoDB\Driver\Cursor; +use MongoDB\Driver\CursorInterface; use MongoDB\Driver\ReadPreference; use MongoDB\Driver\Server; use MongoDB\Driver\Session; @@ -82,9 +82,8 @@ public function __construct(private string $databaseName, array|object $command, * Execute the operation. * * @see Executable::execute() - * @return Cursor */ - public function execute(Server $server) + public function execute(Server $server): CursorInterface { $cursor = $server->executeCommand($this->databaseName, $this->command, $this->createOptions()); diff --git a/src/Operation/Delete.php b/src/Operation/Delete.php index 09e39a922..ae2a46306 100644 --- a/src/Operation/Delete.php +++ b/src/Operation/Delete.php @@ -121,11 +121,10 @@ public function __construct(private string $databaseName, private string $collec * Execute the operation. * * @see Executable::execute() - * @return DeleteResult * @throws UnsupportedException if hint or write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): DeleteResult { /* CRUD spec requires a client-side error when using "hint" with an * unacknowledged write concern on an unsupported server. */ @@ -153,9 +152,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { $cmd = ['delete' => $this->collectionName, 'deletes' => [['q' => $this->filter] + $this->createDeleteOptions()]]; diff --git a/src/Operation/DeleteMany.php b/src/Operation/DeleteMany.php index 2d85727a8..78090c464 100644 --- a/src/Operation/DeleteMany.php +++ b/src/Operation/DeleteMany.php @@ -75,11 +75,10 @@ public function __construct(string $databaseName, string $collectionName, array| * Execute the operation. * * @see Executable::execute() - * @return DeleteResult * @throws UnsupportedException if collation is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): DeleteResult { return $this->delete->execute($server); } @@ -88,9 +87,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->delete->getCommandDocument(); } diff --git a/src/Operation/DeleteOne.php b/src/Operation/DeleteOne.php index c9460a916..157bb748a 100644 --- a/src/Operation/DeleteOne.php +++ b/src/Operation/DeleteOne.php @@ -75,11 +75,10 @@ public function __construct(string $databaseName, string $collectionName, array| * Execute the operation. * * @see Executable::execute() - * @return DeleteResult * @throws UnsupportedException if collation is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): DeleteResult { return $this->delete->execute($server); } @@ -88,9 +87,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->delete->getCommandDocument(); } diff --git a/src/Operation/Distinct.php b/src/Operation/Distinct.php index e69adabac..1f06c0ff2 100644 --- a/src/Operation/Distinct.php +++ b/src/Operation/Distinct.php @@ -110,12 +110,11 @@ public function __construct(private string $databaseName, private string $collec * Execute the operation. * * @see Executable::execute() - * @return array * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if read concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['readConcern'])) { @@ -141,9 +140,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { $cmd = $this->createCommandDocument(); diff --git a/src/Operation/DropCollection.php b/src/Operation/DropCollection.php index 3384bd998..d1a0b65a8 100644 --- a/src/Operation/DropCollection.php +++ b/src/Operation/DropCollection.php @@ -88,7 +88,7 @@ public function __construct(private string $databaseName, private string $collec * @throws UnsupportedException if write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['writeConcern'])) { diff --git a/src/Operation/DropDatabase.php b/src/Operation/DropDatabase.php index cb1563612..c60015e5c 100644 --- a/src/Operation/DropDatabase.php +++ b/src/Operation/DropDatabase.php @@ -82,7 +82,7 @@ public function __construct(private string $databaseName, private array $options * @return array|object Command result document * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions()); diff --git a/src/Operation/DropEncryptedCollection.php b/src/Operation/DropEncryptedCollection.php index 1d90f89f4..32f143ee5 100644 --- a/src/Operation/DropEncryptedCollection.php +++ b/src/Operation/DropEncryptedCollection.php @@ -89,7 +89,7 @@ public function __construct(string $databaseName, string $collectionName, array * @return array|object Command result document from dropping the encrypted collection * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { foreach ($this->dropMetadataCollections as $dropMetadataCollection) { $dropMetadataCollection->execute($server); diff --git a/src/Operation/DropIndexes.php b/src/Operation/DropIndexes.php index 69cc8ce4c..d6b1beb59 100644 --- a/src/Operation/DropIndexes.php +++ b/src/Operation/DropIndexes.php @@ -97,7 +97,7 @@ public function __construct(private string $databaseName, private string $collec * @throws UnsupportedException if write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['writeConcern'])) { diff --git a/src/Operation/EstimatedDocumentCount.php b/src/Operation/EstimatedDocumentCount.php index 3a6ce256b..2a5aada61 100644 --- a/src/Operation/EstimatedDocumentCount.php +++ b/src/Operation/EstimatedDocumentCount.php @@ -88,12 +88,11 @@ public function __construct(private string $databaseName, private string $collec * Execute the operation. * * @see Executable::execute() - * @return integer * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if collation or read concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): int { return $this->createCount()->execute($server); } @@ -102,9 +101,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->createCount()->getCommandDocument(); } diff --git a/src/Operation/Executable.php b/src/Operation/Executable.php index 5bd8c68b3..2c8dbc9f2 100644 --- a/src/Operation/Executable.php +++ b/src/Operation/Executable.php @@ -32,7 +32,8 @@ interface Executable /** * Execute the operation. * - * @return mixed + * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint + * @return mixed|void */ public function execute(Server $server); } diff --git a/src/Operation/Explain.php b/src/Operation/Explain.php index a6e14303f..0c3f5e5e3 100644 --- a/src/Operation/Explain.php +++ b/src/Operation/Explain.php @@ -87,11 +87,10 @@ public function __construct(private string $databaseName, private Explainable $e * Execute the operation. * * @see Executable::execute() - * @return array|object * @throws UnsupportedException if the server does not support explaining the operation * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { $cursor = $server->executeCommand($this->databaseName, $this->createCommand(), $this->createOptions()); diff --git a/src/Operation/Explainable.php b/src/Operation/Explainable.php index f380e1c32..372d4cb29 100644 --- a/src/Operation/Explainable.php +++ b/src/Operation/Explainable.php @@ -27,8 +27,6 @@ interface Explainable extends Executable { /** * Returns the command document for this operation. - * - * @return array */ - public function getCommandDocument(); + public function getCommandDocument(): array; } diff --git a/src/Operation/Find.php b/src/Operation/Find.php index f391faea5..43838d479 100644 --- a/src/Operation/Find.php +++ b/src/Operation/Find.php @@ -17,7 +17,6 @@ namespace MongoDB\Operation; -use Iterator; use MongoDB\Codec\DocumentCodec; use MongoDB\Driver\CursorInterface; use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; @@ -300,11 +299,10 @@ public function __construct(private string $databaseName, private string $collec * Execute the operation. * * @see Executable::execute() - * @return CursorInterface&Iterator * @throws UnsupportedException if read concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): CursorInterface { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['readConcern'])) { @@ -328,9 +326,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { $cmd = ['find' => $this->collectionName, 'filter' => (object) $this->filter]; diff --git a/src/Operation/FindAndModify.php b/src/Operation/FindAndModify.php index 07abfe80e..8b1f14f2e 100644 --- a/src/Operation/FindAndModify.php +++ b/src/Operation/FindAndModify.php @@ -222,12 +222,11 @@ public function __construct(private string $databaseName, private string $collec * Execute the operation. * * @see Executable::execute() - * @return array|object|null * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if hint or write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object|null { /* Server versions >= 4.2.0 raise errors for unsupported update options. * For previous versions, the CRUD spec requires a client-side error. */ @@ -274,9 +273,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->createCommandDocument(); } diff --git a/src/Operation/FindOne.php b/src/Operation/FindOne.php index 0670d97c6..0290356ee 100644 --- a/src/Operation/FindOne.php +++ b/src/Operation/FindOne.php @@ -118,11 +118,10 @@ public function __construct(string $databaseName, string $collectionName, array| * Execute the operation. * * @see Executable::execute() - * @return array|object|null * @throws UnsupportedException if collation or read concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object|null { $cursor = $this->find->execute($server); $document = current($cursor->toArray()); @@ -134,9 +133,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->find->getCommandDocument(); } diff --git a/src/Operation/FindOneAndDelete.php b/src/Operation/FindOneAndDelete.php index 68be63e23..bf70bfc4a 100644 --- a/src/Operation/FindOneAndDelete.php +++ b/src/Operation/FindOneAndDelete.php @@ -108,11 +108,10 @@ public function __construct(string $databaseName, string $collectionName, array| * Execute the operation. * * @see Executable::execute() - * @return array|object|null * @throws UnsupportedException if collation or write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object|null { return $this->findAndModify->execute($server); } @@ -121,9 +120,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->findAndModify->getCommandDocument(); } diff --git a/src/Operation/FindOneAndReplace.php b/src/Operation/FindOneAndReplace.php index 21a34fc77..b9a5bdf7d 100644 --- a/src/Operation/FindOneAndReplace.php +++ b/src/Operation/FindOneAndReplace.php @@ -151,11 +151,10 @@ public function __construct(string $databaseName, string $collectionName, array| * Execute the operation. * * @see Executable::execute() - * @return array|object|null * @throws UnsupportedException if collation or write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object|null { return $this->findAndModify->execute($server); } @@ -164,15 +163,13 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->findAndModify->getCommandDocument(); } - /** @return array|object */ - private function validateReplacement(array|object $replacement, ?DocumentCodec $codec) + private function validateReplacement(array|object $replacement, ?DocumentCodec $codec): array|object { if (isset($codec)) { $replacement = $codec->encode($replacement); diff --git a/src/Operation/FindOneAndUpdate.php b/src/Operation/FindOneAndUpdate.php index f44cc4421..56db8cb8e 100644 --- a/src/Operation/FindOneAndUpdate.php +++ b/src/Operation/FindOneAndUpdate.php @@ -151,11 +151,10 @@ public function __construct(string $databaseName, string $collectionName, array| * Execute the operation. * * @see Executable::execute() - * @return array|object|null * @throws UnsupportedException if collation or write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object|null { return $this->findAndModify->execute($server); } @@ -164,9 +163,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->findAndModify->getCommandDocument(); } diff --git a/src/Operation/InsertMany.php b/src/Operation/InsertMany.php index 8f99fc771..9de46a1f0 100644 --- a/src/Operation/InsertMany.php +++ b/src/Operation/InsertMany.php @@ -115,11 +115,10 @@ public function __construct(private string $databaseName, private string $collec * Execute the operation. * * @see Executable::execute() - * @return InsertManyResult * @throws UnsupportedException if write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): InsertManyResult { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['writeConcern'])) { diff --git a/src/Operation/InsertOne.php b/src/Operation/InsertOne.php index 95d49c129..2c08d8db2 100644 --- a/src/Operation/InsertOne.php +++ b/src/Operation/InsertOne.php @@ -98,11 +98,10 @@ public function __construct(private string $databaseName, private string $collec * Execute the operation. * * @see Executable::execute() - * @return InsertOneResult * @throws UnsupportedException if write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): InsertOneResult { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if (isset($this->options['writeConcern']) && $inTransaction) { @@ -156,8 +155,7 @@ private function createExecuteOptions(): array return $options; } - /** @return array|object */ - private function validateDocument(array|object $document, ?DocumentCodec $codec) + private function validateDocument(array|object $document, ?DocumentCodec $codec): array|object { if ($codec) { $document = $codec->encode($document); diff --git a/src/Operation/ListCollections.php b/src/Operation/ListCollections.php index dfdf203e4..efce4da48 100644 --- a/src/Operation/ListCollections.php +++ b/src/Operation/ListCollections.php @@ -24,6 +24,7 @@ use MongoDB\Exception\InvalidArgumentException; use MongoDB\Model\CollectionInfo; use MongoDB\Model\CollectionInfoCommandIterator; +use MongoDB\Model\CollectionInfoIterator; /** * Operation for the listCollections command. @@ -72,7 +73,7 @@ public function __construct(private string $databaseName, array $options = []) * @return Iterator * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): CollectionInfoIterator { return new CollectionInfoCommandIterator($this->listCollections->execute($server), $this->databaseName); } diff --git a/src/Operation/ListDatabases.php b/src/Operation/ListDatabases.php index 06703f622..1e67daafd 100644 --- a/src/Operation/ListDatabases.php +++ b/src/Operation/ListDatabases.php @@ -24,6 +24,7 @@ use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\UnexpectedValueException; use MongoDB\Model\DatabaseInfo; +use MongoDB\Model\DatabaseInfoIterator; use MongoDB\Model\DatabaseInfoLegacyIterator; /** @@ -73,7 +74,7 @@ public function __construct(array $options = []) * @throws UnexpectedValueException if the command response was malformed * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): DatabaseInfoIterator { return new DatabaseInfoLegacyIterator($this->listDatabases->execute($server)); } diff --git a/src/Operation/ListIndexes.php b/src/Operation/ListIndexes.php index 57140a63c..a32b96b97 100644 --- a/src/Operation/ListIndexes.php +++ b/src/Operation/ListIndexes.php @@ -27,6 +27,7 @@ use MongoDB\Exception\InvalidArgumentException; use MongoDB\Model\CachingIterator; use MongoDB\Model\IndexInfo; +use MongoDB\Model\IndexInfoIterator; use MongoDB\Model\IndexInfoIteratorIterator; use function is_integer; @@ -79,7 +80,7 @@ public function __construct(private string $databaseName, private string $collec * @return Iterator * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): IndexInfoIterator { return $this->executeCommand($server); } diff --git a/src/Operation/MapReduce.php b/src/Operation/MapReduce.php index dcb1be4c6..197f340fa 100644 --- a/src/Operation/MapReduce.php +++ b/src/Operation/MapReduce.php @@ -241,12 +241,11 @@ public function __construct(private string $databaseName, private string $collec * Execute the operation. * * @see Executable::execute() - * @return MapReduceResult * @throws UnexpectedValueException if the command response was malformed * @throws UnsupportedException if read concern or write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): MapReduceResult { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction) { diff --git a/src/Operation/ModifyCollection.php b/src/Operation/ModifyCollection.php index dd707cd2d..45a5f1c4b 100644 --- a/src/Operation/ModifyCollection.php +++ b/src/Operation/ModifyCollection.php @@ -87,7 +87,7 @@ public function __construct(private string $databaseName, private string $collec * @return array|object Command result document * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions()); diff --git a/src/Operation/RenameCollection.php b/src/Operation/RenameCollection.php index d90c9815b..078bf487f 100644 --- a/src/Operation/RenameCollection.php +++ b/src/Operation/RenameCollection.php @@ -102,7 +102,7 @@ public function __construct(string $fromDatabaseName, string $fromCollectionName * @throws UnsupportedException if write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): array|object { $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction(); if ($inTransaction && isset($this->options['writeConcern'])) { diff --git a/src/Operation/ReplaceOne.php b/src/Operation/ReplaceOne.php index 47277e058..ab4944b27 100644 --- a/src/Operation/ReplaceOne.php +++ b/src/Operation/ReplaceOne.php @@ -104,17 +104,15 @@ public function __construct(string $databaseName, string $collectionName, array| * Execute the operation. * * @see Executable::execute() - * @return UpdateResult * @throws UnsupportedException if collation is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): UpdateResult { return $this->update->execute($server); } - /** @return array|object */ - private function validateReplacement(array|object $replacement, ?DocumentCodec $codec) + private function validateReplacement(array|object $replacement, ?DocumentCodec $codec): array|object { if ($codec) { $replacement = $codec->encode($replacement); diff --git a/src/Operation/Update.php b/src/Operation/Update.php index 1eb0bc9da..79f64fecb 100644 --- a/src/Operation/Update.php +++ b/src/Operation/Update.php @@ -165,11 +165,10 @@ public function __construct(private string $databaseName, private string $collec * Execute the operation. * * @see Executable::execute() - * @return UpdateResult * @throws UnsupportedException if hint or write concern is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): UpdateResult { /* CRUD spec requires a client-side error when using "hint" with an * unacknowledged write concern on an unsupported server. */ @@ -197,9 +196,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { $cmd = ['update' => $this->collectionName, 'updates' => [['q' => $this->filter, 'u' => $this->update] + $this->createUpdateOptions()]]; diff --git a/src/Operation/UpdateMany.php b/src/Operation/UpdateMany.php index a0f204837..ac1f932a7 100644 --- a/src/Operation/UpdateMany.php +++ b/src/Operation/UpdateMany.php @@ -98,11 +98,10 @@ public function __construct(string $databaseName, string $collectionName, array| * Execute the operation. * * @see Executable::execute() - * @return UpdateResult * @throws UnsupportedException if collation is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): UpdateResult { return $this->update->execute($server); } @@ -111,9 +110,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->update->getCommandDocument(); } diff --git a/src/Operation/UpdateOne.php b/src/Operation/UpdateOne.php index ac0f20720..d1026e65f 100644 --- a/src/Operation/UpdateOne.php +++ b/src/Operation/UpdateOne.php @@ -98,11 +98,10 @@ public function __construct(string $databaseName, string $collectionName, array| * Execute the operation. * * @see Executable::execute() - * @return UpdateResult * @throws UnsupportedException if collation is used and unsupported * @throws DriverRuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): UpdateResult { return $this->update->execute($server); } @@ -111,9 +110,8 @@ public function execute(Server $server) * Returns the command document for this operation. * * @see Explainable::getCommandDocument() - * @return array */ - public function getCommandDocument() + public function getCommandDocument(): array { return $this->update->getCommandDocument(); } diff --git a/src/Operation/Watch.php b/src/Operation/Watch.php index ea93d1937..45074b2ca 100644 --- a/src/Operation/Watch.php +++ b/src/Operation/Watch.php @@ -17,7 +17,6 @@ namespace MongoDB\Operation; -use Iterator; use MongoDB\BSON\TimestampInterface; use MongoDB\ChangeStream; use MongoDB\Codec\DocumentCodec; @@ -266,11 +265,10 @@ public function __construct(private Manager $manager, ?string $databaseName, pri * Execute the operation. * * @see Executable::execute() - * @return ChangeStream * @throws UnsupportedException if collation or read concern is used and unsupported * @throws RuntimeException for other driver errors (e.g. connection errors) */ - public function execute(Server $server) + public function execute(Server $server): ChangeStream { return new ChangeStream( $this->createChangeStreamIterator($server), @@ -353,10 +351,8 @@ private function createChangeStreamIterator(Server $server): ChangeStreamIterato * * The command will be executed using APM so that we can capture data from * its response (e.g. firstBatch size, postBatchResumeToken). - * - * @return CursorInterface&Iterator */ - private function executeAggregate(Server $server) + private function executeAggregate(Server $server): CursorInterface { addSubscriber($this); @@ -371,9 +367,8 @@ private function executeAggregate(Server $server) * Return the initial resume token for creating the ChangeStreamIterator. * * @see https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst#updating-the-cached-resume-token - * @return array|object|null */ - private function getInitialResumeToken() + private function getInitialResumeToken(): array|object|null { if ($this->firstBatchSize === 0 && isset($this->postBatchResumeToken)) { return $this->postBatchResumeToken; diff --git a/src/UpdateResult.php b/src/UpdateResult.php index 58a73a890..9e8ef487f 100644 --- a/src/UpdateResult.php +++ b/src/UpdateResult.php @@ -38,10 +38,9 @@ public function __construct(private WriteResult $writeResult) * This method should only be called if the write was acknowledged. * * @see UpdateResult::isAcknowledged() - * @return integer|null * @throws BadMethodCallException if the write result is unacknowledged */ - public function getMatchedCount() + public function getMatchedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getMatchedCount(); @@ -59,10 +58,9 @@ public function getMatchedCount() * This method should only be called if the write was acknowledged. * * @see UpdateResult::isAcknowledged() - * @return integer|null * @throws BadMethodCallException if the write result is unacknowledged */ - public function getModifiedCount() + public function getModifiedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getModifiedCount(); @@ -77,10 +75,9 @@ public function getModifiedCount() * This method should only be called if the write was acknowledged. * * @see UpdateResult::isAcknowledged() - * @return integer|null * @throws BadMethodCallException if the write result is unacknowledged */ - public function getUpsertedCount() + public function getUpsertedCount(): ?int { if ($this->isAcknowledged) { return $this->writeResult->getUpsertedCount(); @@ -101,10 +98,9 @@ public function getUpsertedCount() * This method should only be called if the write was acknowledged. * * @see UpdateResult::isAcknowledged() - * @return mixed|null * @throws BadMethodCallException if the write result is unacknowledged */ - public function getUpsertedId() + public function getUpsertedId(): mixed { if ($this->isAcknowledged) { foreach ($this->writeResult->getUpsertedIds() as $id) { @@ -123,10 +119,8 @@ public function getUpsertedId() * If the update was not acknowledged, other fields from the WriteResult * (e.g. matchedCount) will be undefined and their getter methods should not * be invoked. - * - * @return boolean */ - public function isAcknowledged() + public function isAcknowledged(): bool { return $this->isAcknowledged; } diff --git a/src/functions.php b/src/functions.php index a445467ba..5d66bd13a 100644 --- a/src/functions.php +++ b/src/functions.php @@ -122,10 +122,9 @@ function all_servers_support_write_stage_on_secondary(array $servers): bool * @internal * @param array|object $document Document to which the type map will be applied * @param array $typeMap Type map for BSON deserialization. - * @return array|object * @throws InvalidArgumentException */ -function apply_type_map_to_document(array|object $document, array $typeMap) +function apply_type_map_to_document(array|object $document, array $typeMap): array|object { if (! is_document($document)) { throw InvalidArgumentException::expectedDocumentType('$document', $document); @@ -183,9 +182,8 @@ function document_to_array(array|object $document): array * @see Collection::drop() * @see Database::createCollection() * @see Database::dropCollection() - * @return array|object|null */ -function get_encrypted_fields_from_driver(string $databaseName, string $collectionName, Manager $manager) +function get_encrypted_fields_from_driver(string $databaseName, string $collectionName, Manager $manager): array|object|null { $encryptedFieldsMap = (array) $manager->getEncryptedFieldsMap(); @@ -199,9 +197,8 @@ function get_encrypted_fields_from_driver(string $databaseName, string $collecti * @see https://github.com/mongodb/specifications/blob/master/source/client-side-encryption/client-side-encryption.rst#collection-encryptedfields-lookup-getencryptedfields * @see Collection::drop() * @see Database::dropCollection() - * @return array|object|null */ -function get_encrypted_fields_from_server(string $databaseName, string $collectionName, Manager $manager, Server $server) +function get_encrypted_fields_from_server(string $databaseName, string $collectionName, Manager $manager, Server $server): array|object|null { // No-op if the encryptedFieldsMap autoEncryption driver option was omitted if ($manager->getEncryptedFieldsMap() === null) { @@ -469,10 +466,9 @@ function is_string_array(mixed $input): bool * @internal * @see https://bugs.php.net/bug.php?id=49664 * @param mixed $element Value to be copied - * @return mixed * @throws ReflectionException */ -function recursive_copy(mixed $element) +function recursive_copy(mixed $element): mixed { if (is_array($element)) { foreach ($element as $key => $value) { diff --git a/stubs/Driver/Cursor.stub.php b/stubs/Driver/Cursor.stub.php new file mode 100644 index 000000000..2ee403832 --- /dev/null +++ b/stubs/Driver/Cursor.stub.php @@ -0,0 +1,59 @@ + + */ +final class Cursor implements CursorInterface +{ + /** + * @return TValue|null + * @psalm-ignore-nullable-return + */ + public function current(): array|object|null + { + } + + public function next(): void + { + } + + /** @psalm-ignore-nullable-return */ + public function key(): ?int + { + } + + public function valid(): bool + { + } + + public function rewind(): void + { + } + + /** @return array */ + public function toArray(): array + { + } + + public function getId(): Int64 + { + } + + public function getServer(): Server + { + } + + public function isDead(): bool + { + } + + public function setTypeMap(array $typemap): void + { + } +} diff --git a/stubs/Driver/CursorInterface.stub.php b/stubs/Driver/CursorInterface.stub.php new file mode 100644 index 000000000..d2a89737a --- /dev/null +++ b/stubs/Driver/CursorInterface.stub.php @@ -0,0 +1,33 @@ + + */ +interface CursorInterface extends Iterator +{ + /** + * @return TValue|null + * @psalm-ignore-nullable-return + */ + public function current(): array|object|null; + + public function getId(): Int64; + + public function getServer(): Server; + + public function isDead(): bool; + + /** @psalm-ignore-nullable-return */ + public function key(): ?int; + + public function setTypeMap(array $typemap): void; + + /** @return array */ + public function toArray(): array; +} diff --git a/tests/Model/CodecCursorFunctionalTest.php b/tests/Model/CodecCursorFunctionalTest.php index 432d71732..0fb2b35c6 100644 --- a/tests/Model/CodecCursorFunctionalTest.php +++ b/tests/Model/CodecCursorFunctionalTest.php @@ -4,16 +4,9 @@ use MongoDB\BSON\Int64; use MongoDB\Codec\DocumentCodec; -use MongoDB\Driver\CursorId; use MongoDB\Model\CodecCursor; use MongoDB\Tests\FunctionalTestCase; -use function restore_error_handler; -use function set_error_handler; - -use const E_DEPRECATED; -use const E_USER_DEPRECATED; - class CodecCursorFunctionalTest extends FunctionalTestCase { public function setUp(): void @@ -36,44 +29,6 @@ public function testSetTypeMap(): void $codecCursor->setTypeMap(['root' => 'array']); } - public function testGetIdReturnTypeWithoutArgument(): void - { - $collection = self::createTestClient()->selectCollection($this->getDatabaseName(), $this->getCollectionName()); - $cursor = $collection->find(); - - $codecCursor = CodecCursor::fromCursor($cursor, $this->createMock(DocumentCodec::class)); - - $deprecations = []; - - try { - $previousErrorHandler = set_error_handler( - function (...$args) use (&$previousErrorHandler, &$deprecations) { - $deprecations[] = $args; - - return true; - }, - E_USER_DEPRECATED | E_DEPRECATED, - ); - - $cursorId = $codecCursor->getId(); - } finally { - restore_error_handler(); - } - - self::assertInstanceOf(CursorId::class, $cursorId); - - // Expect 2 deprecations: 1 from CodecCursor, one from Cursor - self::assertCount(2, $deprecations); - self::assertSame( - 'The method "MongoDB\Model\CodecCursor::getId" will no longer return a "MongoDB\Driver\CursorId" instance in the future. Pass "true" as argument to change to the new behavior and receive a "MongoDB\BSON\Int64" instance instead.', - $deprecations[0][1], - ); - self::assertSame( - 'MongoDB\Driver\Cursor::getId(): The method "MongoDB\Driver\Cursor::getId" will no longer return a "MongoDB\Driver\CursorId" instance in the future. Pass "true" as argument to change to the new behavior and receive a "MongoDB\BSON\Int64" instance instead.', - $deprecations[1][1], - ); - } - public function testGetIdReturnTypeWithArgument(): void { $collection = self::createTestClient()->selectCollection($this->getDatabaseName(), $this->getCollectionName()); @@ -81,24 +36,6 @@ public function testGetIdReturnTypeWithArgument(): void $codecCursor = CodecCursor::fromCursor($cursor, $this->createMock(DocumentCodec::class)); - $deprecations = []; - - try { - $previousErrorHandler = set_error_handler( - function (...$args) use (&$previousErrorHandler, &$deprecations) { - $deprecations[] = $args; - - return true; - }, - E_USER_DEPRECATED | E_DEPRECATED, - ); - - $cursorId = $codecCursor->getId(true); - } finally { - restore_error_handler(); - } - - self::assertInstanceOf(Int64::class, $cursorId); - self::assertCount(0, $deprecations); + self::assertInstanceOf(Int64::class, $codecCursor->getId()); } } diff --git a/tests/Operation/WatchFunctionalTest.php b/tests/Operation/WatchFunctionalTest.php index cc6690b0f..eed98fa88 100644 --- a/tests/Operation/WatchFunctionalTest.php +++ b/tests/Operation/WatchFunctionalTest.php @@ -721,7 +721,7 @@ public function testInitialCursorIsNotClosed(): void * reports the cursor as alive. While the cursor ID is accessed through * ChangeStream, we'll need to use reflection to access the internal * Cursor and call isDead(). */ - $this->assertNotEquals('0', (string) $changeStream->getCursorId(true)); + $this->assertNotEquals(0, $changeStream->getCursorId()); $rc = new ReflectionClass(ChangeStream::class); $rp = $rc->getProperty('iterator'); @@ -1371,11 +1371,11 @@ public function testOriginalReadPreferenceIsPreservedOnResume(): void } $changeStream = $operation->execute($secondary); - $previousCursorId = $changeStream->getCursorId(true); + $previousCursorId = $changeStream->getCursorId(); $this->forceChangeStreamResume($secondary); $changeStream->next(); - $this->assertNotEquals($previousCursorId, $changeStream->getCursorId(true)); + $this->assertNotEquals($previousCursorId, $changeStream->getCursorId()); $getCursor = Closure::bind( fn () => $this->iterator->getInnerIterator(), From ea818c85c08bd2b74e35ddc8ba5a09d09980f49f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Thu, 26 Sep 2024 18:21:07 +0200 Subject: [PATCH 6/6] PHPLIB-1518 `WriteResult::get*Count()` always return an int on acknowledged result (#1454) --- psalm.xml.dist | 1 + src/BulkWriteResult.php | 65 ++++++-------------- src/DeleteResult.php | 17 ++--- src/Exception/BadMethodCallException.php | 11 ---- src/GridFS/Bucket.php | 13 +--- src/GridFS/CollectionWrapper.php | 4 +- src/InsertManyResult.php | 15 ++--- src/InsertOneResult.php | 15 ++--- src/UpdateResult.php | 49 +++++---------- stubs/Driver/WriteResult.stub.php | 32 ++++++++++ tests/Operation/BulkWriteFunctionalTest.php | 26 ++++---- tests/Operation/DeleteFunctionalTest.php | 6 +- tests/Operation/InsertManyFunctionalTest.php | 6 +- tests/Operation/InsertOneFunctionalTest.php | 6 +- tests/Operation/UpdateFunctionalTest.php | 18 +++--- 15 files changed, 116 insertions(+), 168 deletions(-) create mode 100644 stubs/Driver/WriteResult.stub.php diff --git a/psalm.xml.dist b/psalm.xml.dist index d9640583b..9aa4d0a7e 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -23,6 +23,7 @@ + diff --git a/src/BulkWriteResult.php b/src/BulkWriteResult.php index 548acc9a7..43c60ea2d 100644 --- a/src/BulkWriteResult.php +++ b/src/BulkWriteResult.php @@ -17,19 +17,16 @@ namespace MongoDB; +use MongoDB\Driver\Exception\LogicException; use MongoDB\Driver\WriteResult; -use MongoDB\Exception\BadMethodCallException; /** * Result class for a bulk write operation. */ class BulkWriteResult { - private bool $isAcknowledged; - public function __construct(private WriteResult $writeResult, private array $insertedIds) { - $this->isAcknowledged = $writeResult->isAcknowledged(); } /** @@ -38,15 +35,11 @@ public function __construct(private WriteResult $writeResult, private array $ins * This method should only be called if the write was acknowledged. * * @see BulkWriteResult::isAcknowledged() - * @throws BadMethodCallException if the write result is unacknowledged + * @throws LogicException if the write result is unacknowledged */ - public function getDeletedCount(): ?int + public function getDeletedCount(): int { - if ($this->isAcknowledged) { - return $this->writeResult->getDeletedCount(); - } - - throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + return $this->writeResult->getDeletedCount(); } /** @@ -55,15 +48,11 @@ public function getDeletedCount(): ?int * This method should only be called if the write was acknowledged. * * @see BulkWriteResult::isAcknowledged() - * @throws BadMethodCallException if the write result is unacknowledged + * @throws LogicException if the write result is unacknowledged */ - public function getInsertedCount(): ?int + public function getInsertedCount(): int { - if ($this->isAcknowledged) { - return $this->writeResult->getInsertedCount(); - } - - throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + return $this->writeResult->getInsertedCount(); } /** @@ -86,15 +75,11 @@ public function getInsertedIds(): array * This method should only be called if the write was acknowledged. * * @see BulkWriteResult::isAcknowledged() - * @throws BadMethodCallException if the write result is unacknowledged + * @throws LogicException if the write result is unacknowledged */ - public function getMatchedCount(): ?int + public function getMatchedCount(): int { - if ($this->isAcknowledged) { - return $this->writeResult->getMatchedCount(); - } - - throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + return $this->writeResult->getMatchedCount(); } /** @@ -106,15 +91,11 @@ public function getMatchedCount(): ?int * This method should only be called if the write was acknowledged. * * @see BulkWriteResult::isAcknowledged() - * @throws BadMethodCallException if the write result is unacknowledged + * @throws LogicException if the write result is unacknowledged */ - public function getModifiedCount(): ?int + public function getModifiedCount(): int { - if ($this->isAcknowledged) { - return $this->writeResult->getModifiedCount(); - } - - throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + return $this->writeResult->getModifiedCount(); } /** @@ -123,15 +104,11 @@ public function getModifiedCount(): ?int * This method should only be called if the write was acknowledged. * * @see BulkWriteResult::isAcknowledged() - * @throws BadMethodCallException if the write result is unacknowledged + * @throws LogicException if the write result is unacknowledged */ - public function getUpsertedCount(): ?int + public function getUpsertedCount(): int { - if ($this->isAcknowledged) { - return $this->writeResult->getUpsertedCount(); - } - - throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + return $this->writeResult->getUpsertedCount(); } /** @@ -145,15 +122,11 @@ public function getUpsertedCount(): ?int * This method should only be called if the write was acknowledged. * * @see BulkWriteResult::isAcknowledged() - * @throws BadMethodCallException if the write result is unacknowledged + * @throws LogicException if the write result is unacknowledged */ public function getUpsertedIds(): array { - if ($this->isAcknowledged) { - return $this->writeResult->getUpsertedIds(); - } - - throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + return $this->writeResult->getUpsertedIds(); } /** @@ -164,6 +137,6 @@ public function getUpsertedIds(): array */ public function isAcknowledged(): bool { - return $this->isAcknowledged; + return $this->writeResult->isAcknowledged(); } } diff --git a/src/DeleteResult.php b/src/DeleteResult.php index b58d3650d..23b416d0a 100644 --- a/src/DeleteResult.php +++ b/src/DeleteResult.php @@ -17,19 +17,16 @@ namespace MongoDB; +use MongoDB\Driver\Exception\LogicException; use MongoDB\Driver\WriteResult; -use MongoDB\Exception\BadMethodCallException; /** * Result class for a delete operation. */ class DeleteResult { - private bool $isAcknowledged; - public function __construct(private WriteResult $writeResult) { - $this->isAcknowledged = $writeResult->isAcknowledged(); } /** @@ -38,15 +35,11 @@ public function __construct(private WriteResult $writeResult) * This method should only be called if the write was acknowledged. * * @see DeleteResult::isAcknowledged() - * @throws BadMethodCallException if the write result is unacknowledged + * @throws LogicException if the write result is unacknowledged */ - public function getDeletedCount(): ?int + public function getDeletedCount(): int { - if ($this->isAcknowledged) { - return $this->writeResult->getDeletedCount(); - } - - throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + return $this->writeResult->getDeletedCount(); } /** @@ -57,6 +50,6 @@ public function getDeletedCount(): ?int */ public function isAcknowledged(): bool { - return $this->isAcknowledged; + return $this->writeResult->isAcknowledged(); } } diff --git a/src/Exception/BadMethodCallException.php b/src/Exception/BadMethodCallException.php index e165b95ac..00cece346 100644 --- a/src/Exception/BadMethodCallException.php +++ b/src/Exception/BadMethodCallException.php @@ -33,15 +33,4 @@ public static function classIsImmutable(string $class): self { return new self(sprintf('%s is immutable', $class)); } - - /** - * Thrown when accessing a result field on an unacknowledged write result. - * - * @param string $method Method name - * @internal - */ - public static function unacknowledgedWriteResultAccess(string $method): self - { - return new self(sprintf('%s should not be called for an unacknowledged write result', $method)); - } } diff --git a/src/GridFS/Bucket.php b/src/GridFS/Bucket.php index e054450cf..234af8954 100644 --- a/src/GridFS/Bucket.php +++ b/src/GridFS/Bucket.php @@ -583,16 +583,9 @@ public function rename(mixed $id, string $newFilename): void return; } - /* If the update resulted in no modification, it's possible that the - * file did not exist, in which case we must raise an error. Checking - * the write result's matched count will be most efficient, but fall - * back to a findOne operation if necessary (i.e. legacy writes). - */ - $found = $updateResult->getMatchedCount() !== null - ? $updateResult->getMatchedCount() === 1 - : $this->collectionWrapper->findFileById($id) !== null; - - if (! $found) { + // If the update resulted in no modification, it's possible that the + // file did not exist, in which case we must raise an error. + if ($updateResult->getMatchedCount() !== 1) { throw FileNotFoundException::byId($id, $this->getFilesNamespace()); } } diff --git a/src/GridFS/CollectionWrapper.php b/src/GridFS/CollectionWrapper.php index 30923ccde..5941992ef 100644 --- a/src/GridFS/CollectionWrapper.php +++ b/src/GridFS/CollectionWrapper.php @@ -73,7 +73,7 @@ public function deleteChunksByFilesId(mixed $id): void /** * Delete all GridFS files and chunks for a given filename. */ - public function deleteFileAndChunksByFilename(string $filename): ?int + public function deleteFileAndChunksByFilename(string $filename): int { /** @var iterable $files */ $files = $this->findFiles(['filename' => $filename], [ @@ -262,7 +262,7 @@ public function insertFile(array|object $file): void /** * Updates the filename field in the file document for all the files with a given filename. */ - public function updateFilenameForFilename(string $filename, string $newFilename): ?int + public function updateFilenameForFilename(string $filename, string $newFilename): int { return $this->filesCollection->updateMany( ['filename' => $filename], diff --git a/src/InsertManyResult.php b/src/InsertManyResult.php index 3d2176e58..2f27bd24e 100644 --- a/src/InsertManyResult.php +++ b/src/InsertManyResult.php @@ -17,19 +17,16 @@ namespace MongoDB; +use MongoDB\Driver\Exception\LogicException; use MongoDB\Driver\WriteResult; -use MongoDB\Exception\BadMethodCallException; /** * Result class for a multi-document insert operation. */ class InsertManyResult { - private bool $isAcknowledged; - public function __construct(private WriteResult $writeResult, private array $insertedIds) { - $this->isAcknowledged = $writeResult->isAcknowledged(); } /** @@ -38,15 +35,11 @@ public function __construct(private WriteResult $writeResult, private array $ins * This method should only be called if the write was acknowledged. * * @see InsertManyResult::isAcknowledged() - * @throws BadMethodCallException if the write result is unacknowledged + * @throws LogicException if the write result is unacknowledged */ - public function getInsertedCount(): ?int + public function getInsertedCount(): int { - if ($this->isAcknowledged) { - return $this->writeResult->getInsertedCount(); - } - - throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + return $this->writeResult->getInsertedCount(); } /** diff --git a/src/InsertOneResult.php b/src/InsertOneResult.php index 8e3d4b3ab..47e1d26bc 100644 --- a/src/InsertOneResult.php +++ b/src/InsertOneResult.php @@ -17,19 +17,16 @@ namespace MongoDB; +use MongoDB\Driver\Exception\LogicException; use MongoDB\Driver\WriteResult; -use MongoDB\Exception\BadMethodCallException; /** * Result class for a single-document insert operation. */ class InsertOneResult { - private bool $isAcknowledged; - public function __construct(private WriteResult $writeResult, private mixed $insertedId) { - $this->isAcknowledged = $writeResult->isAcknowledged(); } /** @@ -38,15 +35,11 @@ public function __construct(private WriteResult $writeResult, private mixed $ins * This method should only be called if the write was acknowledged. * * @see InsertOneResult::isAcknowledged() - * @throws BadMethodCallException if the write result is unacknowledged + * @throws LogicException if the write result is unacknowledged */ - public function getInsertedCount(): ?int + public function getInsertedCount(): int { - if ($this->isAcknowledged) { - return $this->writeResult->getInsertedCount(); - } - - throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + return $this->writeResult->getInsertedCount(); } /** diff --git a/src/UpdateResult.php b/src/UpdateResult.php index 9e8ef487f..a9d50b751 100644 --- a/src/UpdateResult.php +++ b/src/UpdateResult.php @@ -17,19 +17,16 @@ namespace MongoDB; +use MongoDB\Driver\Exception\LogicException; use MongoDB\Driver\WriteResult; -use MongoDB\Exception\BadMethodCallException; /** * Result class for an update operation. */ class UpdateResult { - private bool $isAcknowledged; - public function __construct(private WriteResult $writeResult) { - $this->isAcknowledged = $writeResult->isAcknowledged(); } /** @@ -38,15 +35,11 @@ public function __construct(private WriteResult $writeResult) * This method should only be called if the write was acknowledged. * * @see UpdateResult::isAcknowledged() - * @throws BadMethodCallException if the write result is unacknowledged + * @throws LogicException if the write result is unacknowledged */ - public function getMatchedCount(): ?int + public function getMatchedCount(): int { - if ($this->isAcknowledged) { - return $this->writeResult->getMatchedCount(); - } - - throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + return $this->writeResult->getMatchedCount(); } /** @@ -58,15 +51,11 @@ public function getMatchedCount(): ?int * This method should only be called if the write was acknowledged. * * @see UpdateResult::isAcknowledged() - * @throws BadMethodCallException if the write result is unacknowledged + * @throws LogicException if the write result is unacknowledged */ - public function getModifiedCount(): ?int + public function getModifiedCount(): int { - if ($this->isAcknowledged) { - return $this->writeResult->getModifiedCount(); - } - - throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + return $this->writeResult->getModifiedCount(); } /** @@ -75,15 +64,11 @@ public function getModifiedCount(): ?int * This method should only be called if the write was acknowledged. * * @see UpdateResult::isAcknowledged() - * @throws BadMethodCallException if the write result is unacknowledged + * @throws LogicException if the write result is unacknowledged */ - public function getUpsertedCount(): ?int + public function getUpsertedCount(): int { - if ($this->isAcknowledged) { - return $this->writeResult->getUpsertedCount(); - } - - throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + return $this->writeResult->getUpsertedCount(); } /** @@ -98,19 +83,15 @@ public function getUpsertedCount(): ?int * This method should only be called if the write was acknowledged. * * @see UpdateResult::isAcknowledged() - * @throws BadMethodCallException if the write result is unacknowledged + * @throws LogicException if the write result is unacknowledged */ public function getUpsertedId(): mixed { - if ($this->isAcknowledged) { - foreach ($this->writeResult->getUpsertedIds() as $id) { - return $id; - } - - return null; + foreach ($this->writeResult->getUpsertedIds() as $id) { + return $id; } - throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__); + return null; } /** @@ -122,6 +103,6 @@ public function getUpsertedId(): mixed */ public function isAcknowledged(): bool { - return $this->isAcknowledged; + return $this->writeResult->isAcknowledged(); } } diff --git a/stubs/Driver/WriteResult.stub.php b/stubs/Driver/WriteResult.stub.php new file mode 100644 index 000000000..daa2f4eb1 --- /dev/null +++ b/stubs/Driver/WriteResult.stub.php @@ -0,0 +1,32 @@ +expectException(BadMethodCallException::class); - $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/'); + $this->expectException(LogicException::class); + $this->expectExceptionMessageMatches('/[\w:\\\\\(\)]+ should not be called for an unacknowledged write result/'); $result->getDeletedCount(); } /** @depends testUnacknowledgedWriteConcern */ public function testUnacknowledgedWriteConcernAccessesInsertCount(BulkWriteResult $result): void { - $this->expectException(BadMethodCallException::class); - $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/'); + $this->expectException(LogicException::class); + $this->expectExceptionMessageMatches('/[\w:\\\\\(\)]+ should not be called for an unacknowledged write result/'); $result->getInsertedCount(); } /** @depends testUnacknowledgedWriteConcern */ public function testUnacknowledgedWriteConcernAccessesMatchedCount(BulkWriteResult $result): void { - $this->expectException(BadMethodCallException::class); - $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/'); + $this->expectException(LogicException::class); + $this->expectExceptionMessageMatches('/[\w:\\\\\(\)]+ should not be called for an unacknowledged write result/'); $result->getMatchedCount(); } /** @depends testUnacknowledgedWriteConcern */ public function testUnacknowledgedWriteConcernAccessesModifiedCount(BulkWriteResult $result): void { - $this->expectException(BadMethodCallException::class); - $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/'); + $this->expectException(LogicException::class); + $this->expectExceptionMessageMatches('/[\w:\\\\\(\)]+ should not be called for an unacknowledged write result/'); $result->getModifiedCount(); } /** @depends testUnacknowledgedWriteConcern */ public function testUnacknowledgedWriteConcernAccessesUpsertedCount(BulkWriteResult $result): void { - $this->expectException(BadMethodCallException::class); - $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/'); + $this->expectException(LogicException::class); + $this->expectExceptionMessageMatches('/[\w:\\\\\(\)]+ should not be called for an unacknowledged write result/'); $result->getUpsertedCount(); } /** @depends testUnacknowledgedWriteConcern */ public function testUnacknowledgedWriteConcernAccessesUpsertedIds(BulkWriteResult $result): void { - $this->expectException(BadMethodCallException::class); - $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/'); + $this->expectException(LogicException::class); + $this->expectExceptionMessageMatches('/[\w:\\\\\(\)]+ should not be called for an unacknowledged write result/'); $result->getUpsertedIds(); } diff --git a/tests/Operation/DeleteFunctionalTest.php b/tests/Operation/DeleteFunctionalTest.php index 7ff002f97..b112bcc2a 100644 --- a/tests/Operation/DeleteFunctionalTest.php +++ b/tests/Operation/DeleteFunctionalTest.php @@ -5,8 +5,8 @@ use MongoDB\Collection; use MongoDB\DeleteResult; use MongoDB\Driver\BulkWrite; +use MongoDB\Driver\Exception\LogicException; use MongoDB\Driver\WriteConcern; -use MongoDB\Exception\BadMethodCallException; use MongoDB\Exception\UnsupportedException; use MongoDB\Operation\Delete; use MongoDB\Tests\CommandObserver; @@ -136,8 +136,8 @@ public function testUnacknowledgedWriteConcern() /** @depends testUnacknowledgedWriteConcern */ public function testUnacknowledgedWriteConcernAccessesDeletedCount(DeleteResult $result): void { - $this->expectException(BadMethodCallException::class); - $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/'); + $this->expectException(LogicException::class); + $this->expectExceptionMessageMatches('/[\w:\\\\\(\)]+ should not be called for an unacknowledged write result/'); $result->getDeletedCount(); } diff --git a/tests/Operation/InsertManyFunctionalTest.php b/tests/Operation/InsertManyFunctionalTest.php index d4a786e71..1499aca8b 100644 --- a/tests/Operation/InsertManyFunctionalTest.php +++ b/tests/Operation/InsertManyFunctionalTest.php @@ -5,8 +5,8 @@ use MongoDB\BSON\Document; use MongoDB\BSON\ObjectId; use MongoDB\Collection; +use MongoDB\Driver\Exception\LogicException; use MongoDB\Driver\WriteConcern; -use MongoDB\Exception\BadMethodCallException; use MongoDB\InsertManyResult; use MongoDB\Model\BSONDocument; use MongoDB\Operation\InsertMany; @@ -192,8 +192,8 @@ public function testUnacknowledgedWriteConcern() /** @depends testUnacknowledgedWriteConcern */ public function testUnacknowledgedWriteConcernAccessesInsertedCount(InsertManyResult $result): void { - $this->expectException(BadMethodCallException::class); - $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/'); + $this->expectException(LogicException::class); + $this->expectExceptionMessageMatches('/[\w:\\\\\(\)]+ should not be called for an unacknowledged write result/'); $result->getInsertedCount(); } diff --git a/tests/Operation/InsertOneFunctionalTest.php b/tests/Operation/InsertOneFunctionalTest.php index 218a8853c..054406798 100644 --- a/tests/Operation/InsertOneFunctionalTest.php +++ b/tests/Operation/InsertOneFunctionalTest.php @@ -5,8 +5,8 @@ use MongoDB\BSON\Document; use MongoDB\BSON\ObjectId; use MongoDB\Collection; +use MongoDB\Driver\Exception\LogicException; use MongoDB\Driver\WriteConcern; -use MongoDB\Exception\BadMethodCallException; use MongoDB\InsertOneResult; use MongoDB\Model\BSONDocument; use MongoDB\Operation\InsertOne; @@ -183,8 +183,8 @@ public function testUnacknowledgedWriteConcern() /** @depends testUnacknowledgedWriteConcern */ public function testUnacknowledgedWriteConcernAccessesInsertedCount(InsertOneResult $result): void { - $this->expectException(BadMethodCallException::class); - $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/'); + $this->expectException(LogicException::class); + $this->expectExceptionMessageMatches('/[\w:\\\\\(\)]+ should not be called for an unacknowledged write result/'); $result->getInsertedCount(); } diff --git a/tests/Operation/UpdateFunctionalTest.php b/tests/Operation/UpdateFunctionalTest.php index 2a18f13aa..3f3db19c5 100644 --- a/tests/Operation/UpdateFunctionalTest.php +++ b/tests/Operation/UpdateFunctionalTest.php @@ -5,8 +5,8 @@ use MongoDB\BSON\ObjectId; use MongoDB\Collection; use MongoDB\Driver\BulkWrite; +use MongoDB\Driver\Exception\LogicException; use MongoDB\Driver\WriteConcern; -use MongoDB\Exception\BadMethodCallException; use MongoDB\Exception\UnsupportedException; use MongoDB\Operation\Update; use MongoDB\Tests\CommandObserver; @@ -287,32 +287,32 @@ public function testUnacknowledgedWriteConcern() /** @depends testUnacknowledgedWriteConcern */ public function testUnacknowledgedWriteConcernAccessesMatchedCount(UpdateResult $result): void { - $this->expectException(BadMethodCallException::class); - $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/'); + $this->expectException(LogicException::class); + $this->expectExceptionMessageMatches('/[\w:\\\\\(\)]+ should not be called for an unacknowledged write result/'); $result->getMatchedCount(); } /** @depends testUnacknowledgedWriteConcern */ public function testUnacknowledgedWriteConcernAccessesModifiedCount(UpdateResult $result): void { - $this->expectException(BadMethodCallException::class); - $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/'); + $this->expectException(LogicException::class); + $this->expectExceptionMessageMatches('/[\w:\\\\\(\)]+ should not be called for an unacknowledged write result/'); $result->getModifiedCount(); } /** @depends testUnacknowledgedWriteConcern */ public function testUnacknowledgedWriteConcernAccessesUpsertedCount(UpdateResult $result): void { - $this->expectException(BadMethodCallException::class); - $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/'); + $this->expectException(LogicException::class); + $this->expectExceptionMessageMatches('/[\w:\\\\\(\)]+ should not be called for an unacknowledged write result/'); $result->getUpsertedCount(); } /** @depends testUnacknowledgedWriteConcern */ public function testUnacknowledgedWriteConcernAccessesUpsertedId(UpdateResult $result): void { - $this->expectException(BadMethodCallException::class); - $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/'); + $this->expectException(LogicException::class); + $this->expectExceptionMessageMatches('/[\w:\\\\\(\)]+ should not be called for an unacknowledged write result/'); $result->getUpsertedId(); }