Browse Source

Fix #17203: Fix `yii\db\Connection` to persist customized `queryBuilder` configuration after the `close()` → `open()` cycle

bizley-patch-1
Dmytro Naumenko 4 years ago committed by GitHub
parent
commit
10bb71a822
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      framework/CHANGELOG.md
  2. 33
      framework/db/Connection.php
  3. 47
      tests/framework/db/ConnectionTest.php

1
framework/CHANGELOG.md

@ -15,6 +15,7 @@ Yii Framework 2 Change Log
- Bug #18526: Fix `yii\caching\DbCache` to work with MSSQL, add `normalizeTableRowData()` to `yii\db\mssql\QueryBuilder::upsert()` (darkdef) - Bug #18526: Fix `yii\caching\DbCache` to work with MSSQL, add `normalizeTableRowData()` to `yii\db\mssql\QueryBuilder::upsert()` (darkdef)
- Bug #14343: Fix `yii\test\ActiveFixture` to use model's DB connection instead of the default one (margori, bizley) - Bug #14343: Fix `yii\test\ActiveFixture` to use model's DB connection instead of the default one (margori, bizley)
- Bug #17631: Fix `yii\widgets\BaseListView` to properly render custom summary (sjaakp, bizley) - Bug #17631: Fix `yii\widgets\BaseListView` to properly render custom summary (sjaakp, bizley)
- Bug #17203: Fix `yii\db\Connection` to persist customized `queryBuilder` configuration after the `close()``open()` cycle (silverfire)
- Bug #18325: Fix `yii\db\pgsql\Schema` to respect non-default PgSQL schema name for data types (theonedemon, silverfire) - Bug #18325: Fix `yii\db\pgsql\Schema` to respect non-default PgSQL schema name for data types (theonedemon, silverfire)

33
framework/db/Connection.php

@ -425,6 +425,15 @@ class Connection extends Component
public $isSybase = false; public $isSybase = false;
/** /**
* @var array An array of [[setQueryBuilder()]] calls, holding the passed arguments.
* Is used to restore a QueryBuilder configuration after the connection close/open cycle.
*
* @see restoreQueryBuilderConfiguration()
* @since 2.0.42
*/
private $_queryBuilderConfigurations = [];
/**
* @var Transaction the currently active transaction * @var Transaction the currently active transaction
*/ */
private $_transaction; private $_transaction;
@ -851,7 +860,10 @@ class Connection extends Component
$config = !is_array($this->schemaMap[$driver]) ? ['class' => $this->schemaMap[$driver]] : $this->schemaMap[$driver]; $config = !is_array($this->schemaMap[$driver]) ? ['class' => $this->schemaMap[$driver]] : $this->schemaMap[$driver];
$config['db'] = $this; $config['db'] = $this;
return $this->_schema = Yii::createObject($config); $this->_schema = Yii::createObject($config);
$this->restoreQueryBuilderConfiguration();
return $this->_schema;
} }
throw new NotSupportedException("Connection does not support reading schema information for '$driver' DBMS."); throw new NotSupportedException("Connection does not support reading schema information for '$driver' DBMS.");
@ -875,6 +887,25 @@ class Connection extends Component
public function setQueryBuilder($value) public function setQueryBuilder($value)
{ {
Yii::configure($this->getQueryBuilder(), $value); Yii::configure($this->getQueryBuilder(), $value);
$this->_queryBuilderConfigurations[] = $value;
}
/**
* Restores custom QueryBuilder configuration after the connection close/open cycle
*
* @since 2.0.42
*/
private function restoreQueryBuilderConfiguration()
{
if ($this->_queryBuilderConfigurations === []) {
return;
}
$queryBuilderConfigurations = $this->_queryBuilderConfigurations;
$this->_queryBuilderConfigurations = [];
foreach ($queryBuilderConfigurations as $queryBuilderConfiguration) {
$this->setQueryBuilder($queryBuilderConfiguration);
}
} }
/** /**

47
tests/framework/db/ConnectionTest.php

@ -10,6 +10,9 @@ namespace yiiunit\framework\db;
use Yii; use Yii;
use yii\base\InvalidConfigException; use yii\base\InvalidConfigException;
use yii\caching\ArrayCache; use yii\caching\ArrayCache;
use yii\db\conditions\AndCondition;
use yii\db\conditions\ExistsConditionBuilder;
use yii\db\conditions\OrCondition;
use yii\db\Connection; use yii\db\Connection;
use yii\db\Transaction; use yii\db\Transaction;
@ -46,6 +49,50 @@ abstract class ConnectionTest extends DatabaseTestCase
$connection->open(); $connection->open();
} }
public function testQueryBuilderConfigurationAfterOpenClose()
{
$connection = $this->getConnection(false, false);
$connection->setQueryBuilder([
'expressionBuilders' => [
// Just a dumb mapping to make sure it's applied
'yii\db\conditions\OrCondition' => 'yii\db\conditions\ExistsConditionBuilder'
],
]);
// Second call to make sure that consecutive calls are handled correctly
$connection->setQueryBuilder([
'expressionBuilders' => [
'yii\db\conditions\AndCondition' => 'yii\db\conditions\InConditionBuilder'
],
]);
$orCondition = new OrCondition(['dumb']);
$andCondition = new AndCondition(['dumb']);
$connection->open();
$this->assertInstanceOf(
'\yii\db\conditions\ExistsConditionBuilder',
$connection->getQueryBuilder()->getExpressionBuilder($orCondition)
);
$this->assertInstanceOf(
'\yii\db\conditions\InConditionBuilder',
$connection->getQueryBuilder()->getExpressionBuilder($andCondition)
);
$connection->close();
$this->assertNull($connection->pdo);
$connection->open();
$this->assertInstanceOf(
'\yii\db\conditions\ExistsConditionBuilder',
$connection->getQueryBuilder()->getExpressionBuilder($orCondition)
);
$this->assertInstanceOf(
'\yii\db\conditions\InConditionBuilder',
$connection->getQueryBuilder()->getExpressionBuilder($andCondition)
);
}
public function testSerialize() public function testSerialize()
{ {
$connection = $this->getConnection(false, false); $connection = $this->getConnection(false, false);

Loading…
Cancel
Save