Skip to content
Permalink
Browse files

Completing the EagerLoader API to also have a function that returns

associations to be eager laoded
  • Loading branch information...
lorenzo committed Feb 5, 2014
1 parent 5556270 commit 49f19d248c7baf5e8ba5a03ace65c4c4aaecc0eb
Showing with 32 additions and 23 deletions.
  1. +32 −23 src/ORM/EagerLoader.php
@@ -104,7 +104,7 @@ public function contain($associations = []) {
}
$associations = $this->_reformatContain($associations, $this->_containments);
$this->_normalized = null;
$this->_normalized = $this->_loadExternal = null;
return $this->_containments = $associations;
}
@@ -149,7 +149,7 @@ public function matching($assoc, callable $builder = null) {
*/
public function normalized(Table $repository) {
if ($this->_normalized !== null || empty($this->_containments)) {
return $this->_normalized;
return (array)$this->_normalized;
}
$contain = [];
@@ -169,20 +169,6 @@ public function normalized(Table $repository) {
return $this->_normalized = $contain;
}
/**
* Returns whether or not there are associations that need to be loaded by
* decorating results from a query and executing a separate one for injecting
* them.
*
* @param \Cake\ORM\Table $repository The table containing the associations described in
* the `contain` array
* @return boolean
*/
protected function _hasExternal(Table $repository) {
$this->normalized($repository);
return !empty($this->_loadExternal);
}
/**
* Formats the containments array so that associations are always set as keys
* in the array. This function merges the original associations array with
@@ -276,6 +262,27 @@ public function attachableAssociations(Table $repository) {
return $this->_resolveJoins($contain);
}
/**
* Returns an array with the associations that need to be fetched using a
* separate query, each array value will contain the following keys:
*
* - instance: the association object instance
* - config: the options set for fetching such association
*
* @param \Cake\ORM\Table $repository The table containing the associations
* to be loaded
* @return array
*/
public function externalAssociations(Table $repository) {
if ($this->_loadExternal) {
return $this->_loadExternal;
}
$contain = $this->normalized($repository);
$this->_resolveJoins($contain);
return $this->_loadExternal;
}
/**
* Auxiliary function responsible for fully normalizing deep associations defined
* using `contain()`
@@ -329,7 +336,7 @@ protected function _resolveJoins($associations) {
$result[$table] = $options;
$result += $this->_resolveJoins($options['associations']);
} else {
$this->_loadExternal[$table] = $options;
$this->_loadExternal[] = $options;
}
}
return $result;
@@ -345,13 +352,14 @@ protected function _resolveJoins($associations) {
* @return CallbackStatement $statement modified statement with extra loaders
*/
public function loadExternal($query, $statement) {
if (!$this->_hasExternal($query->repository())) {
$external = $this->externalAssociations($query->repository());
if (empty($external)) {
return $statement;
}
$driver = $query->connection()->driver();
list($collected, $statement) = $this->_collectKeys($query, $statement);
foreach ($this->_loadExternal as $meta) {
list($collected, $statement) = $this->_collectKeys($external, $query, $statement);
foreach ($external as $meta) {
$contain = $meta['associations'];
$alias = $meta['instance']->source()->alias();
$keys = isset($collected[$alias]) ? $collected[$alias] : null;
@@ -368,13 +376,14 @@ public function loadExternal($query, $statement) {
* Helper function used to return the keys from the query records that will be used
* to eagerly load associations.
*
* @param \Cake\ORM\Query $query
* @param array $external the list of external associations to be loaded
* @param \Cake\ORM\Query $query The query from which the results where generated
* @param BufferedStatement $statement
* @return array
*/
protected function _collectKeys($query, $statement) {
protected function _collectKeys($external, $query, $statement) {
$collectKeys = [];
foreach ($this->_loadExternal as $meta) {
foreach ($external as $meta) {
$source = $meta['instance']->source();
if ($meta['instance']->requiresKeys($meta['config'])) {
$alias = $source->alias();

0 comments on commit 49f19d2

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