Skip to content

Commit

Permalink
PHPLIB-1489: Handle CursorId deprecations
Browse files Browse the repository at this point in the history
  • Loading branch information
alcaeus committed Jul 25, 2024
1 parent f2900db commit 11890ef
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 5 deletions.
24 changes: 21 additions & 3 deletions src/ChangeStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand Down Expand Up @@ -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);

Check failure on line 129 in src/ChangeStream.php

View workflow job for this annotation

GitHub Actions / Psalm

TooManyArguments

src/ChangeStream.php:129:53: TooManyArguments: Too many arguments for MongoDB\Driver\CursorInterface::getId - expecting 0 but saw 1 (see https://psalm.dev/026)
}

/**
Expand Down
21 changes: 19 additions & 2 deletions src/Model/CodecCursor.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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 */

Check failure on line 79 in src/Model/CodecCursor.php

View workflow job for this annotation

GitHub Actions / Psalm

ImplementedReturnTypeMismatch

src/Model/CodecCursor.php:79:17: ImplementedReturnTypeMismatch: The inherited return type 'MongoDB\Driver\CursorId' for MongoDB\Driver\CursorInterface::getId is different to the implemented return type for MongoDB\Model\CodecCursor::getid 'MongoDB\BSON\Int64|MongoDB\Driver\CursorId' (see https://psalm.dev/123)
#[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);

Check failure on line 95 in src/Model/CodecCursor.php

View workflow job for this annotation

GitHub Actions / Psalm

TooManyArguments

src/Model/CodecCursor.php:95:31: TooManyArguments: Too many arguments for MongoDB\Driver\Cursor::getId - expecting 0 but saw 1 (see https://psalm.dev/026)
}

public function getServer(): Server
Expand Down
74 changes: 74 additions & 0 deletions tests/Model/CodecCursorFunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
}

0 comments on commit 11890ef

Please sign in to comment.