Unverified Commit e02296ec authored by alexpott's avatar alexpott

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

(cherry picked from commit f156b5c6)
parent 8a947dd2
......@@ -2,6 +2,8 @@
namespace Drupal\Core\Database;
use Drupal\Core\Database\Query\Condition;
/**
* Base Database API class.
*
......@@ -865,6 +867,11 @@ public function getDriverClass($class) {
}
$driver_class = $this->connectionOptions['namespace'] . '\\' . $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];
}
......@@ -1026,6 +1033,22 @@ public function 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.
*
......
......@@ -2,7 +2,6 @@
namespace Drupal\Core\Database\Driver\mysql;
use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Database\SchemaException;
use Drupal\Core\Database\SchemaObjectExistsException;
use Drupal\Core\Database\SchemaObjectDoesNotExistException;
......@@ -75,7 +74,7 @@ protected function getPrefixInfo($table = 'default', $add_prefix = TRUE) {
protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) {
$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_name', $table_info['table'], $operator);
return $condition;
......
......@@ -399,7 +399,7 @@ protected function mapConditionOperator($operator) {
* {@inheritdoc}
*/
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 = [])
parent::__construct($connection, $options);
$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 = [])
parent::__construct($connection, $options);
$this->table = $table;
$this->conditionTable = $table;
$this->condition = new Condition('AND');
$this->condition = $this->connection->condition('AND');
}
/**
......
......@@ -108,7 +108,7 @@ public function compiled() {
* {@inheritdoc}
*/
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
$options['return'] = Database::RETURN_STATEMENT;
parent::__construct($connection, $options);
$conjunction = isset($options['conjunction']) ? $options['conjunction'] : 'AND';
$this->condition = new Condition($conjunction);
$this->having = new Condition($conjunction);
$this->condition = $this->connection->condition($conjunction);
$this->having = $this->connection->condition($conjunction);
$this->addJoin(NULL, $table, $alias);
}
......
......@@ -521,7 +521,7 @@ public function __call($method, $args) {
* {@inheritdoc}
*/
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 = [])
parent::__construct($connection, $options);
$this->table = $table;
$this->condition = new Condition('AND');
$this->condition = $this->connection->condition('AND');
}
/**
......
......@@ -2,7 +2,6 @@
namespace Drupal\Core\Database;
use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Database\Query\PlaceholderInterface;
/**
......@@ -150,7 +149,7 @@ protected function buildTableNameCondition($table_name, $operator = '=', $add_pr
// Retrieve the table name and schema
$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_schema', $table_info['schema']);
$condition->condition('table_name', $table_info['table'], $operator);
......
......@@ -2,6 +2,8 @@
namespace Drupal\database_statement_monitoring_test;
use Drupal\Core\Database\Query\Condition;
/**
* Trait for Connection classes that can store logged statements.
*/
......@@ -48,7 +50,13 @@ public function getDriverClass($class) {
// based on object, which would break.
$namespace = (new \ReflectionClass(get_parent_class($this)))->getNamespaceName();
$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 @@
use Drupal\Core\Database\Database;
use Drupal\Core\Database\DatabaseExceptionWrapper;
use Drupal\Core\Database\Query\Condition;
/**
* Tests of the core database system.
......@@ -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 @@
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Database\Query\PlaceholderInterface;
use Drupal\Tests\Core\Database\Stub\StubPDO;
use Drupal\Tests\UnitTestCase;
use Prophecy\Argument;
use PHPUnit\Framework\Error\Error;
......@@ -176,4 +177,34 @@ public function providerTestCompileWithSqlInjectionForOperator() {
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