Skip to content

Commit

Permalink
Issue #3113403 by Beakerboy, neelam_wadhwani, daffie, alexpott: Make …
Browse files Browse the repository at this point in the history
…Drupal\Core\Database\Query\Condition driver overridable
  • Loading branch information
alexpott committed Mar 23, 2020
1 parent 5ccd66a commit 026674b
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 13 deletions.
23 changes: 23 additions & 0 deletions lib/Drupal/Core/Database/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Drupal\Core\Database;

use Drupal\Core\Database\Query\Condition;

/**
* Base Database API class.
*
Expand Down Expand Up @@ -783,6 +785,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];
}
Expand Down Expand Up @@ -944,6 +951,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.
*
Expand Down
3 changes: 1 addition & 2 deletions lib/Drupal/Core/Database/Driver/mysql/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion lib/Drupal/Core/Database/Query/Condition.php
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ protected function mapConditionOperator($operator) {
* {@inheritdoc}
*/
public function conditionGroupFactory($conjunction = 'AND') {
return new Condition($conjunction);
return new static($conjunction);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/Drupal/Core/Database/Query/Delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/Drupal/Core/Database/Query/Merge.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/Drupal/Core/Database/Query/QueryConditionTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public function compiled() {
* {@inheritdoc}
*/
public function conditionGroupFactory($conjunction = 'AND') {
return new Condition($conjunction);
return $this->connection->condition($conjunction);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions lib/Drupal/Core/Database/Query/Select.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ public function __construct($table, $alias, Connection $connection, $options = [
$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);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/Drupal/Core/Database/Query/SelectExtender.php
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ public function __call($method, $args) {
* {@inheritdoc}
*/
public function conditionGroupFactory($conjunction = 'AND') {
return new Condition($conjunction);
return $this->connection->condition($conjunction);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/Drupal/Core/Database/Query/Update.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}

/**
Expand Down
3 changes: 1 addition & 2 deletions lib/Drupal/Core/Database/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Drupal\Core\Database;

use Drupal\Core\Database\Query\Condition;
use Drupal\Core\Database\Query\PlaceholderInterface;

/**
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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;
}

/**
Expand Down
14 changes: 14 additions & 0 deletions tests/Drupal/KernelTests/Core/Database/ConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\DatabaseExceptionWrapper;
use Drupal\Core\Database\Query\Condition;

/**
* Tests of the core database system.
Expand Down Expand Up @@ -175,4 +176,17 @@ public function testPostgresqlReservedWords() {
}
}

/**
* 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));
}

}
27 changes: 27 additions & 0 deletions tests/Drupal/Tests/Core/Database/ConditionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -176,4 +177,30 @@ 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])
->getMockForAbstractClass();

$condition = $connection->condition('AND');
$this->assertSame('MockCondition', get_class($condition));
}

}

0 comments on commit 026674b

Please sign in to comment.