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

QueryTest::testProcessParameterValueObject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 1
b 0
f 0
nop 0
dl 0
loc 9
rs 10
nc 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Query;
6
7
use DateTime;
8
use Doctrine\Common\Cache\ArrayCache;
9
use Doctrine\Common\Collections\ArrayCollection;
10
use Doctrine\DBAL\ParameterType;
11
use Doctrine\DBAL\Types\Type;
12
use Doctrine\ORM\Internal\Hydration\IterableResult;
13
use Doctrine\ORM\Query\Parameter;
14
use Doctrine\ORM\Query\QueryException;
15
use Doctrine\ORM\UnitOfWork;
16
use Doctrine\Tests\Mocks\DriverConnectionMock;
17
use Doctrine\Tests\Mocks\EntityManagerMock;
18
use Doctrine\Tests\Mocks\StatementArrayMock;
19
use Doctrine\Tests\Models\CMS\CmsAddress;
20
use Doctrine\Tests\Models\CMS\CmsUser;
21
use Doctrine\Tests\Models\Generic\DateTimeModel;
22
use Doctrine\Tests\OrmTestCase;
23
24
class QueryTest extends OrmTestCase
25
{
26
    /** @var EntityManagerMock */
27
    protected $em;
28
29
    protected function setUp() : void
30
    {
31
        $this->em = $this->getTestEntityManager();
32
    }
33
34
    public function testGetParameters() : void
35
    {
36
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1');
37
38
        $parameters = new ArrayCollection();
39
40
        self::assertEquals($parameters, $query->getParameters());
41
    }
42
43
    public function testGetParametersHasSomeAlready() : void
44
    {
45
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1');
46
        $query->setParameter(2, 84);
47
48
        $parameters = new ArrayCollection();
49
        $parameters->add(new Parameter(2, 84));
50
51
        self::assertEquals($parameters, $query->getParameters());
52
    }
53
54
    public function testSetParameters() : void
55
    {
56
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1');
57
58
        $parameters = new ArrayCollection();
59
        $parameters->add(new Parameter(1, 'foo'));
60
        $parameters->add(new Parameter(2, 'bar'));
61
62
        $query->setParameters($parameters);
63
64
        self::assertEquals($parameters, $query->getParameters());
65
    }
66
67
    public function testFree() : void
68
    {
69
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1');
70
        $query->setParameter(2, 84, ParameterType::INTEGER);
71
72
        $query->free();
73
74
        self::assertCount(0, $query->getParameters());
75
    }
76
77
    public function testClone() : void
78
    {
79
        $dql = 'select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = ?1';
80
81
        $query = $this->em->createQuery($dql);
82
        $query->setParameter(2, 84, ParameterType::INTEGER);
83
        $query->setHint('foo', 'bar');
84
85
        $cloned = clone $query;
86
87
        self::assertEquals($dql, $cloned->getDQL());
88
        self::assertCount(0, $cloned->getParameters());
89
        self::assertFalse($cloned->getHint('foo'));
90
    }
91
92
    public function testFluentQueryInterface() : void
93
    {
94
        $q  = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a');
95
        $q2 = $q->expireQueryCache(true)
96
          ->setQueryCacheLifetime(3600)
97
          ->setQueryCacheDriver(null)
98
          ->expireResultCache(true)
99
          ->setHint('foo', 'bar')
100
          ->setHint('bar', 'baz')
101
          ->setParameter(1, 'bar')
102
          ->setParameters(new ArrayCollection([new Parameter(2, 'baz')]))
103
          ->setResultCacheDriver(null)
104
          ->setResultCacheId('foo')
105
          ->setDQL('foo')
106
          ->setFirstResult(10)
107
          ->setMaxResults(10);
108
109
        self::assertSame($q2, $q);
110
    }
111
112
    /**
113
     * @group DDC-968
114
     */
115
    public function testHints() : void
116
    {
117
        $q = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a');
118
        $q->setHint('foo', 'bar')->setHint('bar', 'baz');
119
120
        self::assertEquals('bar', $q->getHint('foo'));
121
        self::assertEquals('baz', $q->getHint('bar'));
122
        self::assertEquals(['foo' => 'bar', 'bar' => 'baz'], $q->getHints());
123
        self::assertTrue($q->hasHint('foo'));
124
        self::assertFalse($q->hasHint('barFooBaz'));
125
    }
126
127
    /**
128
     * @group DDC-1588
129
     */
130
    public function testQueryDefaultResultCache() : void
131
    {
132
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
133
        $q = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a');
134
        $q->useResultCache(true);
135
        self::assertSame($this->em->getConfiguration()->getResultCacheImpl(), $q->getQueryCacheProfile()->getResultCacheDriver());
136
    }
137
138
    public function testIterateWithNoDistinctAndWrongSelectClause() : void
139
    {
140
        $this->expectException(QueryException::class);
141
142
        $q = $this->em->createQuery('select u, a from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
143
        $q->iterate();
144
    }
145
146
    public function testGetIterableWithNoDistinctAndWrongSelectClause() : void
147
    {
148
        $this->expectException(QueryException::class);
149
150
        $q = $this->em->createQuery('select u, a from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
151
        $q->getIterable();
152
    }
153
154
    public function testIterateWithNoDistinctAndWithValidSelectClause() : void
155
    {
156
        $this->expectException(QueryException::class);
157
158
        $q = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
159
        $q->iterate();
160
    }
161
162
    public function testGetIterableWithNoDistinctAndWithValidSelectClause() : void
163
    {
164
        $this->expectException(QueryException::class);
165
166
        $q = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
167
        $q->getIterable();
168
    }
169
170
    public function testIterateWithDistinct() : void
171
    {
172
        $q = $this->em->createQuery('SELECT DISTINCT u from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a');
173
174
        self::assertInstanceOf(IterableResult::class, $q->iterate());
175
    }
176
177
    public function testIterateEmptyResult() : void
178
    {
179
        $q = $this->em->createQuery('SELECT u from Doctrine\Tests\Models\CMS\CmsUser u');
180
181
        // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedForeach
182
        foreach ($q->getIterable() as $item) {
183
        }
184
185
        self::assertTrue(true);
186
    }
187
188
    /**
189
     * @group DDC-1697
190
     */
191
    public function testCollectionParameters() : void
192
    {
193
        $cities = [
194
            0 => 'Paris',
195
            3 => 'Canne',
196
            9 => 'St Julien',
197
        ];
198
199
        $query = $this->em
200
                ->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.city IN (:cities)')
201
                ->setParameter('cities', $cities);
202
203
        $parameters = $query->getParameters();
204
        $parameter  = $parameters->first();
205
206
        self::assertEquals('cities', $parameter->getName());
207
        self::assertEquals($cities, $parameter->getValue());
208
    }
209
210
    /**
211
     * @group DDC-2224
212
     */
213
    public function testProcessParameterValueClassMetadata() : void
214
    {
215
        $query = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.city IN (:cities)');
216
        self::assertEquals(
217
            CmsAddress::class,
218
            $query->processParameterValue($this->em->getClassMetadata(CmsAddress::class))
219
        );
220
    }
221
222
    public function testProcessParameterValueObject() : void
223
    {
224
        $query    = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user = :user');
225
        $user     = new CmsUser();
226
        $user->id = 12345;
227
228
        self::assertSame(
229
            12345,
230
            $query->processParameterValue($user)
231
        );
232
    }
233
234
    public function testProcessParameterValueNull() : void
235
    {
236
        $query = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user = :user');
237
238
        self::assertNull($query->processParameterValue(null));
239
    }
240
241
    public function testDefaultQueryHints() : void
242
    {
243
        $config       = $this->em->getConfiguration();
244
        $defaultHints = [
245
            'hint_name_1' => 'hint_value_1',
246
            'hint_name_2' => 'hint_value_2',
247
            'hint_name_3' => 'hint_value_3',
248
        ];
249
250
        $config->setDefaultQueryHints($defaultHints);
251
        $query = $this->em->createQuery();
252
        self::assertSame($config->getDefaultQueryHints(), $query->getHints());
253
        $this->em->getConfiguration()->setDefaultQueryHint('hint_name_1', 'hint_another_value_1');
254
        self::assertNotSame($config->getDefaultQueryHints(), $query->getHints());
255
        $q2 = clone $query;
256
        self::assertSame($config->getDefaultQueryHints(), $q2->getHints());
257
    }
258
259
    /**
260
     * @group DDC-3714
261
     */
262
    public function testResultCacheCaching() : void
263
    {
264
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
265
        $this->em->getConfiguration()->setQueryCacheImpl(new ArrayCache());
266
        /** @var DriverConnectionMock $driverConnectionMock */
267
        $driverConnectionMock = $this->em->getConnection()->getWrappedConnection();
268
        $stmt                 = new StatementArrayMock([
269
            ['c0' => 1],
270
        ]);
271
        $driverConnectionMock->setStatementMock($stmt);
272
        $res = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u')
273
            ->useQueryCache(true)
274
            ->useResultCache(true, 60)
275
            //let it cache
276
            ->getResult();
277
278
        self::assertCount(1, $res);
279
280
        $driverConnectionMock->setStatementMock(null);
281
282
        $res = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u')
283
            ->useQueryCache(true)
284
            ->useResultCache(false)
285
            ->getResult();
286
        self::assertCount(0, $res);
287
    }
288
289
    /**
290
     * @group DDC-3741
291
     */
292
    public function testSetHydrationCacheProfileNull() : void
293
    {
294
        $query = $this->em->createQuery();
295
        $query->setHydrationCacheProfile(null);
296
297
        self::assertNull($query->getHydrationCacheProfile());
298
    }
299
300
    /**
301
     * @group 2947
302
     */
303
    public function testResultCacheEviction() : void
304
    {
305
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
306
307
        $query = $this->em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
308
                          ->useResultCache(true);
309
310
        /** @var DriverConnectionMock $driverConnectionMock */
311
        $driverConnectionMock = $this->em->getConnection()
312
            ->getWrappedConnection();
313
314
        // Performs the query and sets up the initial cache
315
        self::assertCount(0, $query->getResult());
316
317
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1]]));
318
319
        // Performs the query and sets up the initial cache
320
        self::assertCount(1, $query->expireResultCache(true)->getResult());
321
322
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1], ['c0' => 2]]));
323
324
        // Retrieves cached data since expire flag is false and we have a cached result set
325
        self::assertCount(1, $query->expireResultCache(false)->getResult());
326
327
        // Performs the query and caches the result set since expire flag is true
328
        self::assertCount(2, $query->expireResultCache(true)->getResult());
329
330
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1]]));
331
332
        // Retrieves cached data since expire flag is false and we have a cached result set
333
        self::assertCount(2, $query->expireResultCache(false)->getResult());
334
    }
335
336
    /**
337
     * @group #6162
338
     */
339
    public function testSelectJoinSubquery() : void
340
    {
341
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u JOIN (SELECT )');
342
343
        $this->expectException(QueryException::class);
344
        $this->expectExceptionMessage('Subquery');
345
        $query->getSQL();
346
    }
347
348
    /**
349
     * @group #6162
350
     */
351
    public function testSelectFromSubquery() : void
352
    {
353
        $query = $this->em->createQuery('select u from (select Doctrine\Tests\Models\CMS\CmsUser c) as u');
354
355
        $this->expectException(QueryException::class);
356
        $this->expectExceptionMessage('Subquery');
357
        $query->getSQL();
358
    }
359
360
    /**
361
     * @group 6699
362
     */
363
    public function testGetParameterTypeJuggling() : void
364
    {
365
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id = ?0');
366
367
        $query->setParameter(0, 0);
368
369
        self::assertCount(1, $query->getParameters());
370
        self::assertSame(0, $query->getParameter(0)->getValue());
371
        self::assertSame(0, $query->getParameter('0')->getValue());
372
    }
373
374
    /**
375
     * @group 6699
376
     */
377
    public function testSetParameterWithNameZeroIsNotOverridden() : void
378
    {
379
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
380
381
        $query->setParameter(0, 0);
382
        $query->setParameter('name', 'Doctrine');
383
384
        self::assertCount(2, $query->getParameters());
385
        self::assertSame(0, $query->getParameter('0')->getValue());
386
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
387
    }
388
389
    /**
390
     * @group 6699
391
     */
392
    public function testSetParameterWithNameZeroDoesNotOverrideAnotherParameter() : void
393
    {
394
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
395
396
        $query->setParameter('name', 'Doctrine');
397
        $query->setParameter(0, 0);
398
399
        self::assertCount(2, $query->getParameters());
400
        self::assertSame(0, $query->getParameter(0)->getValue());
401
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
402
    }
403
404
    /**
405
     * @group 6699
406
     */
407
    public function testSetParameterWithTypeJugglingWorks() : void
408
    {
409
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
410
411
        $query->setParameter('0', 1);
412
        $query->setParameter('name', 'Doctrine');
413
        $query->setParameter(0, 2);
414
        $query->setParameter('0', 3);
415
416
        self::assertCount(2, $query->getParameters());
417
        self::assertSame(3, $query->getParameter(0)->getValue());
418
        self::assertSame(3, $query->getParameter('0')->getValue());
419
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
420
    }
421
422
    /**
423
     * @group 6748
424
     */
425
    public function testResultCacheProfileCanBeRemovedViaSetter() : void
426
    {
427
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
428
429
        $query = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u');
430
        $query->useResultCache(true);
431
        $query->setResultCacheProfile();
432
433
        self::assertAttributeSame(null, 'queryCacheProfile', $query);
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\Assert::assertAttributeSame() has been deprecated: https://github.com/sebastianbergmann/phpunit/issues/3338 ( Ignorable by Annotation )

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

433
        /** @scrutinizer ignore-deprecated */ self::assertAttributeSame(null, 'queryCacheProfile', $query);

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...
434
    }
435
436
    /** @group 7527 */
437
    public function testValuesAreNotBeingResolvedForSpecifiedParameterTypes() : void
438
    {
439
        $unitOfWork = $this->createMock(UnitOfWork::class);
440
441
        $this->em->setUnitOfWork($unitOfWork);
442
443
        $unitOfWork
444
            ->expects(self::never())
445
            ->method('getSingleIdentifierValue');
446
447
        $query = $this->em->createQuery('SELECT d FROM ' . DateTimeModel::class . ' d WHERE d.datetime = :value');
448
449
        $query->setParameter('value', new DateTime(), Type::DATETIME);
450
451
        self::assertEmpty($query->getResult());
452
    }
453
}
454