Failed Conditions
Pull Request — master (#7885)
by Šimon
06:26
created

testQueryBuilderWithStringWhereClauseContainingOrAndConditionalPrimary()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 0
dl 0
loc 12
rs 10
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]);
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')]),
243
            Query::HYDRATE_ARRAY
244
        );
245
246
        $found = [];
247
248
        foreach ($articles as $article) {
249
            $found[] = $article;
250
        }
251
252
        self::assertCount(1, $found);
253
        self::assertEquals(
254
            [$expectedArticle],
255
            $found
256
        );
257
    }
258
259
    public function testIterateResultIterativelyBuildUpUnitOfWork() : void
260
    {
261
        $article1        = new CmsArticle();
262
        $article1->topic = 'Doctrine 2';
263
        $article1->text  = 'This is an introduction to Doctrine 2.';
264
265
        $article2        = new CmsArticle();
266
        $article2->topic = 'Symfony 2';
267
        $article2->text  = 'This is an introduction to Symfony 2.';
268
269
        $this->em->persist($article1);
270
        $this->em->persist($article2);
271
272
        $this->em->flush();
273
        $this->em->clear();
274
275
        $query    = $this->em->createQuery('select a from ' . CmsArticle::class . ' a');
276
        $articles = $query->iterate();
277
278
        $iteratedCount = 0;
279
        $topics        = [];
280
281
        foreach ($articles as $row) {
282
            $article  = $row[0];
283
            $topics[] = $article->topic;
284
285
            $identityMap      = $this->em->getUnitOfWork()->getIdentityMap();
286
            $identityMapCount = count($identityMap[CmsArticle::class]);
287
            self::assertGreaterThan($iteratedCount, $identityMapCount);
288
289
            $iteratedCount++;
290
        }
291
292
        self::assertSame(['Doctrine 2', 'Symfony 2'], $topics);
293
        self::assertSame(2, $iteratedCount);
294
295
        $articles = $query->getIterable();
296
297
        $iteratedCount = 0;
298
        $topics        = [];
299
300
        foreach ($articles as $article) {
301
            $topics[] = $article->topic;
302
303
            $identityMap      = $this->em->getUnitOfWork()->getIdentityMap();
304
            $identityMapCount = count($identityMap[CmsArticle::class]);
305
            self::assertGreaterThan($iteratedCount, $identityMapCount);
306
307
            $iteratedCount++;
308
        }
309
310
        self::assertSame(['Doctrine 2', 'Symfony 2'], $topics);
311
        self::assertSame(2, $iteratedCount);
312
    }
313
314
    public function testIterateResultClearEveryCycle() : void
315
    {
316
        $article1        = new CmsArticle();
317
        $article1->topic = 'Doctrine 2';
318
        $article1->text  = 'This is an introduction to Doctrine 2.';
319
320
        $article2        = new CmsArticle();
321
        $article2->topic = 'Symfony 2';
322
        $article2->text  = 'This is an introduction to Symfony 2.';
323
324
        $this->em->persist($article1);
325
        $this->em->persist($article2);
326
327
        $this->em->flush();
328
        $this->em->clear();
329
330
        $query = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a');
331
332
        $articles      = $query->iterate();
333
        $iteratedCount = 0;
334
        $topics        = [];
335
        foreach ($articles as $row) {
336
            $article  = $row[0];
337
            $topics[] = $article->topic;
338
339
            $this->em->clear();
340
341
            $iteratedCount++;
342
        }
343
344
        self::assertSame(['Doctrine 2', 'Symfony 2'], $topics);
345
        self::assertSame(2, $iteratedCount);
346
347
        $articles      = $query->getIterable();
348
        $iteratedCount = 0;
349
        $topics        = [];
350
        foreach ($articles as $article) {
351
            $topics[] = $article->topic;
352
353
            $this->em->clear();
354
355
            $iteratedCount++;
356
        }
357
358
        self::assertSame(['Doctrine 2', 'Symfony 2'], $topics);
359
        self::assertSame(2, $iteratedCount);
360
361
        $this->em->flush();
362
    }
363
364
    public function testIterateResultFetchJoinedCollectionThrowsException() : void
365
    {
366
        $this->expectException(QueryException::class);
367
368
        $query = $this->em->createQuery("SELECT u, a FROM ' . CmsUser::class . ' u JOIN u.articles a");
369
        $query->iterate();
370
    }
371
372
    public function testGetIterableResultFetchJoinedCollectionThrowsException() : void
373
    {
374
        $this->expectException(QueryException::class);
375
376
        $query = $this->em->createQuery("SELECT u, a FROM ' . CmsUser::class . ' u JOIN u.articles a");
377
        $query->getIterable();
378
    }
379
380
    /**
381
     * @expectedException Doctrine\ORM\NoResultException
382
     */
383
    public function testGetSingleResultThrowsExceptionOnNoResult() : void
384
    {
385
        $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a')
386
             ->getSingleResult();
387
    }
388
389
    /**
390
     * @expectedException Doctrine\ORM\NoResultException
391
     */
392
    public function testGetSingleScalarResultThrowsExceptionOnNoResult() : void
393
    {
394
        $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a')
395
             ->getSingleScalarResult();
396
    }
397
398
    /**
399
     * @expectedException Doctrine\ORM\NonUniqueResultException
400
     */
401
    public function testGetSingleScalarResultThrowsExceptionOnNonUniqueResult() : void
402
    {
403
        $user           = new CmsUser();
404
        $user->name     = 'Guilherme';
405
        $user->username = 'gblanco';
406
        $user->status   = 'developer';
407
408
        $article1        = new CmsArticle();
409
        $article1->topic = 'Doctrine 2';
410
        $article1->text  = 'This is an introduction to Doctrine 2.';
411
        $user->addArticle($article1);
412
413
        $article2        = new CmsArticle();
414
        $article2->topic = 'Symfony 2';
415
        $article2->text  = 'This is an introduction to Symfony 2.';
416
        $user->addArticle($article2);
417
418
        $this->em->persist($user);
419
        $this->em->persist($article1);
420
        $this->em->persist($article2);
421
422
        $this->em->flush();
423
        $this->em->clear();
424
425
        $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a')
426
             ->getSingleScalarResult();
427
    }
428
429
    public function testModifiedLimitQuery() : void
430
    {
431
        for ($i = 0; $i < 5; $i++) {
432
            $user           = new CmsUser();
433
            $user->name     = 'Guilherme' . $i;
434
            $user->username = 'gblanco' . $i;
435
            $user->status   = 'developer';
436
            $this->em->persist($user);
437
        }
438
439
        $this->em->flush();
440
        $this->em->clear();
441
442
        $data = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u')
443
                  ->setFirstResult(1)
444
                  ->setMaxResults(2)
445
                  ->getResult();
446
447
        self::assertCount(2, $data);
448
        self::assertEquals('gblanco1', $data[0]->username);
449
        self::assertEquals('gblanco2', $data[1]->username);
450
451
        $data = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u')
452
                  ->setFirstResult(3)
453
                  ->setMaxResults(2)
454
                  ->getResult();
455
456
        self::assertCount(2, $data);
457
        self::assertEquals('gblanco3', $data[0]->username);
458
        self::assertEquals('gblanco4', $data[1]->username);
459
460
        $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...
461
                  ->setFirstResult(3)
462
                  ->setMaxResults(2)
463
                  ->getScalarResult();
464
    }
465
466
    /**
467
     * @group DDC-604
468
     */
469
    public function testEntityParameters() : void
470
    {
471
        $article          = new CmsArticle();
472
        $article->topic   = 'dr. dolittle';
473
        $article->text    = 'Once upon a time ...';
474
        $author           = new CmsUser();
475
        $author->name     = 'anonymous';
476
        $author->username = 'anon';
477
        $author->status   = 'here';
478
        $article->user    = $author;
479
        $this->em->persist($author);
480
        $this->em->persist($article);
481
        $this->em->flush();
482
        $this->em->clear();
483
484
        /** @var CmsArticle[] $result */
485
        $result = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a where a.topic = :topic and a.user = :user')
486
                ->setParameter('user', $this->em->getReference(CmsUser::class, $author->id))
487
                ->setParameter('topic', 'dr. dolittle')
488
                ->getResult();
489
490
        self::assertCount(1, $result);
491
        self::assertInstanceOf(CmsArticle::class, $result[0]);
492
        self::assertEquals('dr. dolittle', $result[0]->topic);
493
494
        /** @var CmsUser|GhostObjectInterface $user */
495
        $user = $result[0]->user;
496
497
        self::assertInstanceOf(CmsUser::class, $user);
498
        self::assertInstanceOf(GhostObjectInterface::class, $user);
499
        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

499
        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...
500
    }
501
502
    /**
503
     * @group DDC-952
504
     */
505
    public function testEnableFetchEagerMode() : void
506
    {
507
        for ($i = 0; $i < 10; $i++) {
508
            $article = new CmsArticle();
509
510
            $article->topic = 'dr. dolittle';
511
            $article->text  = 'Once upon a time ...';
512
513
            $author = new CmsUser();
514
515
            $author->name     = 'anonymous';
516
            $author->username = 'anon' . $i;
517
            $author->status   = 'here';
518
            $article->user    = $author;
519
520
            $this->em->persist($author);
521
            $this->em->persist($article);
522
        }
523
524
        $this->em->flush();
525
        $this->em->clear();
526
527
        $articles = $this->em
528
            ->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a')
529
            ->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

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