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

Add support for ManyToMany Criteria #885

Merged
merged 15 commits into from
Mar 16, 2014

Conversation

bakura10
Copy link
Member

This replaces #773

It adds support for ManyToMany but also do an efficient filtering instead of loading the whole collection. I think it can also benefits from #882 when this one get merged.

@doctrinebot
Copy link

Hello,

thank you for creating this pull request. I have automatically opened an issue
on our Jira Bug Tracker for you. See the issue link:

http://www.doctrine-project.org/jira/browse/DDC-2868

We use Jira to track the state of pull requests and the versions they got
included in.

@guilhermeblanco
Copy link
Member

@bakura10 tests! =)

@bakura10
Copy link
Member Author

Yep yep. I'm just not sure of the approach yet, and I've found a bug :(.

@bakura10
Copy link
Member Author

I've fixed the logic, however I have no idea about how to test this. Actually, there is no test for most persisters :(.

throw new \RuntimeException("Matching Criteria on PersistentCollection only works on OneToMany associations at the moment.");
if ($this->association['type'] !== ClassMetadata::ONE_TO_MANY
&& $this->association['type'] !== ClassMetadata::MANY_TO_MANY) {
throw new \RuntimeException("Matching Criteria on PersistentCollection only works on OneToMany and ManyToMany associations at the moment.");
Copy link
Member

Choose a reason for hiding this comment

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

this means it works for all PersistentCollection, as there are the only 2 types of toMany relations (and a toOne relation is not a collection). You should simply remove the exception

@beberlei
Copy link
Member

beberlei commented Jan 2, 2014

Please don't do multiple things at once. The lazy thing sounds very complicated, support for ManyToMany to start with would be awesome all alone.

@bakura10
Copy link
Member Author

bakura10 commented Jan 2, 2014

I think this PR does only one thing no? (Actually the other PR is MUCH more needed than this one :))

@bakura10
Copy link
Member Author

bakura10 commented Jan 3, 2014

Tests no longer should break!

@beberlei
Copy link
Member

beberlei commented Jan 3, 2014

Still breaks, plesae run the tests locally, just call phpunit

@bakura10
Copy link
Member Author

bakura10 commented Jan 4, 2014

I'm not sure to understand, all tests pass without any problem locally :/.

@bakura10
Copy link
Member Author

bakura10 commented Jan 4, 2014

Furthermore the failing tests on Travis have nothing to do with my changes :/.

@bakura10
Copy link
Member Author

bakura10 commented Jan 5, 2014

Some errors I had locally then were because of an older DBAL. I leo updated DBAL and now all tests pass locally, so I don't really understand.

EDIT : this is actually passing, it seems there was an error with one stack on Travis.

@bakura10
Copy link
Member Author

I really really need this. What do you want me to do in order to merge? :)

throw new \RuntimeException("Matching Criteria on PersistentCollection only works on OneToMany associations at the moment.");
if ($this->association['type'] === ClassMetadata::MANY_TO_MANY) {
$persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association);
return new ArrayCollection($persister->loadCriteria($this, $criteria));
Copy link
Member

Choose a reason for hiding this comment

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

Add an empty newline before this line

@Ocramius
Copy link
Member

@bakura10 a rebase is needed, plus I'm not sure about what kind of coverage you get with the current tests...

@bakura10
Copy link
Member Author

Hi,

I've fixed the CS and added a functional test. However, it fails! In fact, the SQL query that is executed is perfectly right, however the hydration does not work. I'm not confident enough about how ResultSetMapping and hydrators work, so a bit of help would be appreciated. I think this is the problem: https://github.com/doctrine/doctrine2/pull/885/files#diff-982b7374bbe9d5f4b6b71f4869a446eaR512

@aeneasr
Copy link

aeneasr commented Jan 29, 2014

👍 on this, super useful

@bakura10
Copy link
Member Author

bakura10 commented Feb 2, 2014

Anyone can help me on the issue I'm having? Sorry for being a bit persistent on this one but this is really useful !

@Ocramius
Copy link
Member

Ocramius commented Feb 2, 2014

@FabioBatSilva do you know if this clashes with SLC?

@bakura10
Copy link
Member Author

bakura10 commented Feb 9, 2014

Hi,

I've been doing more debugging. I can confirm that the SQL queries is generated correctly, and manually calling "fetchAll" from the prepared statement correctly returns the wanted rows.

Where it fails is indeed in the hydrator. The method "gatherRowData" from ObjectHydrator returns an empty array. I'm not sure why, but when I compared with other results, the query returns result like this:

array(4) {
  'id' =>
  string(1) "1"
  'name' =>
  string(12) "Developers_0"
  'user_id' =>
  string(1) "1"
  'group_id' =>
  string(1) "1"
}

This contains both the columns from the table and from the join table, but none of the columns are suffixed by an number (like "id0", "name1"...) and I suppose the hydrator must reuse this info to map those things to objects using the ResultSetMapping.

Any idea @beberlei ?

@bakura10
Copy link
Member Author

bakura10 commented Feb 9, 2014

I've finally made it by using the ResultSetMappingBuilder!!!

Could someone have a look at the approach (performance wise)? Only one test is failing locally but it seems it has nothing to do with my PR.

@bakura10
Copy link
Member Author

@Ocramius could you give this one a quick review please? To me it's ready to be merged :).

*
* @return array
*/
public function loadCriteria(PersistentCollection $collection, Criteria $criteria);
Copy link
Member

Choose a reason for hiding this comment

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

@bakura10 Shouldn't the contract here be to throw an exception if the operation is unsupported by the implementing collection persister? IMO that should be documented here as you already do throw an exception in AbstractCollectionPersister. What do you think?

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 mimic the other methods. All the other methods (slice, containsKey...) throw an exception in the AbstractCollectionPersister but it's not in the interface. I just followed the same pattern, if I add it here I should also add it for all other methods then :).

Copy link
Member

Choose a reason for hiding this comment

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

@bakura10 Okay I didn't know that. Then it's perfectly fine to me, no need to go a different way here then :)

@bakura10
Copy link
Member Author

Rebased @beberlei

@bakura10
Copy link
Member Author

Tests are all passing, only one just did not execute. Can someone relaunch tests so that Travis goes green? :)

@bakura10
Copy link
Member Author

Hi,

It seems someone relaunched the tests, and everything is passing now. What is preventing this to being merged, so that I can eventually work on it quickly?

@aeneasr
Copy link

aeneasr commented Mar 16, 2014

👍

guilhermeblanco added a commit that referenced this pull request Mar 16, 2014
Add support for ManyToMany Criteria
@guilhermeblanco guilhermeblanco merged commit 44c1dae into doctrine:master Mar 16, 2014
@bakura10
Copy link
Member Author

Awesome, thanks!

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.

8 participants