-
-
Notifications
You must be signed in to change notification settings - Fork 509
[BC break!] Fix DocumentRepository to fit ObjectRepository interface #752
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
[BC break!] Fix DocumentRepository to fit ObjectRepository interface #752
Conversation
@jmikola we can't change that interface in 2.x - I'd rather fix the behavior here in a minor bump. Users should not have relied on the cursor anyway given the interface... |
@jwage: Thoughts? |
👍 for this necessary BC break. |
*/ | ||
public function findBy(array $criteria, array $sort = null, $limit = null, $skip = null) | ||
{ | ||
return $this->uow->getDocumentPersister($this->documentName)->loadAll($criteria, $sort, $limit, $skip); | ||
return iterator_to_array($this->getDocumentPersister()->loadAll($criteria, $sort, $limit, $skip)); |
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.
You should add false
as the second iterator_to_array()
argument here, in case the document has a non-scalar _id
value. This will also ensure the user gets back a numerically indexed (i.e. real) array, instead of an associative one.
@lemoinem: Please make the above changes (feel free to squash commits), and I'll create the changelog entry for this before merging. Thanks! |
@jmikola Thanks for the feedback. I took your comments into account and double checked my commit, I don't think I forget anything. Here is the new one! |
Here, I rebased on current master and update the phpDoc (to change |
Manually merged in 64ed807. I left |
I have two questions in my mind: |
|
@lemoinem , thank for your answer. As i see, calling toArray() would be a good example of DRY principle. |
…ay() As per doctrine#752 (comment) by @tgabi333 and following. This replace a direct call to iterator_to_array by a call to Cursor::toArray() (DRY principal and better respect of encapsulation).
@tgabi333 Indeed. To be frank, I didn't even consider using toArray() in my original PR. New PR (#769) addressing this issue. There is still whether calling Perhaps including a test to ensure we are under the right conditions? Consistency is actually rather important IMHO. @jmikola and others, Any thoughts? |
…ay() As per doctrine#752 (comment) by @tgabi333 and following. This replaces a direct call to iterator_to_array by a call to Cursor::toArray() (DRY principal and better respect of encapsulation).
@jmikola Yes, I agree, but in the case of findAll or findBy, the user doesn't have access to the QueryBuilder or the Cursor, although they will (and should) expect consistency... |
If we exhaust the result set immediately by converting it to an array, it's less likely a snapshot would be necessary. Granted, it's still possible if another connection changes and moves data around while the driver fetches all of the batches. |
Fair point! Thanks for the explanation. |
Thank you guys. |
Since #752, the repository find methods return arrays instead of cursors in order to be consistent with the common repository interface. With this change, a query builder is used, and the skip/limit/hydrate options can be applied to the builder directly.
Hello,
https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/Persistence/ObjectRepository.php#L60 explicitly document the
findBy()
method as returning an array of objects.This interface spec is broken in spec and behaviour by https://github.com/doctrine/mongodb-odm/blob/master/lib/Doctrine/ODM/MongoDB/DocumentRepository.php#L164
This PR aims to fix this. It is quite a major BC break for the MongoDB ODM (as the various updated tests show), but I believe the interface shouldn't have been broken in the first place. We were able to break the interface only because PHP doesn't provide a way to check the type of the return value of a method and because Doctrine Common does not provide implementation tests for its interfaces (I don't intend this remark as a critic, but to describe a fact here 😉). It prevents code base engineered to interact with the Doctrine\Common\Persistence interfaces to crash miserably without clean workarounds.
In order to minimize BC break. I provided the protected method
getDocumentPersister()
in the DocumentRepository so custom repositories could easily return a Cursor (For example, to load associations through custom repository methods).If you have any ideas that could fix this without BC Break, I would be happy to ear about it and try as hard as possible to reduce BC breaks and update my PR accordingly.