-
Notifications
You must be signed in to change notification settings - Fork 266
PHPLIB-475: Use ReadPreference string constant consistently in the code and the doc #1082
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
Conversation
tests/ClientTest.php
Outdated
@@ -94,8 +94,7 @@ public function testSelectCollectionInheritsOptions(): void | |||
|
|||
$this->assertInstanceOf(ReadConcern::class, $debug['readConcern']); | |||
$this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel()); | |||
$this->assertInstanceOf(ReadPreference::class, $debug['readPreference']); | |||
$this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode()); | |||
$this->assertEquals(new ReadPreference(ReadPreference::SECONDARY_PREFERRED), $debug['readPreference']); |
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.
This doesn't work like you'd expect. Consider:
$a = new MongoDB\Driver\ReadPreference('primary');
$b = new MongoDB\Driver\ReadPreference('secondary');
$c = new MongoDB\Driver\ReadPreference('secondary', [[]]);
var_dump($a);
var_dump($b);
var_dump($c);
var_dump($a == $b);
var_dump($b == $c);
var_dump($c == $a);
Running that yields:
object(MongoDB\Driver\ReadPreference)#2 (1) {
["mode"]=>
string(7) "primary"
}
object(MongoDB\Driver\ReadPreference)#4 (1) {
["mode"]=>
string(9) "secondary"
}
object(MongoDB\Driver\ReadPreference)#5 (2) {
["mode"]=>
string(9) "secondary"
["tags"]=>
array(1) {
[0]=>
object(stdClass)#6 (0) {
}
}
}
bool(true)
bool(true)
bool(true)
This is because zend_std_compare_objects()
defaults to comparing the properties
HashTable of the zend_object
struct, which we don't use in the extension. Each PHPC class has its own struct (e.g. php_phongo_readpreference_t
) which contains internal properties (a mongoc_read_prefs_t*
in this case) followed by an embedded zend_object
struct. There is a separate properties
HashTable in our struct, but it's only used by our own get_properties
object handlers. The distinction is important, as zend_object.properties
is what gets modified if you were to assign a dynamic property on a ReadPreference object in userland. That's one reason we chose to keep everything separate.
In any event, using assertEquals()
here would require the ReadPreference, ReadConcern, and WriteConcern classes to implement explicit compare_objects
handlers like we currently have for BSON classes.
If that sounds like something you're interested in (would make for a good PHPC onboarding task down the line), feel free to create two tickets:
- One PHPC ticket to implement the compare_objects handlers on those classes
- A second PHPLIB ticket to propose this refactoring, which should depend on the PHPC issue
In the meantime, please revert the assertions back to separate instanceof
and field-level checks.
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.
🤯 I didn't suspect it for a second. Indeed, it's preferable to implement compare_objects
to prevent other developers from making the same mistake without having the chance to be corrected by @jmikola.
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.
One question about whether we should remove the rector rule. I defer to your decision there.
Reverting the RST docs to use string literals SGTM.
Provisional LGTM with those two items addressed.
ReadPreference::RP_* constants are deprecated in favor of the string constants
This reverts commit d3d1811.
Fix PHPLIB-475
Caused by PHPC-1489
Block PHPC-1021
The
ReadPreference::RP_*
constants are deprecated and replaced by the string constants for readability.int
constants by their equivalentstring
constants$readPreference->getModeString()
instead of$readPreference->getMode()
to compare string values.I used rector to automate the refactoring. Library users can do the same by copying the rule in
rector.php
. I have an issue to change the constructor argument from the string"primary"
to the constantMongoDB\Driver\ReadPreference::PRIMARY
rectorphp/rector#7956. More rector automation expected in PHPLIB-1141.