-
Notifications
You must be signed in to change notification settings - Fork 265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PHPLIB-954: Add return types to all methods #1391
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some explanations. A number of the psalm errors are due to vimeo/psalm#10019, which doesn't correctly infer the return type or (object) ['foo' => 'bar']
as stdClass
but instead assumes object
. I'll take a look at the other psalm errors regarding codec generics, but feel free to leave feedback in the meantime.
src/Collection.php
Outdated
* @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&Iterator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have any plans for this yet, but I propose having CursorInterface
extend Iterator
to avoid the need for an intersection type here. Currently, only the Cursor
class implements Iterator
(added in PHPC-1691, but not added to CursorInterface
due to BC constraints).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CursorInterface
already extends Traversable
, which is better IMO. We should not require the Iterator
interface for custom cursor classes.
In case people really need the Iterator
API, they can wrap it in an IteratorIterator
.
public function aggregate(array $pipeline, array $options = []): CursorInterface&Iterator | |
public function aggregate(array $pipeline, array $options = []): CursorInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A CursorInterface
type without an intersection with Iterator
won't allow you to call $cursor->next();
- that's an issue we faced in ODM. Ideally, we'd fix this in PHPC by having CursorInterface
extend Iterator
, but until then we're stuck with this solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is always solutions to wrap a Transversable that is not an Iterator
.
With a Generator (see UnrewindableIterator, IteratorIterator
or IteratorAggregate::getIterator()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Providing some additional context and throwing in my two cents:
- We added Iterator to Cursor in PHPC-1691 in order to comply with PHP 8.
- CursorInterface was introduced in PHPC-1123 to allow other classes to fill in for a Cursor, which cannot be extended. AFAIK, the only existing use case for this within our own driver is CodecCursor.
- CodecCursor currently implements both CursorInterface and Iterator, so that would not be negatively impacted by this change.
While conditionally wrapping a CursorInterface to get access to Iterator methods is always possible, it may be tedious. Given that CursorInterface is intended to be used for classes that compose a Cursor, it seems a small ask for the wrapping class to also implement Iterator.
I'm not sure what the use case would be for a CursorInterface implementation to rely on IteratorAggregate, as it would then have no way to influence the inner Cursor's iteration. Hypothetically, it could proxy other methods (e.g. toArray()
), but I've never encountered such an implementation in the wild.
If having CursorInterface extend Iterator doesn't negatively impact PHPLIB, Doctrine ODM, and the Laravel integration, I wouldn't be too concerned about other use cases. Worst case, we're asking users to implement a implement a few extra methods (easily accomplished with a trait if needed).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. Added PHPC-2447 to track this.
I'll note that we shouldn't implement IteratorAggregate
, as that would suggest one can obtain multiple iterators from a single cursor. As a cursor can't be rewound and may only ever yield a single iterator, I don't think we should consider implementing IteratorAggregate
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CursorInterface
was changed to extend Iterator
, and this PR now includes changes for PHPLIB-1114, using CursorInterface
where possible.
7adcc67
to
062b5db
Compare
src/Collection.php
Outdated
* @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&Iterator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CursorInterface
already extends Traversable
, which is better IMO. We should not require the Iterator
interface for custom cursor classes.
In case people really need the Iterator
API, they can wrap it in an IteratorIterator
.
public function aggregate(array $pipeline, array $options = []): CursorInterface&Iterator | |
public function aggregate(array $pipeline, array $options = []): CursorInterface |
a903ddc
to
f731e0f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional suggestions.
Decide how to handle the CI warnings, but LGTM.
f731e0f
to
6a4681b
Compare
Updated the PR. This currently includes changes from #1427, but I'll wait until that PR has been merged up to 2.x and rebasing this PR to preserve proper history. |
6a4681b
to
9864dbc
Compare
*/ | ||
private function executeAggregate(Server $server) | ||
private function executeAggregate(Server $server): CursorInterface | ||
{ | ||
addSubscriber($this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing relevant to this PR, but I want to point out that it's a bit awkward that we can assign subscribers to Managers but not individual Servers. That forces us to use a global subscriber here.
I suppose we could add Server::getManager()
to work around that 🤷♂️
df78dcf
to
17352ee
Compare
@@ -720,7 +720,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()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make the test more robust if you don't rely on int cast?
$this->assertNotEquals(0, $changeStream->getCursorId()); | |
$this->assertNotEquals(new Int64(0), $changeStream->getCursorId()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't make a difference, as the custom Int64Comparator
will always handle these assertions, and it leverages the comparison behaviour implemented in Int64
directly.
$previousCursorId = $changeStream->getCursorId(true); | ||
$this->forceChangeStreamResume(); | ||
$previousCursorId = $changeStream->getCursorId(); | ||
$this->forceChangeStreamResume($secondary); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: this method previously created the fail point on the primary server, instead of on the secondary server where the changestream was created. This meant that the change stream was never resumed and the cursor ID was the same as before. We just didn't catch this mistake as the assertNotSame
comparison always saw the objects as different as they didn't have the same identity. Lessons learned...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be fixed on the 1.x branch, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extracted to #1434. Will rebase when that PR is merged.
Squashed commit of the following: commit bc37a4b83e86edba06f97148d9a1b4a194623097 Author: Andreas Braun <[email protected]> Date: Thu Sep 19 13:32:18 2024 +0200 TMP: Use branch reporting 2.0 version for testing commit 938c4cd5be825b605a01e1f3129a2e233c62ac1b Author: Andreas Braun <[email protected]> Date: Wed Sep 18 10:49:01 2024 +0200 Update CI config to test with ext-mongodb 2.0 commit 23b11ec Author: Andreas Braun <[email protected]> Date: Wed Sep 18 10:47:33 2024 +0200 Require ext-mongodb 2.0
1511aa6
to
7c987aa
Compare
Squashed commit of the following: commit b06bffe Author: Andreas Braun <[email protected]> Date: Thu Sep 19 12:56:07 2024 +0200 Update psalm baseline commit bb4bb56 Author: Andreas Braun <[email protected]> Date: Thu Sep 19 12:55:52 2024 +0200 Remove CursorInterface::getId compatibility layer commit 00fa5e4 Author: Andreas Braun <[email protected]> Date: Thu Sep 19 12:55:32 2024 +0200 Add temporary stubs for cursor classes in 2.x
7c987aa
to
16547cd
Compare
* v2.x: PHPLIB-954: Add return types to all methods (#1391) PHPLIB-797: Remove unused methods in UnsupportedException (#1436) Revert "Add final annotations to non-internal Operation classes (#1410)" PHPLIB-953 Make internal classes and Operation classes final (#1392) PHPLIB-1218 Remove deprecated fields from GridFS files (#1398)
* v2.x: PHPLIB-954: Add return types to all methods (#1391) PHPLIB-797: Remove unused methods in UnsupportedException (#1436) Revert "Add final annotations to non-internal Operation classes (#1410)" PHPLIB-953 Make internal classes and Operation classes final (#1392) PHPLIB-1218 Remove deprecated fields from GridFS files (#1398)
* v2.x: PHPLIB-954: Add return types to all methods (#1391) PHPLIB-797: Remove unused methods in UnsupportedException (#1436) Revert "Add final annotations to non-internal Operation classes (#1410)" PHPLIB-953 Make internal classes and Operation classes final (#1392) PHPLIB-1218 Remove deprecated fields from GridFS files (#1398)
* v2.x: PHPLIB-1518 `WriteResult::get*Count()` always return an int on acknowledged result (#1454) PHPLIB-954: Add return types to all methods (#1391) PHPLIB-797: Remove unused methods in UnsupportedException (#1436) Revert "Add final annotations to non-internal Operation classes (#1410)" PHPLIB-953 Make internal classes and Operation classes final (#1392) PHPLIB-1218 Remove deprecated fields from GridFS files (#1398)
* v2.x: PHPLIB-1546 and PHPLIB-1159: Remove CreateCollection flags and autoIndexId options (#1478) PHPLIB-1227 Use void return types for operations without meaningful result document (#1468) Remove deprecated functionality (#1439) PHPLIB-1518 `WriteResult::get*Count()` always return an int on acknowledged result (#1454) PHPLIB-954: Add return types to all methods (#1391) PHPLIB-797: Remove unused methods in UnsupportedException (#1436) Revert "Add final annotations to non-internal Operation classes (#1410)" PHPLIB-953 Make internal classes and Operation classes final (#1392) PHPLIB-1218 Remove deprecated fields from GridFS files (#1398)
…db v2 (GromNaN) This PR was merged into the 5.4 branch. Discussion ---------- [HttpFoundation][Lock] Ensure compatibility with ext-mongodb v2 | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | - | License | MIT The extension `mongodb` and the library `mongodb/mongodb` will soon have a version 2.0 that brings breaking changes (see [extension changes](https://jira.mongodb.org/browse/PHPC-2445) and [library changes](https://jira.mongodb.org/browse/PHPLIB-1332)). This PR ensures compatibility with the upcoming version for Symfony 5.4. - Return types added to `MongoDB\Collection::updateOne()`, the closure in the mock `willReturnCallback` must return an object. mongodb/mongo-php-library#1391 - `MongoDB\Driver\Exception\WriteException` removed in favor of `BulkWriteException` mongodb/mongo-php-driver#1685. No need to keep catching `WriteException` since a the driver bulk API have always be used. - `float` support to construct `MongoDB\BSON\UTCDateTime` is removed mongodb/mongo-php-driver#1709 Commits ------- 81366bf Ensure compatibility with mongodb v2
* v2.x: PHPLIB-1546 and PHPLIB-1159: Remove CreateCollection flags and autoIndexId options (#1478) PHPLIB-1227 Use void return types for operations without meaningful result document (#1468) Remove deprecated functionality (#1439) PHPLIB-1518 `WriteResult::get*Count()` always return an int on acknowledged result (#1454) PHPLIB-954: Add return types to all methods (#1391) PHPLIB-797: Remove unused methods in UnsupportedException (#1436) Revert "Add final annotations to non-internal Operation classes (#1410)" PHPLIB-953 Make internal classes and Operation classes final (#1392) PHPLIB-1218 Remove deprecated fields from GridFS files (#1398)
* v2.x: Regenerate evergreen configuration (#1503) PHPLIB-1546 and PHPLIB-1159: Remove CreateCollection flags and autoIndexId options (#1478) PHPLIB-1227 Use void return types for operations without meaningful result document (#1468) Remove deprecated functionality (#1439) PHPLIB-1518 `WriteResult::get*Count()` always return an int on acknowledged result (#1454) PHPLIB-954: Add return types to all methods (#1391) PHPLIB-797: Remove unused methods in UnsupportedException (#1436) Revert "Add final annotations to non-internal Operation classes (#1410)" PHPLIB-953 Make internal classes and Operation classes final (#1392) PHPLIB-1218 Remove deprecated fields from GridFS files (#1398)
* v2.x: Add return type hint for Encoder::encode() implementation Reverse pipeline init from an array (#1596) PHPLIB-1617 Accept a Pipeline instance in aggregate and watch methods (#1580) Fix CS Require latest python version (#1564) (#1565) Update src/Operation/Find.php Ignore `disableMD5` option as `md5` field is removed from the spec (#1502) Remove obsolete baseline entries Regenerate evergreen configuration (#1503) PHPLIB-1546 and PHPLIB-1159: Remove CreateCollection flags and autoIndexId options (#1478) PHPLIB-1227 Use void return types for operations without meaningful result document (#1468) Remove deprecated functionality (#1439) PHPLIB-1518 `WriteResult::get*Count()` always return an int on acknowledged result (#1454) PHPLIB-954: Add return types to all methods (#1391) PHPLIB-797: Remove unused methods in UnsupportedException (#1436) Revert "Add final annotations to non-internal Operation classes (#1410)" PHPLIB-953 Make internal classes and Operation classes final (#1392) PHPLIB-1218 Remove deprecated fields from GridFS files (#1398)
PHPLIB-954
This PR:
ReturnTypeWillChange
attributes where presentCursor
types withCursorInterface
CursorId
deprecation