Commit 265940c8 authored by alexpott's avatar alexpott

Issue #2038707 by chx, rlmumford, yanniboi, andrewbelcher: Entity query sql...

Issue #2038707 by chx, rlmumford, yanniboi, andrewbelcher: Entity query sql backend limits storage controllers changes in contrib.
parent 55092dc7
......@@ -9,7 +9,6 @@
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Entity\EntityManager;
use Drupal\Core\Entity\EntityStorageControllerInterface;
use Drupal\Core\Entity\Query\QueryBase;
use Drupal\Core\Entity\Query\QueryInterface;
......@@ -51,13 +50,6 @@ function __construct($entity_type, $conjunction, EntityManager $entity_manager,
$this->configStorage = $config_storage;
}
/**
* Implements \Drupal\Core\Entity\Query\QueryInterface::conditionGroupFactory().
*/
public function conditionGroupFactory($conjunction = 'AND') {
return new Condition($conjunction);
}
/**
* Overrides \Drupal\Core\Entity\Query\QueryBase::condition().
*
......
......@@ -29,14 +29,22 @@ abstract class ConditionFundamentals {
*/
protected $conjunction;
/**
* The query this condition belongs to.
*
* @var \Drupal\Core\Entity\Query\QueryInterface
*/
protected $query;
/**
* Constructs a Condition object.
*
* @param string $conjunction
* The operator to use to combine conditions: 'AND' or 'OR'.
*/
public function __construct($conjunction = 'AND') {
public function __construct($conjunction, QueryInterface $query) {
$this->conjunction = $conjunction;
$this->query = $query;
}
/**
......
......@@ -170,6 +170,23 @@ public function range($start = NULL, $length = NULL) {
return $this;
}
/**
* Creates an object holding a group of conditions.
*
* See andConditionGroup() and orConditionGroup() for more.
*
* @param string $conjunction
* - AND (default): this is the equivalent of andConditionGroup().
* - OR: this is the equivalent of orConditionGroup().
*
* @return \Drupal\Core\Entity\Query\ConditionInterface
* An object holding a group of conditions.
*/
protected function conditionGroupFactory($conjunction = 'AND') {
$class = static::getNamespace($this) . '\\Condition';
return new $class($conjunction, $this);
}
/**
* Implements \Drupal\Core\Entity\Query\QueryInterface::andConditionGroup().
*/
......@@ -402,4 +419,18 @@ protected function getAggregationAlias($field, $function) {
return strtolower($field . '_'. $function);
}
/**
* Returns the namespace of an object.
*
* @param $object
* The object.
*
* @return string
* The namespace.
*/
public static function getNamespace($object) {
$class = get_class($object);
return substr($class, 0, strrpos($class, '\\'));
}
}
......@@ -176,20 +176,6 @@ public function age($age = FIELD_LOAD_CURRENT);
*/
public function execute();
/**
* Creates an object holding a group of conditions.
*
* See andConditionGroup() and orConditionGroup() for more.
*
* @param $conjunction
* - AND (default): this is the equivalent of andConditionGroup().
* - OR: this is the equivalent of andConditionGroup().
*
* return ConditionInterface
* An object holding a group of conditions.
*/
public function conditionGroupFactory($conjunction = 'AND');
/**
* Creates a new group of conditions ANDed together.
*
......
......@@ -14,6 +14,13 @@
class Condition extends ConditionBase {
/**
* The SQL entity query object this condition belongs to.
*
* @var \Drupal\Core\Entity\Query\Sql\Query
*/
protected $query;
/**
* Implements Drupal\Core\Entity\Query\ConditionInterface::compile().
*/
......@@ -24,7 +31,7 @@ public function compile($conditionContainer) {
// can join tables as necessary. On the other hand, conditions need to be
// added to the $conditionContainer object to keep grouping.
$sqlQuery = $conditionContainer instanceof SelectInterface ? $conditionContainer : $conditionContainer->sqlQuery;
$tables = new Tables($sqlQuery);
$tables = $this->query->getTables($sqlQuery);
foreach ($this->conditions as $condition) {
if ($condition['field'] instanceOf ConditionInterface) {
$sqlCondition = new SqlCondition($condition['field']->getConjunction());
......
......@@ -8,6 +8,7 @@
namespace Drupal\Core\Entity\Query\Sql;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\EntityManager;
use Drupal\Core\Entity\Query\QueryBase;
use Drupal\Core\Entity\Query\QueryException;
......@@ -86,13 +87,6 @@ public function __construct($entity_type, EntityManager $entity_manager, $conjun
}
/**
* Implements Drupal\Core\Entity\Query\QueryInterface::conditionGroupFactory().
*/
public function conditionGroupFactory($conjunction = 'AND') {
return new Condition($conjunction);
}
/**
* Implements \Drupal\Core\Entity\Query\QueryInterface::execute().
*/
......@@ -289,7 +283,7 @@ protected function result() {
*/
protected function getSqlField($field, $langcode) {
if (!isset($this->tables)) {
$this->tables = new Tables($this->sqlQuery);
$this->tables = $this->getTables($this->sqlQuery);
}
$base_property = "base_table.$field";
if (isset($this->sqlFields[$base_property])) {
......@@ -320,4 +314,18 @@ public function __clone() {
$this->sqlGroupBy = array();
}
/**
* Gets the Tables object for this query.
*
* @param \Drupal\Core\Database\Query\SelectInterface $sql_query
* The SQL query object being built.
*
* @return \Drupal\Core\Entity\Query\Sql\TablesInterface
* The object that adds tables and fields to the SQL query object.
*/
public function getTables(SelectInterface $sql_query) {
$class = QueryBase::getNamespace($this) . '\\Tables';
return new $class($sql_query);
}
}
......@@ -52,7 +52,7 @@ public function prepare() {
* Implements \Drupal\Core\Entity\Query\QueryAggregateInterface::conditionAggregateGroupFactory().
*/
public function conditionAggregateGroupFactory($conjunction = 'AND') {
return new ConditionAggregate($conjunction);
return new ConditionAggregate($conjunction, $this);
}
/**
......
......@@ -9,6 +9,7 @@
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityManager;
use Drupal\Core\Entity\Query\QueryBase;
use Drupal\Core\Entity\Query\QueryFactoryInterface;
/**
......@@ -32,7 +33,7 @@ class QueryFactory implements QueryFactoryInterface {
* @param \Drupal\Core\Database\Connection $connection
* The database connection used by the entity query.
*/
function __construct(Connection $connection) {
public function __construct(Connection $connection) {
$this->connection = $connection;
}
......@@ -48,8 +49,9 @@ function __construct(Connection $connection) {
* @return \Drupal\Core\Entity\Query\Sql\Query
* The factored query.
*/
function get($entity_type, $conjunction, EntityManager $entity_manager) {
return new Query($entity_type, $entity_manager, $conjunction, $this->connection);
public function get($entity_type, $conjunction, EntityManager $entity_manager) {
$class = QueryBase::getNamespace($this) . '\\Query';
return new $class($entity_type, $entity_manager, $conjunction, $this->connection);
}
/**
......@@ -64,8 +66,9 @@ function get($entity_type, $conjunction, EntityManager $entity_manager) {
* @return \Drupal\Core\Entity\Query\Sql\QueryAggregate
* The factored aggregation query.
*/
function getAggregate($entity_type, $conjunction, EntityManager $entity_manager) {
return new QueryAggregate($entity_type, $entity_manager, $conjunction, $this->connection);
public function getAggregate($entity_type, $conjunction, EntityManager $entity_manager) {
$class = QueryBase::getNamespace($this) . '\\QueryAggregate';
return new $class($entity_type, $entity_manager, $conjunction, $this->connection);
}
}
......@@ -15,7 +15,7 @@
/**
* Adds tables and fields to the SQL entity query.
*/
class Tables {
class Tables implements TablesInterface {
/**
* @var \Drupal\Core\Database\Query\SelectInterface
......@@ -45,22 +45,14 @@ class Tables {
/**
* @param \Drupal\Core\Database\Query\SelectInterface $sql_query
*/
function __construct(SelectInterface $sql_query) {
public function __construct(SelectInterface $sql_query) {
$this->sqlQuery = $sql_query;
}
/**
* @param string $field
* If it contains a dot, then field name dot field column. If it doesn't
* then entity property name.
* @param string $type
* Join type, can either be INNER or LEFT.
* @return string
* The return value is a string containing the alias of the table, a dot
* and the appropriate SQL column as passed in. This allows the direct use
* of this in a query for a condition or sort.
* {@inheritdoc}
*/
function addField($field, $type, $langcode) {
public function addField($field, $type, $langcode) {
$entity_type = $this->sqlQuery->getMetaData('entity_type');
$age = $this->sqlQuery->getMetaData('age');
// This variable ensures grouping works correctly. For example:
......
<?php
/**
* @file
* Contains \Drupal\Core\Entity\Query\Sql\TablesInterface.
*/
namespace Drupal\Core\Entity\Query\Sql;
/**
* Adds tables and fields to the SQL entity query.
*/
interface TablesInterface {
/**
* Adds a field to a database query.
*
* @param string $field
* If it contains a dot, then field name dot field column. If it doesn't
* then entity property name.
* @param string $type
* Join type, can either be INNER or LEFT.
* @param $langcode
* The language code the field values are to be shown in.
*
* @throws \Drupal\Core\Entity\Query\QueryException
* If $field specifies an invalid relationship.
*
* @return string
* The return value is a string containing the alias of the table, a dot
* and the appropriate SQL column as passed in. This allows the direct use
* of this in a query for a condition or sort.
*/
public function addField($field, $type, $langcode);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment