Failed Conditions
Pull Request — master (#7885)
by Šimon
11:22
created

QueryTest::testResultCacheEviction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 31
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 13
nc 1
nop 0
dl 0
loc 31
rs 9.8333
c 0
b 0
f 0
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
        self::assertIsIterable($q->getIterable());
176
    }
177
178
    /**
179
     * @group DDC-1697
180
     */
181
    public function testCollectionParameters() : void
182
    {
183
        $cities = [
184
            0 => 'Paris',
185
            3 => 'Canne',
186
            9 => 'St Julien',
187
        ];
188
189
        $query = $this->em
190
                ->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.city IN (:cities)')
191
                ->setParameter('cities', $cities);
192
193
        $parameters = $query->getParameters();
194
        $parameter  = $parameters->first();
195
196
        self::assertEquals('cities', $parameter->getName());
197
        self::assertEquals($cities, $parameter->getValue());
198
    }
199
200
    /**
201
     * @group DDC-2224
202
     */
203
    public function testProcessParameterValueClassMetadata() : void
204
    {
205
        $query = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.city IN (:cities)');
206
        self::assertEquals(
207
            CmsAddress::class,
208
            $query->processParameterValue($this->em->getClassMetadata(CmsAddress::class))
209
        );
210
    }
211
212
    public function testProcessParameterValueObject() : void
213
    {
214
        $query    = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user = :user');
215
        $user     = new CmsUser();
216
        $user->id = 12345;
217
218
        self::assertSame(
219
            12345,
220
            $query->processParameterValue($user)
221
        );
222
    }
223
224
    public function testProcessParameterValueNull() : void
225
    {
226
        $query = $this->em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user = :user');
227
228
        self::assertNull($query->processParameterValue(null));
229
    }
230
231
    public function testDefaultQueryHints() : void
232
    {
233
        $config       = $this->em->getConfiguration();
234
        $defaultHints = [
235
            'hint_name_1' => 'hint_value_1',
236
            'hint_name_2' => 'hint_value_2',
237
            'hint_name_3' => 'hint_value_3',
238
        ];
239
240
        $config->setDefaultQueryHints($defaultHints);
241
        $query = $this->em->createQuery();
242
        self::assertSame($config->getDefaultQueryHints(), $query->getHints());
243
        $this->em->getConfiguration()->setDefaultQueryHint('hint_name_1', 'hint_another_value_1');
244
        self::assertNotSame($config->getDefaultQueryHints(), $query->getHints());
245
        $q2 = clone $query;
246
        self::assertSame($config->getDefaultQueryHints(), $q2->getHints());
247
    }
248
249
    /**
250
     * @group DDC-3714
251
     */
252
    public function testResultCacheCaching() : void
253
    {
254
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
255
        $this->em->getConfiguration()->setQueryCacheImpl(new ArrayCache());
256
        /** @var DriverConnectionMock $driverConnectionMock */
257
        $driverConnectionMock = $this->em->getConnection()->getWrappedConnection();
258
        $stmt                 = new StatementArrayMock([
259
            ['c0' => 1],
260
        ]);
261
        $driverConnectionMock->setStatementMock($stmt);
262
        $res = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u')
263
            ->useQueryCache(true)
264
            ->useResultCache(true, 60)
265
            //let it cache
266
            ->getResult();
267
268
        self::assertCount(1, $res);
269
270
        $driverConnectionMock->setStatementMock(null);
271
272
        $res = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u')
273
            ->useQueryCache(true)
274
            ->useResultCache(false)
275
            ->getResult();
276
        self::assertCount(0, $res);
277
    }
278
279
    /**
280
     * @group DDC-3741
281
     */
282
    public function testSetHydrationCacheProfileNull() : void
283
    {
284
        $query = $this->em->createQuery();
285
        $query->setHydrationCacheProfile(null);
286
287
        self::assertNull($query->getHydrationCacheProfile());
288
    }
289
290
    /**
291
     * @group 2947
292
     */
293
    public function testResultCacheEviction() : void
294
    {
295
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
296
297
        $query = $this->em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
298
                          ->useResultCache(true);
299
300
        /** @var DriverConnectionMock $driverConnectionMock */
301
        $driverConnectionMock = $this->em->getConnection()
302
            ->getWrappedConnection();
303
304
        // Performs the query and sets up the initial cache
305
        self::assertCount(0, $query->getResult());
306
307
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1]]));
308
309
        // Performs the query and sets up the initial cache
310
        self::assertCount(1, $query->expireResultCache(true)->getResult());
311
312
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1], ['c0' => 2]]));
313
314
        // Retrieves cached data since expire flag is false and we have a cached result set
315
        self::assertCount(1, $query->expireResultCache(false)->getResult());
316
317
        // Performs the query and caches the result set since expire flag is true
318
        self::assertCount(2, $query->expireResultCache(true)->getResult());
319
320
        $driverConnectionMock->setStatementMock(new StatementArrayMock([['c0' => 1]]));
321
322
        // Retrieves cached data since expire flag is false and we have a cached result set
323
        self::assertCount(2, $query->expireResultCache(false)->getResult());
324
    }
325
326
    /**
327
     * @group #6162
328
     */
329
    public function testSelectJoinSubquery() : void
330
    {
331
        $query = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u JOIN (SELECT )');
332
333
        $this->expectException(QueryException::class);
334
        $this->expectExceptionMessage('Subquery');
335
        $query->getSQL();
336
    }
337
338
    /**
339
     * @group #6162
340
     */
341
    public function testSelectFromSubquery() : void
342
    {
343
        $query = $this->em->createQuery('select u from (select Doctrine\Tests\Models\CMS\CmsUser c) as u');
344
345
        $this->expectException(QueryException::class);
346
        $this->expectExceptionMessage('Subquery');
347
        $query->getSQL();
348
    }
349
350
    /**
351
     * @group 6699
352
     */
353
    public function testGetParameterTypeJuggling() : void
354
    {
355
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id = ?0');
356
357
        $query->setParameter(0, 0);
358
359
        self::assertCount(1, $query->getParameters());
360
        self::assertSame(0, $query->getParameter(0)->getValue());
361
        self::assertSame(0, $query->getParameter('0')->getValue());
362
    }
363
364
    /**
365
     * @group 6699
366
     */
367
    public function testSetParameterWithNameZeroIsNotOverridden() : void
368
    {
369
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
370
371
        $query->setParameter(0, 0);
372
        $query->setParameter('name', 'Doctrine');
373
374
        self::assertCount(2, $query->getParameters());
375
        self::assertSame(0, $query->getParameter('0')->getValue());
376
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
377
    }
378
379
    /**
380
     * @group 6699
381
     */
382
    public function testSetParameterWithNameZeroDoesNotOverrideAnotherParameter() : void
383
    {
384
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
385
386
        $query->setParameter('name', 'Doctrine');
387
        $query->setParameter(0, 0);
388
389
        self::assertCount(2, $query->getParameters());
390
        self::assertSame(0, $query->getParameter(0)->getValue());
391
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
392
    }
393
394
    /**
395
     * @group 6699
396
     */
397
    public function testSetParameterWithTypeJugglingWorks() : void
398
    {
399
        $query = $this->em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name');
400
401
        $query->setParameter('0', 1);
402
        $query->setParameter('name', 'Doctrine');
403
        $query->setParameter(0, 2);
404
        $query->setParameter('0', 3);
405
406
        self::assertCount(2, $query->getParameters());
407
        self::assertSame(3, $query->getParameter(0)->getValue());
408
        self::assertSame(3, $query->getParameter('0')->getValue());
409
        self::assertSame('Doctrine', $query->getParameter('name')->getValue());
410
    }
411
412
    /**
413
     * @group 6748
414
     */
415
    public function testResultCacheProfileCanBeRemovedViaSetter() : void
416
    {
417
        $this->em->getConfiguration()->setResultCacheImpl(new ArrayCache());
418
419
        $query = $this->em->createQuery('SELECT u FROM ' . CmsUser::class . ' u');
420
        $query->useResultCache(true);
421
        $query->setResultCacheProfile();
422
423
        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

423
        /** @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...
424
    }
425
426
    /** @group 7527 */
427
    public function testValuesAreNotBeingResolvedForSpecifiedParameterTypes() : void
428
    {
429
        $unitOfWork = $this->createMock(UnitOfWork::class);
430
431
        $this->em->setUnitOfWork($unitOfWork);
432
433
        $unitOfWork
434
            ->expects(self::never())
435
            ->method('getSingleIdentifierValue');
436
437
        $query = $this->em->createQuery('SELECT d FROM ' . DateTimeModel::class . ' d WHERE d.datetime = :value');
438
439
        $query->setParameter('value', new DateTime(), Type::DATETIME);
440
441
        self::assertEmpty($query->getResult());
442
    }
443
}
444