Skip to content
Permalink
Browse files

Adding fields for contained tables when the 'fields' key is defined

  • Loading branch information...
lorenzo committed May 4, 2013
1 parent 1f7f87d commit 915ae6debdb1e72f4d14fb6c24435d052888ecb4
Showing with 71 additions and 22 deletions.
  1. +40 −20 lib/Cake/ORM/Query.php
  2. +31 −2 lib/Cake/Test/TestCase/ORM/QueryTest.php
@@ -41,26 +41,37 @@ public function toArray() {
return $this->execute()->toArray();
}
public function aliasField($field) {
if (strpos($field, '.') !== false) {
public function aliasedTable() {
return $this->repository();
}
public function aliasField($field, $alias = null) {
$namespaced = strpos($field, '.') !== false;
$_field = $field;
if ($namespaced) {
list($alias, $field) = explode('.', $field);
} else {
}
if (!$alias) {
$alias = $this->repository()->alias();
}
return sprintf('%s__%s', $alias, $field);
}
public function aliasedTable($alias) {
return $this->repository();
$key = sprintf('%s__%s', $alias, $field);
if (!$namespaced) {
$_field = $alias . '.' . $field;
}
return [$key => $_field];
}
protected function _transformQuery() {
if (!$this->_dirty) {
return parent::_transformQuery();
}
$this->_addDefaultFields();
$this->_addContainments();
$this->_aliasFields();
return parent::_transformQuery();
}
@@ -156,26 +167,35 @@ protected function _resolveFirstLevel($associations) {
protected function _addJoin($alias, $options) {
$joinOptions = ['table' => 1, 'conditions' => 1, 'type' => 1];
$options = array_intersect_key($options, $joinOptions);
$this->join([$alias => $options]);
}
protected function _aliasFields() {
$select = $this->clause('select');
$schema = $this->repository()->schema();
$this->join([$alias => array_intersect_key($options, $joinOptions)]);
if (!count($select)) {
$this->select(array_keys($schema));
$select = $this->clause('select');
if (!empty($options['fields'])) {
$this->select($this->_aliasFields($options['fields'], $alias));
}
}
protected function _aliasFields($fields, $defaultAlias = null) {
$aliased = [];
foreach ($select as $alias => $field) {
foreach ($fields as $alias => $field) {
if (is_numeric($alias) && is_string($field)) {
$alias = $this->aliasField($field);
$aliased += $this->aliasField($field, $defaultAlias);
continue;
}
$aliased[$alias] = $field;
}
return $aliased;
}
protected function _addDefaultFields() {
$select = $this->clause('select');
if (!count($select)) {
$this->select(array_keys($this->repository()->schema()));
$select = $this->clause('select');
}
$aliased = $this->_aliasFields($select, $this->repository()->alias());
$this->select($aliased, true);
}
@@ -31,12 +31,16 @@ public function setUp() {
$this->connection = new Connection(Configure::read('Datasource.test'));
}
public function tearDown() {
Table::clearRegistry();
}
/**
* Tests that fully defined belongsTo and hasOne relationships are joined correctly
*
* @return void
**/
public function testContainToJoins() {
public function testContainToJoinsOneLevel() {
$contains = ['client' => [
'associationType' => 'belongsTo',
'table' => 'clients',
@@ -116,10 +120,35 @@ public function testContainToJoins() {
]])
->will($this->returnValue($query));
$query
$s = $query
->select('foo.id')
->repository($table)
->contain($contains)->sql();
}
public function testContainToFieldsPredefined() {
$contains = ['client' => [
'associationType' => 'belongsTo',
'fields' => ['name', 'company_id', 'client.telephone'],
'table' => 'clients',
'order' => [
'associationType' => 'hasOne',
'fields' => ['total', 'placed']
]
]];
$table = Table::build('foo', ['schema' => ['id' => ['type' => 'integer']]]);
$query = new Query($this->connection);
$query->select('foo.id')->repository($table)->contain($contains)->sql();
$select = $query->clause('select');
$expected = [
'foo__id' => 'foo.id', 'client__name' => 'client.name',
'client__company_id' => 'client.company_id',
'client__telephone' => 'client.telephone',
'order__total' => 'order.total', 'order__placed' => 'order.placed'
];
$this->assertEquals($expected, $select);
}
}

0 comments on commit 915ae6d

Please sign in to comment.
You can’t perform that action at this time.