Passed
Pull Request — master (#7305)
by COLE
11:41
created

QueryTest::testgetOneOrNullResult()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 14
nc 1
nop 0
dl 0
loc 20
rs 9.7998
c 0
b 0
f 0
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]);
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 = 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
        $found = [];
223
224
        foreach ($articles as $article) {
225
            $found[] = $article;
226
        }
227
228
        self::assertCount(1, $found);
229
        self::assertEquals(
230
            [
231
                [
232
                    [
233
                        'id'      => $articleId,
234
                        'topic'   => 'Doctrine 2',
235
                        'text'    => 'This is an introduction to Doctrine 2.',
236
                        'version' => 1,
237
                    ],
238
                ],
239
            ],
240
            $found
241
        );
242
    }
243
244
    public function testIterateResultIterativelyBuildUpUnitOfWork() : void
245
    {
246
        $article1        = new CmsArticle();
247
        $article1->topic = 'Doctrine 2';
248
        $article1->text  = 'This is an introduction to Doctrine 2.';
249
250
        $article2        = new CmsArticle();
251
        $article2->topic = 'Symfony 2';
252
        $article2->text  = 'This is an introduction to Symfony 2.';
253
254
        $this->em->persist($article1);
255
        $this->em->persist($article2);
256
257
        $this->em->flush();
258
        $this->em->clear();
259
260
        $query    = $this->em->createQuery('select a from ' . CmsArticle::class . ' a');
261
        $articles = $query->iterate();
262
263
        $iteratedCount = 0;
264
        $topics        = [];
265
266
        foreach ($articles as $row) {
267
            $article  = $row[0];
268
            $topics[] = $article->topic;
269
270
            $identityMap      = $this->em->getUnitOfWork()->getIdentityMap();
271
            $identityMapCount = count($identityMap[CmsArticle::class]);
272
            self::assertGreaterThan($iteratedCount, $identityMapCount);
273
274
            $iteratedCount++;
275
        }
276
277
        self::assertSame(['Doctrine 2', 'Symfony 2'], $topics);
278
        self::assertSame(2, $iteratedCount);
279
280
        $this->em->flush();
281
        $this->em->clear();
282
    }
283
284
    public function testIterateResultClearEveryCycle() : void
285
    {
286
        $article1        = new CmsArticle();
287
        $article1->topic = 'Doctrine 2';
288
        $article1->text  = 'This is an introduction to Doctrine 2.';
289
290
        $article2        = new CmsArticle();
291
        $article2->topic = 'Symfony 2';
292
        $article2->text  = 'This is an introduction to Symfony 2.';
293
294
        $this->em->persist($article1);
295
        $this->em->persist($article2);
296
297
        $this->em->flush();
298
        $this->em->clear();
299
300
        $query    = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a');
301
        $articles = $query->iterate();
302
303
        $iteratedCount = 0;
304
        $topics        = [];
305
        foreach ($articles as $row) {
306
            $article  = $row[0];
307
            $topics[] = $article->topic;
308
309
            $this->em->clear();
310
311
            $iteratedCount++;
312
        }
313
314
        self::assertSame(['Doctrine 2', 'Symfony 2'], $topics);
315
        self::assertSame(2, $iteratedCount);
316
317
        $this->em->flush();
318
    }
319
320
    /**
321
     * @expectedException \Doctrine\ORM\Query\QueryException
322
     */
323
    public function testIterateResultFetchJoinedCollectionThrowsException() : void
324
    {
325
        $query    = $this->em->createQuery("SELECT u, a FROM ' . CmsUser::class . ' u JOIN u.articles a");
326
        $articles = $query->iterate();
0 ignored issues
show
Unused Code introduced by
The assignment to $articles is dead and can be removed.
Loading history...
327
    }
328
329
    /**
330
     * @expectedException Doctrine\ORM\NoResultException
331
     */
332
    public function testGetSingleResultThrowsExceptionOnNoResult() : void
333
    {
334
        $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a')
335
             ->getSingleResult();
336
    }
337
338
    /**
339
     * @expectedException Doctrine\ORM\NoResultException
340
     */
341
    public function testGetSingleScalarResultThrowsExceptionOnNoResult() : void
342
    {
343
        $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a')
344
             ->getSingleScalarResult();
345
    }
346
347
    /**
348
     * @expectedException Doctrine\ORM\NonUniqueResultException
349
     */
350
    public function testGetSingleScalarResultThrowsExceptionOnNonUniqueResult() : void
351
    {
352
        $user           = new CmsUser();
353
        $user->name     = 'Guilherme';
354
        $user->username = 'gblanco';
355
        $user->status   = 'developer';
356
357
        $article1        = new CmsArticle();
358
        $article1->topic = 'Doctrine 2';
359
        $article1->text  = 'This is an introduction to Doctrine 2.';
360
        $user->addArticle($article1);
361
362
        $article2        = new CmsArticle();
363
        $article2->topic = 'Symfony 2';
364
        $article2->text  = 'This is an introduction to Symfony 2.';
365
        $user->addArticle($article2);
366
367
        $this->em->persist($user);
368
        $this->em->persist($article1);
369
        $this->em->persist($article2);
370
371
        $this->em->flush();
372
        $this->em->clear();
373
374
        $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a')
375
             ->getSingleScalarResult();
376
    }
377
378
    public function testModifiedLimitQuery() : void
379
    {
380
        for ($i = 0; $i < 5; $i++) {
381
            $user           = new CmsUser();
382
            $user->name     = 'Guilherme' . $i;
383
            $user->username = 'gblanco' . $i;
384
            $user->status   = 'developer';
385
            $this->em->persist($user);
386
        }
387
388
        $this->em->flush();
389
        $this->em->clear();
390
391
        $data = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u')
392
                  ->setFirstResult(1)
393
                  ->setMaxResults(2)
394
                  ->getResult();
395
396
        self::assertCount(2, $data);
397
        self::assertEquals('gblanco1', $data[0]->username);
398
        self::assertEquals('gblanco2', $data[1]->username);
399
400
        $data = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u')
401
                  ->setFirstResult(3)
402
                  ->setMaxResults(2)
403
                  ->getResult();
404
405
        self::assertCount(2, $data);
406
        self::assertEquals('gblanco3', $data[0]->username);
407
        self::assertEquals('gblanco4', $data[1]->username);
408
409
        $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...
410
                  ->setFirstResult(3)
411
                  ->setMaxResults(2)
412
                  ->getScalarResult();
413
    }
414
415
    /**
416
     * @group DDC-604
417
     */
418
    public function testEntityParameters() : void
419
    {
420
        $article          = new CmsArticle();
421
        $article->topic   = 'dr. dolittle';
422
        $article->text    = 'Once upon a time ...';
423
        $author           = new CmsUser();
424
        $author->name     = 'anonymous';
425
        $author->username = 'anon';
426
        $author->status   = 'here';
427
        $article->user    = $author;
428
        $this->em->persist($author);
429
        $this->em->persist($article);
430
        $this->em->flush();
431
        $this->em->clear();
432
433
        /** @var CmsArticle[] $result */
434
        $result = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a where a.topic = :topic and a.user = :user')
435
                ->setParameter('user', $this->em->getReference(CmsUser::class, $author->id))
436
                ->setParameter('topic', 'dr. dolittle')
437
                ->getResult();
438
439
        self::assertCount(1, $result);
440
        self::assertInstanceOf(CmsArticle::class, $result[0]);
441
        self::assertEquals('dr. dolittle', $result[0]->topic);
442
443
        /** @var CmsUser|GhostObjectInterface $user */
444
        $user = $result[0]->user;
445
446
        self::assertInstanceOf(CmsUser::class, $user);
447
        self::assertInstanceOf(GhostObjectInterface::class, $user);
448
        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

448
        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...
449
    }
450
451
    /**
452
     * @group DDC-952
453
     */
454
    public function testEnableFetchEagerMode() : void
455
    {
456
        for ($i = 0; $i < 10; $i++) {
457
            $article = new CmsArticle();
458
459
            $article->topic = 'dr. dolittle';
460
            $article->text  = 'Once upon a time ...';
461
462
            $author = new CmsUser();
463
464
            $author->name     = 'anonymous';
465
            $author->username = 'anon' . $i;
466
            $author->status   = 'here';
467
            $article->user    = $author;
468
469
            $this->em->persist($author);
470
            $this->em->persist($article);
471
        }
472
473
        $this->em->flush();
474
        $this->em->clear();
475
476
        $articles = $this->em
477
            ->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a')
478
            ->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

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