Adding fix for to correct additional 1:1 associations failing to query when there is a self join association.

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@4770 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
phpnut 2007-04-05 03:31:46 +00:00
parent f49183f70e
commit f0cd2d49ea
2 changed files with 51 additions and 64 deletions

View file

@ -48,12 +48,6 @@ class DboSource extends DataSource {
* @var unknown_type * @var unknown_type
*/ */
var $__bypass = false; var $__bypass = false;
/**
* Enter description here...
*
* @var array
*/
var $__assocJoins = null;
/** /**
* Enter description here... * Enter description here...
* *
@ -571,7 +565,6 @@ class DboSource extends DataSource {
$array = array(); $array = array();
$linkedModels = array(); $linkedModels = array();
$this->__bypass = false; $this->__bypass = false;
$this->__assocJoins = null;
if (!is_null($recursive)) { if (!is_null($recursive)) {
$_recursive = $model->recursive; $_recursive = $model->recursive;
@ -855,25 +848,22 @@ class DboSource extends DataSource {
if (!isset($queryData['selfJoin'])) { if (!isset($queryData['selfJoin'])) {
$queryData['selfJoin'] = array(); $queryData['selfJoin'] = array();
$self = array( $self = array('fields' => $this->fields($model, null, $queryData['fields']),
'fields' => $this->fields($model, null, $queryData['fields']),
'joins' => array(array( 'joins' => array(array(
'table' => $this->fullTableName($linkModel), 'table' => $this->fullTableName($linkModel),
'alias' => $alias, 'alias' => $alias,
'type' => 'LEFT', 'type' => 'LEFT',
'conditions' => array($model->escapeField($assocData['foreignKey']) => '{$__cakeIdentifier[' . "{$alias}.{$linkModel->primaryKey}" . ']__$}') 'conditions' => array($model->escapeField($assocData['foreignKey']) =>
)), '{$__cakeIdentifier[' . "{$alias}.{$linkModel->primaryKey}" . ']__$}'))),
'table' => $this->fullTableName($model), 'table' => $this->fullTableName($model),
'alias' => $model->name, 'alias' => $model->name,
'limit' => $queryData['limit'], 'limit' => $queryData['limit'],
'offset' => $queryData['offset'], 'offset' => $queryData['offset'],
'conditions'=> $queryData['conditions'], 'conditions'=> $queryData['conditions'],
'order' => $queryData['order'] 'order' => $queryData['order']);
);
if (!empty($assocData['conditions'])) { if (!empty($assocData['conditions'])) {
$self['joins'][0]['conditions'] = trim($this->conditions(am($self['joins'][0]['conditions'], $assocData['conditions']), true, false)); $self['joins'][0]['conditions'] = trim($this->conditions(am($self['joins'][0]['conditions'], $assocData['conditions']), true, false));
} }
if (!empty($queryData['joins'])) { if (!empty($queryData['joins'])) {
@ -885,20 +875,30 @@ class DboSource extends DataSource {
if($this->__bypass === false) { if($this->__bypass === false) {
$self['fields'] = am($self['fields'], $this->fields($linkModel, $alias, (isset($assocData['fields']) ? $assocData['fields'] : ''))); $self['fields'] = am($self['fields'], $this->fields($linkModel, $alias, (isset($assocData['fields']) ? $assocData['fields'] : '')));
} }
$sql = $this->buildStatement($self, $model);
if (!in_array($sql, $queryData['selfJoin'])) { if (!in_array($self, $queryData['selfJoin'])) {
$queryData['selfJoin'][] = $sql; $queryData['selfJoin'][] = $self;
return true; return true;
} }
} elseif (isset($linkModel)) { } elseif (isset($linkModel)) {
return $this->generateAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet); return $this->generateAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet);
} else { } else {
$result = $queryData['selfJoin'][0]; $result = $queryData['selfJoin'][0];
if (isset($this->__assocJoins)) { if (!empty($queryData['joins'])) {
$result = preg_replace('/FROM/', ', ' . join(', ', $this->__assocJoins['fields']) . ' FROM', $result); foreach($queryData['joins'] as $join) {
$result['joins'][] = $join;
} }
return $result; }
if (!empty($queryData['conditions'])) {
$result['conditions'] = trim($this->conditions(am($result['conditions'], $assocData['conditions']), true, false));
}
if (!empty($queryData['fields'])) {
$result['fields'] = array_unique(am($result['fields'], $queryData['fields']));
}
$sql = $this->buildStatement($result, $model);
return $sql;
} }
} }
/** /**
@ -927,22 +927,14 @@ class DboSource extends DataSource {
if (array_key_exists('selfJoin', $queryData)) { if (array_key_exists('selfJoin', $queryData)) {
return $this->generateSelfAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet); return $this->generateSelfAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet);
} else { } else {
if (isset($this->__assocJoins)) { return $this->buildStatement(array('fields' => array_unique($queryData['fields']),
$joinFields = ', ';
$joinFields .= join(', ', $this->__assocJoins['fields']);
} else {
$joinFields = null;
}
return $this->buildStatement(array(
'fields' => array_unique($queryData['fields']),
'table' => $this->fullTableName($model), 'table' => $this->fullTableName($model),
'alias' => $model->name, 'alias' => $model->name,
'limit' => $queryData['limit'], 'limit' => $queryData['limit'],
'offset' => $queryData['offset'], 'offset' => $queryData['offset'],
'joins' => $queryData['joins'], 'joins' => $queryData['joins'],
'conditions' => $queryData['conditions'], 'conditions' => $queryData['conditions'],
'order' => $queryData['order'] 'order' => $queryData['order']), $model);
), $model);
} }
} }
$alias = $association; $alias = $association;
@ -982,20 +974,16 @@ class DboSource extends DataSource {
} elseif ($type == 'belongsTo') { } elseif ($type == 'belongsTo') {
$conditions = $this->__mergeConditions($assocData['conditions'], array("{$alias}.{$linkModel->primaryKey}" => '{$__cakeForeignKey__$}')); $conditions = $this->__mergeConditions($assocData['conditions'], array("{$alias}.{$linkModel->primaryKey}" => '{$__cakeForeignKey__$}'));
} }
$query = am($assocData, array( $query = am($assocData, array('conditions' => $conditions,
'conditions' => $conditions,
'table' => $this->fullTableName($linkModel), 'table' => $this->fullTableName($linkModel),
'fields' => $fields, 'fields' => $fields,
'alias' => $alias 'alias' => $alias));
));
if ($type == 'belongsTo') { if ($type == 'belongsTo') {
// Dunno if we should be doing this for hasOne also...? // Dunno if we should be doing this for hasOne also...?
// Or maybe not doing it at all...? // Or maybe not doing it at all...?
$query = am($query, array( $query = am($query, array('order' => $assocData['order'],
'order' => $assocData['order'], 'limit' => $limit));
'limit' => $limit
));
} }
} else { } else {
if ($type == 'hasOne') { if ($type == 'hasOne') {
@ -1004,12 +992,11 @@ class DboSource extends DataSource {
$conditions = $this->__mergeConditions($assocData['conditions'], array($model->escapeField($assocData['foreignKey']) => '{$__cakeIdentifier[' . "{$alias}.{$linkModel->primaryKey}" . ']__$}')); $conditions = $this->__mergeConditions($assocData['conditions'], array($model->escapeField($assocData['foreignKey']) => '{$__cakeIdentifier[' . "{$alias}.{$linkModel->primaryKey}" . ']__$}'));
} }
$join = array( $join = array('table' => $this->fullTableName($linkModel),
'table' => $this->fullTableName($linkModel),
'alias' => $alias, 'alias' => $alias,
'type' => 'LEFT', 'type' => 'LEFT',
'conditions' => trim($this->conditions($conditions, true, false)) 'conditions' => trim($this->conditions($conditions, true, false)));
);
$queryData['fields'] = am($queryData['fields'], $fields); $queryData['fields'] = am($queryData['fields'], $fields);
if (!empty($assocData['order'])) { if (!empty($assocData['order'])) {

View file

@ -595,9 +595,9 @@ class DboSourceTest extends UnitTestCase {
$result = $this->db->generateSelfAssociationQuery($this->model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet); $result = $this->db->generateSelfAssociationQuery($this->model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
$this->assertTrue($result); $this->assertTrue($result);
$this->assertPattern('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel4Parent`\.`id`, `TestModel4Parent`\.`name`, `TestModel4Parent`\.`created`, `TestModel4Parent`\.`updated`\s+/', $queryData['selfJoin'][0]); //$this->assertPattern('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel4Parent`\.`id`, `TestModel4Parent`\.`name`, `TestModel4Parent`\.`created`, `TestModel4Parent`\.`updated`\s+/', $queryData['selfJoin'][0]);
$this->assertPattern('/FROM\s+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+`test_model4` AS `TestModel4Parent`/', $queryData['selfJoin'][0]); //$this->assertPattern('/FROM\s+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+`test_model4` AS `TestModel4Parent`/', $queryData['selfJoin'][0]);
$this->assertPattern('/\s+ON\s+\(`TestModel4`.`parent_id` = `TestModel4Parent`.`id`\)\s+WHERE\s+1 = 1\s*$/', $queryData['selfJoin'][0]); //$this->assertPattern('/\s+ON\s+\(`TestModel4`.`parent_id` = `TestModel4Parent`.`id`\)\s+WHERE\s+1 = 1\s*$/', $queryData['selfJoin'][0]);
$result = $this->db->generateAssociationQuery($this->model, $null, null, null, null, $queryData, false, $null); $result = $this->db->generateAssociationQuery($this->model, $null, null, null, null, $queryData, false, $null);
$this->assertPattern('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel4Parent`\.`id`, `TestModel4Parent`\.`name`, `TestModel4Parent`\.`created`, `TestModel4Parent`\.`updated`\s+/', $result); $this->assertPattern('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel4Parent`\.`id`, `TestModel4Parent`\.`name`, `TestModel4Parent`\.`created`, `TestModel4Parent`\.`updated`\s+/', $result);