Skip to content

Commit d00d45a

Browse files
committed
Add deprecation layer and upgrade path for QueryBuilder::reset*() methods
1 parent e8479d1 commit d00d45a

File tree

5 files changed

+275
-19
lines changed

5 files changed

+275
-19
lines changed

UPGRADE.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,23 @@ awareness about deprecated code.
88

99
# Upgrade to 3.8
1010

11+
## Deprecated reset methods from `QueryBuilder`
12+
13+
`QueryBuilder::resetQueryParts()` has been deprecated.
14+
15+
Resetting individual query parts through the generic `resetQueryPart()` method has been deprecated as well.
16+
However, several replacements have been put in place depending on the `$queryPartName` parameter:
17+
18+
| `$queryPartName` | suggested replacement |
19+
|------------------|--------------------------------------------|
20+
| `'select'` | Call `select()` with a new set of columns. |
21+
| `'distinct'` | `distinct(false)` |
22+
| `'where'` | `resetWhere()` |
23+
| `'groupBy'` | `resetGroupBy()` |
24+
| `'having'` | `resetHaving()` |
25+
| `'orderBy'` | `resetOrderBy()` |
26+
| `'values'` | Call `values()` with a new set of values. |
27+
1128
## Deprecated getting query parts from `QueryBuilder`
1229

1330
The usage of `QueryBuilder::getQueryPart()` and `::getQueryParts()` is deprecated. The query parts

phpstan.neon.dist

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ parameters:
112112
paths:
113113
- src/Platforms/AbstractPlatform.php
114114

115+
# Deprecated method, will be removed in 4.0.0
116+
-
117+
message: '~^Variable method call on \$this\(Doctrine\\DBAL\\Query\\QueryBuilder\)\.$~'
118+
paths:
119+
- src/Query/QueryBuilder.php
120+
115121
# There is no way to make this assertion in the code,
116122
# and the API doesn't support parametrization of returned column types.
117123
-

psalm.xml.dist

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,8 @@
504504
-->
505505
<referencedMethod name="Doctrine\DBAL\Query\QueryBuilder::getQueryPart"/>
506506
<referencedMethod name="Doctrine\DBAL\Query\QueryBuilder::getQueryParts"/>
507+
<referencedMethod name="Doctrine\DBAL\Query\QueryBuilder::resetQueryPart"/>
508+
<referencedMethod name="Doctrine\DBAL\Query\QueryBuilder::resetQueryParts"/>
507509

508510
<!-- TODO for PHPUnit 10 -->
509511
<referencedMethod name="PHPUnit\Framework\MockObject\Builder\InvocationMocker::withConsecutive"/>
@@ -658,6 +660,12 @@
658660
<file name="src/Schema/PostgreSQLSchemaManager.php"/>
659661
</errorLevel>
660662
</NullableReturnStatement>
663+
<ParadoxicalCondition>
664+
<errorLevel type="suppress">
665+
<!-- False positive in deprecation layer. Can be removed in 4.0.x -->
666+
<file name="src/Query/QueryBuilder.php" />
667+
</errorLevel>
668+
</ParadoxicalCondition>
661669
<PossiblyInvalidArgument>
662670
<errorLevel type="suppress">
663671
<!-- PgSql objects are represented as resources in PHP 7.4 -->

src/Query/QueryBuilder.php

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@
1717
use function array_keys;
1818
use function array_unshift;
1919
use function count;
20+
use function func_get_arg;
2021
use function func_get_args;
2122
use function func_num_args;
2223
use function implode;
2324
use function is_array;
2425
use function is_object;
2526
use function key;
27+
use function method_exists;
2628
use function strtoupper;
2729
use function substr;
30+
use function ucfirst;
2831

2932
/**
3033
* QueryBuilder class is responsible to dynamically create SQL queries.
@@ -35,6 +38,8 @@
3538
* The query builder does no validation whatsoever if certain features even work with the
3639
* underlying database vendor. Limit queries and joins are NOT applied to UPDATE and DELETE statements
3740
* even if some vendors such as MySQL support it.
41+
*
42+
* @method $this distinct(bool $distinct = true) Adds or removes DISTINCT to/from the query.
3843
*/
3944
class QueryBuilder
4045
{
@@ -677,7 +682,7 @@ public function select($select = null/*, string ...$selects*/)
677682
}
678683

679684
/**
680-
* Adds DISTINCT to the query.
685+
* Adds or removes DISTINCT to/from the query.
681686
*
682687
* <code>
683688
* $qb = $conn->createQueryBuilder()
@@ -688,9 +693,10 @@ public function select($select = null/*, string ...$selects*/)
688693
*
689694
* @return $this This QueryBuilder instance.
690695
*/
691-
public function distinct(): self
696+
public function distinct(/* bool $distinct = true */): self
692697
{
693-
$this->sqlParts['distinct'] = true;
698+
$this->sqlParts['distinct'] = func_num_args() < 1 || func_get_arg(0);
699+
$this->state = self::STATE_DIRTY;
694700

695701
return $this;
696702
}
@@ -1335,37 +1341,126 @@ public function getQueryParts()
13351341
/**
13361342
* Resets SQL parts.
13371343
*
1344+
* @deprecated Use the dedicated reset*() methods instead.
1345+
*
13381346
* @param string[]|null $queryPartNames
13391347
*
13401348
* @return $this This QueryBuilder instance.
13411349
*/
13421350
public function resetQueryParts($queryPartNames = null)
13431351
{
1352+
Deprecation::trigger(
1353+
'doctrine/dbal',
1354+
'TODO',
1355+
'%s() is deprecated, instead use dedicated reset methods for the parts that shall be reset.',
1356+
__METHOD__,
1357+
);
1358+
13441359
$queryPartNames ??= array_keys($this->sqlParts);
13451360

13461361
foreach ($queryPartNames as $queryPartName) {
1347-
$this->resetQueryPart($queryPartName);
1362+
$this->sqlParts[$queryPartName] = self::SQL_PARTS_DEFAULTS[$queryPartName];
13481363
}
13491364

1365+
$this->state = self::STATE_DIRTY;
1366+
13501367
return $this;
13511368
}
13521369

13531370
/**
13541371
* Resets a single SQL part.
13551372
*
1373+
* @deprecated Use the dedicated reset*() methods instead.
1374+
*
13561375
* @param string $queryPartName
13571376
*
13581377
* @return $this This QueryBuilder instance.
13591378
*/
13601379
public function resetQueryPart($queryPartName)
13611380
{
1381+
if ($queryPartName === 'distinct') {
1382+
Deprecation::trigger(
1383+
'doctrine/dbal',
1384+
'TODO',
1385+
'Calling %s() with "distinct" is deprecated, call distinct(false) instead.',
1386+
__METHOD__,
1387+
);
1388+
1389+
return $this->distinct(false);
1390+
}
1391+
1392+
$newMethodName = 'reset' . ucfirst($queryPartName);
1393+
if (array_key_exists($queryPartName, self::SQL_PARTS_DEFAULTS) && method_exists($this, $newMethodName)) {
1394+
Deprecation::trigger(
1395+
'doctrine/dbal',
1396+
'TODO',
1397+
'Calling %s() with "%s" is deprecated, call %s() instead.',
1398+
__METHOD__,
1399+
$queryPartName,
1400+
$newMethodName,
1401+
);
1402+
1403+
return $this->$newMethodName();
1404+
}
1405+
1406+
Deprecation::trigger(
1407+
'doctrine/dbal',
1408+
'TODO',
1409+
'Calling %s() with "%s" is deprecated without replacement.',
1410+
__METHOD__,
1411+
$queryPartName,
1412+
$newMethodName,
1413+
);
1414+
13621415
$this->sqlParts[$queryPartName] = self::SQL_PARTS_DEFAULTS[$queryPartName];
13631416

13641417
$this->state = self::STATE_DIRTY;
13651418

13661419
return $this;
13671420
}
13681421

1422+
/**
1423+
* Resets the WHERE conditions for the query.
1424+
*
1425+
* @return $this This QueryBuilder instance.
1426+
*/
1427+
public function resetWhere(): self
1428+
{
1429+
$this->sqlParts['where'] = self::SQL_PARTS_DEFAULTS['where'];
1430+
1431+
$this->state = self::STATE_DIRTY;
1432+
1433+
return $this;
1434+
}
1435+
1436+
/**
1437+
* Resets the grouping for the query.
1438+
*
1439+
* @return $this This QueryBuilder instance.
1440+
*/
1441+
public function resetGroupBy(): self
1442+
{
1443+
$this->sqlParts['groupBy'] = self::SQL_PARTS_DEFAULTS['groupBy'];
1444+
1445+
$this->state = self::STATE_DIRTY;
1446+
1447+
return $this;
1448+
}
1449+
1450+
/**
1451+
* Resets the HAVING conditions for the query.
1452+
*
1453+
* @return $this This QueryBuilder instance.
1454+
*/
1455+
public function resetHaving(): self
1456+
{
1457+
$this->sqlParts['having'] = self::SQL_PARTS_DEFAULTS['having'];
1458+
1459+
$this->state = self::STATE_DIRTY;
1460+
1461+
return $this;
1462+
}
1463+
13691464
/**
13701465
* Resets the ordering for the query.
13711466
*

0 commit comments

Comments
 (0)