From 5d5a138825b37817e61cb66cdadc669f7965ac0b Mon Sep 17 00:00:00 2001 From: Ben Lumley Date: Tue, 21 Jun 2011 00:44:22 +0100 Subject: [PATCH 1/3] I was getting an sql error when filtering a record by a relation (ie: filtering comments by blog post). Error was relating to incorrect parameter count. After some trial and error, passing 0 (suppresses limit subquery) to getSqlQuery as it's second argument fixes this. I've seen no side effects yet ... should be ok, as i think the aim is to make doctrine create the query, the limit subquery isn't needed. --- lib/Doctrine/Template/Listener/LooselyCoupled.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Doctrine/Template/Listener/LooselyCoupled.php b/lib/Doctrine/Template/Listener/LooselyCoupled.php index cdcfcba..58b6800 100644 --- a/lib/Doctrine/Template/Listener/LooselyCoupled.php +++ b/lib/Doctrine/Template/Listener/LooselyCoupled.php @@ -86,7 +86,7 @@ protected function _getDqlCallbackComponents($query) } $copy = $query->copy(); - $copy->getSqlQuery($params); + $copy->getSqlQuery($params, 0); $componentsAfter = $copy->getQueryComponents(); if ($componentsBefore !== $componentsAfter) From 2ded9576f116a802f89d4caea516729a045cb1a8 Mon Sep 17 00:00:00 2001 From: Ben Lumley Date: Thu, 18 Aug 2011 11:14:16 +0200 Subject: [PATCH 2/3] Documentation correction --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d3ea327..87e6bdb 100644 --- a/README.md +++ b/README.md @@ -97,8 +97,8 @@ The above example will issue 1 query to the database to fetch all `YourModel` in This is where the two new hydrator modes come into play. Rewriting the above example using these new modes we get this. - Doctrine_Manager::getInstance()->registerHydrator('ArrayCoupled', 'Doctrine_Hydrator_ArrayCoupled'); - Doctrine_Manager::getInstance()->registerHydrator('RecordCoupled', 'Doctrine_Hydrator_RecordCoupled'); + Doctrine_Manager::getInstance()->registerHydrator('ArrayCoupled', 'Doctrine_Hydrator_ArrayCoupled_Driver'); + Doctrine_Manager::getInstance()->registerHydrator('RecordCoupled', 'Doctrine_Hydrator_RecordCoupled_Driver'); $yourModels = Doctrine_Core::getTable('YourModel')->findAll('RecordCoupled'); foreach($yourModels as $yourModel) From bb8d05e714f83f16498a287dc021ff2f6a2e492e Mon Sep 17 00:00:00 2001 From: Ben Lumley Date: Thu, 18 Aug 2011 23:00:08 +0100 Subject: [PATCH 3/3] Change to the preDqlSelect listener on the LooselyCoupled Record Listener to fix two bugs, as detailed below. Suppose you have: Categories, which have many Posts. You also have an Image object. Both "Category" and "Post" are LooselyCoupled to "Image". If you try to do a query like this: Doctrine::getTable('Category')->createQuery('c') ->leftJoin('c.Images ci') ->leftJoin('c.Post p') ->leftJoin('p.Images pi'); things go a bit wrong - key bit is that the same LooselyCoupleable component (Image) is joined twice to two different components (Post and Category). We end up with SQL that looks like: ... FROM category c LEFT JOIN post p ON c.id = p.category_id LEFT JOIN image i ON c.id = i.obj_pk AND (i.obj_type = "Category") AND (i.obj_type = "Category") LEFT JOIN image i2 ON p.id = i2.obj_pk AND (i2.obj_type = "Category") AND (i2.obj_type = "Category") ... Two things wrong here: 1. The obj_type is always the root alias/component of the query (I think it goes even more wrong if the root component is not part of a LooselyCoupled relationship) 2. Inconsequential, but annoying - the obj_type condition is added twice to each join. This patch makes it create the expected: ... FROM category c LEFT JOIN Post p ON c.id = p.category_id LEFT JOIN image i ON c.id = i.obj_pk AND (i.obj_type = "Category") LEFT JOIN image i2 ON p.id = i2.obj_pk AND (i2.obj_type = "Post") ... --- .../Template/Listener/LooselyCoupled.php | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/lib/Doctrine/Template/Listener/LooselyCoupled.php b/lib/Doctrine/Template/Listener/LooselyCoupled.php index 58b6800..30a8d9f 100644 --- a/lib/Doctrine/Template/Listener/LooselyCoupled.php +++ b/lib/Doctrine/Template/Listener/LooselyCoupled.php @@ -53,25 +53,12 @@ public function preDqlSelect(Doctrine_Event $event) $query = $event->getQuery(); $relations = array_keys($this->_options); - + $components = $this->_getDqlCallbackComponents($query); - $rootComponentName = false; foreach ($components as $alias => $component) { - if(!$rootComponentName) - { - $rootComponentName = $component['table']->getComponentName(); - } - if (isset($component['relation'])) - { - foreach ($event->getInvoker()->getTable()->getRelations() as $relation) - { - if ($component['table'] == $relation->getTable() && $relation->getTable()->hasTemplate('LooselyCoupleable')) - { - $query->addPendingJoinCondition($alias, $alias.'.obj_type = "'.$rootComponentName.'"'); - continue; - } - } + if (isset($component['relation']) && $event->getInvoker()->getTable()->getComponentName() == $component['relation']['localTable']->getComponentName() && $component['table']->hasTemplate('LooselyCoupleable')) { + $query->addPendingJoinCondition($alias, $alias.'.obj_type = "'.$component['relation']['localTable']->getComponentName().'"'); } } }