Skip to content

Commit

Permalink
Improve belongsTo and hasOne for unneeded queries when recursive > 1.
Browse files Browse the repository at this point in the history
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 ce2fc6c
Showing 1 changed file with 21 additions and 3 deletions.
24 changes: 21 additions & 3 deletions lib/Cake/Model/Datasource/DboSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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};
Expand All @@ -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);

Expand Down Expand Up @@ -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)));
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit ce2fc6c

Please sign in to comment.