Permalink
Browse files

Moving more code into EagerLoader

  • Loading branch information...
1 parent 621fe36 commit 1b861aa80f2731c75a25c04f7c38609e0cecba6a @lorenzo lorenzo committed Jan 29, 2014
Showing with 58 additions and 43 deletions.
  1. +26 −4 src/ORM/EagerLoader.php
  2. +32 −39 src/ORM/Query.php
View
@@ -179,12 +179,10 @@ public function normalizedContainments() {
}
/**
- * Helper function used to add the required joins for associations defined using
- * `contain()`
*
* @return void
*/
- protected function _addContainments() {
+ public function attachAssociations($query, $includeFields) {
$this->_loadEagerly = [];
if (empty($this->_containments)) {
return;
@@ -199,7 +197,8 @@ protected function _addContainments() {
foreach ($this->_resolveJoins($this->_table, $contain) as $options) {
$table = $options['instance']->target();
- $this->_addJoin($options['instance'], $options['config']);
+ $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;
@@ -264,6 +263,29 @@ protected function _resolveJoins($source, $associations) {
}
/**
+ * Helper method that will calculate those associations that cannot be joined
+ * directly in this query and will setup the required extra queries for fetching
+ * the extra data.
+ *
+ * @param Statement $statement original query statement
+ * @return CallbackStatement $statement modified statement with extra loaders
+ */
+ public function eagerLoad($statement) {
+ $collected = $this->_collectKeys($statement);
+ foreach ($this->_loadEagerly as $meta) {
+ $contain = $meta['associations'];
+ $alias = $meta['instance']->source()->alias();
+ $keys = isset($collected[$alias]) ? $collected[$alias] : null;
+ $f = $meta['instance']->eagerLoader(
+ $meta['config'] + ['query' => $this, 'contain' => $contain, 'keys' => $keys]
+ );
+ $statement = new CallbackStatement($statement, $this->connection()->driver(), $f);
+ }
+
+ return $statement;
+ }
+
+/**
* Helper function used to return the keys from the query records that will be used
* to eagerly load associations.
*
View
@@ -19,6 +19,7 @@
use Cake\Database\Statement\BufferedStatement;
use Cake\Database\Statement\CallbackStatement;
use Cake\Event\Event;
+use Cake\ORM\EagerLoader;
use Cake\ORM\QueryCacher;
use Cake\ORM\Table;
@@ -132,6 +133,14 @@ class Query extends DatabaseQuery {
protected $_counter;
/**
+ * Instance of a class responsible for storing association containments and
+ * for eager loading them when this query is executed
+ *
+ * @var \Cake\ORM\EagerLoader
+ */
+ protected $_eagerLoader;
+
+/**
* Constuctor
*
* @param Cake\Database\Connection $connection
@@ -140,7 +149,6 @@ class Query extends DatabaseQuery {
public function __construct($connection, $table) {
$this->connection($connection);
$this->repository($table);
- $this->_eagerLoader = new EagerLoader;
}
/**
@@ -186,6 +194,25 @@ public function addDefaultTypes(Table $table) {
}
/**
+ * Sets the instance of the eager loader class to use for loading associations
+ * and storing containments. If called with no arguments, it will return the
+ * currently configured instance.
+ *
+ * @param \Cake\ORM\EagerLoader $instance
+ * @return \Cake\ORM\Eager|\Cake\ORM\Query
+ */
+ public function eagerLoader(EagerLoader $instance = null) {
+ if ($instance === null) {
+ if ($this->_eagerLoader === null) {
+ $this->_eagerLoader = new EagerLoader;
+ }
+ return $this->_eagerLoader;
+ }
+ $this->_eagerLoader = $instance;
+ return $this;
+ }
+
+/**
* Sets the list of associations that should be eagerly loaded along with this
* query. The list of associated tables passed must have been previously set as
* associations using the Table API.
@@ -287,7 +314,7 @@ public function contain($associations = null, $override = false) {
return $this;
}
- $result = $this->_eagerLoader->contain($associations, $override);
+ $result = $this->eagerLoader()->contain($associations, $override);
if ($associations === null) {
return $result;
}
@@ -346,7 +373,7 @@ public function contain($associations = null, $override = false) {
* @return Query
*/
public function matching($assoc, callable $builder = null) {
- $this->_eagerLoader->matching($assoc, $builder);
+ $this->eagerLoader()->matching($assoc, $builder);
$this->_dirty();
return $this;
}
@@ -882,7 +909,7 @@ protected function _decorateStatement($statement) {
if (!($statement instanceof BufferedStatement)) {
$statement = new BufferedStatement($statement, $this->connection()->driver());
}
- $statement = $this->_eagerLoad($statement);
+ $statement = $this->eagerLoader()->eagerLoad($statement);
}
return $statement;
@@ -907,46 +934,12 @@ protected function _transformQuery() {
$this->from([$this->_table->alias() => $this->_table->table()]);
}
$this->_addDefaultFields();
- $this->_addContainments();
+ $this->eagerLoader()->attachAssociations($this, !$this->_hasFields);
}
return parent::_transformQuery();
}
/**
- * Adds a join based on a particular association and some custom options
- *
- * @param Association $association
- * @param array $options
- * @return void
- */
- protected function _addJoin($association, $options) {
- $association->attachTo($this, $options + ['includeFields' => !$this->_hasFields]);
- }
-
-/**
- * Helper method that will calculate those associations that cannot be joined
- * directly in this query and will setup the required extra queries for fetching
- * the extra data.
- *
- * @param Statement $statement original query statement
- * @return CallbackStatement $statement modified statement with extra loaders
- */
- protected function _eagerLoad($statement) {
- $collected = $this->_collectKeys($statement);
- foreach ($this->_loadEagerly as $meta) {
- $contain = $meta['associations'];
- $alias = $meta['instance']->source()->alias();
- $keys = isset($collected[$alias]) ? $collected[$alias] : null;
- $f = $meta['instance']->eagerLoader(
- $meta['config'] + ['query' => $this, 'contain' => $contain, 'keys' => $keys]
- );
- $statement = new CallbackStatement($statement, $this->connection()->driver(), $f);
- }
-
- return $statement;
- }
-
-/**
* Inspects if there are any set fields for selecting, otherwise adds all
* the fields for the default table.
*

0 comments on commit 1b861aa

Please sign in to comment.