Permalink
Browse files

Improve belongsTo and hasOne for unneeded queries when recursive > 1.

Reuse already joined data for 'belongsTo' and 'hasOne' associations instead of running unneeded queries for each record.
Fixes #47
  • Loading branch information...
majna committed May 27, 2012
1 parent 1c0f97e commit ce2fc6c83dca564ee7a46235d5c1fbb3c785617e
Showing with 21 additions and 3 deletions.
  1. +21 −3 lib/Cake/Model/Datasource/DboSource.php
@@ -1080,6 +1080,7 @@ public function read(Model $model, $queryData = array(), $recursive = null) {
$query = trim($this->generateAssociationQuery($model, null, null, null, null, $queryData, false, $null));
$resultSet = $this->fetchAll($query, $model->cacheQueries);
+
if ($resultSet === false) {
$model->onError();
return false;
@@ -1092,6 +1093,10 @@ public function read(Model $model, $queryData = array(), $recursive = null) {
}
if ($model->recursive > -1) {
+ $joined = array();
+ if (isset($queryData['joins'][0]['alias'])) {
+ $joined[$model->alias] = (array)Hash::extract($queryData['joins'], '{n}.alias');
+ }
foreach ($_associations as $type) {
foreach ($model->{$type} as $assoc => $assocData) {
$linkModel = $model->{$assoc};
@@ -1108,6 +1113,7 @@ public function read(Model $model, $queryData = array(), $recursive = null) {
if (isset($db) && method_exists($db, 'queryAssociation')) {
$stack = array($assoc);
+ $stack['joined'] = $joined;
$db->queryAssociation($model, $linkModel, $type, $assoc, $assocData, $array, true, $resultSet, $model->recursive - 1, $stack);
unset($db);
@@ -1176,6 +1182,11 @@ protected function _filterResults(&$results, Model $model, $filtered = array())
* @throws CakeException when results cannot be created.
*/
public function queryAssociation(Model $model, &$linkModel, $type, $association, $assocData, &$queryData, $external, &$resultSet, $recursive, $stack) {
+ if (isset($stack['joined'])) {
+ $joined = $stack['joined'];
+ unset($stack['joined']);
+ }
+
if ($query = $this->generateAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet)) {
if (!is_array($resultSet)) {
throw new CakeException(__d('cake_dev', 'Error in Model %s', get_class($model)));
@@ -1251,10 +1262,17 @@ public function queryAssociation(Model $model, &$linkModel, $type, $association,
foreach ($resultSet as &$row) {
if ($type !== 'hasAndBelongsToMany') {
$q = $this->insertQueryData($query, $row, $association, $assocData, $model, $linkModel, $stack);
+ $fetch = null;
if ($q !== false) {
- $fetch = $this->fetchAll($q, $model->cacheQueries);
- } else {
- $fetch = null;
+ $joinedData = array();
+ if (($type === 'belongsTo' || $type === 'hasOne') && isset($row[$linkModel->alias], $joined[$model->alias]) && in_array($linkModel->alias, $joined[$model->alias])) {
+ $joinedData = Hash::filter($row[$linkModel->alias]);
+ if (!empty($joinedData)) {
+ $fetch[0] = array($linkModel->alias => $row[$linkModel->alias]);
+ }
+ } else {
+ $fetch = $this->fetchAll($q, $model->cacheQueries);
+ }
}
}
$selfJoin = $linkModel->name === $model->name;

0 comments on commit ce2fc6c

Please sign in to comment.