Failed Conditions
Pull Request — master (#7885)
by Šimon
09:02
created

QueryTest   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 894
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 539
dl 0
loc 894
rs 8.8
c 0
b 0
f 0
wmc 45

34 Methods

Rating   Name   Duplication   Size   Complexity  
A testUsingZeroBasedQueryParameterShouldWork() 0 15 1
A testSetParametersBackwardsCompatible() 0 11 1
A testTooManyParametersShouldThrowException() 0 10 1
A setUp() 0 5 1
A testJoinQueries() 0 32 1
A testSetParameters() 0 17 1
A testTooFewParametersShouldThrowException() 0 7 1
A testSimpleQueries() 0 38 1
A testUsingUnknownQueryParameterShouldThrowException() 0 8 1
A testInvalidInputParameterThrowsException() 0 7 1
A testgetOneOrNullResultNoRows() 0 7 1
A testGetSingleResultThrowsExceptionOnNoResult() 0 4 1
A testSetCollectionParameterBindingSingleIdentifierObject() 0 45 1
A testQueryWithArrayOfEntitiesAsParameter() 0 30 1
A testIterateResultIterativelyBuildUpUnitOfWork() 0 53 3
A testGetSingleScalarResultThrowsExceptionOnNoResult() 0 4 1
A testgetOneOrNullResultSeveralRows() 0 20 1
A testEnableFetchEagerMode() 0 31 3
A testGetIterableResultFetchJoinedCollectionThrowsException() 0 6 1
A testModifiedLimitQuery() 0 35 2
A testQueryWithHiddenAsSelectExpression() 0 28 1
A testSetParameterBindingSingleIdentifierObject() 0 18 1
A testGetSingleScalarResultThrowsExceptionOnNonUniqueResult() 0 26 1
A testIterateResultAsArrayAndParams() 0 53 3
A testDqlWithAutoInferOfParameters() 0 29 1
A testIterateResultFetchJoinedCollectionThrowsException() 0 6 1
A testParameterOrder() 0 33 1
A testMultipleJoinComponentsUsingInnerJoin() 0 31 1
A testUnexpectedResultException() 0 29 3
A testIterateResultClearEveryCycle() 0 48 3
A testMultipleJoinComponentsUsingLeftJoin() 0 33 1
A testEntityParameters() 0 31 1
A testQueryBuilderWithStringWhereClauseContainingOrAndConditionalPrimary() 0 12 1
A testgetOneOrNullResult() 0 20 1

How to fix   Complexity   

Complex Class

Complex classes like QueryTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use QueryTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Functional;
6
7
use Doctrine\Common\Collections\ArrayCollection;
8
use Doctrine\ORM\Mapping\FetchMode;
9
use Doctrine\ORM\NonUniqueResultException;
10
use Doctrine\ORM\Query;
11
use Doctrine\ORM\Query\Parameter;
12
use Doctrine\ORM\Query\QueryException;
13
use Doctrine\ORM\UnexpectedResultException;
14
use Doctrine\Tests\Models\CMS\CmsArticle;
15
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
16
use Doctrine\Tests\Models\CMS\CmsUser;
17
use Doctrine\Tests\OrmFunctionalTestCase;
18
use ProxyManager\Proxy\GhostObjectInterface;
19
use function array_values;
20
use function count;
21
22
/**
23
 * Functional Query tests.
24
 */
25
class QueryTest extends OrmFunctionalTestCase
26
{
27
    protected function setUp() : void
28
    {
29
        $this->useModelSet('cms');
30
31
        parent::setUp();
32
    }
33
34
    public function testSimpleQueries() : void
35
    {
36
        $user           = new CmsUser();
37
        $user->name     = 'Guilherme';
38
        $user->username = 'gblanco';
39
        $user->status   = 'developer';
40
        $this->em->persist($user);
41
        $this->em->flush();
42
        $this->em->clear();
43
44
        $query = $this->em->createQuery("select u, upper(u.name) from Doctrine\Tests\Models\CMS\CmsUser u where u.username = 'gblanco'");
45
46
        $result = $query->getResult();
47
48
        self::assertCount(1, $result);
49
        self::assertInstanceOf(CmsUser::class, $result[0][0]);
50
        self::assertEquals('Guilherme', $result[0][0]->name);
51
        self::assertEquals('gblanco', $result[0][0]->username);
52
        self::assertEquals('developer', $result[0][0]->status);
53
        self::assertEquals('GUILHERME', $result[0][1]);
54
55
        $resultArray = $query->getArrayResult();
56
        self::assertCount(1, $resultArray);
57
        self::assertInternalType('array', $resultArray[0][0]);
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\Assert::assertInternalType() has been deprecated: https://github.com/sebastianbergmann/phpunit/issues/3369 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

57
        /** @scrutinizer ignore-deprecated */ self::assertInternalType('array', $resultArray[0][0]);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
58
        self::assertEquals('Guilherme', $resultArray[0][0]['name']);
59
        self::assertEquals('gblanco', $resultArray[0][0]['username']);
60
        self::assertEquals('developer', $resultArray[0][0]['status']);
61
        self::assertEquals('GUILHERME', $resultArray[0][1]);
62
63
        $scalarResult = $query->getScalarResult();
64
        self::assertCount(1, $scalarResult);
65
        self::assertEquals('Guilherme', $scalarResult[0]['u_name']);
66
        self::assertEquals('gblanco', $scalarResult[0]['u_username']);
67
        self::assertEquals('developer', $scalarResult[0]['u_status']);
68
        self::assertEquals('GUILHERME', $scalarResult[0][1]);
69
70
        $query = $this->em->createQuery("select upper(u.name) from Doctrine\Tests\Models\CMS\CmsUser u where u.username = 'gblanco'");
71
        self::assertEquals('GUILHERME', $query->getSingleScalarResult());
72
    }
73
74
    public function testJoinQueries() : void
75
    {
76
        $user           = new CmsUser();
77
        $user->name     = 'Guilherme';
78
        $user->username = 'gblanco';
79
        $user->status   = 'developer';
80
81
        $article1        = new CmsArticle();
82
        $article1->topic = 'Doctrine 2';
83
        $article1->text  = 'This is an introduction to Doctrine 2.';
84
        $user->addArticle($article1);
85
86
        $article2        = new CmsArticle();
87
        $article2->topic = 'Symfony 2';
88
        $article2->text  = 'This is an introduction to Symfony 2.';
89
        $user->addArticle($article2);
90
91
        $this->em->persist($user);
92
        $this->em->persist($article1);
93
        $this->em->persist($article2);
94
95
        $this->em->flush();
96
        $this->em->clear();
97
98
        $query = $this->em->createQuery('select u, a from ' . CmsUser::class . ' u join u.articles a ORDER BY a.topic');
99
        $users = $query->getResult();
100
101
        self::assertCount(1, $users);
102
        self::assertInstanceOf(CmsUser::class, $users[0]);
103
        self::assertCount(2, $users[0]->articles);
104
        self::assertEquals('Doctrine 2', $users[0]->articles[0]->topic);
105
        self::assertEquals('Symfony 2', $users[0]->articles[1]->topic);
106
    }
107
108
    public function testUsingZeroBasedQueryParameterShouldWork() : void
109
    {
110
        $user           = new CmsUser();
111
        $user->name     = 'Jonathan';
112
        $user->username = 'jwage';
113
        $user->status   = 'developer';
114
        $this->em->persist($user);
115
        $this->em->flush();
116
        $this->em->clear();
117
118
        $q = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u WHERE u.username = ?0');
119
        $q->setParameter(0, 'jwage');
120
        $user = $q->getSingleResult();
121
122
        self::assertNotNull($user);
123
    }
124
125
    public function testUsingUnknownQueryParameterShouldThrowException() : void
126
    {
127
        $this->expectException(QueryException::class);
128
        $this->expectExceptionMessage('Invalid parameter: token 2 is not defined in the query.');
129
130
        $q = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u WHERE u.name = ?1');
131
        $q->setParameter(2, 'jwage');
132
        $user = $q->getSingleResult();
0 ignored issues
show
Unused Code introduced by
The assignment to $user is dead and can be removed.
Loading history...
133
    }
134
135
    public function testTooManyParametersShouldThrowException() : void
136
    {
137
        $this->expectException(QueryException::class);
138
        $this->expectExceptionMessage('Too many parameters: the query defines 1 parameters and you bound 2');
139
140
        $q = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u WHERE u.name = ?1');
141
        $q->setParameter(1, 'jwage');
142
        $q->setParameter(2, 'jwage');
143
144
        $user = $q->getSingleResult();
0 ignored issues
show
Unused Code introduced by
The assignment to $user is dead and can be removed.
Loading history...
145
    }
146
147
    public function testTooFewParametersShouldThrowException() : void
148
    {
149
        $this->expectException(QueryException::class);
150
        $this->expectExceptionMessage('Too few parameters: the query defines 1 parameters but you only bound 0');
151
152
        $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u WHERE u.name = ?1')
153
                  ->getSingleResult();
154
    }
155
156
    public function testInvalidInputParameterThrowsException() : void
157
    {
158
        $this->expectException(QueryException::class);
159
160
        $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u WHERE u.name = ?')
161
                  ->setParameter(1, 'jwage')
162
                  ->getSingleResult();
163
    }
164
165
    public function testSetParameters() : void
166
    {
167
        $parameters = new ArrayCollection();
168
        $parameters->add(new Parameter(1, 'jwage'));
169
        $parameters->add(new Parameter(2, 'active'));
170
171
        $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u WHERE u.name = ?1 AND u.status = ?2')
172
                  ->setParameters($parameters)
173
                  ->getResult();
174
175
        $extractValue = static function (Parameter $parameter) {
176
            return $parameter->getValue();
177
        };
178
179
        self::assertSame(
180
            $parameters->map($extractValue)->toArray(),
181
            $this->sqlLoggerStack->queries[$this->sqlLoggerStack->currentQuery]['params']
182
        );
183
    }
184
185
    public function testSetParametersBackwardsCompatible() : void
186
    {
187
        $parameters = [1 => 'jwage', 2 => 'active'];
188
189
        $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u WHERE u.name = ?1 AND u.status = ?2')
190
                  ->setParameters($parameters)
191
                  ->getResult();
192
193
        self::assertSame(
194
            array_values($parameters),
195
            $this->sqlLoggerStack->queries[$this->sqlLoggerStack->currentQuery]['params']
196
        );
197
    }
198
199
    /**
200
     * @group DDC-1070
201
     */
202
    public function testIterateResultAsArrayAndParams() : void
203
    {
204
        $article1        = new CmsArticle();
205
        $article1->topic = 'Doctrine 2';
206
        $article1->text  = 'This is an introduction to Doctrine 2.';
207
208
        $article2        = new CmsArticle();
209
        $article2->topic = 'Symfony 2';
210
        $article2->text  = 'This is an introduction to Symfony 2.';
211
212
        $this->em->persist($article1);
213
        $this->em->persist($article2);
214
215
        $this->em->flush();
216
        $this->em->clear();
217
        $articleId = $article1->id;
218
219
        $query    = $this->em->createQuery('select a from ' . CmsArticle::class . ' a WHERE a.topic = ?1');
220
        $articles = $query->iterate(new ArrayCollection([new Parameter(1, 'Doctrine 2')]), Query::HYDRATE_ARRAY);
221
222
        $expectedArticle = [
223
            'id'      => $articleId,
224
            'topic'   => 'Doctrine 2',
225
            'text'    => 'This is an introduction to Doctrine 2.',
226
            'version' => 1,
227
        ];
228
229
        $found = [];
230
231
        foreach ($articles as $article) {
232
            $found[] = $article;
233
        }
234
235
        self::assertCount(1, $found);
236
        self::assertEquals(
237
            [[$expectedArticle]],
238
            $found
239
        );
240
241
        $articles = $query->getIterable(
242
            new ArrayCollection([new Parameter(1, 'Doctrine 2')]), Query::HYDRATE_ARRAY
243
        );
244
245
        $found = [];
246
247
        foreach ($articles as $article) {
248
            $found[] = $article;
249
        }
250
251
        self::assertCount(1, $found);
252
        self::assertEquals(
253
            [$expectedArticle],
254
            $found
255
        );
256
    }
257
258
    public function testIterateResultIterativelyBuildUpUnitOfWork() : void
259
    {
260
        $article1        = new CmsArticle();
261
        $article1->topic = 'Doctrine 2';
262
        $article1->text  = 'This is an introduction to Doctrine 2.';
263
264
        $article2        = new CmsArticle();
265
        $article2->topic = 'Symfony 2';
266
        $article2->text  = 'This is an introduction to Symfony 2.';
267
268
        $this->em->persist($article1);
269
        $this->em->persist($article2);
270
271
        $this->em->flush();
272
        $this->em->clear();
273
274
        $query    = $this->em->createQuery('select a from ' . CmsArticle::class . ' a');
275
        $articles = $query->iterate();
276
277
        $iteratedCount = 0;
278
        $topics        = [];
279
280
        foreach ($articles as $row) {
281
            $article  = $row[0];
282
            $topics[] = $article->topic;
283
284
            $identityMap      = $this->em->getUnitOfWork()->getIdentityMap();
285
            $identityMapCount = count($identityMap[CmsArticle::class]);
286
            self::assertGreaterThan($iteratedCount, $identityMapCount);
287
288
            $iteratedCount++;
289
        }
290
291
        self::assertSame(['Doctrine 2', 'Symfony 2'], $topics);
292
        self::assertSame(2, $iteratedCount);
293
294
        $articles = $query->getIterable();
295
296
        $iteratedCount = 0;
297
        $topics        = [];
298
299
        foreach ($articles as $article) {
300
            $topics[] = $article->topic;
301
302
            $identityMap      = $this->em->getUnitOfWork()->getIdentityMap();
303
            $identityMapCount = count($identityMap[CmsArticle::class]);
304
            self::assertGreaterThan($iteratedCount, $identityMapCount);
305
306
            $iteratedCount++;
307
        }
308
309
        self::assertSame(['Doctrine 2', 'Symfony 2'], $topics);
310
        self::assertSame(2, $iteratedCount);
311
    }
312
313
    public function testIterateResultClearEveryCycle() : void
314
    {
315
        $article1        = new CmsArticle();
316
        $article1->topic = 'Doctrine 2';
317
        $article1->text  = 'This is an introduction to Doctrine 2.';
318
319
        $article2        = new CmsArticle();
320
        $article2->topic = 'Symfony 2';
321
        $article2->text  = 'This is an introduction to Symfony 2.';
322
323
        $this->em->persist($article1);
324
        $this->em->persist($article2);
325
326
        $this->em->flush();
327
        $this->em->clear();
328
329
        $query = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a');
330
331
        $articles = $query->iterate();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
332
        $iteratedCount = 0;
333
        $topics        = [];
334
        foreach ($articles as $row) {
335
            $article  = $row[0];
336
            $topics[] = $article->topic;
337
338
            $this->em->clear();
339
340
            $iteratedCount++;
341
        }
342
343
        self::assertSame(['Doctrine 2', 'Symfony 2'], $topics);
344
        self::assertSame(2, $iteratedCount);
345
346
        $articles      = $query->getIterable();
347
        $iteratedCount = 0;
348
        $topics        = [];
349
        foreach ($articles as $article) {
350
            $topics[] = $article->topic;
351
352
            $this->em->clear();
353
354
            $iteratedCount++;
355
        }
356
357
        self::assertSame(['Doctrine 2', 'Symfony 2'], $topics);
358
        self::assertSame(2, $iteratedCount);
359
360
        $this->em->flush();
361
    }
362
363
    public function testIterateResultFetchJoinedCollectionThrowsException() : void
364
    {
365
        $this->expectException(QueryException::class);
366
367
        $query = $this->em->createQuery("SELECT u, a FROM ' . CmsUser::class . ' u JOIN u.articles a");
368
        $query->iterate();
369
    }
370
371
    public function testGetIterableResultFetchJoinedCollectionThrowsException() : void
372
    {
373
        $this->expectException(QueryException::class);
374
375
        $query = $this->em->createQuery("SELECT u, a FROM ' . CmsUser::class . ' u JOIN u.articles a");
376
        $query->getIterable();
377
    }
378
379
    /**
380
     * @expectedException Doctrine\ORM\NoResultException
381
     */
382
    public function testGetSingleResultThrowsExceptionOnNoResult() : void
383
    {
384
        $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a')
385
             ->getSingleResult();
386
    }
387
388
    /**
389
     * @expectedException Doctrine\ORM\NoResultException
390
     */
391
    public function testGetSingleScalarResultThrowsExceptionOnNoResult() : void
392
    {
393
        $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a')
394
             ->getSingleScalarResult();
395
    }
396
397
    /**
398
     * @expectedException Doctrine\ORM\NonUniqueResultException
399
     */
400
    public function testGetSingleScalarResultThrowsExceptionOnNonUniqueResult() : void
401
    {
402
        $user           = new CmsUser();
403
        $user->name     = 'Guilherme';
404
        $user->username = 'gblanco';
405
        $user->status   = 'developer';
406
407
        $article1        = new CmsArticle();
408
        $article1->topic = 'Doctrine 2';
409
        $article1->text  = 'This is an introduction to Doctrine 2.';
410
        $user->addArticle($article1);
411
412
        $article2        = new CmsArticle();
413
        $article2->topic = 'Symfony 2';
414
        $article2->text  = 'This is an introduction to Symfony 2.';
415
        $user->addArticle($article2);
416
417
        $this->em->persist($user);
418
        $this->em->persist($article1);
419
        $this->em->persist($article2);
420
421
        $this->em->flush();
422
        $this->em->clear();
423
424
        $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a')
425
             ->getSingleScalarResult();
426
    }
427
428
    public function testModifiedLimitQuery() : void
429
    {
430
        for ($i = 0; $i < 5; $i++) {
431
            $user           = new CmsUser();
432
            $user->name     = 'Guilherme' . $i;
433
            $user->username = 'gblanco' . $i;
434
            $user->status   = 'developer';
435
            $this->em->persist($user);
436
        }
437
438
        $this->em->flush();
439
        $this->em->clear();
440
441
        $data = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u')
442
                  ->setFirstResult(1)
443
                  ->setMaxResults(2)
444
                  ->getResult();
445
446
        self::assertCount(2, $data);
447
        self::assertEquals('gblanco1', $data[0]->username);
448
        self::assertEquals('gblanco2', $data[1]->username);
449
450
        $data = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u')
451
                  ->setFirstResult(3)
452
                  ->setMaxResults(2)
453
                  ->getResult();
454
455
        self::assertCount(2, $data);
456
        self::assertEquals('gblanco3', $data[0]->username);
457
        self::assertEquals('gblanco4', $data[1]->username);
458
459
        $data = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u')
0 ignored issues
show
Unused Code introduced by
The assignment to $data is dead and can be removed.
Loading history...
460
                  ->setFirstResult(3)
461
                  ->setMaxResults(2)
462
                  ->getScalarResult();
463
    }
464
465
    /**
466
     * @group DDC-604
467
     */
468
    public function testEntityParameters() : void
469
    {
470
        $article          = new CmsArticle();
471
        $article->topic   = 'dr. dolittle';
472
        $article->text    = 'Once upon a time ...';
473
        $author           = new CmsUser();
474
        $author->name     = 'anonymous';
475
        $author->username = 'anon';
476
        $author->status   = 'here';
477
        $article->user    = $author;
478
        $this->em->persist($author);
479
        $this->em->persist($article);
480
        $this->em->flush();
481
        $this->em->clear();
482
483
        /** @var CmsArticle[] $result */
484
        $result = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a where a.topic = :topic and a.user = :user')
485
                ->setParameter('user', $this->em->getReference(CmsUser::class, $author->id))
486
                ->setParameter('topic', 'dr. dolittle')
487
                ->getResult();
488
489
        self::assertCount(1, $result);
490
        self::assertInstanceOf(CmsArticle::class, $result[0]);
491
        self::assertEquals('dr. dolittle', $result[0]->topic);
492
493
        /** @var CmsUser|GhostObjectInterface $user */
494
        $user = $result[0]->user;
495
496
        self::assertInstanceOf(CmsUser::class, $user);
497
        self::assertInstanceOf(GhostObjectInterface::class, $user);
498
        self::assertFalse($user->isProxyInitialized());
0 ignored issues
show
Bug introduced by
The method isProxyInitialized() does not exist on Doctrine\Tests\Models\CMS\CmsUser. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

498
        self::assertFalse($user->/** @scrutinizer ignore-call */ isProxyInitialized());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
499
    }
500
501
    /**
502
     * @group DDC-952
503
     */
504
    public function testEnableFetchEagerMode() : void
505
    {
506
        for ($i = 0; $i < 10; $i++) {
507
            $article = new CmsArticle();
508
509
            $article->topic = 'dr. dolittle';
510
            $article->text  = 'Once upon a time ...';
511
512
            $author = new CmsUser();
513
514
            $author->name     = 'anonymous';
515
            $author->username = 'anon' . $i;
516
            $author->status   = 'here';
517
            $article->user    = $author;
518
519
            $this->em->persist($author);
520
            $this->em->persist($article);
521
        }
522
523
        $this->em->flush();
524
        $this->em->clear();
525
526
        $articles = $this->em
527
            ->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a')
528
            ->setFetchMode(CmsArticle::class, 'user', FetchMode::EAGER)
0 ignored issues
show
Bug introduced by
Doctrine\ORM\Mapping\FetchMode::EAGER of type string is incompatible with the type integer expected by parameter $fetchMode of Doctrine\ORM\AbstractQuery::setFetchMode(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

528
            ->setFetchMode(CmsArticle::class, 'user', /** @scrutinizer ignore-type */ FetchMode::EAGER)
Loading history...
529
            ->getResult();
530
531
        self::assertCount(10, $articles);
532
533
        foreach ($articles as $article) {
534
            self::assertNotInstanceOf(GhostObjectInterface::class, $article);
535
        }
536
    }
537
538
    /**
539
     * @group DDC-991
540
     */
541
    public function testgetOneOrNullResult() : void
542
    {
543
        $user           = new CmsUser();
544
        $user->name     = 'Guilherme';
545
        $user->username = 'gblanco';
546
        $user->status   = 'developer';
547
        $this->em->persist($user);
548
        $this->em->flush();
549
        $this->em->clear();
550
551
        $query       = $this->em->createQuery('select u from ' . CmsUser::class . " u where u.username = 'gblanco'");
552
        $fetchedUser = $query->getOneOrNullResult();
553
554
        self::assertInstanceOf(CmsUser::class, $fetchedUser);
555
        self::assertEquals('gblanco', $fetchedUser->username);
556
557
        $query           = $this->em->createQuery('select u.username from ' . CmsUser::class . " u where u.username = 'gblanco'");
558
        $fetchedUsername = $query->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR);
559
560
        self::assertEquals('gblanco', $fetchedUsername);
561
    }
562
563
    /**
564
     * @group DDC-991
565
     */
566
    public function testgetOneOrNullResultSeveralRows() : void
567
    {
568
        $user           = new CmsUser();
569
        $user->name     = 'Guilherme';
570
        $user->username = 'gblanco';
571
        $user->status   = 'developer';
572
        $this->em->persist($user);
573
        $user           = new CmsUser();
574
        $user->name     = 'Roman';
575
        $user->username = 'romanb';
576
        $user->status   = 'developer';
577
        $this->em->persist($user);
578
        $this->em->flush();
579
        $this->em->clear();
580
581
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u');
582
583
        $this->expectException(NonUniqueResultException::class);
584
585
        $fetchedUser = $query->getOneOrNullResult();
0 ignored issues
show
Unused Code introduced by
The assignment to $fetchedUser is dead and can be removed.
Loading history...
586
    }
587
588
    /**
589
     * @group DDC-991
590
     */
591
    public function testgetOneOrNullResultNoRows() : void
592
    {
593
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u');
594
        self::assertNull($query->getOneOrNullResult());
595
596
        $query = $this->em->createQuery("select u.username from Doctrine\Tests\Models\CMS\CmsUser u where u.username = 'gblanco'");
597
        self::assertNull($query->getOneOrNullResult(Query::HYDRATE_SCALAR));
598
    }
599
600
    /**
601
     * @group DBAL-171
602
     */
603
    public function testParameterOrder() : void
604
    {
605
        $user1           = new CmsUser();
606
        $user1->name     = 'Benjamin';
607
        $user1->username = 'beberlei';
608
        $user1->status   = 'developer';
609
        $this->em->persist($user1);
610
611
        $user2           = new CmsUser();
612
        $user2->name     = 'Roman';
613
        $user2->username = 'romanb';
614
        $user2->status   = 'developer';
615
        $this->em->persist($user2);
616
617
        $user3           = new CmsUser();
618
        $user3->name     = 'Jonathan';
619
        $user3->username = 'jwage';
620
        $user3->status   = 'developer';
621
        $this->em->persist($user3);
622
623
        $this->em->flush();
624
        $this->em->clear();
625
626
        $query = $this->em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.status = :a AND u.id IN (:b)');
627
        $query->setParameters(new ArrayCollection(
628
            [
629
                new Parameter('b', [$user1->id, $user2->id, $user3->id]),
630
                new Parameter('a', 'developer'),
631
            ]
632
        ));
633
        $result = $query->getResult();
634
635
        self::assertCount(3, $result);
636
    }
637
638
    public function testDqlWithAutoInferOfParameters() : void
639
    {
640
        $user           = new CmsUser();
641
        $user->name     = 'Benjamin';
642
        $user->username = 'beberlei';
643
        $user->status   = 'developer';
644
        $this->em->persist($user);
645
646
        $user           = new CmsUser();
647
        $user->name     = 'Roman';
648
        $user->username = 'romanb';
649
        $user->status   = 'developer';
650
        $this->em->persist($user);
651
652
        $user           = new CmsUser();
653
        $user->name     = 'Jonathan';
654
        $user->username = 'jwage';
655
        $user->status   = 'developer';
656
        $this->em->persist($user);
657
658
        $this->em->flush();
659
        $this->em->clear();
660
661
        $query = $this->em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username IN (?0)');
662
        $query->setParameter(0, ['beberlei', 'jwage']);
663
664
        $users = $query->execute();
665
666
        self::assertCount(2, $users);
667
    }
668
669
    public function testQueryBuilderWithStringWhereClauseContainingOrAndConditionalPrimary() : void
670
    {
671
        $qb = $this->em->createQueryBuilder();
672
        $qb->select('u')
673
           ->from(CmsUser::class, 'u')
674
           ->innerJoin('u.articles', 'a')
675
           ->where('(u.id = 0) OR (u.id IS NULL)');
676
677
        $query = $qb->getQuery();
678
        $users = $query->execute();
679
680
        self::assertCount(0, $users);
681
    }
682
683
    public function testQueryWithArrayOfEntitiesAsParameter() : void
684
    {
685
        $userA           = new CmsUser();
686
        $userA->name     = 'Benjamin';
687
        $userA->username = 'beberlei';
688
        $userA->status   = 'developer';
689
        $this->em->persist($userA);
690
691
        $userB           = new CmsUser();
692
        $userB->name     = 'Roman';
693
        $userB->username = 'romanb';
694
        $userB->status   = 'developer';
695
        $this->em->persist($userB);
696
697
        $userC           = new CmsUser();
698
        $userC->name     = 'Jonathan';
699
        $userC->username = 'jwage';
700
        $userC->status   = 'developer';
701
        $this->em->persist($userC);
702
703
        $this->em->flush();
704
        $this->em->clear();
705
706
        $query = $this->em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u IN (?0) OR u.username = ?1');
707
        $query->setParameter(0, [$userA, $userC]);
708
        $query->setParameter(1, 'beberlei');
709
710
        $users = $query->execute();
711
712
        self::assertCount(2, $users);
713
    }
714
715
    public function testQueryWithHiddenAsSelectExpression() : void
716
    {
717
        $userA           = new CmsUser();
718
        $userA->name     = 'Benjamin';
719
        $userA->username = 'beberlei';
720
        $userA->status   = 'developer';
721
        $this->em->persist($userA);
722
723
        $userB           = new CmsUser();
724
        $userB->name     = 'Roman';
725
        $userB->username = 'romanb';
726
        $userB->status   = 'developer';
727
        $this->em->persist($userB);
728
729
        $userC           = new CmsUser();
730
        $userC->name     = 'Jonathan';
731
        $userC->username = 'jwage';
732
        $userC->status   = 'developer';
733
        $this->em->persist($userC);
734
735
        $this->em->flush();
736
        $this->em->clear();
737
738
        $query = $this->em->createQuery('SELECT u, (SELECT COUNT(u2.id) FROM Doctrine\Tests\Models\CMS\CmsUser u2) AS HIDDEN total FROM Doctrine\Tests\Models\CMS\CmsUser u');
739
        $users = $query->execute();
740
741
        self::assertCount(3, $users);
742
        self::assertInstanceOf(CmsUser::class, $users[0]);
743
    }
744
745
    /**
746
     * @group DDC-1651
747
     */
748
    public function testSetParameterBindingSingleIdentifierObject() : void
749
    {
750
        $userC           = new CmsUser();
751
        $userC->name     = 'Jonathan';
752
        $userC->username = 'jwage';
753
        $userC->status   = 'developer';
754
        $this->em->persist($userC);
755
756
        $this->em->flush();
757
        $this->em->clear();
758
759
        $q = $this->em->createQuery('SELECT DISTINCT u from Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1');
760
        $q->setParameter(1, $userC);
761
762
        self::assertEquals($userC, $q->getParameter(1)->getValue());
763
764
        // Parameter is not converted before, but it should be converted during execution. Test should not fail here
765
        $q->getResult();
766
    }
767
768
    /**
769
     * @group DDC-2319
770
     */
771
    public function testSetCollectionParameterBindingSingleIdentifierObject() : void
772
    {
773
        $u1           = new CmsUser();
774
        $u1->name     = 'Name1';
775
        $u1->username = 'username1';
776
        $u1->status   = 'developer';
777
        $this->em->persist($u1);
778
779
        $u2           = new CmsUser();
780
        $u2->name     = 'Name2';
781
        $u2->username = 'username2';
782
        $u2->status   = 'tester';
783
        $this->em->persist($u2);
784
785
        $u3           = new CmsUser();
786
        $u3->name     = 'Name3';
787
        $u3->username = 'username3';
788
        $u3->status   = 'tester';
789
        $this->em->persist($u3);
790
791
        $this->em->flush();
792
        $this->em->clear();
793
794
        $userCollection = new ArrayCollection();
795
796
        $userCollection->add($u1);
797
        $userCollection->add($u2);
798
        $userCollection->add($u3->getId());
799
800
        $q = $this->em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u IN (:users) ORDER BY u.id');
801
        $q->setParameter('users', $userCollection);
802
        $users = $q->execute();
803
804
        self::assertCount(3, $users);
805
        self::assertInstanceOf(CmsUser::class, $users[0]);
806
        self::assertInstanceOf(CmsUser::class, $users[1]);
807
        self::assertInstanceOf(CmsUser::class, $users[2]);
808
809
        $resultUser1 = $users[0];
810
        $resultUser2 = $users[1];
811
        $resultUser3 = $users[2];
812
813
        self::assertEquals($u1->username, $resultUser1->username);
814
        self::assertEquals($u2->username, $resultUser2->username);
815
        self::assertEquals($u3->username, $resultUser3->username);
816
    }
817
818
    /**
819
     * @group DDC-1822
820
     */
821
    public function testUnexpectedResultException() : void
822
    {
823
        $dql          = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u';
824
        $u1           = new CmsUser();
825
        $u2           = new CmsUser();
826
        $u1->name     = 'Fabio B. Silva';
827
        $u1->username = 'FabioBatSilva';
828
        $u1->status   = 'developer';
829
        $u2->name     = 'Test';
830
        $u2->username = 'test';
831
        $u2->status   = 'tester';
832
833
        try {
834
            $this->em->createQuery($dql)->getSingleResult();
835
            $this->fail('Expected exception "\Doctrine\ORM\NoResultException".');
836
        } catch (UnexpectedResultException $exc) {
837
            self::assertInstanceOf('\Doctrine\ORM\NoResultException', $exc);
838
        }
839
840
        $this->em->persist($u1);
841
        $this->em->persist($u2);
842
        $this->em->flush();
843
        $this->em->clear();
844
845
        try {
846
            $this->em->createQuery($dql)->getSingleResult();
847
            $this->fail('Expected exception "\Doctrine\ORM\NonUniqueResultException".');
848
        } catch (UnexpectedResultException $exc) {
849
            self::assertInstanceOf('\Doctrine\ORM\NonUniqueResultException', $exc);
850
        }
851
    }
852
853
    public function testMultipleJoinComponentsUsingInnerJoin() : void
854
    {
855
        $userA           = new CmsUser();
856
        $userA->name     = 'Benjamin';
857
        $userA->username = 'beberlei';
858
        $userA->status   = 'developer';
859
860
        $phonenumberA              = new CmsPhonenumber();
861
        $phonenumberA->phonenumber = '111111';
862
        $userA->addPhonenumber($phonenumberA);
863
864
        $userB           = new CmsUser();
865
        $userB->name     = 'Alexander';
866
        $userB->username = 'asm89';
867
        $userB->status   = 'developer';
868
869
        $this->em->persist($userA);
870
        $this->em->persist($userB);
871
        $this->em->flush();
872
        $this->em->clear();
873
874
        $query = $this->em->createQuery('
875
            SELECT u, p
876
              FROM Doctrine\Tests\Models\CMS\CmsUser u
877
             INNER JOIN Doctrine\Tests\Models\CMS\CmsPhonenumber p WITH u = p.user
878
        ');
879
        $users = $query->execute();
880
881
        self::assertCount(2, $users);
882
        self::assertInstanceOf(CmsUser::class, $users[0]);
883
        self::assertInstanceOf(CmsPhonenumber::class, $users[1]);
884
    }
885
886
    public function testMultipleJoinComponentsUsingLeftJoin() : void
887
    {
888
        $userA           = new CmsUser();
889
        $userA->name     = 'Benjamin';
890
        $userA->username = 'beberlei';
891
        $userA->status   = 'developer';
892
893
        $phonenumberA              = new CmsPhonenumber();
894
        $phonenumberA->phonenumber = '111111';
895
        $userA->addPhonenumber($phonenumberA);
896
897
        $userB           = new CmsUser();
898
        $userB->name     = 'Alexander';
899
        $userB->username = 'asm89';
900
        $userB->status   = 'developer';
901
902
        $this->em->persist($userA);
903
        $this->em->persist($userB);
904
        $this->em->flush();
905
        $this->em->clear();
906
907
        $query = $this->em->createQuery('
908
            SELECT u, p
909
              FROM Doctrine\Tests\Models\CMS\CmsUser u
910
              LEFT JOIN Doctrine\Tests\Models\CMS\CmsPhonenumber p WITH u = p.user
911
        ');
912
        $users = $query->execute();
913
914
        self::assertCount(4, $users);
915
        self::assertInstanceOf(CmsUser::class, $users[0]);
916
        self::assertInstanceOf(CmsPhonenumber::class, $users[1]);
917
        self::assertInstanceOf(CmsUser::class, $users[2]);
918
        self::assertNull($users[3]);
919
    }
920
}
921