From 00be91c95447cb0ee43ef985afb17959c0451c5d Mon Sep 17 00:00:00 2001 From: phpnut Date: Mon, 9 Apr 2007 08:54:25 +0000 Subject: [PATCH] Adding first implementation of hasMany associations using one select statement. git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@4826 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/libs/model/datasources/dbo_source.php | 83 ++-- cake/tests/cases/libs/model/model.test.php | 432 ++++++++++----------- 2 files changed, 277 insertions(+), 238 deletions(-) diff --git a/cake/libs/model/datasources/dbo_source.php b/cake/libs/model/datasources/dbo_source.php index 2732d2636..4d5234bab 100644 --- a/cake/libs/model/datasources/dbo_source.php +++ b/cake/libs/model/datasources/dbo_source.php @@ -720,12 +720,48 @@ class DboSource extends DataSource { } return null; } - $count = count($resultSet); + if($type === 'hasMany') { + $ins = array(); + for($i = 0; $i < $count; $i++) { + $ins[] = $this->insertQueryData('{$__cakeID__$}', $resultSet[$i], $association, $assocData, $model, $linkModel, $stack); + } + + if(!empty($ins)){ + $query = r('{$__cakeID__$}', join(', ',$ins), $query); + $fetch = $this->fetchAll($query, $model->cacheQueries, $model->name); + } else { + $fetch = array(); + } + + if (!empty($fetch) && is_array($fetch)) { + if ($recursive > 0) { + + foreach($linkModel->__associations as $type1) { + foreach($linkModel->{$type1} as $assoc1 => $assocData1) { + + $deepModel =& $linkModel->{$assocData1['className']}; + if ($deepModel->alias != $model->name) { + $tmpStack = $stack; + $tmpStack[] = $assoc1; + if ($linkModel->useDbConfig == $deepModel->useDbConfig) { + $db =& $this; + } else { + $db =& ConnectionManager::getDataSource($deepModel->useDbConfig); + } + $db->queryAssociation($linkModel, $deepModel, $type1, $assoc1, $assocData1, $queryData, true, $fetch, $recursive - 1, $tmpStack); + } + } + } + } + } + return $this->__mergeHasMany($resultSet, $fetch, $association, $model, $linkModel, $recursive); + } for($i = 0; $i < $count; $i++) { $row =& $resultSet[$i]; $q = $this->insertQueryData($query, $resultSet[$i], $association, $assocData, $model, $linkModel, $stack); + if($q != false){ $fetch = $this->fetchAll($q, $model->cacheQueries, $model->name); } else { @@ -761,6 +797,29 @@ class DboSource extends DataSource { } } } + + function __mergeHasMany(&$resultSet, $merge, $association, &$model, &$linkModel){ + foreach($resultSet as $key => $value) { + $merged[$association] = array(); + $count = 0; + foreach ($merge as $assoc => $data) { + if($value[$model->name][$model->primaryKey] === $data[$association][$model->hasMany[$association]['foreignKey']]) { + if(count($data) > 1) { + $temp[] = Set::pushDiff($data[$association], $data); + unset($temp[$count][$association]); + $merged[$association] = $temp; + } else { + $merged[$association][] = $data[$association]; + } + } + $count++; + } + $resultSet[$key] = Set::pushDiff($resultSet[$key], $merged); + unset($merged); + unset($temp); + } + } + /** * Enter description here... * @@ -1018,7 +1077,7 @@ class DboSource extends DataSource { break; case 'hasMany': $query = array( - 'in' => $this->__mergeConditions(array("{$alias}.{$assocData['foreignKey']}" => array('{$__cakeID__$}')), $assocData['conditions']), + 'conditions' => $this->__mergeConditions(array("{$alias}.{$assocData['foreignKey']}" => array('{$__cakeID__$}')), $assocData['conditions']), 'fields' => $this->fields($linkModel, $alias, $assocData['fields']), 'table' => $this->fullTableName($linkModel), 'alias' => $alias, @@ -1092,12 +1151,6 @@ class DboSource extends DataSource { } } } - - if(isset($query['in'])) { - $query['conditions'] = $query['in']; - return $this->renderInStatement($query, $model); - } - return $this->renderStatement(array( 'conditions' => $this->conditions($query['conditions']), 'fields' => join(', ', $query['fields']), @@ -1109,20 +1162,6 @@ class DboSource extends DataSource { )); } - function renderInStatement($query, $model) { - $replace[] = '{$__cakeID__$}'; - $replace[] = $this->renderStatement(array( - 'conditions' => $this->conditions($query['conditions']), - 'fields' => join(', ', $query['fields']), - 'table' => $query['table'], - 'alias' => $this->alias . $this->name($query['alias']), - 'order' => $this->order($query['order']), - 'limit' => $this->limit($query['limit'], $query['offset']), - 'joins' => join(' ', $query['joins']) - )); - return $replace[1]; - } - function renderJoinStatement($data) { extract($data); return trim("{$type} JOIN {$table} {$alias} ON ({$conditions})"); diff --git a/cake/tests/cases/libs/model/model.test.php b/cake/tests/cases/libs/model/model.test.php index b88c2cf73..89195e261 100644 --- a/cake/tests/cases/libs/model/model.test.php +++ b/cake/tests/cases/libs/model/model.test.php @@ -213,8 +213,8 @@ * @subpackage cake.tests.cases.libs.model */ class ModelTest extends CakeTestCase { - var $fixtures = array( - 'core.category', 'core.category_thread', 'core.user', 'core.article', 'core.featured', + var $fixtures = array( + 'core.category', 'core.category_thread', 'core.user', 'core.article', 'core.featured', 'core.article_featured', 'core.tag', 'core.articles_tag', 'core.comment', 'core.attachment', 'core.apple', 'core.sample' ); @@ -1114,265 +1114,265 @@ class ModelTest extends CakeTestCase { ); $this->assertEqual($result, $expected); } - + function testFindCombinedRelations() { $this->model =& new Apple(); - + $result = $this->model->findAll(); - - $expected = array ( - array ( - 'Apple' => array ( - 'id' => '1', - 'apple_id' => '2', - 'color' => 'Red 1', - 'name' => 'Red Apple 1', - 'created' => '2006-11-22 10:38:58', - 'date' => '1951-01-04', + + $expected = array ( + array ( + 'Apple' => array ( + 'id' => '1', + 'apple_id' => '2', + 'color' => 'Red 1', + 'name' => 'Red Apple 1', + 'created' => '2006-11-22 10:38:58', + 'date' => '1951-01-04', 'modified' => '2006-12-01 13:31:26' - ), - 'Parent' => array ( - 'id' => '2', - 'apple_id' => '1', - 'color' => 'Bright Red 1', - 'name' => 'Bright Red Apple', - 'created' => '2006-11-22 10:43:13', - 'date' => '2014-01-01', + ), + 'Parent' => array ( + 'id' => '2', + 'apple_id' => '1', + 'color' => 'Bright Red 1', + 'name' => 'Bright Red Apple', + 'created' => '2006-11-22 10:43:13', + 'date' => '2014-01-01', 'modified' => '2006-11-30 18:38:10' - ), - 'Sample' => array ( - 'id' => null, - 'apple_id' => null, + ), + 'Sample' => array ( + 'id' => null, + 'apple_id' => null, 'name' => null - ), - 'Child' => array ( - array ( - 'id' => '2', - 'apple_id' => '1', - 'color' => 'Bright Red 1', - 'name' => 'Bright Red Apple', - 'created' => '2006-11-22 10:43:13', - 'date' => '2014-01-01', + ), + 'Child' => array ( + array ( + 'id' => '2', + 'apple_id' => '1', + 'color' => 'Bright Red 1', + 'name' => 'Bright Red Apple', + 'created' => '2006-11-22 10:43:13', + 'date' => '2014-01-01', 'modified' => '2006-11-30 18:38:10' ) ) - ), - array ( - 'Apple' => array ( - 'id' => '2', - 'apple_id' => '1', - 'color' => 'Bright Red 1', - 'name' => 'Bright Red Apple', - 'created' => '2006-11-22 10:43:13', - 'date' => '2014-01-01', + ), + array ( + 'Apple' => array ( + 'id' => '2', + 'apple_id' => '1', + 'color' => 'Bright Red 1', + 'name' => 'Bright Red Apple', + 'created' => '2006-11-22 10:43:13', + 'date' => '2014-01-01', 'modified' => '2006-11-30 18:38:10' - ), - 'Parent' => array ( - 'id' => '1', - 'apple_id' => '2', - 'color' => 'Red 1', - 'name' => 'Red Apple 1', - 'created' => '2006-11-22 10:38:58', - 'date' => '1951-01-04', + ), + 'Parent' => array ( + 'id' => '1', + 'apple_id' => '2', + 'color' => 'Red 1', + 'name' => 'Red Apple 1', + 'created' => '2006-11-22 10:38:58', + 'date' => '1951-01-04', 'modified' => '2006-12-01 13:31:26' - ), - 'Sample' => array ( - 'id' => '2', - 'apple_id' => '2', + ), + 'Sample' => array ( + 'id' => '2', + 'apple_id' => '2', 'name' => 'sample2' - ), - 'Child' => array ( - array ( - 'id' => '1', - 'apple_id' => '2', - 'color' => 'Red 1', - 'name' => 'Red Apple 1', - 'created' => '2006-11-22 10:38:58', - 'date' => '1951-01-04', + ), + 'Child' => array ( + array ( + 'id' => '1', + 'apple_id' => '2', + 'color' => 'Red 1', + 'name' => 'Red Apple 1', + 'created' => '2006-11-22 10:38:58', + 'date' => '1951-01-04', 'modified' => '2006-12-01 13:31:26' - ), - array ( - 'id' => '3', - 'apple_id' => '2', - 'color' => 'blue green', - 'name' => 'green blue', - 'created' => '2006-12-25 05:13:36', - 'date' => '2006-12-25', + ), + array ( + 'id' => '3', + 'apple_id' => '2', + 'color' => 'blue green', + 'name' => 'green blue', + 'created' => '2006-12-25 05:13:36', + 'date' => '2006-12-25', 'modified' => '2006-12-25 05:23:24' - ), - array ( - 'id' => '6', - 'apple_id' => '2', - 'color' => 'Blue Green', - 'name' => 'Test Name', - 'created' => '2006-12-25 05:23:36', - 'date' => '2006-12-25', + ), + array ( + 'id' => '6', + 'apple_id' => '2', + 'color' => 'Blue Green', + 'name' => 'Test Name', + 'created' => '2006-12-25 05:23:36', + 'date' => '2006-12-25', 'modified' => '2006-12-25 05:23:36' ) ) - ), - array ( - 'Apple' => array ( - 'id' => '3', - 'apple_id' => '2', - 'color' => 'blue green', - 'name' => 'green blue', - 'created' => '2006-12-25 05:13:36', - 'date' => '2006-12-25', + ), + array ( + 'Apple' => array ( + 'id' => '3', + 'apple_id' => '2', + 'color' => 'blue green', + 'name' => 'green blue', + 'created' => '2006-12-25 05:13:36', + 'date' => '2006-12-25', 'modified' => '2006-12-25 05:23:24' - ), - 'Parent' => array ( - 'id' => '2', - 'apple_id' => '1', - 'color' => 'Bright Red 1', - 'name' => 'Bright Red Apple', - 'created' => '2006-11-22 10:43:13', - 'date' => '2014-01-01', + ), + 'Parent' => array ( + 'id' => '2', + 'apple_id' => '1', + 'color' => 'Bright Red 1', + 'name' => 'Bright Red Apple', + 'created' => '2006-11-22 10:43:13', + 'date' => '2014-01-01', 'modified' => '2006-11-30 18:38:10' - ), - 'Sample' => array ( - 'id' => '1', - 'apple_id' => '3', + ), + 'Sample' => array ( + 'id' => '1', + 'apple_id' => '3', 'name' => 'sample1' - ), + ), 'Child' => array ( ) - ), - array ( - 'Apple' => array ( - 'id' => '6', - 'apple_id' => '2', - 'color' => 'Blue Green', - 'name' => 'Test Name', - 'created' => '2006-12-25 05:23:36', - 'date' => '2006-12-25', + ), + array ( + 'Apple' => array ( + 'id' => '6', + 'apple_id' => '2', + 'color' => 'Blue Green', + 'name' => 'Test Name', + 'created' => '2006-12-25 05:23:36', + 'date' => '2006-12-25', 'modified' => '2006-12-25 05:23:36' - ), - 'Parent' => array ( - 'id' => '2', - 'apple_id' => '1', - 'color' => 'Bright Red 1', - 'name' => 'Bright Red Apple', - 'created' => '2006-11-22 10:43:13', - 'date' => '2014-01-01', + ), + 'Parent' => array ( + 'id' => '2', + 'apple_id' => '1', + 'color' => 'Bright Red 1', + 'name' => 'Bright Red Apple', + 'created' => '2006-11-22 10:43:13', + 'date' => '2014-01-01', 'modified' => '2006-11-30 18:38:10' - ), - 'Sample' => array ( - 'id' => '3', - 'apple_id' => '6', + ), + 'Sample' => array ( + 'id' => '3', + 'apple_id' => '6', 'name' => 'sample3' - ), - 'Child' => array ( - array ( - 'id' => '8', - 'apple_id' => '6', - 'color' => 'My new appleOrange', - 'name' => 'My new apple', - 'created' => '2006-12-25 05:29:39', - 'date' => '2006-12-25', + ), + 'Child' => array ( + array ( + 'id' => '8', + 'apple_id' => '6', + 'color' => 'My new appleOrange', + 'name' => 'My new apple', + 'created' => '2006-12-25 05:29:39', + 'date' => '2006-12-25', 'modified' => '2006-12-25 05:29:39' ) ) - ), - array ( - 'Apple' => array ( - 'id' => '7', - 'apple_id' => '7', - 'color' => 'Green', - 'name' => 'Blue Green', - 'created' => '2006-12-25 05:24:06', - 'date' => '2006-12-25', + ), + array ( + 'Apple' => array ( + 'id' => '7', + 'apple_id' => '7', + 'color' => 'Green', + 'name' => 'Blue Green', + 'created' => '2006-12-25 05:24:06', + 'date' => '2006-12-25', 'modified' => '2006-12-25 05:29:16' - ), - 'Parent' => array ( - 'id' => '7', - 'apple_id' => '7', - 'color' => 'Green', - 'name' => 'Blue Green', - 'created' => '2006-12-25 05:24:06', - 'date' => '2006-12-25', + ), + 'Parent' => array ( + 'id' => '7', + 'apple_id' => '7', + 'color' => 'Green', + 'name' => 'Blue Green', + 'created' => '2006-12-25 05:24:06', + 'date' => '2006-12-25', 'modified' => '2006-12-25 05:29:16' - ), - 'Sample' => array ( - 'id' => '4', - 'apple_id' => '7', + ), + 'Sample' => array ( + 'id' => '4', + 'apple_id' => '7', 'name' => 'sample4' - ), - 'Child' => array ( - array ( - 'id' => '7', - 'apple_id' => '7', - 'color' => 'Green', - 'name' => 'Blue Green', - 'created' => '2006-12-25 05:24:06', - 'date' => '2006-12-25', + ), + 'Child' => array ( + array ( + 'id' => '7', + 'apple_id' => '7', + 'color' => 'Green', + 'name' => 'Blue Green', + 'created' => '2006-12-25 05:24:06', + 'date' => '2006-12-25', 'modified' => '2006-12-25 05:29:16' ) ) - ), - array ( - 'Apple' => array ( - 'id' => '8', - 'apple_id' => '6', - 'color' => 'My new appleOrange', - 'name' => 'My new apple', - 'created' => '2006-12-25 05:29:39', - 'date' => '2006-12-25', + ), + array ( + 'Apple' => array ( + 'id' => '8', + 'apple_id' => '6', + 'color' => 'My new appleOrange', + 'name' => 'My new apple', + 'created' => '2006-12-25 05:29:39', + 'date' => '2006-12-25', 'modified' => '2006-12-25 05:29:39' - ), - 'Parent' => array ( - 'id' => '6', - 'apple_id' => '2', - 'color' => 'Blue Green', - 'name' => 'Test Name', - 'created' => '2006-12-25 05:23:36', - 'date' => '2006-12-25', + ), + 'Parent' => array ( + 'id' => '6', + 'apple_id' => '2', + 'color' => 'Blue Green', + 'name' => 'Test Name', + 'created' => '2006-12-25 05:23:36', + 'date' => '2006-12-25', 'modified' => '2006-12-25 05:23:36' - ), - 'Sample' => array ( - 'id' => null, - 'apple_id' => null, + ), + 'Sample' => array ( + 'id' => null, + 'apple_id' => null, 'name' => null - ), - 'Child' => array ( - array ( - 'id' => '9', - 'apple_id' => '8', - 'color' => 'Some wierd color', - 'name' => 'Some odd color', - 'created' => '2006-12-25 05:34:21', - 'date' => '2006-12-25', + ), + 'Child' => array ( + array ( + 'id' => '9', + 'apple_id' => '8', + 'color' => 'Some wierd color', + 'name' => 'Some odd color', + 'created' => '2006-12-25 05:34:21', + 'date' => '2006-12-25', 'modified' => '2006-12-25 05:34:21' ) ) - ), - array ( - 'Apple' => array ( - 'id' => '9', - 'apple_id' => '8', - 'color' => 'Some wierd color', - 'name' => 'Some odd color', - 'created' => '2006-12-25 05:34:21', - 'date' => '2006-12-25', + ), + array ( + 'Apple' => array ( + 'id' => '9', + 'apple_id' => '8', + 'color' => 'Some wierd color', + 'name' => 'Some odd color', + 'created' => '2006-12-25 05:34:21', + 'date' => '2006-12-25', 'modified' => '2006-12-25 05:34:21' - ), - 'Parent' => array ( - 'id' => '8', - 'apple_id' => '6', - 'color' => 'My new appleOrange', - 'name' => 'My new apple', - 'created' => '2006-12-25 05:29:39', - 'date' => '2006-12-25', + ), + 'Parent' => array ( + 'id' => '8', + 'apple_id' => '6', + 'color' => 'My new appleOrange', + 'name' => 'My new apple', + 'created' => '2006-12-25 05:29:39', + 'date' => '2006-12-25', 'modified' => '2006-12-25 05:29:39' - ), - 'Sample' => array ( - 'id' => null, - 'apple_id' => null, + ), + 'Sample' => array ( + 'id' => null, + 'apple_id' => null, 'name' => null - ), + ), 'Child' => array ( ) ) ); - + $this->assertEqual($result, $expected); } }