Skip to content
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

PHPORM-100 Support query on numerical field names #2642

Merged
merged 9 commits into from Oct 19, 2023

Conversation

GromNaN
Copy link
Member

@GromNaN GromNaN commented Oct 15, 2023

Fix PHPORM-100
Fix #2639
Related to #2634

  • Fix filter on numeric field names.
  • Expand the "Too few arguments" exception in Query::where() to all scalar values instead of only string as column.
  • Cast to field name to string when calling str_* functions.

This bug was existing before 4.0.0, this change could be considered a new feature for 4.1 or merged as a bugfix in 4.0

@GromNaN
Copy link
Member Author

GromNaN commented Oct 16, 2023

Test failure to investigate: MongoDB\Driver\Exception\UnexpectedValueException: Detected recursion for field path "_id.$in.0"

tests/Query/BuilderTest.php Outdated Show resolved Hide resolved
tests/ModelTest.php Outdated Show resolved Hide resolved
@GromNaN GromNaN self-assigned this Oct 16, 2023
tests/ModelTest.php Outdated Show resolved Hide resolved
@mongodb mongodb deleted a comment from codecov-commenter Oct 17, 2023
@GromNaN GromNaN requested a review from alcaeus October 18, 2023 10:50
@@ -961,8 +962,8 @@ public function where($column, $operator = null, $value = null, $boolean = 'and'
}
}

if (func_num_args() === 1 && is_string($column)) {
throw new ArgumentCountError(sprintf('Too few arguments to function %s("%s"), 1 passed and at least 2 expected when the 1st is a string.', __METHOD__, $column));
if (func_num_args() === 1 && is_scalar($column)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're expecting an array, I'd specifically check for that:

Suggested change
if (func_num_args() === 1 && is_scalar($column)) {
if (func_num_args() === 1 && ! is_array($column)) {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

src/Query/Builder.php Show resolved Hide resolved
@GromNaN GromNaN requested a review from alcaeus October 18, 2023 12:19
@@ -212,6 +216,8 @@ public function setAttribute($key, $value)
$value = $builder->convertKey($value);
}

$key = (string) $key;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to move this to the top of the function for consistency with other methods? It won't affect the // Convert _id to ObjectID logic at all, and my understanding is this is the best we can do in lieu of adding a string type hint to the $key argument, which would be a BC break due to our use of strict types.

Also, perhaps that comment should be changed since Builder::convertKey() also converts strings to Binary UUIDs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cast moved.

Also, perhaps that comment should be changed since Builder::convertKey() also converts strings to Binary UUIDs.

I don't understand what you mean.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment here said "Convert _id to ObjectID" but convertKey() also converts UUIDs. Small detail (and most people won't be using UUID identifiers), so no objection if it remains as-is.

src/Query/Builder.php Show resolved Hide resolved
tests/ModelTest.php Show resolved Hide resolved
$this->assertInstanceOf(User::class, $found);
$this->assertEquals([3 => 'two.three'], $found[2]);

$found = User::where(2.3, 'two.three')->first();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hate everything about this. I understand the original request was to support integers, but do we really need to accept floats in this fashion? That seems like something we could outright reject, unless it's problematic.

This made me think of how MongoDB now supports field names with dots and dollars (related spec change in mongodb/specifications@851ca10). Querying still requires special operators, but inserting does not. I'm not sure this comes into play with this library, but I wouldn't want to allow someone to use a float to insert a field this way and would much rather force them to format it as a string.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alcaeus you asked for this test case.

I can't add an exception here for something that "works". But sure, using a float here is totally missleading as the dot is understood as a subfields separator.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the logic to throw an exception when the column is not a string or an int.

}

if (! is_int($column) && ! is_string($column)) {
throw new InvalidArgumentException(sprintf('First argument of %s must be a column name as "string". Got "%s"', __METHOD__, get_debug_type($column)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you intentionally do not want to tell people that an "int" is accepted, since you silently convert it. SGTM.

@codecov-commenter

This comment was marked as off-topic.

@GromNaN GromNaN changed the base branch from 4.0 to 4.1 October 19, 2023 16:03
@GromNaN GromNaN merged commit 063d73f into mongodb:4.1 Oct 19, 2023
12 of 13 checks passed
@GromNaN GromNaN deleted the PHPORM-100 branch October 19, 2023 16:22
@GromNaN GromNaN added this to the 4.1 milestone Nov 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

setAttribute does not accept key as integer
4 participants