Unverified Commit f156b5c6 authored by alexpott's avatar alexpott
Browse files

Issue #3113403 by Beakerboy, neelam_wadhwani, daffie, alexpott: Make...

Issue #3113403 by Beakerboy, neelam_wadhwani, daffie, alexpott: Make Drupal\Core\Database\Query\Condition driver overridable
parent 954c622b
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
namespace Drupal\Core\Database; namespace Drupal\Core\Database;
use Drupal\Core\Database\Query\Condition;
/** /**
* Base Database API class. * Base Database API class.
* *
...@@ -865,6 +867,11 @@ public function getDriverClass($class) { ...@@ -865,6 +867,11 @@ public function getDriverClass($class) {
} }
$driver_class = $this->connectionOptions['namespace'] . '\\' . $class; $driver_class = $this->connectionOptions['namespace'] . '\\' . $class;
$this->driverClasses[$class] = class_exists($driver_class) ? $driver_class : $class; $this->driverClasses[$class] = class_exists($driver_class) ? $driver_class : $class;
if ($this->driverClasses[$class] === 'Condition') {
// @todo Deprecate the fallback for contrib and custom drivers in 9.1.x
// in https://www.drupal.org/project/drupal/issues/3120036.
$this->driverClasses[$class] = Condition::class;
}
} }
return $this->driverClasses[$class]; return $this->driverClasses[$class];
} }
...@@ -1026,6 +1033,22 @@ public function schema() { ...@@ -1026,6 +1033,22 @@ public function schema() {
return $this->schema; return $this->schema;
} }
/**
* Prepares and returns a CONDITION query object.
*
* @param string $conjunction
* The operator to use to combine conditions: 'AND' or 'OR'.
*
* @return \Drupal\Core\Database\Query\Condition
* A new Condition query object.
*
* @see \Drupal\Core\Database\Query\Condition
*/
public function condition($conjunction) {
$class = $this->getDriverClass('Condition');
return new $class($conjunction);
}
/** /**
* Escapes a database name string. * Escapes a database name string.
* *
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
namespace Drupal\Core\Database\Driver\mysql; namespace Drupal\Core\Database\Driver\mysql;
use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Database\SchemaException; use Drupal\Core\Database\SchemaException;
use Drupal\Core\Database\SchemaObjectExistsException; use Drupal\Core\Database\SchemaObjectExistsException;
use Drupal\Core\Database\SchemaObjectDoesNotExistException; use Drupal\Core\Database\SchemaObjectDoesNotExistException;
...@@ -75,7 +74,7 @@ protected function getPrefixInfo($table = 'default', $add_prefix = TRUE) { ...@@ -75,7 +74,7 @@ protected function getPrefixInfo($table = 'default', $add_prefix = TRUE) {
protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) { protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) {
$table_info = $this->getPrefixInfo($table_name, $add_prefix); $table_info = $this->getPrefixInfo($table_name, $add_prefix);
$condition = new Condition('AND'); $condition = $this->connection->condition('AND');
$condition->condition('table_schema', $table_info['database']); $condition->condition('table_schema', $table_info['database']);
$condition->condition('table_name', $table_info['table'], $operator); $condition->condition('table_name', $table_info['table'], $operator);
return $condition; return $condition;
......
...@@ -399,7 +399,7 @@ protected function mapConditionOperator($operator) { ...@@ -399,7 +399,7 @@ protected function mapConditionOperator($operator) {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function conditionGroupFactory($conjunction = 'AND') { public function conditionGroupFactory($conjunction = 'AND') {
return new Condition($conjunction); return new static($conjunction);
} }
/** /**
......
...@@ -36,7 +36,7 @@ public function __construct(Connection $connection, $table, array $options = []) ...@@ -36,7 +36,7 @@ public function __construct(Connection $connection, $table, array $options = [])
parent::__construct($connection, $options); parent::__construct($connection, $options);
$this->table = $table; $this->table = $table;
$this->condition = new Condition('AND'); $this->condition = $this->connection->condition('AND');
} }
/** /**
......
...@@ -138,7 +138,7 @@ public function __construct(Connection $connection, $table, array $options = []) ...@@ -138,7 +138,7 @@ public function __construct(Connection $connection, $table, array $options = [])
parent::__construct($connection, $options); parent::__construct($connection, $options);
$this->table = $table; $this->table = $table;
$this->conditionTable = $table; $this->conditionTable = $table;
$this->condition = new Condition('AND'); $this->condition = $this->connection->condition('AND');
} }
/** /**
......
...@@ -108,7 +108,7 @@ public function compiled() { ...@@ -108,7 +108,7 @@ public function compiled() {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function conditionGroupFactory($conjunction = 'AND') { public function conditionGroupFactory($conjunction = 'AND') {
return new Condition($conjunction); return $this->connection->condition($conjunction);
} }
/** /**
......
...@@ -134,8 +134,8 @@ public function __construct(Connection $connection, $table, $alias = NULL, $opti ...@@ -134,8 +134,8 @@ public function __construct(Connection $connection, $table, $alias = NULL, $opti
$options['return'] = Database::RETURN_STATEMENT; $options['return'] = Database::RETURN_STATEMENT;
parent::__construct($connection, $options); parent::__construct($connection, $options);
$conjunction = isset($options['conjunction']) ? $options['conjunction'] : 'AND'; $conjunction = isset($options['conjunction']) ? $options['conjunction'] : 'AND';
$this->condition = new Condition($conjunction); $this->condition = $this->connection->condition($conjunction);
$this->having = new Condition($conjunction); $this->having = $this->connection->condition($conjunction);
$this->addJoin(NULL, $table, $alias); $this->addJoin(NULL, $table, $alias);
} }
......
...@@ -521,7 +521,7 @@ public function __call($method, $args) { ...@@ -521,7 +521,7 @@ public function __call($method, $args) {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function conditionGroupFactory($conjunction = 'AND') { public function conditionGroupFactory($conjunction = 'AND') {
return new Condition($conjunction); return $this->connection->condition($conjunction);
} }
/** /**
......
...@@ -65,7 +65,7 @@ public function __construct(Connection $connection, $table, array $options = []) ...@@ -65,7 +65,7 @@ public function __construct(Connection $connection, $table, array $options = [])
parent::__construct($connection, $options); parent::__construct($connection, $options);
$this->table = $table; $this->table = $table;
$this->condition = new Condition('AND'); $this->condition = $this->connection->condition('AND');
} }
/** /**
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
namespace Drupal\Core\Database; namespace Drupal\Core\Database;
use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Database\Query\PlaceholderInterface; use Drupal\Core\Database\Query\PlaceholderInterface;
/** /**
...@@ -150,7 +149,7 @@ protected function buildTableNameCondition($table_name, $operator = '=', $add_pr ...@@ -150,7 +149,7 @@ protected function buildTableNameCondition($table_name, $operator = '=', $add_pr
// Retrieve the table name and schema // Retrieve the table name and schema
$table_info = $this->getPrefixInfo($table_name, $add_prefix); $table_info = $this->getPrefixInfo($table_name, $add_prefix);
$condition = new Condition('AND'); $condition = $this->connection->condition('AND');
$condition->condition('table_catalog', $info['database']); $condition->condition('table_catalog', $info['database']);
$condition->condition('table_schema', $table_info['schema']); $condition->condition('table_schema', $table_info['schema']);
$condition->condition('table_name', $table_info['table'], $operator); $condition->condition('table_name', $table_info['table'], $operator);
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
namespace Drupal\database_statement_monitoring_test; namespace Drupal\database_statement_monitoring_test;
use Drupal\Core\Database\Query\Condition;
/** /**
* Trait for Connection classes that can store logged statements. * Trait for Connection classes that can store logged statements.
*/ */
...@@ -48,7 +50,13 @@ public function getDriverClass($class) { ...@@ -48,7 +50,13 @@ public function getDriverClass($class) {
// based on object, which would break. // based on object, which would break.
$namespace = (new \ReflectionClass(get_parent_class($this)))->getNamespaceName(); $namespace = (new \ReflectionClass(get_parent_class($this)))->getNamespaceName();
$driver_class = $namespace . '\\' . $class; $driver_class = $namespace . '\\' . $class;
return class_exists($driver_class) ? $driver_class : $class; if (class_exists($driver_class)) {
return $driver_class;
}
elseif ($class == 'Condition') {
return Condition::class;
}
return $class;
} }
/** /**
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
use Drupal\Core\Database\Database; use Drupal\Core\Database\Database;
use Drupal\Core\Database\DatabaseExceptionWrapper; use Drupal\Core\Database\DatabaseExceptionWrapper;
use Drupal\Core\Database\Query\Condition;
/** /**
* Tests of the core database system. * Tests of the core database system.
...@@ -155,4 +156,17 @@ public function testMultipleStatements() { ...@@ -155,4 +156,17 @@ public function testMultipleStatements() {
} }
} }
/**
* Test that the method ::condition() returns a Condition object.
*/
public function testCondition() {
$connection = Database::getConnection('default', 'default');
$namespace = (new \ReflectionObject($connection))->getNamespaceName() . "\\Condition";
if (!class_exists($namespace)) {
$namespace = Condition::class;
}
$condition = $connection->condition('AND');
$this->assertSame($namespace, get_class($condition));
}
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
use Drupal\Core\Database\Connection; use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Query\Condition; use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Database\Query\PlaceholderInterface; use Drupal\Core\Database\Query\PlaceholderInterface;
use Drupal\Tests\Core\Database\Stub\StubPDO;
use Drupal\Tests\UnitTestCase; use Drupal\Tests\UnitTestCase;
use Prophecy\Argument; use Prophecy\Argument;
use PHPUnit\Framework\Error\Error; use PHPUnit\Framework\Error\Error;
...@@ -176,4 +177,34 @@ public function providerTestCompileWithSqlInjectionForOperator() { ...@@ -176,4 +177,34 @@ public function providerTestCompileWithSqlInjectionForOperator() {
return $data; return $data;
} }
/**
* Test that the core Condition can be overridden.
*/
public function testContribCondition() {
$mockCondition = $this->getMockBuilder(Condition::class)
->setMockClassName('MockCondition')
->setConstructorArgs([NULL])
->disableOriginalConstructor()
->getMock();
$contrib_namespace = 'Drupal\Driver\Database\mock';
$mocked_namespace = $contrib_namespace . '\\Condition';
class_alias('MockCondition', $mocked_namespace);
$options['namespace'] = $contrib_namespace;
$options['prefix']['default'] = '';
$mockPdo = $this->createMock(StubPDO::class);
$connection = $this->getMockBuilder(Connection::class)
->setConstructorArgs([$mockPdo, $options])
->setMethods(['identifierQuote'])
->getMockForAbstractClass();
// @todo In drupal:10.0.0 this function will be abstract and the mock
// builder will automatically create it. This can be
// can be removed at that time.
$connection->method('identifierQuote')->willReturn(NULL);
$condition = $connection->condition('AND');
$this->assertSame('MockCondition', get_class($condition));
}
} }
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