17
17
use function array_keys ;
18
18
use function array_unshift ;
19
19
use function count ;
20
+ use function func_get_arg ;
20
21
use function func_get_args ;
21
22
use function func_num_args ;
22
23
use function implode ;
23
24
use function is_array ;
24
25
use function is_object ;
25
26
use function key ;
27
+ use function method_exists ;
26
28
use function strtoupper ;
27
29
use function substr ;
30
+ use function ucfirst ;
28
31
29
32
/**
30
33
* QueryBuilder class is responsible to dynamically create SQL queries.
35
38
* The query builder does no validation whatsoever if certain features even work with the
36
39
* underlying database vendor. Limit queries and joins are NOT applied to UPDATE and DELETE statements
37
40
* 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.
38
43
*/
39
44
class QueryBuilder
40
45
{
@@ -677,7 +682,7 @@ public function select($select = null/*, string ...$selects*/)
677
682
}
678
683
679
684
/**
680
- * Adds DISTINCT to the query.
685
+ * Adds or removes DISTINCT to/from the query.
681
686
*
682
687
* <code>
683
688
* $qb = $conn->createQueryBuilder()
@@ -688,9 +693,10 @@ public function select($select = null/*, string ...$selects*/)
688
693
*
689
694
* @return $this This QueryBuilder instance.
690
695
*/
691
- public function distinct (): self
696
+ public function distinct (/* bool $distinct = true */ ): self
692
697
{
693
- $ this ->sqlParts ['distinct ' ] = true ;
698
+ $ this ->sqlParts ['distinct ' ] = func_num_args () < 1 || func_get_arg (0 );
699
+ $ this ->state = self ::STATE_DIRTY ;
694
700
695
701
return $ this ;
696
702
}
@@ -1335,37 +1341,126 @@ public function getQueryParts()
1335
1341
/**
1336
1342
* Resets SQL parts.
1337
1343
*
1344
+ * @deprecated Use the dedicated reset*() methods instead.
1345
+ *
1338
1346
* @param string[]|null $queryPartNames
1339
1347
*
1340
1348
* @return $this This QueryBuilder instance.
1341
1349
*/
1342
1350
public function resetQueryParts ($ queryPartNames = null )
1343
1351
{
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
+
1344
1359
$ queryPartNames ??= array_keys ($ this ->sqlParts );
1345
1360
1346
1361
foreach ($ queryPartNames as $ queryPartName ) {
1347
- $ this ->resetQueryPart ( $ queryPartName) ;
1362
+ $ this ->sqlParts [ $ queryPartName] = self :: SQL_PARTS_DEFAULTS [ $ queryPartName ] ;
1348
1363
}
1349
1364
1365
+ $ this ->state = self ::STATE_DIRTY ;
1366
+
1350
1367
return $ this ;
1351
1368
}
1352
1369
1353
1370
/**
1354
1371
* Resets a single SQL part.
1355
1372
*
1373
+ * @deprecated Use the dedicated reset*() methods instead.
1374
+ *
1356
1375
* @param string $queryPartName
1357
1376
*
1358
1377
* @return $this This QueryBuilder instance.
1359
1378
*/
1360
1379
public function resetQueryPart ($ queryPartName )
1361
1380
{
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
+
1362
1415
$ this ->sqlParts [$ queryPartName ] = self ::SQL_PARTS_DEFAULTS [$ queryPartName ];
1363
1416
1364
1417
$ this ->state = self ::STATE_DIRTY ;
1365
1418
1366
1419
return $ this ;
1367
1420
}
1368
1421
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
+
1369
1464
/**
1370
1465
* Resets the ordering for the query.
1371
1466
*
0 commit comments