‪TYPO3CMS  ‪main
QueryBuilderTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Doctrine\DBAL\ArrayParameterType;
21 use Doctrine\DBAL\ParameterType;
22 use Doctrine\DBAL\Platforms\AbstractPlatform as DoctrineAbstractPlatform;
23 use Doctrine\DBAL\Platforms\MariaDBPlatform as DoctrineMariaDBPlatform;
24 use Doctrine\DBAL\Platforms\MySQLPlatform as DoctrineMySQLPlatform;
25 use Doctrine\DBAL\Platforms\PostgreSQLPlatform as DoctrinePostgreSQLPlatform;
26 use Doctrine\DBAL\Platforms\SQLitePlatform as DoctrineSQLitePlatform;
27 use Doctrine\DBAL\Query\From;
28 use Doctrine\DBAL\Query\Join;
29 use Doctrine\DBAL\Query\QueryType;
30 use Doctrine\DBAL\Result;
31 use Doctrine\DBAL\Types\Type;
32 use PHPUnit\Framework\Attributes\DataProvider;
33 use PHPUnit\Framework\Attributes\Test;
34 use PHPUnit\Framework\MockObject\MockObject;
38 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
45 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
46 
47 final class ‪QueryBuilderTest extends UnitTestCase
48 {
49  private ‪Connection&MockObject ‪$connection;
50  private ?QueryBuilder ‪$subject;
52 
56  protected function ‪setUp(): void
57  {
58  parent::setUp();
59  $this->concreteQueryBuilder = $this->createMock(ConcreteQueryBuilder::class);
60  $this->connection = $this->createMock(Connection::class);
61  $this->subject = new QueryBuilder(
62  $this->connection,
63  null,
64  $this->concreteQueryBuilder
65  );
66  }
67 
68  #[Test]
70  {
71  $this->connection->expects(self::atLeastOnce())->method('getExpressionBuilder')
72  ->willReturn(GeneralUtility::makeInstance(ExpressionBuilder::class, $this->connection));
73  $this->subject->expr();
74  }
75 
76  #[Test]
78  {
79  // Set protected type of the concrete QueryBuilder
80  $setQueryType = \Closure::bind(function (string $property, QueryType $value) {
81  $this->{$property} = $value;
82  }, ‪$this->concreteQueryBuilder, ConcreteQueryBuilder::class);
83  $setQueryType->call($this->concreteQueryBuilder, 'type', QueryType::UPDATE);
84  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('getSQL')
85  ->willReturn('UPDATE aTable SET pid = 7');
86  $this->subject->getSQL();
87  }
88 
89  #[Test]
91  {
92  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('setParameter')->with('aField', 5, self::anything())
93  ->willReturn($this->subject);
94  $this->subject->setParameter('aField', 5);
95  }
96 
97  #[Test]
99  {
100  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('setParameters')->with(['aField' => 'aValue'], [])
101  ->willReturn($this->subject);
102  $this->subject->setParameters(['aField' => 'aValue']);
103  }
104 
105  #[Test]
107  {
108  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('getParameters')
109  ->willReturn(['aField' => 'aValue']);
110  $this->subject->getParameters();
111  }
112 
113  #[Test]
115  {
116  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('getParameter')->with('aField')
117  ->willReturn('aValue');
118  $this->subject->getParameter('aField');
119  }
120 
121  #[Test]
123  {
124  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('getParameterTypes')->willReturn([]);
125  $this->subject->getParameterTypes();
126  }
127 
128  #[Test]
130  {
131  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('getParameterType')->with('aField')
132  ->willReturn(‪Connection::PARAM_STR);
133  $this->subject->getParameterType('aField');
134  }
135 
136  #[Test]
138  {
139  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('setFirstResult')->with(self::anything())
140  ->willReturn($this->subject);
141  $this->subject->setFirstResult(1);
142  }
143 
144  #[Test]
146  {
147  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('getFirstResult')->willReturn(1);
148  $this->subject->getFirstResult();
149  }
150 
151  #[Test]
153  {
154  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('setMaxResults')->with(self::anything())
155  ->willReturn($this->subject);
156  $this->subject->setMaxResults(1);
157  }
158 
159  #[Test]
161  {
162  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('getMaxResults')->willReturn(1);
163  $this->subject->getMaxResults();
164  }
165 
166  #[Test]
168  {
169  $this->connection->method('getDatabasePlatform')->willReturn(new ‪MockPlatform());
170  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('select')->with('COUNT(*)')
171  ->willReturn($this->subject);
172  $this->subject->count('*');
173  }
174 
175  #[Test]
177  {
178  $series = [
179  ['aField'],
180  ['anotherField'],
181  ];
182  $this->connection->expects(self::exactly(2))->method('quoteIdentifier')
183  ->willReturnCallback(function (string $field) use (&$series): string {
184  $arguments = array_shift($series);
185  self::assertSame($arguments[0], $field);
186  return $field;
187  });
188  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('select')->with('aField', 'anotherField')
189  ->willReturn($this->subject);
190  $this->subject->select('aField', 'anotherField');
191  }
192 
193  public static function ‪quoteIdentifiersForSelectDataProvider(): array
194  {
195  return [
196  'fieldName' => [
197  'fieldName',
198  '"fieldName"',
199  ],
200  'tableName.fieldName' => [
201  'tableName.fieldName',
202  '"tableName"."fieldName"',
203  ],
204  'tableName.*' => [
205  'tableName.*',
206  '"tableName".*',
207  ],
208  '*' => [
209  '*',
210  '*',
211  ],
212  'fieldName AS anotherFieldName' => [
213  'fieldName AS anotherFieldName',
214  '"fieldName" AS "anotherFieldName"',
215  ],
216  'tableName.fieldName AS anotherFieldName' => [
217  'tableName.fieldName AS anotherFieldName',
218  '"tableName"."fieldName" AS "anotherFieldName"',
219  ],
220  'tableName.fieldName AS anotherTable.anotherFieldName' => [
221  'tableName.fieldName AS anotherTable.anotherFieldName',
222  '"tableName"."fieldName" AS "anotherTable"."anotherFieldName"',
223  ],
224  'fieldName as anotherFieldName' => [
225  'fieldName as anotherFieldName',
226  '"fieldName" AS "anotherFieldName"',
227  ],
228  'tableName.fieldName as anotherFieldName' => [
229  'tableName.fieldName as anotherFieldName',
230  '"tableName"."fieldName" AS "anotherFieldName"',
231  ],
232  'tableName.fieldName as anotherTable.anotherFieldName' => [
233  'tableName.fieldName as anotherTable.anotherFieldName',
234  '"tableName"."fieldName" AS "anotherTable"."anotherFieldName"',
235  ],
236  'fieldName aS anotherFieldName' => [
237  'fieldName aS anotherFieldName',
238  '"fieldName" AS "anotherFieldName"',
239  ],
240  'tableName.fieldName aS anotherFieldName' => [
241  'tableName.fieldName aS anotherFieldName',
242  '"tableName"."fieldName" AS "anotherFieldName"',
243  ],
244  'tableName.fieldName aS anotherTable.anotherFieldName' => [
245  'tableName.fieldName aS anotherTable.anotherFieldName',
246  '"tableName"."fieldName" AS "anotherTable"."anotherFieldName"',
247  ],
248  ];
249  }
250 
251  #[DataProvider('quoteIdentifiersForSelectDataProvider')]
252  #[Test]
253  public function ‪quoteIdentifiersForSelect(string ‪$identifier, string $expectedResult): void
254  {
255  $this->connection->method('quoteIdentifier')->willReturnCallback(
256  static function (string ‪$identifier): string {
257  return (new ‪MockPlatform())->quoteIdentifier(‪$identifier);
258  }
259  );
260  self::assertSame([$expectedResult], $this->subject->quoteIdentifiersForSelect([‪$identifier]));
261  }
262 
263  #[Test]
265  {
266  $this->expectException(\InvalidArgumentException::class);
267  $this->expectExceptionCode(1461170686);
268  $this->connection->method('quoteIdentifier')->willReturnCallback(
269  static function (string ‪$identifier): string {
270  return (new ‪MockPlatform())->quoteIdentifier(‪$identifier);
271  }
272  );
273  $this->subject->quoteIdentifiersForSelect(['aField AS anotherField,someField AS someThing']);
274  }
275 
276  #[Test]
277  public function ‪selectDoesNotQuoteStarPlaceholder(): void
278  {
279  $this->connection->expects(self::never())->method('quoteIdentifier')->with('*');
280  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('select')->with('*')
281  ->willReturn($this->subject);
282  $this->subject->select('*');
283  }
284 
285  #[Test]
287  {
288  $series = [
289  ['aField'],
290  ['anotherField'],
291  ];
292  $this->connection->expects(self::exactly(2))->method('quoteIdentifier')
293  ->willReturnCallback(function (string $field) use (&$series): string {
294  $arguments = array_shift($series);
295  self::assertSame($arguments[0], $field);
296  return $field;
297  });
298  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('addSelect')->with('aField', 'anotherField')
299  ->willReturn($this->subject);
300  $this->subject->addSelect('aField', 'anotherField');
301  }
302 
303  #[Test]
305  {
306  $this->connection->expects(self::never())->method('quoteIdentifier')->with('*');
307  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('addSelect')->with('*')
308  ->willReturn($this->subject);
309  $this->subject->addSelect('*');
310  }
311 
312  #[Test]
314  {
315  $this->connection->expects(self::never())->method('quoteIdentifier')->with(self::anything());
316  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('select')->with('MAX(aField) AS anAlias')
317  ->willReturn($this->subject);
318  $this->subject->selectLiteral('MAX(aField) AS anAlias');
319  }
320 
321  #[Test]
323  {
324  $this->connection->expects(self::never())->method('quoteIdentifier')->with(self::anything());
325  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('addSelect')->with('MAX(aField) AS anAlias')
326  ->willReturn($this->subject);
327  $this->subject->addSelectLiteral('MAX(aField) AS anAlias');
328  }
329 
330  #[Test]
332  {
333  $this->connection->expects(self::atLeastOnce())->method('quoteIdentifier')->with('aTable')
334  ->willReturnArgument(0);
335  $this->concreteQueryBuilder->method('delete')->with('aTable')->willReturn($this->subject);
336  $this->subject->delete('aTable');
337  }
338 
339  #[Test]
341  {
342  $this->connection->expects(self::atLeastOnce())->method('quoteIdentifier')->with('aTable')
343  ->willReturnArgument(0);
344  $this->concreteQueryBuilder->method('update')->with('aTable')->willReturn($this->subject);
345  $this->subject->update('aTable');
346  }
347 
348  #[Test]
350  {
351  $this->connection->expects(self::atLeastOnce())->method('quoteIdentifier')->with('aTable')
352  ->willReturnArgument(0);
353  $this->concreteQueryBuilder->method('insert')->with('aTable')->willReturn($this->subject);
354  $this->subject->insert('aTable');
355  }
356 
360  #[Test]
362  {
363  $this->connection->expects(self::atLeastOnce())->method('quoteIdentifier')->with('aTable')
364  ->willReturnArgument(0);
365  $this->concreteQueryBuilder->method('from')->with('aTable', self::anything())->willReturn($this->subject);
366  $this->subject->from('aTable');
367  }
368 
369  #[Test]
371  {
372  $series = [
373  ['fromAlias'],
374  ['join'],
375  ['alias'],
376  ];
377  $this->connection->expects(self::exactly(3))->method('quoteIdentifier')
378  ->willReturnCallback(function (string $field) use (&$series): string {
379  $arguments = array_shift($series);
380  self::assertSame($arguments[0], $field);
381  return $field;
382  });
383  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('innerJoin')
384  ->with('fromAlias', 'join', 'alias', null)->willReturn($this->subject);
385  $this->subject->join('fromAlias', 'join', 'alias');
386  }
387 
388  #[Test]
390  {
391  $series = [
392  ['fromAlias'],
393  ['join'],
394  ['alias'],
395  ];
396  $this->connection->expects(self::exactly(3))->method('quoteIdentifier')
397  ->willReturnCallback(function (string $field) use (&$series): string {
398  $arguments = array_shift($series);
399  self::assertSame($arguments[0], $field);
400  return $field;
401  });
402  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('innerJoin')
403  ->with('fromAlias', 'join', 'alias', null)->willReturn($this->subject);
404  $this->subject->innerJoin('fromAlias', 'join', 'alias');
405  }
406 
407  #[Test]
409  {
410  $series = [
411  ['fromAlias'],
412  ['join'],
413  ['alias'],
414  ];
415  $this->connection->expects(self::exactly(3))->method('quoteIdentifier')
416  ->willReturnCallback(function (string $field) use (&$series): string {
417  $arguments = array_shift($series);
418  self::assertSame($arguments[0], $field);
419  return $field;
420  });
421  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('leftJoin')
422  ->with('fromAlias', 'join', 'alias', self::anything())->willReturn($this->subject);
423  $expressionBuilder = GeneralUtility::makeInstance(ExpressionBuilder::class, $this->connection);
424  $this->connection->method('getExpressionBuilder')->willReturn($expressionBuilder);
425  $this->subject->leftJoin('fromAlias', 'join', 'alias');
426  }
427 
428  #[Test]
430  {
431  $series = [
432  ['fromAlias'],
433  ['join'],
434  ['alias'],
435  ];
436  $this->connection->expects(self::exactly(3))->method('quoteIdentifier')
437  ->willReturnCallback(function (string $field) use (&$series): string {
438  $arguments = array_shift($series);
439  self::assertSame($arguments[0], $field);
440  return $field;
441  });
442  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('rightJoin')
443  ->with('fromAlias', 'join', 'alias', self::anything())->willReturn($this->subject);
444  // Set protected properties of the concrete QueryBuilder
445  $setParts = \Closure::bind(function (string $property, array $value) {
446  $this->{$property} = $value;
447  }, ‪$this->concreteQueryBuilder, ConcreteQueryBuilder::class);
448  $setParts->call($this->concreteQueryBuilder, 'from', []);
449  $expressionBuilder = GeneralUtility::makeInstance(ExpressionBuilder::class, $this->connection);
450  $this->connection->method('getExpressionBuilder')->willReturn($expressionBuilder);
451  $this->subject->rightJoin('fromAlias', 'join', 'alias');
452  }
453 
454  #[Test]
456  {
457  $this->connection->expects(self::atLeastOnce())->method('quoteIdentifier')->with('aField')
458  ->willReturnArgument(0);
459  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('createNamedParameter')
460  ->with('aValue', self::anything())->willReturn(':dcValue1');
461  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('set')->with('aField', ':dcValue1')
462  ->willReturn($this->subject);
463  $this->subject->set('aField', 'aValue');
464  }
465 
466  #[Test]
468  {
469  $this->connection->expects(self::atLeastOnce())->method('quoteIdentifier')->with('aField')
470  ->willReturnArgument(0);
471  $this->concreteQueryBuilder->expects(self::never())->method('createNamedParameter')->with(self::anything());
472  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('set')->with('aField', 'aValue')
473  ->willReturn($this->subject);
474  $this->subject->set('aField', 'aValue', false);
475  }
476 
477  #[Test]
479  {
480  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('where')->with('uid=1', 'type=9')
481  ->willReturn($this->subject);
482  $this->subject->where('uid=1', 'type=9');
483  }
484 
485  #[Test]
487  {
488  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('andWhere')->with('uid=1', 'type=9')
489  ->willReturn($this->subject);
490  $this->subject->andWhere('uid=1', 'type=9');
491  }
492 
493  #[Test]
495  {
496  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('orWhere')->with('uid=1', 'type=9')
497  ->willReturn($this->subject);
498  $this->subject->orWhere('uid=1', 'type=9');
499  }
500 
501  #[Test]
503  {
504  $this->connection->expects(self::atLeastOnce())->method('quoteIdentifiers')->with(['aField', 'anotherField'])
505  ->willReturnArgument(0);
506  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('groupBy')->with('aField', 'anotherField')
507  ->willReturn($this->subject);
508  $this->subject->groupBy('aField', 'anotherField');
509  }
510 
511  #[Test]
513  {
514  $this->connection->expects(self::atLeastOnce())->method('quoteIdentifiers')->with(['aField', 'anotherField'])
515  ->willReturnArgument(0);
516  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('addGroupBy')->with('aField', 'anotherField')
517  ->willReturn($this->subject);
518  $this->subject->addGroupBy('aField', 'anotherField');
519  }
520 
521  #[Test]
523  {
524  $this->connection->expects(self::atLeastOnce())->method('quoteIdentifier')->with('aField')
525  ->willReturnArgument(0);
526  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('createNamedParameter')
527  ->with('aValue', self::anything())->willReturn(':dcValue1');
528  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('setValue')->with('aField', ':dcValue1')
529  ->willReturn($this->subject);
530  $this->subject->setValue('aField', 'aValue');
531  }
532 
533  #[Test]
535  {
536  $this->connection->expects(self::atLeastOnce())->method('quoteIdentifier')->with('aField')
537  ->willReturnArgument(0);
538  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('setValue')->with('aField', 'aValue')
539  ->willReturn($this->subject);
540  $this->subject->setValue('aField', 'aValue', false);
541  }
542 
543  #[Test]
545  {
546  $this->connection->expects(self::atLeastOnce())->method('quoteColumnValuePairs')
547  ->with(['aField' => ':dcValue1', 'aValue' => ':dcValue2'])->willReturnArgument(0);
548  $series = [
549  [1, ':dcValue1'],
550  [2, ':dcValue2'],
551  ];
552  $this->concreteQueryBuilder->expects(self::exactly(2))->method('createNamedParameter')
553  ->willReturnCallback(function (int $value) use (&$series): string {
554  $arguments = array_shift($series);
555  self::assertSame($arguments[0], $value);
556  return $arguments[1];
557  });
558  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('values')
559  ->with(['aField' => ':dcValue1', 'aValue' => ':dcValue2'])->willReturn($this->subject);
560  $this->subject->values(['aField' => 1, 'aValue' => 2]);
561  }
562 
563  #[Test]
565  {
566  $this->connection->expects(self::atLeastOnce())->method('quoteColumnValuePairs')
567  ->with(['aField' => 1, 'aValue' => 2])->willReturnArgument(0);
568  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('values')
569  ->with(['aField' => 1, 'aValue' => 2])->willReturn($this->subject);
570  $this->subject->values(['aField' => 1, 'aValue' => 2], false);
571  }
572 
573  #[Test]
575  {
576  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('having')->with('uid=1', 'type=9')
577  ->willReturn($this->subject);
578  $this->subject->having('uid=1', 'type=9');
579  }
580 
581  #[Test]
583  {
584  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('andHaving')->with('uid=1', 'type=9')
585  ->willReturn($this->subject);
586  $this->subject->andHaving('uid=1', 'type=9');
587  }
588 
589  #[Test]
591  {
592  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('orHaving')->with('uid=1', 'type=9')
593  ->willReturn($this->subject);
594  $this->subject->orHaving('uid=1', 'type=9');
595  }
596 
597  #[Test]
599  {
600  $this->connection->expects(self::atLeastOnce())->method('quoteIdentifier')->with('aField')
601  ->willReturnArgument(0);
602  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('orderBy')->with('aField', null)
603  ->willReturn($this->subject);
604  $this->subject->orderBy('aField');
605  }
606 
607  #[Test]
609  {
610  $this->connection->expects(self::atLeastOnce())->method('quoteIdentifier')->with('aField')
611  ->willReturnArgument(0);
612  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('addOrderBy')->with('aField', 'DESC')
613  ->willReturn($this->subject);
614  $this->subject->addOrderBy('aField', 'DESC');
615  }
616 
617  #[Test]
619  {
620  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('createNamedParameter')
621  ->with(5, self::anything())->willReturn(':dcValue1');
622  $this->subject->createNamedParameter(5);
623  }
624 
625  #[Test]
627  {
628  $this->concreteQueryBuilder->expects(self::atLeastOnce())->method('createPositionalParameter')
629  ->with(5, self::anything())->willReturn('?');
630  $this->subject->createPositionalParameter(5);
631  }
632 
633  #[Test]
635  {
636  ‪$GLOBALS['TCA']['pages']['ctrl'] = [
637  'tstamp' => 'tstamp',
638  'versioningWS' => true,
639  'delete' => 'deleted',
640  'crdate' => 'crdate',
641  'enablecolumns' => [
642  'disabled' => 'hidden',
643  ],
644  ];
645 
646  $this->connection->method('getDatabasePlatform')->willReturn(new ‪MockPlatform());
647  $this->connection->method('quoteIdentifier')->with(self::anything())->willReturnArgument(0);
648  $this->connection->method('quoteIdentifiers')->with(self::anything())->willReturnArgument(0);
649 
650  $connectionBuilder = GeneralUtility::makeInstance(
651  ConcreteQueryBuilder::class,
652  $this->connection
653  );
654 
655  $expressionBuilder = GeneralUtility::makeInstance(ExpressionBuilder::class, $this->connection);
656  $this->connection->method('getExpressionBuilder')->willReturn($expressionBuilder);
657 
659  ‪$subject = GeneralUtility::makeInstance(
660  QueryBuilder::class,
661  $this->connection,
662  null,
663  $connectionBuilder,
664  null
665  );
666 
667  ‪$subject->select('*')
668  ->from('pages')
669  ->where('uid=1');
670 
671  $expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))';
672  $this->connection->method('executeQuery')->with($expectedSQL, self::anything(), self::anything(), self::anything())
673  ->willReturn($this->createMock(Result::class));
674 
675  ‪$subject->executeQuery();
676  }
677 
678  #[Test]
680  {
681  ‪$GLOBALS['TCA']['pages']['ctrl'] = [
682  'tstamp' => 'tstamp',
683  'versioningWS' => true,
684  'delete' => 'deleted',
685  'crdate' => 'crdate',
686  'enablecolumns' => [
687  'disabled' => 'hidden',
688  ],
689  ];
690 
691  $this->connection->method('getDatabasePlatform')->willReturn(new ‪MockPlatform());
692  $this->connection->method('quoteIdentifier')->with(self::anything())->willReturnArgument(0);
693  $this->connection->method('quoteIdentifiers')->with(self::anything())->willReturnArgument(0);
694 
695  $connectionBuilder = GeneralUtility::makeInstance(
696  ConcreteQueryBuilder::class,
697  $this->connection
698  );
699 
700  $expressionBuilder = GeneralUtility::makeInstance(ExpressionBuilder::class, $this->connection);
701  $this->connection->method('getExpressionBuilder')->willReturn($expressionBuilder);
702 
703  ‪$subject = GeneralUtility::makeInstance(
704  QueryBuilder::class,
705  $this->connection,
706  null,
707  $connectionBuilder
708  );
709 
710  ‪$subject->count('uid')
711  ->from('pages')
712  ->where('uid=1');
713 
714  $expectedSQL = 'SELECT COUNT(uid) FROM pages WHERE (uid=1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))';
715  $this->connection->method('executeQuery')->with($expectedSQL, self::anything())
716  ->willReturn($this->createMock(Result::class));
717 
718  ‪$subject->executeQuery();
719  }
720 
721  #[Test]
723  {
724  ‪$GLOBALS['TCA']['pages']['ctrl'] = [
725  'tstamp' => 'tstamp',
726  'versioningWS' => true,
727  'delete' => 'deleted',
728  'crdate' => 'crdate',
729  'enablecolumns' => [
730  'disabled' => 'hidden',
731  ],
732  ];
733 
734  $this->connection->method('getDatabasePlatform')->willReturn(new ‪MockPlatform());
735  $this->connection->method('quoteIdentifier')->with(self::anything())->willReturnArgument(0);
736  $this->connection->method('quoteIdentifiers')->with(self::anything())->willReturnArgument(0);
737  $this->connection->method('getExpressionBuilder')
738  ->willReturn(GeneralUtility::makeInstance(ExpressionBuilder::class, $this->connection));
739 
740  ‪$concreteQueryBuilder = GeneralUtility::makeInstance(
741  ConcreteQueryBuilder::class,
742  $this->connection
743  );
744 
745  ‪$subject = GeneralUtility::makeInstance(
746  QueryBuilder::class,
747  $this->connection,
748  null,
750  );
751 
752  ‪$subject->select('*')
753  ->from('pages')
754  ->where('uid=1');
755 
756  $expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))';
757  self::assertSame($expectedSQL, ‪$subject->getSQL());
758 
759  ‪$subject->getRestrictions()->removeAll()->add(new ‪DeletedRestriction());
760 
761  $expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND (pages.deleted = 0)';
762  self::assertSame($expectedSQL, ‪$subject->getSQL());
763  }
764 
765  #[Test]
767  {
768  ‪$GLOBALS['TCA']['pages']['ctrl'] = [
769  'tstamp' => 'tstamp',
770  'versioningWS' => true,
771  'delete' => 'deleted',
772  'crdate' => 'crdate',
773  'enablecolumns' => [
774  'disabled' => 'hidden',
775  ],
776  ];
777 
778  $this->connection->method('getDatabasePlatform')->willReturn(new ‪MockPlatform());
779  $this->connection->method('quoteIdentifier')->with(self::anything())->willReturnArgument(0);
780  $this->connection->method('quoteIdentifiers')->with(self::anything())->willReturnArgument(0);
781  $this->connection->method('getExpressionBuilder')
782  ->willReturn(GeneralUtility::makeInstance(ExpressionBuilder::class, $this->connection));
783 
784  ‪$concreteQueryBuilder = GeneralUtility::makeInstance(
785  ConcreteQueryBuilder::class,
786  $this->connection
787  );
788 
789  ‪$subject = GeneralUtility::makeInstance(
790  QueryBuilder::class,
791  $this->connection,
792  null,
794  );
795 
796  ‪$subject->select('*')
797  ->from('pages')
798  ->where('uid=1');
799 
800  ‪$subject->getRestrictions()->removeAll()->add(new ‪DeletedRestriction());
801 
802  $expectedSQLForQuery = 'SELECT * FROM pages WHERE (uid=1) AND (pages.deleted = 0)';
803  $expectedSQLForResetRestrictions = 'SELECT * FROM pages WHERE (uid=1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))';
804 
805  $series = [
806  [$expectedSQLForQuery, $this->createMock(Result::class)],
807  [$expectedSQLForResetRestrictions, $this->createMock(Result::class)],
808  ];
809  $this->connection->expects(self::exactly(2))->method('executeQuery')
810  ->willReturnCallback(function (string $sql) use (&$series): Result&MockObject {
811  $arguments = array_shift($series);
812  self::assertSame($arguments[0], $sql);
813  return $arguments[1];
814  });
815 
816  ‪$subject->executeQuery();
817  ‪$subject->resetRestrictions();
818 
819  ‪$subject->executeQuery();
820  }
821 
822  #[Test]
824  {
825  $this->connection->method('getDatabasePlatform')->willReturn(new ‪MockPlatform());
826  $from = [
827  new From(table: 'aTable'),
828  ];
829  $joins = [
830  'aTable' => [
831  Join::inner(
832  table: 'aTable',
833  alias: 'aTable_alias',
834  condition: null,
835  ),
836  ],
837  ];
838 
839  // Set protected properties of the concrete QueryBuilder
840  $setParts = \Closure::bind(function (string $property, array $value) {
841  $this->{$property} = $value;
842  }, ‪$this->concreteQueryBuilder, ConcreteQueryBuilder::class);
843  $setParts->call($this->concreteQueryBuilder, 'from', $from);
844  $setParts->call($this->concreteQueryBuilder, 'join', $joins);
845 
846  // Call a protected method
847  $result = \Closure::bind(function () {
848  return $this->getQueriedTables();
849  }, ‪$this->subject, QueryBuilder::class)();
850 
851  $expected = [
852  'aTable' => 'aTable',
853  'aTable_alias' => 'aTable',
854  ];
855  self::assertEquals($expected, $result);
856  }
857 
859  {
860  return [
861  'mysql' => [
862  'platform' => DoctrineMySQLPlatform::class,
863  'quoteChar' => '`',
864  'input' => '`anIdentifier`',
865  'expected' => 'anIdentifier',
866  ],
867  'mysql with spaces' => [
868  'platform' => DoctrineMySQLPlatform::class,
869  'quoteChar' => '`',
870  'input' => ' `anIdentifier` ',
871  'expected' => 'anIdentifier',
872  ],
873  'mariadb' => [
874  'platform' => DoctrineMariaDBPlatform::class,
875  'quoteChar' => '`',
876  'input' => '`anIdentifier`',
877  'expected' => 'anIdentifier',
878  ],
879  'mariadb with spaces' => [
880  'platform' => DoctrineMariaDBPlatform::class,
881  'quoteChar' => '`',
882  'input' => ' `anIdentifier` ',
883  'expected' => 'anIdentifier',
884  ],
885  'postgres' => [
886  'platform' => DoctrinePostgreSQLPlatform::class,
887  'quoteChar' => '"',
888  'input' => '"anIdentifier"',
889  'expected' => 'anIdentifier',
890  ],
891  'postgres with spaces ' => [
892  'platform' => DoctrinePostgreSQLPlatform::class,
893  'quoteChar' => '"',
894  'input' => ' "anIdentifier" ',
895  'expected' => 'anIdentifier',
896  ],
897  'sqlite' => [
898  'platform' => DoctrineSQLitePlatform::class,
899  'quoteChar' => '"',
900  'input' => '"anIdentifier"',
901  'expected' => 'anIdentifier',
902  ],
903  'sqlite with spaces' => [
904  'platform' => DoctrineSQLitePlatform::class,
905  'quoteChar' => '"',
906  'input' => ' "anIdentifier" ',
907  'expected' => 'anIdentifier',
908  ],
909  ];
910  }
911 
912  #[DataProvider('unquoteSingleIdentifierUnquotesCorrectlyOnDifferentPlatformsDataProvider')]
913  #[Test]
914  public function ‪unquoteSingleIdentifierUnquotesCorrectlyOnDifferentPlatforms(string $platform, string $quoteChar, string $input, string $expected): void
915  {
916  $connectionMock = $this->createMock(Connection::class);
917  $databasePlatformMock = $this->createMock($platform);
918  $databasePlatformMock->method('quoteSingleIdentifier')->willReturnCallback(static function (string $str) use ($quoteChar): string {
919  return $quoteChar . str_replace($quoteChar, $quoteChar . $quoteChar, $str) . $quoteChar;
920  });
921  $connectionMock->method('getDatabasePlatform')->willReturn($databasePlatformMock);
922  ‪$subject = $this->getAccessibleMock(QueryBuilder::class, null, [$connectionMock]);
923  $result = ‪$subject->_call('unquoteSingleIdentifier', $input);
924  self::assertEquals($expected, $result);
925  }
926 
927  #[Test]
929  {
930  $clonedQueryBuilder = clone ‪$this->subject;
931  self::assertNotSame($this->subject->getConcreteQueryBuilder(), $clonedQueryBuilder->getConcreteQueryBuilder());
932  }
933 
934  #[Test]
936  {
937  ‪$GLOBALS['TCA']['pages']['ctrl'] = [
938  'tstamp' => 'tstamp',
939  'versioningWS' => true,
940  'delete' => 'deleted',
941  'crdate' => 'crdate',
942  'enablecolumns' => [
943  'disabled' => 'hidden',
944  ],
945  ];
946 
947  $this->connection->method('getDatabasePlatform')->willReturn(new ‪MockPlatform());
948  $this->connection->method('quoteIdentifier')->with(self::anything())->willReturnArgument(0);
949  $this->connection->method('quoteIdentifiers')->with(self::anything())->willReturnArgument(0);
950  $this->connection->method('getExpressionBuilder')
951  ->willReturn(GeneralUtility::makeInstance(ExpressionBuilder::class, $this->connection));
952 
953  ‪$concreteQueryBuilder = GeneralUtility::makeInstance(
954  ConcreteQueryBuilder::class,
955  $this->connection
956  );
957 
958  ‪$subject = GeneralUtility::makeInstance(
959  QueryBuilder::class,
960  $this->connection,
961  null,
963  );
964 
965  ‪$subject->select('*')
966  ->from('pages')
967  ->where('uid=1');
968 
969  $expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))';
970  self::assertSame($expectedSQL, ‪$subject->getSQL());
971 
972  $clonedQueryBuilder = clone ‪$subject;
973  //just after cloning both query builders should return the same sql
974  self::assertSame($expectedSQL, $clonedQueryBuilder->getSQL());
975 
976  //change cloned QueryBuilder
977  $clonedQueryBuilder->count('*');
978  $expectedCountSQL = 'SELECT COUNT(*) FROM pages WHERE (uid=1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))';
979  self::assertSame($expectedCountSQL, $clonedQueryBuilder->getSQL());
980 
981  //check if the original QueryBuilder has not changed
982  self::assertSame($expectedSQL, ‪$subject->getSQL());
983 
984  //change restrictions in the original QueryBuilder and check if cloned has changed
985  ‪$subject->getRestrictions()->removeAll()->add(new ‪DeletedRestriction());
986  $expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND (pages.deleted = 0)';
987  self::assertSame($expectedSQL, ‪$subject->getSQL());
988 
989  self::assertSame($expectedCountSQL, $clonedQueryBuilder->getSQL());
990  }
991 
992  #[Test]
994  {
995  $restrictionClass = get_class($this->createMock(QueryRestrictionInterface::class));
996  $queryBuilder = new QueryBuilder(
997  $this->connection,
998  null,
999  $this->concreteQueryBuilder,
1000  [
1001  $restrictionClass => [],
1002  ]
1003  );
1004 
1005  $container = $this->createMock(AbstractRestrictionContainer::class);
1006  $container->expects(self::atLeastOnce())->method('add')->with(new $restrictionClass());
1007 
1008  $queryBuilder->setRestrictions($container);
1009  }
1010 
1011  #[Test]
1013  {
1014  $restrictionClass = get_class($this->createMock(QueryRestrictionInterface::class));
1015  ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['additionalQueryRestrictions'][$restrictionClass] = [];
1016  $queryBuilder = new QueryBuilder(
1017  $this->connection,
1018  null,
1019  $this->concreteQueryBuilder
1020  );
1021 
1022  $container = $this->createMock(AbstractRestrictionContainer::class);
1023  $container->expects(self::atLeastOnce())->method('add')->with(new $restrictionClass());
1024 
1025  $queryBuilder->setRestrictions($container);
1026  }
1027 
1028  #[Test]
1030  {
1031  $restrictionClass = get_class($this->createMock(QueryRestrictionInterface::class));
1032  ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['additionalQueryRestrictions'][$restrictionClass] = ['disabled' => true];
1033  $queryBuilder = new QueryBuilder(
1034  $this->connection,
1035  null,
1036  $this->concreteQueryBuilder
1037  );
1038 
1039  $container = $this->createMock(AbstractRestrictionContainer::class);
1040  $container->expects(self::never())->method('add')->with(new $restrictionClass());
1041 
1042  $queryBuilder->setRestrictions($container);
1043  }
1044 
1045  #[Test]
1047  {
1048  $restrictionClass = get_class($this->createMock(QueryRestrictionInterface::class));
1049  $queryBuilder = new QueryBuilder(
1050  $this->connection,
1051  null,
1052  $this->concreteQueryBuilder,
1053  [
1054  $restrictionClass => [],
1055  ]
1056  );
1057 
1058  $container = $this->createMock(DefaultRestrictionContainer::class);
1059  $container->expects(self::atLeastOnce())->method('add')->with(new $restrictionClass());
1060  GeneralUtility::addInstance(DefaultRestrictionContainer::class, $container);
1061 
1062  $queryBuilder->resetRestrictions();
1063  }
1064 
1068  #[DataProvider('createNamedParameterInput')]
1069  #[Test]
1070  public function ‪setWithNamedParameterPassesGivenTypeToCreateNamedParameter($input, string|ParameterType|Type|ArrayParameterType $type): void
1071  {
1072  $this->connection->method('quoteIdentifier')->with('aField')
1073  ->willReturnArgument(0);
1074  ‪$concreteQueryBuilder = new ‪ConcreteQueryBuilder($this->connection);
1075 
1076  ‪$subject = new QueryBuilder($this->connection, null, ‪$concreteQueryBuilder);
1077  ‪$subject->set('aField', $input, true, $type);
1078  self::assertSame($type, ‪$concreteQueryBuilder->getParameterType('dcValue1'));
1079  }
1080 
1081  public static function ‪createNamedParameterInput(): array
1082  {
1083  return [
1084  'string input and output' => [
1085  'aValue',
1087  ],
1088  'int input and string output' => [
1089  17,
1091  ],
1092  'int input and int output' => [
1093  17,
1095  ],
1096  'string input and array output' => [
1097  'aValue',
1099  ],
1100  ];
1101  }
1102 
1103  public static function ‪castFieldToTextTypeDataProvider(): array
1104  {
1105  return [
1106  'Test cast for MySQLPlatform' => [
1107  new DoctrineMySQLPlatform(),
1108  'CONVERT(aField, CHAR)',
1109  ],
1110  'Test cast for MariaDBPlatform' => [
1111  new DoctrineMariaDBPlatform(),
1112  'CONVERT(aField, CHAR)',
1113  ],
1114  'Test cast for PostgreSqlPlatform' => [
1115  new DoctrinePostgreSQLPlatform(),
1116  'aField::text',
1117  ],
1118  'Test cast for SqlitePlatform' => [
1119  new DoctrineSQLitePlatform(),
1120  'CAST(aField as TEXT)',
1121  ],
1122  ];
1123  }
1124 
1125  #[DataProvider('castFieldToTextTypeDataProvider')]
1126  #[Test]
1127  public function ‪castFieldToTextType(DoctrineAbstractPlatform $platform, string $expectation): void
1128  {
1129  $this->connection->expects(self::atLeastOnce())->method('quoteIdentifier')->with('aField')
1130  ->willReturnArgument(0);
1131 
1132  $this->connection->method('getDatabasePlatform')->willReturn($platform);
1133 
1134  ‪$concreteQueryBuilder = new ‪ConcreteQueryBuilder($this->connection);
1135 
1136  ‪$subject = new QueryBuilder($this->connection, null, ‪$concreteQueryBuilder);
1137  $result = ‪$subject->castFieldToTextType('aField');
1138 
1139  self::assertSame($expectation, $result);
1140  }
1141 
1142  #[Test]
1144  {
1145  ‪$GLOBALS['TCA']['tt_content']['ctrl'] = ‪$GLOBALS['TCA']['pages']['ctrl'] = [
1146  'delete' => 'deleted',
1147  'enablecolumns' => [
1148  'disabled' => 'hidden',
1149  ],
1150  ];
1151 
1152  $this->connection->method('getDatabasePlatform')->willReturn(new ‪MockPlatform());
1153  $this->connection->method('quoteIdentifier')->with(self::anything())->willReturnArgument(0);
1154  $this->connection->method('quoteIdentifiers')->with(self::anything())->willReturnArgument(0);
1155 
1156  $connectionBuilder = GeneralUtility::makeInstance(
1157  ConcreteQueryBuilder::class,
1158  $this->connection
1159  );
1160 
1161  $expressionBuilder = GeneralUtility::makeInstance(ExpressionBuilder::class, $this->connection);
1162  $this->connection->method('getExpressionBuilder')->willReturn($expressionBuilder);
1163 
1164  ‪$subject = new QueryBuilder(
1165  $this->connection,
1166  null,
1167  $connectionBuilder
1168  );
1169  ‪$subject->limitRestrictionsToTables(['pages']);
1170 
1171  ‪$subject->select('*')
1172  ->from('pages')
1173  ->leftJoin(
1174  'pages',
1175  'tt_content',
1176  'content',
1177  'pages.uid = content.pid'
1178  )
1179  ->where($expressionBuilder->eq('uid', 1));
1180 
1181  $this->connection->method('executeQuery')->with(
1182  'SELECT * FROM pages LEFT JOIN tt_content content ON pages.uid = content.pid WHERE (uid = 1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))',
1183  self::anything()
1184  )->willReturn($this->createMock(Result::class));
1185 
1186  ‪$subject->executeQuery();
1187  }
1188 
1189  #[Test]
1191  {
1192  ‪$GLOBALS['TCA']['tt_content']['ctrl'] = ‪$GLOBALS['TCA']['pages']['ctrl'] = [
1193  'delete' => 'deleted',
1194  'enablecolumns' => [
1195  'disabled' => 'hidden',
1196  ],
1197  ];
1198 
1199  $this->connection->method('getDatabasePlatform')->willReturn(new ‪MockPlatform());
1200  $this->connection->method('quoteIdentifier')->with(self::anything())->willReturnArgument(0);
1201  $this->connection->method('quoteIdentifiers')->with(self::anything())->willReturnArgument(0);
1202 
1203  $connectionBuilder = GeneralUtility::makeInstance(
1204  ConcreteQueryBuilder::class,
1205  $this->connection
1206  );
1207 
1208  $expressionBuilder = GeneralUtility::makeInstance(ExpressionBuilder::class, $this->connection);
1209  $this->connection->method('getExpressionBuilder')->willReturn($expressionBuilder);
1210 
1211  ‪$subject = new QueryBuilder(
1212  $this->connection,
1213  null,
1214  $connectionBuilder
1215  );
1216  ‪$subject->limitRestrictionsToTables(['pages']);
1217  ‪$subject->getRestrictions()->removeByType(DeletedRestriction::class);
1218 
1219  ‪$subject->select('*')
1220  ->from('pages')
1221  ->leftJoin(
1222  'pages',
1223  'tt_content',
1224  'content',
1225  'pages.uid = content.pid'
1226  )
1227  ->where($expressionBuilder->eq('uid', 1));
1228 
1229  $this->connection->method('executeQuery')->with(
1230  'SELECT * FROM pages LEFT JOIN tt_content content ON pages.uid = content.pid WHERE (uid = 1) AND (pages.hidden = 0)',
1231  self::anything()
1232  )->willReturn($this->createMock(Result::class));
1233 
1234  ‪$subject->executeQuery();
1235  }
1236 
1237  #[Test]
1239  {
1240  ‪$GLOBALS['TCA']['tt_content']['ctrl'] = ‪$GLOBALS['TCA']['pages']['ctrl'] = [
1241  'delete' => 'deleted',
1242  'enablecolumns' => [
1243  'disabled' => 'hidden',
1244  ],
1245  ];
1246 
1247  $this->connection->method('getDatabasePlatform')->willReturn(new ‪MockPlatform());
1248  $this->connection->method('quoteIdentifier')->with(self::anything())->willReturnArgument(0);
1249  $this->connection->method('quoteIdentifiers')->with(self::anything())->willReturnArgument(0);
1250 
1251  $connectionBuilder = GeneralUtility::makeInstance(
1252  ConcreteQueryBuilder::class,
1253  $this->connection
1254  );
1255 
1256  $expressionBuilder = GeneralUtility::makeInstance(ExpressionBuilder::class, $this->connection);
1257  $this->connection->method('getExpressionBuilder')->willReturn($expressionBuilder);
1258 
1259  ‪$subject = new QueryBuilder(
1260  $this->connection,
1261  null,
1262  $connectionBuilder
1263  );
1264 
1265  ‪$subject->select('*')
1266  ->from('pages')
1267  ->leftJoin(
1268  'pages',
1269  'tt_content',
1270  'content',
1271  'pages.uid = content.pid'
1272  )
1273  ->where($expressionBuilder->eq('uid', 1));
1274 
1275  $this->connection->method('executeQuery')->with(
1276  'SELECT * FROM pages LEFT JOIN tt_content content ON ((pages.uid = content.pid) AND (((content.deleted = 0) AND (content.hidden = 0)))) WHERE (uid = 1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))',
1277  self::anything()
1278  )->willReturn($this->createMock(Result::class));
1279 
1280  ‪$subject->executeQuery();
1281  }
1282 
1283  #[Test]
1285  {
1286  ‪$GLOBALS['TCA']['tt_content']['ctrl'] = ‪$GLOBALS['TCA']['pages']['ctrl'] = [
1287  'delete' => 'deleted',
1288  'enablecolumns' => [
1289  'disabled' => 'hidden',
1290  ],
1291  ];
1292 
1293  $this->connection->method('getDatabasePlatform')->willReturn(new ‪MockPlatform());
1294  $this->connection->method('quoteIdentifier')->with(self::anything())->willReturnArgument(0);
1295  $this->connection->method('quoteIdentifiers')->with(self::anything())->willReturnArgument(0);
1296 
1297  $connectionBuilder = GeneralUtility::makeInstance(
1298  ConcreteQueryBuilder::class,
1299  $this->connection
1300  );
1301 
1302  $expressionBuilder = GeneralUtility::makeInstance(ExpressionBuilder::class, $this->connection);
1303  $this->connection->method('getExpressionBuilder')->willReturn($expressionBuilder);
1304 
1305  ‪$subject = new QueryBuilder(
1306  $this->connection,
1307  null,
1308  $connectionBuilder
1309  );
1310 
1311  ‪$subject->select('*')
1312  ->from('tt_content')
1313  ->rightJoin(
1314  'tt_content',
1315  'pages',
1316  'pages',
1317  'pages.uid = tt_content.pid'
1318  )
1319  ->where($expressionBuilder->eq('uid', 1));
1320 
1321  $this->connection->method('executeQuery')->with(
1322  'SELECT * FROM tt_content RIGHT JOIN pages pages ON ((pages.uid = tt_content.pid) AND (((tt_content.deleted = 0) AND (tt_content.hidden = 0)))) WHERE (uid = 1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))',
1323  self::anything()
1324  )->willReturn($this->createMock(Result::class));
1325 
1326  ‪$subject->executeQuery();
1327  }
1328 }
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\$connection
‪Connection &MockObject $connection
Definition: QueryBuilderTest.php:49
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\queryRestrictionsAreAddedForCountOnExecuteQuery
‪queryRestrictionsAreAddedForCountOnExecuteQuery()
Definition: QueryBuilderTest.php:679
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\valuesQuotesIdentifiersAndDelegatesToConcreteQueryBuilder
‪valuesQuotesIdentifiersAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:544
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\havingDelegatesToConcreteQueryBuilder
‪havingDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:574
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:52
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder
Definition: ExpressionBuilder.php:40
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\queryRestrictionsAreReevaluatedOnSettingsChangeForGetSQL
‪queryRestrictionsAreReevaluatedOnSettingsChangeForGetSQL()
Definition: QueryBuilderTest.php:722
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\addOrderByQuotesIdentifierAndDelegatesToConcreteQueryBuilder
‪addOrderByQuotesIdentifierAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:608
‪TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionInterface
Definition: QueryRestrictionInterface.php:27
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\rightJoinQuotesIdentifiersAndDelegatesToConcreteQueryBuilder
‪rightJoinQuotesIdentifiersAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:429
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\quoteIdentifiersForSelectWithInvalidAlias
‪quoteIdentifiersForSelectWithInvalidAlias()
Definition: QueryBuilderTest.php:264
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\createNamedParameterDelegatesToConcreteQueryBuilder
‪createNamedParameterDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:618
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\castFieldToTextType
‪castFieldToTextType(DoctrineAbstractPlatform $platform, string $expectation)
Definition: QueryBuilderTest.php:1127
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\restrictionsCanStillBeRemovedAfterTheyHaveBeenLimitedToTables
‪restrictionsCanStillBeRemovedAfterTheyHaveBeenLimitedToTables()
Definition: QueryBuilderTest.php:1190
‪TYPO3\CMS\Core\Database\Query\ConcreteQueryBuilder
Definition: ConcreteQueryBuilder.php:41
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\createPositionalParameterDelegatesToConcreteQueryBuilder
‪createPositionalParameterDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:626
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\getMaxResultsDelegatesToConcreteQueryBuilder
‪getMaxResultsDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:160
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\settingRestrictionContainerWillAddAdditionalRestrictionsFromConfiguration
‪settingRestrictionContainerWillAddAdditionalRestrictionsFromConfiguration()
Definition: QueryBuilderTest.php:1012
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\resettingToDefaultRestrictionContainerWillAddAdditionalRestrictionsFromConfiguration
‪resettingToDefaultRestrictionContainerWillAddAdditionalRestrictionsFromConfiguration()
Definition: QueryBuilderTest.php:1046
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\getSQLDelegatesToConcreteQueryBuilder
‪getSQLDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:77
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\selectLiteralDirectlyDelegatesToConcreteQueryBuilder
‪selectLiteralDirectlyDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:313
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\updateQuotesIdentifierAndDelegatesToConcreteQueryBuilder
‪updateQuotesIdentifierAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:340
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\innerJoinQuotesIdentifiersAndDelegatesToConcreteQueryBuilder
‪innerJoinQuotesIdentifiersAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:389
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest
Definition: QueryBuilderTest.php:48
‪TYPO3\CMS\Core\Database\Connection\PARAM_STR
‪const PARAM_STR
Definition: Connection.php:57
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\exprReturnsExpressionBuilderForConnection
‪exprReturnsExpressionBuilderForConnection()
Definition: QueryBuilderTest.php:69
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\setMaxResultsDelegatesToConcreteQueryBuilder
‪setMaxResultsDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:152
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\setValueQuotesIdentifierAndDelegatesToConcreteQueryBuilder
‪setValueQuotesIdentifierAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:522
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\setValueWithoutNamedParameterQuotesIdentifierAndDelegatesToConcreteQueryBuilder
‪setValueWithoutNamedParameterQuotesIdentifierAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:534
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\setParametersDelegatesToConcreteQueryBuilder
‪setParametersDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:98
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\joinQuotesIdentifiersAndDelegatesToConcreteQueryBuilder
‪joinQuotesIdentifiersAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:370
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\queryRestrictionsAreAddedForSelectOnExecuteQuery
‪queryRestrictionsAreAddedForSelectOnExecuteQuery()
Definition: QueryBuilderTest.php:634
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\fromQuotesIdentifierAndDelegatesToConcreteQueryBuilder
‪fromQuotesIdentifierAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:361
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\settingRestrictionContainerWillAddAdditionalRestrictionsFromConstructor
‪settingRestrictionContainerWillAddAdditionalRestrictionsFromConstructor()
Definition: QueryBuilderTest.php:993
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\getQueriedTablesReturnsSameTableTwiceForInnerJoin
‪getQueriedTablesReturnsSameTableTwiceForInnerJoin()
Definition: QueryBuilderTest.php:823
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\unquoteSingleIdentifierUnquotesCorrectlyOnDifferentPlatforms
‪unquoteSingleIdentifierUnquotesCorrectlyOnDifferentPlatforms(string $platform, string $quoteChar, string $input, string $expected)
Definition: QueryBuilderTest.php:914
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\quoteIdentifiersForSelectDataProvider
‪static quoteIdentifiersForSelectDataProvider()
Definition: QueryBuilderTest.php:193
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\cloningQueryBuilderClonesConcreteQueryBuilder
‪cloningQueryBuilderClonesConcreteQueryBuilder()
Definition: QueryBuilderTest.php:928
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\setWithNamedParameterPassesGivenTypeToCreateNamedParameter
‪setWithNamedParameterPassesGivenTypeToCreateNamedParameter($input, string|ParameterType|Type|ArrayParameterType $type)
Definition: QueryBuilderTest.php:1070
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\addSelectLiteralDirectlyDelegatesToConcreteQueryBuilder
‪addSelectLiteralDirectlyDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:322
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\getParameterDelegatesToConcreteQueryBuilder
‪getParameterDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:114
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\restrictionsAreAppliedInJoinConditionForRightJoins
‪restrictionsAreAppliedInJoinConditionForRightJoins()
Definition: QueryBuilderTest.php:1284
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\castFieldToTextTypeDataProvider
‪static castFieldToTextTypeDataProvider()
Definition: QueryBuilderTest.php:1103
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\unquoteSingleIdentifierUnquotesCorrectlyOnDifferentPlatformsDataProvider
‪static unquoteSingleIdentifierUnquotesCorrectlyOnDifferentPlatformsDataProvider()
Definition: QueryBuilderTest.php:858
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\restrictionsAreAppliedInJoinConditionForLeftJoins
‪restrictionsAreAppliedInJoinConditionForLeftJoins()
Definition: QueryBuilderTest.php:1238
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\insertQuotesIdentifierAndDelegatesToConcreteQueryBuilder
‪insertQuotesIdentifierAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:349
‪TYPO3\CMS\Core\Database\Connection\PARAM_STR_ARRAY
‪const PARAM_STR_ARRAY
Definition: Connection.php:77
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\setUp
‪setUp()
Definition: QueryBuilderTest.php:56
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\settingRestrictionContainerWillNotAddAdditionalRestrictionsFromConfigurationIfNotDisabled
‪settingRestrictionContainerWillNotAddAdditionalRestrictionsFromConfigurationIfNotDisabled()
Definition: QueryBuilderTest.php:1029
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\getParameterTypeDelegatesToConcreteQueryBuilder
‪getParameterTypeDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:129
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\andWhereDelegatesToConcreteQueryBuilder
‪andWhereDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:486
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\orderByQuotesIdentifierAndDelegatesToConcreteQueryBuilder
‪orderByQuotesIdentifierAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:598
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\addSelectQuotesIdentifiersAndDelegatesToConcreteQueryBuilder
‪addSelectQuotesIdentifiersAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:286
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\addSelectDoesNotQuoteStarPlaceholder
‪addSelectDoesNotQuoteStarPlaceholder()
Definition: QueryBuilderTest.php:304
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\setParameterDelegatesToConcreteQueryBuilder
‪setParameterDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:90
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\orHavingDelegatesToConcreteQueryBuilder
‪orHavingDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:590
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\setFirstResultDelegatesToConcreteQueryBuilder
‪setFirstResultDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:137
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\selectDoesNotQuoteStarPlaceholder
‪selectDoesNotQuoteStarPlaceholder()
Definition: QueryBuilderTest.php:277
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:41
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\orWhereDelegatesToConcreteQueryBuilder
‪orWhereDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:494
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\changingClonedQueryBuilderDoesNotInfluenceSourceOne
‪changingClonedQueryBuilderDoesNotInfluenceSourceOne()
Definition: QueryBuilderTest.php:935
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\limitRestrictionsToTablesLimitsRestrictionsInTheContainerToTheGivenTables
‪limitRestrictionsToTablesLimitsRestrictionsInTheContainerToTheGivenTables()
Definition: QueryBuilderTest.php:1143
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\getFirstResultDelegatesToConcreteQueryBuilder
‪getFirstResultDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:145
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\groupByQuotesIdentifierAndDelegatesToConcreteQueryBuilder
‪groupByQuotesIdentifierAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:502
‪TYPO3\CMS\Core\Database\Query\Restriction\AbstractRestrictionContainer
Definition: AbstractRestrictionContainer.php:28
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\andHavingDelegatesToConcreteQueryBuilder
‪andHavingDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:582
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\$concreteQueryBuilder
‪ConcreteQueryBuilder &MockObject $concreteQueryBuilder
Definition: QueryBuilderTest.php:51
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:28
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\addGroupByQuotesIdentifierAndDelegatesToConcreteQueryBuilder
‪addGroupByQuotesIdentifierAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:512
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\createNamedParameterInput
‪static createNamedParameterInput()
Definition: QueryBuilderTest.php:1081
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\selectQuotesIdentifiersAndDelegatesToConcreteQueryBuilder
‪selectQuotesIdentifiersAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:176
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\deleteQuotesIdentifierAndDelegatesToConcreteQueryBuilder
‪deleteQuotesIdentifierAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:331
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\whereDelegatesToConcreteQueryBuilder
‪whereDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:478
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\countBuildsExpressionAndCallsSelect
‪countBuildsExpressionAndCallsSelect()
Definition: QueryBuilderTest.php:167
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\queryRestrictionsAreReevaluatedOnSettingsChangeForExecuteQuery
‪queryRestrictionsAreReevaluatedOnSettingsChangeForExecuteQuery()
Definition: QueryBuilderTest.php:766
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\leftJoinQuotesIdentifiersAndDelegatesToConcreteQueryBuilder
‪leftJoinQuotesIdentifiersAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:408
‪TYPO3\CMS\Core\Tests\Unit\Database\Query
Definition: BulkInsertTest.php:18
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\getParametersDelegatesToConcreteQueryBuilder
‪getParametersDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:106
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\$subject
‪QueryBuilder $subject
Definition: QueryBuilderTest.php:50
‪TYPO3\CMS\Core\Tests\Unit\Database\Mocks\MockPlatform\MockPlatform
Definition: MockPlatform.php:32
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\setWithoutNamedParameterQuotesIdentifierAndDelegatesToConcreteQueryBuilder
‪setWithoutNamedParameterQuotesIdentifierAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:467
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Core\Database\Query\Restriction\DefaultRestrictionContainer
Definition: DefaultRestrictionContainer.php:24
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\setQuotesIdentifierAndDelegatesToConcreteQueryBuilder
‪setQuotesIdentifierAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:455
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\quoteIdentifiersForSelect
‪quoteIdentifiersForSelect(string $identifier, string $expectedResult)
Definition: QueryBuilderTest.php:253
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\getParameterTypesDelegatesToConcreteQueryBuilder
‪getParameterTypesDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:122
‪TYPO3\CMS\Core\Tests\Unit\Database\Query\QueryBuilderTest\valuesWithoutNamedParametersQuotesIdentifiersAndDelegatesToConcreteQueryBuilder
‪valuesWithoutNamedParametersQuotesIdentifiersAndDelegatesToConcreteQueryBuilder()
Definition: QueryBuilderTest.php:564