Skip to content

Commit

Permalink
More refactoring to make tests pass, also cleaning up EagerLoader to do
Browse files Browse the repository at this point in the history
less useless looping
  • Loading branch information
lorenzo committed Jan 29, 2014
1 parent d249953 commit dc8efcc
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 47 deletions.
83 changes: 38 additions & 45 deletions src/ORM/EagerLoader.php
Expand Up @@ -99,6 +99,40 @@ public function matching($assoc, callable $builder = null) {
return $this->contain($containments);
}

/**
* Returns the fully normalized array of associations that should be eagerly
* loaded for a table. The normalized array will restructure the original array
* by sorting all associations under one key and special options under another.
*
* Additionally it will set an 'instance' key per association containing the
* association instance from the corresponding source table
*
* @param \Cake\ORM\Table $repository The table containing the association that
* will be normalized
* @return array
*/
public function normalized(Table $repository) {
if ($this->_normalized !== null || empty($this->_containments)) {
return $this->_normalized;
}

$contain = [];
foreach ($this->_containments as $table => $options) {
if (!empty($options['instance'])) {
$contain = (array)$this->_containments;
break;
}
$contain[$table] = $this->_normalizeContain($repository, $table, $options);
}

return $this->_normalized = $contain;
}

public function hasExternal(Table $repository) {
$this->normalized($repository);
return !empty($this->_loadEagerly);
}

/**
* Formats the containments array so that associations are always set as keys
* in the array. This function merges the original associations array with
Expand Down Expand Up @@ -148,64 +182,19 @@ protected function _reformatContain($associations, $original) {
return $result;
}

/**
* Returns the fully normalized array of associations that should be eagerly
* loaded for a table. The normalized array will restructure the original array
* by sorting all associations under one key and special options under another.
*
* Additionally it will set an 'instance' key per association containing the
* association instance from the corresponding source table
*
* @param \Cake\ORM\Table $repository The table containing the association that
* will be normalized
* @return array
*/
public function normalized(Table $repository) {
if ($this->_normalized !== null || empty($this->_containments)) {
return $this->_normalized;
}

$contain = [];
foreach ($this->_containments as $table => $options) {
if (!empty($options['instance'])) {
$contain = (array)$this->_containments;
break;
}
$contain[$table] = $this->_normalizeContain(
$repository,
$table,
$options
);
}

return $this->_normalized = $contain;
}

/**
*
* @return void
*/
public function attachAssociations($query, $includeFields) {
$this->_loadEagerly = [];
if (empty($this->_containments)) {
return;
}

$contain = $this->normalized($query->repository());
foreach ($contain as $relation => $meta) {
if ($meta['instance'] && !$meta['canBeJoined']) {
$this->_loadEagerly[$relation] = $meta;
}
}

foreach ($this->_resolveJoins($contain) as $options) {
$config = $options['config'] + ['includeFields' => $includeFields];
$options['instance']->attachTo($query, $config);
foreach ($options['associations'] as $relation => $meta) {
if ($meta['instance'] && !$meta['canBeJoined']) {
$this->_loadEagerly[$relation] = $meta;
}
}
}
}

Expand Down Expand Up @@ -238,6 +227,10 @@ protected function _normalizeContain(Table $parent, $alias, $options) {
];
$config['canBeJoined'] = $instance->canBeJoined($config['config']);

if (!$config['canBeJoined']) {
$this->_loadEagerly[$alias] = $config;
}

foreach ($extra as $t => $assoc) {
$config['associations'][$t] = $this->_normalizeContain($table, $t, $assoc);
}
Expand Down
6 changes: 4 additions & 2 deletions src/ORM/Query.php
Expand Up @@ -903,11 +903,13 @@ protected function _decorateResults($result) {
*/
protected function _decorateStatement($statement) {
$statement = parent::_decorateStatement($statement);
if ($this->_loadEagerly) {
$loader = $this->eagerLoader();

if ($loader->hasExternal($this->repository())) {
if (!($statement instanceof BufferedStatement)) {
$statement = new BufferedStatement($statement, $this->connection()->driver());
}
$statement = $this->eagerLoader()->eagerLoad($statement);
$statement = $loader->eagerLoad($statement);
}

return $statement;
Expand Down

0 comments on commit dc8efcc

Please sign in to comment.