diff --git a/psalm-baseline.xml b/psalm-baseline.xml index f08663096..8ba6e2760 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + @@ -9,10 +9,10 @@ - $document - $index - $index - $index + + + + name]]> @@ -21,7 +21,7 @@ queryable]]> - $uri + @@ -37,14 +37,17 @@ ]]]> - stdClass - stdClass + + - self::CURSOR_NOT_FOUND + + + + @@ -56,18 +59,18 @@ - $options + - $cmd[$option] + - $cmd[$option] + @@ -77,12 +80,12 @@ - $context + - $ids[] + @@ -93,26 +96,26 @@ - private function getContext(string $path, string $mode): array + getContext($path, $mode)]]> getContext($path, $mode)]]> - $context - $count - $count + + + - deleteFileAndChunksByFilename - updateFilenameForFilename + + - $this[$key] - $value + + @@ -123,11 +126,11 @@ getArrayCopy()]]> - $this[$key] - $value + + - stdClass + @@ -135,7 +138,7 @@ cursor->nextBatch]]> - $resumeToken + postBatchResumeToken]]> @@ -146,6 +149,14 @@ current()]]> + + + + + + + + @@ -159,7 +170,7 @@ databases)]]> - int + databases)]]> @@ -168,21 +179,21 @@ index]]> - $fieldName + - $fieldName - $type + + - $type + index['name']]]> - stdClass + @@ -190,7 +201,7 @@ index]]> - stdClass + @@ -200,110 +211,110 @@ - $cmd[$option] + - $options[$option] + - isInTransaction + - $args - $args - $args - $args[0] - $args[0] - $args[0] - $args[0] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[2] + + + + + + + + + + + + + + + - $args[0] - $args[0] - $args[0] - $args[0] - $args[0] - $args[0] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[1] - $args[2] - $args[2] - $args[2] - $args[2] - $args[2] - $args[2] - $args[2] + + + + + + + + + + + + + + + + + + + + + + + + + + + + - $args[1] - $args[1] - $args[1] + + + - $args[2] - $args[2] - $args[2] - $args[2] - $args[2] - $args[2] + + + + + + - $operations[$i][$type][0] - $operations[$i][$type][1] - $operations[$i][$type][1] - $operations[$i][$type][2] - $operations[$i][$type][2] + + + + + - $args - $args - $args[2] - $args[2] - $insertedIds[$i] - $operations[$i][$type][1] - $operations[$i][$type][2] - $operations[$i][$type][2] - $options[$option] + + + + + + + + + - isInTransaction + - $args[2] - $args[2] + + - $cmd[$option] + @@ -311,7 +322,7 @@ - isInTransaction + @@ -319,7 +330,7 @@ options['typeMap']]]> - $cmd[$option] + @@ -332,18 +343,18 @@ - $cmd[$option] + - isInTransaction + - $index + @@ -370,7 +381,7 @@ - isInTransaction + @@ -378,14 +389,14 @@ options['typeMap']]]> - $cmd[$option] + - isInTransaction + @@ -398,7 +409,7 @@ - isInTransaction + @@ -421,12 +432,12 @@ options['typeMap']]]> - $cmd[$option] + - isInTransaction + @@ -439,7 +450,7 @@ options['typeMap']]]> - $cmd[$option] + @@ -453,13 +464,13 @@ - $options[$modifier[0]] - $options[$option] + + - isInTransaction + @@ -468,19 +479,19 @@ options['writeConcern']]]> - $cmd[$option] + - $value + - array|object|null + - decode - isInTransaction + + options['codec']->decode($value)]]> @@ -491,14 +502,14 @@ - $document + - array|object|null + - $document === false ? null : $document - $document === false ? null : $document + + @@ -514,7 +525,7 @@ - $replacement + @@ -524,35 +535,35 @@ - $insertedIds[$i] - $options[$option] + + - isInTransaction + - $document + - $insertedId - $options[$option] + + - isInTransaction + - $document + - $cmd[$option] + @@ -563,14 +574,14 @@ options['typeMap']]]> - $cmd[$option] + - isInTransaction + @@ -588,17 +599,17 @@ options['typeMap']]]> - $cmd[$option] + - isInTransaction + - $replacement + @@ -607,13 +618,13 @@ - $options[$option] + - $updateOptions[$option] + - isInTransaction + @@ -629,7 +640,7 @@ postBatchResumeToken]]> - array|object|null + cursor->firstBatch]]> @@ -642,13 +653,13 @@ - $id + - $stage - $wireVersionForWriteStageOnSecondary + + getServers()]]> @@ -661,16 +672,16 @@ - $element[$key] - $stage - $type + + + - $value + - array|object|null - array|object|null + + diff --git a/src/ChangeStream.php b/src/ChangeStream.php index afd4ade2b..9565adfb0 100644 --- a/src/ChangeStream.php +++ b/src/ChangeStream.php @@ -19,6 +19,7 @@ use Iterator; use MongoDB\BSON\Document; +use MongoDB\BSON\Int64; use MongoDB\Codec\DocumentCodec; use MongoDB\Driver\CursorId; use MongoDB\Driver\Exception\ConnectionException; @@ -32,6 +33,10 @@ 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. @@ -105,10 +110,23 @@ public function current() return $this->codec->decode($value); } - /** @return CursorId */ - public function getCursorId() + /** @return CursorId|Int64 */ + #[ReturnTypeWillChange] + public function getCursorId(bool $asInt64 = false) { - return $this->iterator->getInnerIterator()->getId(); + 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); } /** diff --git a/src/Model/CodecCursor.php b/src/Model/CodecCursor.php index b3b5061ae..556f76c0f 100644 --- a/src/Model/CodecCursor.php +++ b/src/Model/CodecCursor.php @@ -19,17 +19,20 @@ 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; /** @@ -73,9 +76,23 @@ public static function fromCursor(Cursor $cursor, DocumentCodec $codec): self return new self($cursor, $codec); } - public function getId(): CursorId + /** @return CursorId|Int64 */ + #[ReturnTypeWillChange] + public function getId(bool $asInt64 = false) { - return $this->cursor->getId(); + 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); } public function getServer(): Server diff --git a/tests/Model/CodecCursorFunctionalTest.php b/tests/Model/CodecCursorFunctionalTest.php index 563cbbbdf..432d71732 100644 --- a/tests/Model/CodecCursorFunctionalTest.php +++ b/tests/Model/CodecCursorFunctionalTest.php @@ -2,10 +2,18 @@ namespace MongoDB\Tests\Model; +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 @@ -27,4 +35,70 @@ 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()); + $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(true); + } finally { + restore_error_handler(); + } + + self::assertInstanceOf(Int64::class, $cursorId); + self::assertCount(0, $deprecations); + } }