-
Notifications
You must be signed in to change notification settings - Fork 824
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
ENH Zero limit no results #10652
ENH Zero limit no results #10652
Conversation
78e2146
to
9b0ab46
Compare
if ($length < 0) { | ||
throw new InvalidArgumentException("\$length can not be negative. $length was provided."); | ||
} | ||
|
||
if ($offset < 0) { | ||
throw new InvalidArgumentException("\$offset can not be negative. $offset was provided."); | ||
} |
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 weren't validating for this before. If you give a negative length, methods like array slice will want to start from the end.
While this might make sense for an array, most DB don't think like that. Seems more logical to throw an exception.
|
||
if ($length === 0) { | ||
// If we set the limit to 0, we return an empty list. | ||
$list->items = []; |
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.
If you let array slice below do its thing, you'll end up with the same results. Seems clearer to do it explicitly.
src/ORM/DataList.php
Outdated
if ($length !== null && $length < 0) { | ||
throw new InvalidArgumentException('$length can not be a negative value'); | ||
} | ||
|
||
if ($offset < 0) { | ||
throw new InvalidArgumentException('$offset can not be a negative value'); | ||
} | ||
|
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.
Exceptions would be thrown any way by the queries below eventually. Seems better to just do it now.
*/ | ||
public function limit($limit, $offset = 0) | ||
public function limit(?int $limit, int $offset = 0): static |
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.
Not necessary to meet the ACs, but seems logical to change this while we are at it.
@@ -249,7 +249,7 @@ public function setLimit($limit, $offset = 0) | |||
throw new InvalidArgumentException("SQLSelect::setLimit() only takes positive values"); | |||
} | |||
|
|||
if (is_numeric($limit) && ($limit || $offset)) { |
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.
The second part of this IF statement would fail if 0,0
was provided. This would effectively prevent you from setting a zero limit.
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.
setLimit()
actually accept strings and array. This seems a bit weird but refactoring this is probably beyond the scope of this card.
@@ -117,34 +117,69 @@ function ($item) use (&$count, $test) { | |||
$this->assertEquals($list->Count(), $count); | |||
} | |||
|
|||
public function testLimit() |
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's a bit weird how limited the test coverage was for such a critical method.
tests/php/ORM/DataListTest.php
Outdated
$check = $list->limit(false); | ||
$this->assertEquals(3, $check->count()); | ||
$this->assertEquals(0, $check->count()); |
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.
Not done with this part yet.
src/ORM/Limitable.php
Outdated
*/ | ||
public function limit($limit, $offset = 0); | ||
public function limit(?int $length, int $offset = 0): static; |
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've decided to rename the first parameter $length
. My instinct is that this makes clearer that there's multiple possible parameters here.
src/ORM/ArrayList.php
Outdated
$length = count($this->items ?? []); | ||
if ($length === null) { | ||
// If we unset the limit, we set the length to the size of the list. We still want the offset to be picked up | ||
$length = sizeof($this->items); |
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.
What's the advantage of sizeof
over count
? count
seems to be the more standard way to get the number of items in a Countable
or array
.
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.
Apparently it's exactly the same thing. https://www.php.net/manual/en/function.sizeof.php
For some reason, I've always defaulted to sizeof
. Don't have any preference either way.
src/ORM/DataList.php
Outdated
throw new InvalidArgumentException('$length can not be a negative value'); | ||
} | ||
|
||
if ($offset < 0) { | ||
throw new InvalidArgumentException('$offset can not be a negative value'); |
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.
Make these the same as the text used for the ArrayList exceptions
*/ | ||
public function limit($limit, $offset = 0) | ||
public function limit(?int $limit, int $offset = 0): static | ||
{ | ||
$this->query->setLimit($limit, $offset); |
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.
No exceptions on this one?
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 method is really just an alias for calling $query->setLimit()
. So it seems rational to just let setLimit
do all the work.
@@ -249,7 +249,7 @@ public function setLimit($limit, $offset = 0) | |||
throw new InvalidArgumentException("SQLSelect::setLimit() only takes positive values"); |
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.
Make this the same as the other exceptions
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.
SQLSelect::setLimit()
does substantially different things than the other limit
methods. It accepts all sort of weird values like arrays and strings that the other don't.
We could change this error message to something more specific ... but I think it needs to be different than the other methods.
8c607a7
to
9c4302f
Compare
*/ | ||
public function limit($limit, $offset = 0); | ||
public function limit(?int $length, int $offset = 0): Limitable; |
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 wanted to return a static
here ... but list decorator doesn't actually return a version of itself, so I couldn't do that.
Ran the full sink against my PR branch and got all greens: https://github.com/maxime-rainville/recipe-kitchen-sink/actions/runs/4002316914 |
@@ -16,21 +16,16 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable, | |||
/** | |||
* @var SS_List | |||
*/ | |||
protected $list; | |||
protected SS_List&Sortable&Filterable&Limitable $list; |
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.
Basically, every method on the class assumes that we will return a List that implements all these interfaces.
Added a test for the tweak to |
5f5db9c
to
fc6c45d
Compare
All feedback answered. |
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.
Looks good for me
Passed tests locally. Approved and merged. |
Parent issue:
#10604