Failed Conditions
Pull Request — develop (#6935)
by Michael
65:23
created

testInvalidInputParameterThrowsException()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 5
nc 1
nop 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
20
/**
21
 * Functional Query tests.
22
 *
23
 * @author robo
24
 */
25
class QueryTest extends OrmFunctionalTestCase
26
{
27
    protected function setUp()
28
    {
29
        $this->useModelSet('cms');
30
31
        parent::setUp();
32
    }
33
34
    public function testSimpleQueries()
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()
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()
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 View Code Duplication
    public function testUsingUnknownQueryParameterShouldThrowException()
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
$user is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
133
    }
134
135 View Code Duplication
    public function testTooManyParametersShouldThrowException()
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
$user is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
145
    }
146
147
    public function testTooFewParametersShouldThrowException()
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()
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()
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()
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()
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 testIterateResult_IterativelyBuildUpUnitOfWork()
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()
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 testIterateResult_FetchJoinedCollection_ThrowsException()
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
$articles is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
327
    }
328
329
    /**
330
     * @expectedException Doctrine\ORM\NoResultException
331
     */
332
    public function testGetSingleResultThrowsExceptionOnNoResult()
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()
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()
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()
379
    {
380 View Code Duplication
        for ($i = 0; $i < 5; $i++) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
$data is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
410
                  ->setFirstResult(3)
411
                  ->setMaxResults(2)
412
                  ->getScalarResult();
413
    }
414
415
    /**
416
     * @group DDC-604
417
     */
418
    public function testEntityParameters()
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 $result CmsArticle[] */
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 $user CmsUser|GhostObjectInterface */
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 only exist in ProxyManager\Proxy\GhostObjectInterface, but not in Doctrine\Tests\Models\CMS\CmsUser.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
449
    }
450
451
    /**
452
     * @group DDC-952
453
     */
454
    public function testEnableFetchEagerMode()
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)
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()
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()
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
$fetchedUser is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
536
    }
537
538
    /**
539
     * @group DDC-991
540
     */
541
    public function testgetOneOrNullResultNoRows()
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()
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()
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()
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()
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()
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()
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()
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()
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
791
        $this->em->persist($u1);
792
        $this->em->persist($u2);
793
        $this->em->flush();
794
        $this->em->clear();
795
796
        try {
797
            $this->em->createQuery($dql)->getSingleResult();
798
            $this->fail('Expected exception "\Doctrine\ORM\NonUniqueResultException".');
799
        } catch (UnexpectedResultException $exc) {
800
            self::assertInstanceOf('\Doctrine\ORM\NonUniqueResultException', $exc);
801
        }
802
    }
803
804
    public function testMultipleJoinComponentsUsingInnerJoin()
805
    {
806
        $userA = new CmsUser;
807
        $userA->name = 'Benjamin';
808
        $userA->username = 'beberlei';
809
        $userA->status = 'developer';
810
811
        $phonenumberA = new CmsPhonenumber;
812
        $phonenumberA->phonenumber = '111111';
813
        $userA->addPhonenumber($phonenumberA);
814
815
        $userB = new CmsUser;
816
        $userB->name = 'Alexander';
817
        $userB->username = 'asm89';
818
        $userB->status = 'developer';
819
820
        $this->em->persist($userA);
821
        $this->em->persist($userB);
822
        $this->em->flush();
823
        $this->em->clear();
824
825
        $query = $this->em->createQuery("
826
            SELECT u, p
827
              FROM Doctrine\Tests\Models\CMS\CmsUser u
828
             INNER JOIN Doctrine\Tests\Models\CMS\CmsPhonenumber p WITH u = p.user
829
        ");
830
        $users = $query->execute();
831
832
        self::assertCount(2, $users);
833
        self::assertInstanceOf(CmsUser::class, $users[0]);
834
        self::assertInstanceOf(CmsPhonenumber::class, $users[1]);
835
    }
836
837
    public function testMultipleJoinComponentsUsingLeftJoin()
838
    {
839
        $userA = new CmsUser;
840
        $userA->name = 'Benjamin';
841
        $userA->username = 'beberlei';
842
        $userA->status = 'developer';
843
844
        $phonenumberA = new CmsPhonenumber;
845
        $phonenumberA->phonenumber = '111111';
846
        $userA->addPhonenumber($phonenumberA);
847
848
        $userB = new CmsUser;
849
        $userB->name = 'Alexander';
850
        $userB->username = 'asm89';
851
        $userB->status = 'developer';
852
853
        $this->em->persist($userA);
854
        $this->em->persist($userB);
855
        $this->em->flush();
856
        $this->em->clear();
857
858
        $query = $this->em->createQuery("
859
            SELECT u, p
860
              FROM Doctrine\Tests\Models\CMS\CmsUser u
861
              LEFT JOIN Doctrine\Tests\Models\CMS\CmsPhonenumber p WITH u = p.user
862
        ");
863
        $users = $query->execute();
864
865
        self::assertCount(4, $users);
866
        self::assertInstanceOf(CmsUser::class, $users[0]);
867
        self::assertInstanceOf(CmsPhonenumber::class, $users[1]);
868
        self::assertInstanceOf(CmsUser::class, $users[2]);
869
        self::assertNull($users[3]);
870
    }
871
}
872