Skip to content

Commit 90d8dfd

Browse files
committed
Remove compatibility layer for CursorId deprecation
Squashed commit of the following: commit b06bffe Author: Andreas Braun <andreas.braun@mongodb.com> Date: Thu Sep 19 12:56:07 2024 +0200 Update psalm baseline commit bb4bb56 Author: Andreas Braun <andreas.braun@mongodb.com> Date: Thu Sep 19 12:55:52 2024 +0200 Remove CursorInterface::getId compatibility layer commit 00fa5e4 Author: Andreas Braun <andreas.braun@mongodb.com> Date: Thu Sep 19 12:55:32 2024 +0200 Add temporary stubs for cursor classes in 2.x
1 parent 18f4766 commit 90d8dfd

File tree

9 files changed

+129
-168
lines changed

9 files changed

+129
-168
lines changed

psalm-baseline.xml

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@
55
<code><![CDATA[$document['name']]]></code>
66
<code><![CDATA[$index->name]]></code>
77
</MixedArgument>
8-
<MixedArrayAccess>
9-
<code><![CDATA[$document['name']]]></code>
10-
</MixedArrayAccess>
118
<MixedAssignment>
12-
<code><![CDATA[$document]]></code>
139
<code><![CDATA[$index]]></code>
1410
<code><![CDATA[$index]]></code>
1511
<code><![CDATA[$index]]></code>
@@ -23,6 +19,9 @@
2319
<PossiblyFalseArgument>
2420
<code><![CDATA[$uri]]></code>
2521
</PossiblyFalseArgument>
22+
<PossiblyInvalidArrayAccess>
23+
<code><![CDATA[$document['name']]]></code>
24+
</PossiblyInvalidArrayAccess>
2625
</file>
2726
<file src="examples/persistable.php">
2827
<LessSpecificReturnStatement>
@@ -184,9 +183,6 @@
184183
<DeprecatedConstant>
185184
<code><![CDATA[self::CURSOR_NOT_FOUND]]></code>
186185
</DeprecatedConstant>
187-
<TooManyArguments>
188-
<code><![CDATA[getId]]></code>
189-
</TooManyArguments>
190186
</file>
191187
<file src="src/Client.php">
192188
<MixedArgument>
@@ -339,6 +335,15 @@
339335
</MixedArgument>
340336
</file>
341337
<file src="src/Model/ChangeStreamIterator.php">
338+
<InvalidReturnStatement>
339+
<code><![CDATA[$cursor]]></code>
340+
</InvalidReturnStatement>
341+
<InvalidReturnType>
342+
<code><![CDATA[CursorInterface<TValue>]]></code>
343+
</InvalidReturnType>
344+
<LessSpecificImplementedReturnType>
345+
<code><![CDATA[CursorInterface<TValue>]]></code>
346+
</LessSpecificImplementedReturnType>
342347
<MixedArgument>
343348
<code><![CDATA[$reply->cursor->nextBatch]]></code>
344349
</MixedArgument>
@@ -354,11 +359,6 @@
354359
<code><![CDATA[$this->current()]]></code>
355360
</PossiblyNullArgument>
356361
</file>
357-
<file src="src/Model/CodecCursor.php">
358-
<TooManyArguments>
359-
<code><![CDATA[getId]]></code>
360-
</TooManyArguments>
361-
</file>
362362
<file src="src/Model/CollectionInfoCommandIterator.php">
363363
<DeprecatedInterface>
364364
<code><![CDATA[CollectionInfoCommandIterator]]></code>
@@ -724,18 +724,6 @@
724724
<code><![CDATA[is_object($result) ? ($result->value ?? null) : null]]></code>
725725
</MixedReturnStatement>
726726
</file>
727-
<file src="src/Operation/FindOne.php">
728-
<MixedAssignment>
729-
<code><![CDATA[$document]]></code>
730-
</MixedAssignment>
731-
<MixedInferredReturnType>
732-
<code><![CDATA[array|object|null]]></code>
733-
</MixedInferredReturnType>
734-
<MixedReturnStatement>
735-
<code><![CDATA[$document === false ? null : $document]]></code>
736-
<code><![CDATA[$document === false ? null : $document]]></code>
737-
</MixedReturnStatement>
738-
</file>
739727
<file src="src/Operation/FindOneAndDelete.php">
740728
<MixedAssignment>
741729
<code><![CDATA[$options['fields']]]></code>

psalm.xml.dist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
<file name="stubs/BSON/Document.stub.php"/>
2222
<file name="stubs/BSON/Iterator.stub.php"/>
2323
<file name="stubs/BSON/PackedArray.stub.php"/>
24+
<file name="stubs/Driver/Cursor.stub.php"/>
25+
<file name="stubs/Driver/CursorInterface.stub.php"/>
2426
</stubs>
2527

2628
<issueHandlers>

src/ChangeStream.php

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
use MongoDB\BSON\Document;
2222
use MongoDB\BSON\Int64;
2323
use MongoDB\Codec\DocumentCodec;
24-
use MongoDB\Driver\CursorId;
2524
use MongoDB\Driver\Exception\ConnectionException;
2625
use MongoDB\Driver\Exception\RuntimeException;
2726
use MongoDB\Driver\Exception\ServerException;
@@ -33,10 +32,6 @@
3332
use function assert;
3433
use function call_user_func;
3534
use function in_array;
36-
use function sprintf;
37-
use function trigger_error;
38-
39-
use const E_USER_DEPRECATED;
4035

4136
/**
4237
* Iterator for a change stream.
@@ -88,12 +83,8 @@ class ChangeStream implements Iterator
8883
*/
8984
private bool $hasAdvanced = false;
9085

91-
/**
92-
* @see https://php.net/iterator.current
93-
* @return array|object|null
94-
*/
95-
#[ReturnTypeWillChange]
96-
public function current()
86+
/** @see https://php.net/iterator.current */
87+
public function current(): array|object|null
9788
{
9889
$value = $this->iterator->current();
9990

@@ -106,26 +97,9 @@ public function current()
10697
return $this->codec->decode($value);
10798
}
10899

109-
/**
110-
* @return CursorId|Int64
111-
* @psalm-return ($asInt64 is true ? Int64 : CursorId)
112-
*/
113-
#[ReturnTypeWillChange]
114-
public function getCursorId(bool $asInt64 = false)
100+
public function getCursorId(): Int64
115101
{
116-
if (! $asInt64) {
117-
@trigger_error(
118-
sprintf(
119-
'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.',
120-
__METHOD__,
121-
CursorId::class,
122-
Int64::class,
123-
),
124-
E_USER_DEPRECATED,
125-
);
126-
}
127-
128-
return $this->iterator->getInnerIterator()->getId($asInt64);
102+
return $this->iterator->getInnerIterator()->getId();
129103
}
130104

131105
/**
@@ -255,7 +229,8 @@ private function onIteration(bool $incrementKey): void
255229
* have been received in the last response. Therefore, we can unset the
256230
* resumeCallable. This will free any reference to Watch as well as the
257231
* only reference to any implicit session created therein. */
258-
if ((string) $this->getCursorId(true) === '0') {
232+
// Use a type-unsafe comparison to compare with Int64 instances
233+
if ($this->getCursorId() == 0) {
259234
$this->resumeCallable = null;
260235
}
261236

src/Model/ChangeStreamIterator.php

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
namespace MongoDB\Model;
1919

20-
use Iterator;
2120
use IteratorIterator;
2221
use MongoDB\BSON\Document;
2322
use MongoDB\BSON\Serializable;
@@ -49,7 +48,7 @@
4948
*
5049
* @internal
5150
* @template TValue of array|object
52-
* @template-extends IteratorIterator<int, TValue, CursorInterface<int, TValue>&Iterator<int, TValue>>
51+
* @template-extends IteratorIterator<int, TValue, CursorInterface<TValue>>
5352
*/
5453
final class ChangeStreamIterator extends IteratorIterator implements CommandSubscriber
5554
{
@@ -77,18 +76,17 @@ public function current()
7776
}
7877

7978
/**
80-
* Necessary to let psalm know that we're always expecting a cursor as inner
81-
* iterator. This could be side-stepped due to the class not being final,
82-
* but it's very much an invalid use-case. This method can be dropped in 2.0
83-
* once the class is final.
79+
* This method is necessary as psalm does not properly set the return type
80+
* of IteratorIterator::getInnerIterator to the templated iterator
8481
*
85-
* @return CursorInterface<int, TValue>&Iterator<int, TValue>
82+
* @see https://github.com/vimeo/psalm/pull/11100.
83+
*
84+
* @return CursorInterface<TValue>
8685
*/
87-
final public function getInnerIterator(): Iterator
86+
public function getInnerIterator(): CursorInterface
8887
{
8988
$cursor = parent::getInnerIterator();
9089
assert($cursor instanceof CursorInterface);
91-
assert($cursor instanceof Iterator);
9290

9391
return $cursor;
9492
}
@@ -173,18 +171,10 @@ public function valid(): bool
173171

174172
/**
175173
* @internal
176-
* @psalm-param CursorInterface<int, TValue>&Iterator<int, TValue> $cursor
174+
* @psalm-param CursorInterface<TValue> $cursor
177175
*/
178176
public function __construct(CursorInterface $cursor, int $firstBatchSize, array|object|null $initialResumeToken, private ?object $postBatchResumeToken = null)
179177
{
180-
if (! $cursor instanceof Iterator) {
181-
throw InvalidArgumentException::invalidType(
182-
'$cursor',
183-
$cursor,
184-
CursorInterface::class . '&' . Iterator::class,
185-
);
186-
}
187-
188178
if (isset($initialResumeToken) && ! is_document($initialResumeToken)) {
189179
throw InvalidArgumentException::expectedDocumentType('$initialResumeToken', $initialResumeToken);
190180
}

src/Model/CodecCursor.php

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,24 @@
1717

1818
namespace MongoDB\Model;
1919

20-
use Iterator;
2120
use MongoDB\BSON\Document;
2221
use MongoDB\BSON\Int64;
2322
use MongoDB\Codec\DocumentCodec;
24-
use MongoDB\Driver\Cursor;
25-
use MongoDB\Driver\CursorId;
2623
use MongoDB\Driver\CursorInterface;
2724
use MongoDB\Driver\Server;
28-
use ReturnTypeWillChange;
2925

3026
use function assert;
3127
use function iterator_to_array;
3228
use function sprintf;
3329
use function trigger_error;
3430

35-
use const E_USER_DEPRECATED;
3631
use const E_USER_WARNING;
3732

3833
/**
3934
* @template TValue of object
40-
* @template-implements CursorInterface<int, TValue>
41-
* @template-implements Iterator<int, TValue>
35+
* @template-implements CursorInterface<TValue>
4236
*/
43-
class CodecCursor implements CursorInterface, Iterator
37+
class CodecCursor implements CursorInterface
4438
{
4539
private const TYPEMAP = ['root' => 'bson'];
4640

@@ -64,33 +58,16 @@ public function current(): ?object
6458
* @param DocumentCodec<NativeClass> $codec
6559
* @return self<NativeClass>
6660
*/
67-
public static function fromCursor(Cursor $cursor, DocumentCodec $codec): self
61+
public static function fromCursor(CursorInterface $cursor, DocumentCodec $codec): self
6862
{
6963
$cursor->setTypeMap(self::TYPEMAP);
7064

7165
return new self($cursor, $codec);
7266
}
7367

74-
/**
75-
* @return CursorId|Int64
76-
* @psalm-return ($asInt64 is true ? Int64 : CursorId)
77-
*/
78-
#[ReturnTypeWillChange]
79-
public function getId(bool $asInt64 = false)
68+
public function getId(): Int64
8069
{
81-
if (! $asInt64) {
82-
@trigger_error(
83-
sprintf(
84-
'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.',
85-
__METHOD__,
86-
CursorId::class,
87-
Int64::class,
88-
),
89-
E_USER_DEPRECATED,
90-
);
91-
}
92-
93-
return $this->cursor->getId($asInt64);
70+
return $this->cursor->getId();
9471
}
9572

9673
public function getServer(): Server
@@ -138,7 +115,7 @@ public function valid(): bool
138115
}
139116

140117
/** @param DocumentCodec<TValue> $codec */
141-
private function __construct(private Cursor $cursor, private DocumentCodec $codec)
118+
private function __construct(private CursorInterface $cursor, private DocumentCodec $codec)
142119
{
143120
}
144121
}

stubs/Driver/Cursor.stub.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
namespace MongoDB\Driver;
4+
5+
use MongoDB\BSON\Int64;
6+
7+
/**
8+
* @template-covariant TValue of array|object
9+
*
10+
* @template-implements CursorInterface<TValue>
11+
*/
12+
final class Cursor implements CursorInterface
13+
{
14+
/**
15+
* @return TValue|null
16+
* @psalm-ignore-nullable-return
17+
*/
18+
public function current(): array|object|null
19+
{
20+
}
21+
22+
public function next(): void
23+
{
24+
}
25+
26+
/** @psalm-ignore-nullable-return */
27+
public function key(): ?int
28+
{
29+
}
30+
31+
public function valid(): bool
32+
{
33+
}
34+
35+
public function rewind(): void
36+
{
37+
}
38+
39+
/** @return array<TValue> */
40+
public function toArray(): array
41+
{
42+
}
43+
44+
public function getId(): Int64
45+
{
46+
}
47+
48+
public function getServer(): Server
49+
{
50+
}
51+
52+
public function isDead(): bool
53+
{
54+
}
55+
56+
public function setTypeMap(array $typemap): void
57+
{
58+
}
59+
}

stubs/Driver/CursorInterface.stub.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace MongoDB\Driver;
4+
5+
use Iterator;
6+
use MongoDB\BSON\Int64;
7+
8+
/**
9+
* @template TValue of array|object
10+
* @template-implements Iterator<int, TValue>
11+
*/
12+
interface CursorInterface extends Iterator
13+
{
14+
/**
15+
* @return TValue|null
16+
* @psalm-ignore-nullable-return
17+
*/
18+
public function current(): array|object|null;
19+
20+
public function getId(): Int64;
21+
22+
public function getServer(): Server;
23+
24+
public function isDead(): bool;
25+
26+
/** @psalm-ignore-nullable-return */
27+
public function key(): ?int;
28+
29+
public function setTypeMap(array $typemap): void;
30+
31+
/** @return array<TValue> */
32+
public function toArray(): array;
33+
}

0 commit comments

Comments
 (0)