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 #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 #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)

33
framework/db/Connection.php

@ -425,6 +425,15 @@ class Connection extends Component
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
*/
private $_transaction;
@ -851,7 +860,10 @@ class Connection extends Component
$config = !is_array($this->schemaMap[$driver]) ? ['class' => $this->schemaMap[$driver]] : $this->schemaMap[$driver];
$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.");
@ -875,6 +887,25 @@ class Connection extends Component
public function setQueryBuilder($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\base\InvalidConfigException;
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\Transaction;
@ -46,6 +49,50 @@ abstract class ConnectionTest extends DatabaseTestCase
$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()
{
$connection = $this->getConnection(false, false);

Loading…
Cancel
Save