Completed
Pull Request — 2.7 (#8050)
by Benjamin
63:54
created

testBasicQueryCachePutEntityCache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 62
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 45
nc 1
nop 0
dl 0
loc 62
rs 9.2
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Doctrine\Tests\ORM\Functional;
4
5
use Doctrine\ORM\AbstractQuery;
6
use Doctrine\ORM\Cache;
7
use Doctrine\ORM\Cache\EntityCacheEntry;
8
use Doctrine\ORM\Cache\EntityCacheKey;
9
use Doctrine\ORM\Cache\QueryCacheKey;
10
use Doctrine\ORM\Proxy\Proxy;
11
use Doctrine\ORM\Query;
12
use Doctrine\ORM\Query\ResultSetMapping;
13
use Doctrine\Tests\Models\Cache\Attraction;
14
use Doctrine\Tests\Models\Cache\City;
15
use Doctrine\Tests\Models\Cache\Country;
16
use Doctrine\Tests\Models\Cache\State;
17
18
/**
19
 * @group DDC-2183
20
 */
21
class SecondLevelCacheQueryCacheTest extends SecondLevelCacheAbstractTest
22
{
23
    public function testBasicQueryCache()
24
    {
25
        $this->evictRegions();
26
        $this->loadFixturesCountries();
27
28
        $this->secondLevelCacheLogger->clearStats();
29
        $this->_em->clear();
30
31
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
32
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
33
34
        $queryCount = $this->getCurrentQueryCount();
35
        $dql        = 'SELECT c FROM Doctrine\Tests\Models\Cache\Country c';
36
        $result1    = $this->_em->createQuery($dql)->setCacheable(true)->getResult();
37
38
        $this->assertCount(2, $result1);
39
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
40
        $this->assertEquals($this->countries[0]->getId(), $result1[0]->getId());
41
        $this->assertEquals($this->countries[1]->getId(), $result1[1]->getId());
42
        $this->assertEquals($this->countries[0]->getName(), $result1[0]->getName());
43
        $this->assertEquals($this->countries[1]->getName(), $result1[1]->getName());
44
45
        $this->assertEquals(1, $this->secondLevelCacheLogger->getPutCount());
46
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
47
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount($this->getDefaultQueryRegionName()));
48
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount($this->getDefaultQueryRegionName()));
49
50
        $this->_em->clear();
51
52
        $result2  = $this->_em->createQuery($dql)
53
            ->setCacheable(true)
54
            ->getResult();
55
56
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
57
        $this->assertCount(2, $result2);
58
59
        $this->assertEquals(1, $this->secondLevelCacheLogger->getPutCount());
60
        $this->assertEquals(3, $this->secondLevelCacheLogger->getHitCount());
61
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
62
63
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount($this->getDefaultQueryRegionName()));
64
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionHitCount($this->getDefaultQueryRegionName()));
65
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount($this->getDefaultQueryRegionName()));
66
67
        $this->assertInstanceOf(Country::class, $result2[0]);
68
        $this->assertInstanceOf(Country::class, $result2[1]);
69
70
        $this->assertEquals($result1[0]->getId(), $result2[0]->getId());
71
        $this->assertEquals($result1[1]->getId(), $result2[1]->getId());
72
73
        $this->assertEquals($result1[0]->getName(), $result2[0]->getName());
74
        $this->assertEquals($result1[1]->getName(), $result2[1]->getName());
75
76
        $this->assertEquals(1, $this->secondLevelCacheLogger->getPutCount());
77
        $this->assertEquals(3, $this->secondLevelCacheLogger->getHitCount());
78
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
79
80
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount($this->getDefaultQueryRegionName()));
81
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionHitCount($this->getDefaultQueryRegionName()));
82
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount($this->getDefaultQueryRegionName()));
83
    }
84
85
    public function testQueryCacheModeGet()
86
    {
87
        $this->evictRegions();
88
        $this->loadFixturesCountries();
89
        $this->evictRegions();
90
91
        $this->secondLevelCacheLogger->clearStats();
92
        $this->_em->clear();
93
94
        $this->assertFalse($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
95
        $this->assertFalse($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
96
97
        $queryCount = $this->getCurrentQueryCount();
98
        $dql        = 'SELECT c FROM Doctrine\Tests\Models\Cache\Country c';
99
        $queryGet   = $this->_em->createQuery($dql)
100
            ->setCacheMode(Cache::MODE_GET)
101
            ->setCacheable(true);
102
103
        // MODE_GET should never add items to the cache.
104
        $this->assertCount(2, $queryGet->getResult());
105
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
106
107
        $this->assertCount(2, $queryGet->getResult());
108
        $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
109
110
        $result = $this->_em->createQuery($dql)
111
            ->setCacheable(true)
112
            ->getResult();
113
114
        $this->assertCount(2, $result);
115
        $this->assertEquals($queryCount + 3, $this->getCurrentQueryCount());
116
117
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
118
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
119
120
        // MODE_GET should read items if exists.
121
        $this->assertCount(2, $queryGet->getResult());
122
        $this->assertEquals($queryCount + 3, $this->getCurrentQueryCount());
123
    }
124
125
    public function testQueryCacheModePut()
126
    {
127
        $this->evictRegions();
128
        $this->loadFixturesCountries();
129
        $this->evictRegions();
130
131
        $this->secondLevelCacheLogger->clearStats();
132
        $this->_em->clear();
133
134
        $this->assertFalse($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
135
        $this->assertFalse($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
136
137
        $queryCount = $this->getCurrentQueryCount();
138
        $dql        = 'SELECT c FROM Doctrine\Tests\Models\Cache\Country c';
139
        $result     = $this->_em->createQuery($dql)
140
            ->setCacheable(true)
141
            ->getResult();
142
143
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
144
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
145
146
        $this->assertCount(2, $result);
147
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
148
149
        $queryPut = $this->_em->createQuery($dql)
150
            ->setCacheMode(Cache::MODE_PUT)
151
            ->setCacheable(true);
152
153
        // MODE_PUT should never read itens from cache.
154
        $this->assertCount(2, $queryPut->getResult());
155
        $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
156
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
157
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
158
159
        $this->assertCount(2, $queryPut->getResult());
160
        $this->assertEquals($queryCount + 3, $this->getCurrentQueryCount());
161
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
162
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
163
    }
164
165
    public function testQueryCacheModeRefresh()
166
    {
167
        $this->evictRegions();
168
        $this->loadFixturesCountries();
169
        $this->evictRegions();
170
171
        $this->secondLevelCacheLogger->clearStats();
172
        $this->_em->clear();
173
174
        $this->assertFalse($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
175
        $this->assertFalse($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
176
177
        $region     = $this->cache->getEntityCacheRegion(Country::class);
178
        $queryCount = $this->getCurrentQueryCount();
179
        $dql        = 'SELECT c FROM Doctrine\Tests\Models\Cache\Country c';
180
        $result     = $this->_em->createQuery($dql)
181
            ->setCacheable(true)
182
            ->getResult();
183
184
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
185
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
186
187
        $this->assertCount(2, $result);
188
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
189
190
        $countryId1     = $this->countries[0]->getId();
191
        $countryId2     = $this->countries[1]->getId();
192
        $countryName1   = $this->countries[0]->getName();
193
        $countryName2   = $this->countries[1]->getName();
194
195
        $key1           = new EntityCacheKey(Country::class, ['id'=>$countryId1]);
196
        $key2           = new EntityCacheKey(Country::class, ['id'=>$countryId2]);
197
        $entry1         = new EntityCacheEntry(Country::class, ['id'=>$countryId1, 'name'=>'outdated']);
198
        $entry2         = new EntityCacheEntry(Country::class, ['id'=>$countryId2, 'name'=>'outdated']);
199
200
        $region->put($key1, $entry1);
201
        $region->put($key2, $entry2);
202
        $this->_em->clear();
203
204
        $queryRefresh = $this->_em->createQuery($dql)
205
            ->setCacheMode(Cache::MODE_REFRESH)
206
            ->setCacheable(true);
207
208
        // MODE_REFRESH should never read itens from cache.
209
        $result1 = $queryRefresh->getResult();
210
        $this->assertCount(2, $result1);
211
        $this->assertEquals($countryName1, $result1[0]->getName());
212
        $this->assertEquals($countryName2, $result1[1]->getName());
213
        $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
214
215
        $this->_em->clear();
216
217
        $result2 = $queryRefresh->getResult();
218
        $this->assertCount(2, $result2);
219
        $this->assertEquals($countryName1, $result2[0]->getName());
220
        $this->assertEquals($countryName2, $result2[1]->getName());
221
        $this->assertEquals($queryCount + 3, $this->getCurrentQueryCount());
222
    }
223
224
    public function testBasicQueryCachePutEntityCache()
225
    {
226
        $this->evictRegions();
227
        $this->loadFixturesCountries();
228
229
        $this->evictRegions();
230
        $this->secondLevelCacheLogger->clearStats();
231
        $this->_em->clear();
232
233
        $queryCount = $this->getCurrentQueryCount();
234
        $dql        = 'SELECT c FROM Doctrine\Tests\Models\Cache\Country c';
235
        $result1    = $this->_em->createQuery($dql)->setCacheable(true)->getResult();
236
237
        $this->assertCount(2, $result1);
238
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
239
        $this->assertEquals($this->countries[0]->getId(), $result1[0]->getId());
240
        $this->assertEquals($this->countries[1]->getId(), $result1[1]->getId());
241
        $this->assertEquals($this->countries[0]->getName(), $result1[0]->getName());
242
        $this->assertEquals($this->countries[1]->getName(), $result1[1]->getName());
243
244
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
245
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
246
247
        $this->assertEquals(3, $this->secondLevelCacheLogger->getPutCount());
248
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
249
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount($this->getDefaultQueryRegionName()));
250
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount($this->getDefaultQueryRegionName()));
251
        $this->assertEquals(2, $this->secondLevelCacheLogger->getRegionPutCount($this->getEntityRegion(Country::class)));
252
253
        $this->_em->clear();
254
255
        $result2  = $this->_em->createQuery($dql)
256
            ->setCacheable(true)
257
            ->getResult();
258
259
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
260
        $this->assertCount(2, $result2);
261
262
        $this->assertEquals(3, $this->secondLevelCacheLogger->getPutCount());
263
        $this->assertEquals(3, $this->secondLevelCacheLogger->getHitCount());
264
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
265
266
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount($this->getDefaultQueryRegionName()));
267
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionHitCount($this->getDefaultQueryRegionName()));
268
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount($this->getDefaultQueryRegionName()));
269
270
        $this->assertInstanceOf(Country::class, $result2[0]);
271
        $this->assertInstanceOf(Country::class, $result2[1]);
272
273
        $this->assertEquals($result1[0]->getId(), $result2[0]->getId());
274
        $this->assertEquals($result1[1]->getId(), $result2[1]->getId());
275
276
        $this->assertEquals($result1[0]->getName(), $result2[0]->getName());
277
        $this->assertEquals($result1[1]->getName(), $result2[1]->getName());
278
279
        $this->assertEquals(3, $this->secondLevelCacheLogger->getPutCount());
280
        $this->assertEquals(3, $this->secondLevelCacheLogger->getHitCount());
281
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
282
283
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount($this->getDefaultQueryRegionName()));
284
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionHitCount($this->getDefaultQueryRegionName()));
285
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount($this->getDefaultQueryRegionName()));
286
    }
287
288
    /**
289
     * @group 5854
290
     */
291
    public function testMultipleNestedDQLAliases()
292
    {
293
        $this->loadFixturesCountries();
294
        $this->loadFixturesStates();
295
        $this->loadFixturesCities();
296
        $this->loadFixturesAttractions();
297
298
        $queryRegionName      = $this->getDefaultQueryRegionName();
0 ignored issues
show
Unused Code introduced by
The assignment to $queryRegionName is dead and can be removed.
Loading history...
299
        $cityRegionName       = $this->getEntityRegion(City::class);
0 ignored issues
show
Unused Code introduced by
The assignment to $cityRegionName is dead and can be removed.
Loading history...
300
        $stateRegionName      = $this->getEntityRegion(State::class);
0 ignored issues
show
Unused Code introduced by
The assignment to $stateRegionName is dead and can be removed.
Loading history...
301
        $attractionRegionName = $this->getEntityRegion(Attraction::class);
0 ignored issues
show
Unused Code introduced by
The assignment to $attractionRegionName is dead and can be removed.
Loading history...
302
303
        $this->secondLevelCacheLogger->clearStats();
304
        $this->evictRegions();
305
        $this->_em->clear();
306
307
        $queryCount = $this->getCurrentQueryCount();
308
        $dql        = 'SELECT s, c, a FROM Doctrine\Tests\Models\Cache\State s JOIN s.cities c JOIN c.attractions a';
309
        $result1    = $this->_em->createQuery($dql)
310
            ->setCacheable(true)
311
            ->getResult();
312
313
        $this->assertCount(2, $result1);
314
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
315
316
        $this->assertTrue($this->cache->containsEntity(State::class, $this->states[0]->getId()));
317
        $this->assertTrue($this->cache->containsEntity(State::class, $this->states[1]->getId()));
318
319
        $this->assertTrue($this->cache->containsEntity(City::class, $this->cities[0]->getId()));
320
        $this->assertTrue($this->cache->containsEntity(City::class, $this->cities[1]->getId()));
321
        $this->assertTrue($this->cache->containsEntity(City::class, $this->cities[2]->getId()));
322
        $this->assertTrue($this->cache->containsEntity(City::class, $this->cities[3]->getId()));
323
324
        $this->assertTrue($this->cache->containsEntity(Attraction::class, $this->attractions[0]->getId()));
325
        $this->assertTrue($this->cache->containsEntity(Attraction::class, $this->attractions[1]->getId()));
326
        $this->assertTrue($this->cache->containsEntity(Attraction::class, $this->attractions[2]->getId()));
327
        $this->assertTrue($this->cache->containsEntity(Attraction::class, $this->attractions[3]->getId()));
328
329
        $this->assertInstanceOf(State::class, $result1[0]);
330
        $this->assertInstanceOf(State::class, $result1[1]);
331
332
        $this->assertCount(2, $result1[0]->getCities());
333
        $this->assertCount(2, $result1[1]->getCities());
334
335
        $this->assertInstanceOf(City::class, $result1[0]->getCities()->get(0));
336
        $this->assertInstanceOf(City::class, $result1[0]->getCities()->get(1));
337
        $this->assertInstanceOf(City::class, $result1[1]->getCities()->get(0));
338
        $this->assertInstanceOf(City::class, $result1[1]->getCities()->get(1));
339
340
        $this->assertCount(2, $result1[0]->getCities()->get(0)->getAttractions());
341
        $this->assertCount(2, $result1[0]->getCities()->get(1)->getAttractions());
342
        $this->assertCount(2, $result1[1]->getCities()->get(0)->getAttractions());
343
        $this->assertCount(1, $result1[1]->getCities()->get(1)->getAttractions());
344
345
        $this->_em->clear();
346
347
        $result2  = $this->_em->createQuery($dql)
348
            ->setCacheable(true)
349
            ->getResult();
350
351
        $this->assertCount(2, $result2);
352
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
353
354
        $this->assertInstanceOf(State::class, $result2[0]);
355
        $this->assertInstanceOf(State::class, $result2[1]);
356
357
        $this->assertCount(2, $result2[0]->getCities());
358
        $this->assertCount(2, $result2[1]->getCities());
359
360
        $this->assertInstanceOf(City::class, $result2[0]->getCities()->get(0));
361
        $this->assertInstanceOf(City::class, $result2[0]->getCities()->get(1));
362
        $this->assertInstanceOf(City::class, $result2[1]->getCities()->get(0));
363
        $this->assertInstanceOf(City::class, $result2[1]->getCities()->get(1));
364
365
        $this->assertCount(2, $result2[0]->getCities()->get(0)->getAttractions());
366
        $this->assertCount(2, $result2[0]->getCities()->get(1)->getAttractions());
367
        $this->assertCount(2, $result2[1]->getCities()->get(0)->getAttractions());
368
        $this->assertCount(1, $result2[1]->getCities()->get(1)->getAttractions());
369
    }
370
371
    public function testBasicQueryParams()
372
    {
373
        $this->evictRegions();
374
375
        $this->loadFixturesCountries();
376
        $this->_em->clear();
377
378
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
379
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
380
381
        $queryCount = $this->getCurrentQueryCount();
382
        $name       = $this->countries[0]->getName();
383
        $dql        = 'SELECT c FROM Doctrine\Tests\Models\Cache\Country c WHERE c.name = :name';
384
        $result1    = $this->_em->createQuery($dql)
385
                ->setCacheable(true)
386
                ->setParameter('name', $name)
387
                ->getResult();
388
389
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
390
        $this->assertEquals($this->countries[0]->getId(), $result1[0]->getId());
391
        $this->assertEquals($this->countries[0]->getName(), $result1[0]->getName());
392
393
        $this->_em->clear();
394
395
        $result2  = $this->_em->createQuery($dql)->setCacheable(true)
396
                ->setParameter('name', $name)
397
                ->getResult();
398
399
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
400
        $this->assertCount(1, $result2);
401
402
        $this->assertInstanceOf(Country::class, $result2[0]);
403
404
        $this->assertEquals($result1[0]->getId(), $result2[0]->getId());
405
        $this->assertEquals($result1[0]->getName(), $result2[0]->getName());
406
    }
407
408
    public function testLoadFromDatabaseWhenEntityMissing()
409
    {
410
        $this->evictRegions();
411
412
        $this->loadFixturesCountries();
413
        $this->_em->clear();
414
415
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
416
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
417
418
        $queryCount = $this->getCurrentQueryCount();
419
        $dql        = 'SELECT c FROM Doctrine\Tests\Models\Cache\Country c';
420
        $result1    = $this->_em->createQuery($dql)->setCacheable(true)->getResult();
421
422
        $this->assertCount(2, $result1);
423
        $this->assertEquals($queryCount + 1 , $this->getCurrentQueryCount());
424
        $this->assertEquals($this->countries[0]->getId(), $result1[0]->getId());
425
        $this->assertEquals($this->countries[1]->getId(), $result1[1]->getId());
426
        $this->assertEquals($this->countries[0]->getName(), $result1[0]->getName());
427
        $this->assertEquals($this->countries[1]->getName(), $result1[1]->getName());
428
429
        $this->assertEquals(3, $this->secondLevelCacheLogger->getPutCount());
430
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
431
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount($this->getDefaultQueryRegionName()));
432
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount($this->getDefaultQueryRegionName()));
433
434
        $this->cache->evictEntity(Country::class, $result1[0]->getId());
435
        $this->assertFalse($this->cache->containsEntity(Country::class, $result1[0]->getId()));
436
437
        $this->_em->clear();
438
439
        $result2  = $this->_em->createQuery($dql)
440
            ->setCacheable(true)
441
            ->getResult();
442
443
        $this->assertEquals($queryCount + 2 , $this->getCurrentQueryCount());
444
        $this->assertCount(2, $result2);
445
446
        $this->assertEquals(5, $this->secondLevelCacheLogger->getPutCount());
447
        $this->assertEquals(3, $this->secondLevelCacheLogger->getMissCount());
448
        $this->assertEquals(2, $this->secondLevelCacheLogger->getRegionPutCount($this->getDefaultQueryRegionName()));
449
        $this->assertEquals(2, $this->secondLevelCacheLogger->getRegionMissCount($this->getDefaultQueryRegionName()));
450
451
        $this->assertInstanceOf(Country::class, $result2[0]);
452
        $this->assertInstanceOf(Country::class, $result2[1]);
453
454
        $this->assertEquals($result1[0]->getId(), $result2[0]->getId());
455
        $this->assertEquals($result1[1]->getId(), $result2[1]->getId());
456
457
        $this->assertEquals($result1[0]->getName(), $result2[0]->getName());
458
        $this->assertEquals($result1[1]->getName(), $result2[1]->getName());
459
460
        $this->assertEquals($queryCount + 2 , $this->getCurrentQueryCount());
461
    }
462
463
    public function testBasicQueryFetchJoinsOneToMany()
464
    {
465
        $this->loadFixturesCountries();
466
        $this->loadFixturesStates();
467
        $this->loadFixturesCities();
468
469
        $this->evictRegions();
470
        $this->_em->clear();
471
472
        $queryCount = $this->getCurrentQueryCount();
473
        $dql        = 'SELECT s, c FROM Doctrine\Tests\Models\Cache\State s JOIN s.cities c';
474
        $result1    = $this->_em->createQuery($dql)
475
                ->setCacheable(true)
476
                ->getResult();
477
478
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
479
        $this->assertInstanceOf(State::class, $result1[0]);
480
        $this->assertInstanceOf(State::class, $result1[1]);
481
        $this->assertCount(2, $result1[0]->getCities());
482
        $this->assertCount(2, $result1[1]->getCities());
483
484
        $this->assertInstanceOf(City::class, $result1[0]->getCities()->get(0));
485
        $this->assertInstanceOf(City::class, $result1[0]->getCities()->get(1));
486
        $this->assertInstanceOf(City::class, $result1[1]->getCities()->get(0));
487
        $this->assertInstanceOf(City::class, $result1[1]->getCities()->get(1));
488
489
        $this->assertNotNull($result1[0]->getCities()->get(0)->getId());
490
        $this->assertNotNull($result1[0]->getCities()->get(1)->getId());
491
        $this->assertNotNull($result1[1]->getCities()->get(0)->getId());
492
        $this->assertNotNull($result1[1]->getCities()->get(1)->getId());
493
494
        $this->assertNotNull($result1[0]->getCities()->get(0)->getName());
495
        $this->assertNotNull($result1[0]->getCities()->get(1)->getName());
496
        $this->assertNotNull($result1[1]->getCities()->get(0)->getName());
497
        $this->assertNotNull($result1[1]->getCities()->get(1)->getName());
498
499
        $this->_em->clear();
500
501
        $result2  = $this->_em->createQuery($dql)
502
                ->setCacheable(true)
503
                ->getResult();
504
505
        $this->assertInstanceOf(State::class, $result2[0]);
506
        $this->assertInstanceOf(State::class, $result2[1]);
507
        $this->assertCount(2, $result2[0]->getCities());
508
        $this->assertCount(2, $result2[1]->getCities());
509
510
        $this->assertInstanceOf(City::class, $result2[0]->getCities()->get(0));
511
        $this->assertInstanceOf(City::class, $result2[0]->getCities()->get(1));
512
        $this->assertInstanceOf(City::class, $result2[1]->getCities()->get(0));
513
        $this->assertInstanceOf(City::class, $result2[1]->getCities()->get(1));
514
515
        $this->assertNotNull($result2[0]->getCities()->get(0)->getId());
516
        $this->assertNotNull($result2[0]->getCities()->get(1)->getId());
517
        $this->assertNotNull($result2[1]->getCities()->get(0)->getId());
518
        $this->assertNotNull($result2[1]->getCities()->get(1)->getId());
519
520
        $this->assertNotNull($result2[0]->getCities()->get(0)->getName());
521
        $this->assertNotNull($result2[0]->getCities()->get(1)->getName());
522
        $this->assertNotNull($result2[1]->getCities()->get(0)->getName());
523
        $this->assertNotNull($result2[1]->getCities()->get(1)->getName());
524
525
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
526
    }
527
528
    public function testBasicQueryFetchJoinsManyToOne()
529
    {
530
        $this->loadFixturesCountries();
531
        $this->loadFixturesStates();
532
        $this->loadFixturesCities();
533
        $this->_em->clear();
534
535
        $this->evictRegions();
536
        $this->secondLevelCacheLogger->clearStats();
537
538
        $queryCount = $this->getCurrentQueryCount();
539
        $dql        = 'SELECT c, s FROM Doctrine\Tests\Models\Cache\City c JOIN c.state s';
540
        $result1    = $this->_em->createQuery($dql)
541
                ->setCacheable(true)
542
                ->getResult();
543
544
        $this->assertCount(4, $result1);
545
        $this->assertInstanceOf(City::class, $result1[0]);
546
        $this->assertInstanceOf(City::class, $result1[1]);
547
        $this->assertInstanceOf(State::class, $result1[0]->getState());
548
        $this->assertInstanceOf(State::class, $result1[1]->getState());
549
550
        $this->assertTrue($this->cache->containsEntity(City::class, $result1[0]->getId()));
551
        $this->assertTrue($this->cache->containsEntity(City::class, $result1[1]->getId()));
552
        $this->assertTrue($this->cache->containsEntity(State::class, $result1[0]->getState()->getId()));
553
        $this->assertTrue($this->cache->containsEntity(State::class, $result1[1]->getState()->getId()));
554
555
        $this->assertEquals(7, $this->secondLevelCacheLogger->getPutCount());
556
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
557
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount($this->getDefaultQueryRegionName()));
558
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount($this->getDefaultQueryRegionName()));
559
        $this->assertEquals(2, $this->secondLevelCacheLogger->getRegionPutCount($this->getEntityRegion(State::class)));
560
        $this->assertEquals(4, $this->secondLevelCacheLogger->getRegionPutCount($this->getEntityRegion(City::class)));
561
562
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
563
564
        $this->_em->clear();
565
        $this->secondLevelCacheLogger->clearStats();
566
567
        $result2  = $this->_em->createQuery($dql)
568
                ->setCacheable(true)
569
                ->getResult();
570
571
        $this->assertCount(4, $result1);
572
        $this->assertInstanceOf(City::class, $result2[0]);
573
        $this->assertInstanceOf(City::class, $result2[1]);
574
        $this->assertInstanceOf(State::class, $result2[0]->getState());
575
        $this->assertInstanceOf(State::class, $result2[1]->getState());
576
577
        $this->assertNotNull($result2[0]->getId());
578
        $this->assertNotNull($result2[0]->getId());
579
        $this->assertNotNull($result2[1]->getState()->getId());
580
        $this->assertNotNull($result2[1]->getState()->getId());
581
582
        $this->assertNotNull($result2[0]->getName());
583
        $this->assertNotNull($result2[0]->getName());
584
        $this->assertNotNull($result2[1]->getState()->getName());
585
        $this->assertNotNull($result2[1]->getState()->getName());
586
587
        $this->assertEquals($result1[0]->getName(), $result2[0]->getName());
588
        $this->assertEquals($result1[1]->getName(), $result2[1]->getName());
589
        $this->assertEquals($result1[0]->getState()->getName(), $result2[0]->getState()->getName());
590
        $this->assertEquals($result1[1]->getState()->getName(), $result2[1]->getState()->getName());
591
592
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
593
    }
594
595
    public function testReloadQueryIfToOneIsNotFound()
596
    {
597
        $this->loadFixturesCountries();
598
        $this->loadFixturesStates();
599
        $this->loadFixturesCities();
600
        $this->_em->clear();
601
602
        $this->evictRegions();
603
        $this->secondLevelCacheLogger->clearStats();
604
605
        $queryCount = $this->getCurrentQueryCount();
606
        $dql        = 'SELECT c, s FROM Doctrine\Tests\Models\Cache\City c JOIN c.state s';
607
        $result1    = $this->_em->createQuery($dql)
608
                ->setCacheable(true)
609
                ->getResult();
610
611
        $this->assertCount(4, $result1);
612
        $this->assertInstanceOf(City::class, $result1[0]);
613
        $this->assertInstanceOf(City::class, $result1[1]);
614
        $this->assertInstanceOf(State::class, $result1[0]->getState());
615
        $this->assertInstanceOf(State::class, $result1[1]->getState());
616
617
        $this->assertTrue($this->cache->containsEntity(City::class, $result1[0]->getId()));
618
        $this->assertTrue($this->cache->containsEntity(City::class, $result1[1]->getId()));
619
        $this->assertTrue($this->cache->containsEntity(State::class, $result1[0]->getState()->getId()));
620
        $this->assertTrue($this->cache->containsEntity(State::class, $result1[1]->getState()->getId()));
621
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
622
623
        $this->_em->clear();
624
625
        $this->cache->evictEntityRegion(State::class);
626
627
        $result2  = $this->_em->createQuery($dql)
628
                ->setCacheable(true)
629
                ->getResult();
630
631
        $this->assertCount(4, $result1);
632
        $this->assertInstanceOf(City::class, $result2[0]);
633
        $this->assertInstanceOf(City::class, $result2[1]);
634
        $this->assertInstanceOf(State::class, $result2[0]->getState());
635
        $this->assertInstanceOf(State::class, $result2[1]->getState());
636
637
        $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
638
    }
639
640
    public function testReloadQueryIfToManyAssociationItemIsNotFound()
641
    {
642
        $this->loadFixturesCountries();
643
        $this->loadFixturesStates();
644
        $this->loadFixturesCities();
645
646
        $this->evictRegions();
647
        $this->_em->clear();
648
649
        $queryCount = $this->getCurrentQueryCount();
650
        $dql        = 'SELECT s, c FROM Doctrine\Tests\Models\Cache\State s JOIN s.cities c';
651
        $result1    = $this->_em->createQuery($dql)
652
                ->setCacheable(true)
653
                ->getResult();
654
655
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
656
        $this->assertInstanceOf(State::class, $result1[0]);
657
        $this->assertInstanceOf(State::class, $result1[1]);
658
        $this->assertCount(2, $result1[0]->getCities());
659
        $this->assertCount(2, $result1[1]->getCities());
660
661
        $this->assertInstanceOf(City::class, $result1[0]->getCities()->get(0));
662
        $this->assertInstanceOf(City::class, $result1[0]->getCities()->get(1));
663
        $this->assertInstanceOf(City::class, $result1[1]->getCities()->get(0));
664
        $this->assertInstanceOf(City::class, $result1[1]->getCities()->get(1));
665
666
        $this->_em->clear();
667
668
        $this->cache->evictEntityRegion(City::class);
669
670
        $result2  = $this->_em->createQuery($dql)
671
                ->setCacheable(true)
672
                ->getResult();
673
674
        $this->assertInstanceOf(State::class, $result2[0]);
675
        $this->assertInstanceOf(State::class, $result2[1]);
676
        $this->assertCount(2, $result2[0]->getCities());
677
        $this->assertCount(2, $result2[1]->getCities());
678
679
        $this->assertInstanceOf(City::class, $result2[0]->getCities()->get(0));
680
        $this->assertInstanceOf(City::class, $result2[0]->getCities()->get(1));
681
        $this->assertInstanceOf(City::class, $result2[1]->getCities()->get(0));
682
        $this->assertInstanceOf(City::class, $result2[1]->getCities()->get(1));
683
684
        $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
685
    }
686
687
    public function testBasicNativeQueryCache()
688
    {
689
        $this->evictRegions();
690
        $this->loadFixturesCountries();
691
692
        $this->secondLevelCacheLogger->clearStats();
693
        $this->_em->clear();
694
695
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
696
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
697
698
        $rsm = new ResultSetMapping;
699
        $rsm->addEntityResult(Country::class, 'c');
700
        $rsm->addFieldResult('c', 'name', 'name');
701
        $rsm->addFieldResult('c', 'id', 'id');
702
703
        $queryCount = $this->getCurrentQueryCount();
704
        $sql        = 'SELECT id, name FROM cache_country';
705
        $result1    = $this->_em->createNativeQuery($sql, $rsm)->setCacheable(true)->getResult();
706
707
        $this->assertCount(2, $result1);
708
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
709
        $this->assertEquals($this->countries[0]->getId(), $result1[0]->getId());
710
        $this->assertEquals($this->countries[1]->getId(), $result1[1]->getId());
711
        $this->assertEquals($this->countries[0]->getName(), $result1[0]->getName());
712
        $this->assertEquals($this->countries[1]->getName(), $result1[1]->getName());
713
714
        $this->assertEquals(1, $this->secondLevelCacheLogger->getPutCount());
715
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
716
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount($this->getDefaultQueryRegionName()));
717
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount($this->getDefaultQueryRegionName()));
718
719
        $this->_em->clear();
720
721
        $result2  = $this->_em->createNativeQuery($sql, $rsm)
722
            ->setCacheable(true)
723
            ->getResult();
724
725
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
726
        $this->assertCount(2, $result2);
727
728
        $this->assertEquals(1, $this->secondLevelCacheLogger->getPutCount());
729
        $this->assertEquals(3, $this->secondLevelCacheLogger->getHitCount());
730
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
731
732
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount($this->getDefaultQueryRegionName()));
733
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionHitCount($this->getDefaultQueryRegionName()));
734
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount($this->getDefaultQueryRegionName()));
735
736
        $this->assertInstanceOf(Country::class, $result2[0]);
737
        $this->assertInstanceOf(Country::class, $result2[1]);
738
739
        $this->assertEquals($result1[0]->getId(), $result2[0]->getId());
740
        $this->assertEquals($result1[1]->getId(), $result2[1]->getId());
741
742
        $this->assertEquals($result1[0]->getName(), $result2[0]->getName());
743
        $this->assertEquals($result1[1]->getName(), $result2[1]->getName());
744
745
        $this->assertEquals(1, $this->secondLevelCacheLogger->getPutCount());
746
        $this->assertEquals(3, $this->secondLevelCacheLogger->getHitCount());
747
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
748
749
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount($this->getDefaultQueryRegionName()));
750
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionHitCount($this->getDefaultQueryRegionName()));
751
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount($this->getDefaultQueryRegionName()));
752
    }
753
754
    public function testQueryDependsOnFirstAndMaxResultResult()
755
    {
756
        $this->evictRegions();
757
        $this->loadFixturesCountries();
758
759
        $this->secondLevelCacheLogger->clearStats();
760
        $this->_em->clear();
761
762
        $queryCount = $this->getCurrentQueryCount();
763
        $dql        = 'SELECT c FROM Doctrine\Tests\Models\Cache\Country c';
764
        $result1    = $this->_em->createQuery($dql)
0 ignored issues
show
Unused Code introduced by
The assignment to $result1 is dead and can be removed.
Loading history...
765
            ->setCacheable(true)
766
            ->setFirstResult(1)
767
            ->setMaxResults(1)
768
            ->getResult();
769
770
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
771
        $this->assertEquals(1, $this->secondLevelCacheLogger->getPutCount());
772
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
773
774
        $this->_em->clear();
775
776
        $result2  = $this->_em->createQuery($dql)
0 ignored issues
show
Unused Code introduced by
The assignment to $result2 is dead and can be removed.
Loading history...
777
            ->setCacheable(true)
778
            ->setFirstResult(2)
779
            ->setMaxResults(1)
780
            ->getResult();
781
782
        $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
783
        $this->assertEquals(2, $this->secondLevelCacheLogger->getPutCount());
784
        $this->assertEquals(2, $this->secondLevelCacheLogger->getMissCount());
785
786
        $this->_em->clear();
787
788
        $result3  = $this->_em->createQuery($dql)
0 ignored issues
show
Unused Code introduced by
The assignment to $result3 is dead and can be removed.
Loading history...
789
            ->setCacheable(true)
790
            ->getResult();
791
792
        $this->assertEquals($queryCount + 3, $this->getCurrentQueryCount());
793
        $this->assertEquals(3, $this->secondLevelCacheLogger->getPutCount());
794
        $this->assertEquals(3, $this->secondLevelCacheLogger->getMissCount());
795
    }
796
797
    public function testQueryCacheLifetime()
798
    {
799
        $this->evictRegions();
800
        $this->loadFixturesCountries();
801
802
        $this->secondLevelCacheLogger->clearStats();
803
        $this->_em->clear();
804
805
        $getHash = function(AbstractQuery $query){
806
            $method = new \ReflectionMethod($query, 'getHash');
807
            $method->setAccessible(true);
808
809
            return $method->invoke($query);
810
        };
811
812
        $queryCount = $this->getCurrentQueryCount();
813
        $dql        = 'SELECT c FROM Doctrine\Tests\Models\Cache\Country c';
814
        $query      = $this->_em->createQuery($dql);
815
        $result1    = $query->setCacheable(true)
816
            ->setLifetime(3600)
817
            ->getResult();
818
819
        $this->assertNotEmpty($result1);
820
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
821
        $this->assertEquals(1, $this->secondLevelCacheLogger->getPutCount());
822
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
823
824
        $this->_em->clear();
825
826
        $key   = new QueryCacheKey($getHash($query), 3600);
827
        $entry = $this->cache->getQueryCache()
828
            ->getRegion()
829
            ->get($key);
830
831
        $this->assertInstanceOf(Cache\QueryCacheEntry::class, $entry);
832
        $entry->time = $entry->time / 2;
0 ignored issues
show
Bug introduced by
Accessing time on the interface Doctrine\ORM\Cache\CacheEntry suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
833
834
        $this->cache->getQueryCache()
835
            ->getRegion()
836
            ->put($key, $entry);
0 ignored issues
show
Bug introduced by
It seems like $entry can also be of type null; however, parameter $entry of Doctrine\ORM\Cache\Region::put() does only seem to accept Doctrine\ORM\Cache\CacheEntry, maybe add an additional type check? ( Ignorable by Annotation )

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

836
            ->put($key, /** @scrutinizer ignore-type */ $entry);
Loading history...
837
838
        $result2  = $this->_em->createQuery($dql)
839
            ->setCacheable(true)
840
            ->setLifetime(3600)
841
            ->getResult();
842
843
        $this->assertNotEmpty($result2);
844
        $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
845
        $this->assertEquals(2, $this->secondLevelCacheLogger->getPutCount());
846
        $this->assertEquals(2, $this->secondLevelCacheLogger->getMissCount());
847
    }
848
849
    public function testQueryCacheRegion()
850
    {
851
        $this->evictRegions();
852
        $this->loadFixturesCountries();
853
854
        $this->secondLevelCacheLogger->clearStats();
855
        $this->_em->clear();
856
857
        $queryCount = $this->getCurrentQueryCount();
858
        $dql        = 'SELECT c FROM Doctrine\Tests\Models\Cache\Country c';
859
        $query      = $this->_em->createQuery($dql);
860
861
        $query1     = clone $query;
862
        $result1    = $query1->setCacheable(true)
863
            ->setCacheRegion('foo_region')
864
            ->getResult();
865
866
        $this->assertNotEmpty($result1);
867
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
868
        $this->assertEquals(0, $this->secondLevelCacheLogger->getHitCount());
869
        $this->assertEquals(1, $this->secondLevelCacheLogger->getPutCount());
870
        $this->assertEquals(1, $this->secondLevelCacheLogger->getMissCount());
871
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount('foo_region'));
872
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount('foo_region'));
873
874
        $query2     = clone $query;
875
        $result2    = $query2->setCacheable(true)
876
            ->setCacheRegion('bar_region')
877
            ->getResult();
878
879
        $this->assertNotEmpty($result2);
880
        $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
881
        $this->assertEquals(0, $this->secondLevelCacheLogger->getHitCount());
882
        $this->assertEquals(2, $this->secondLevelCacheLogger->getPutCount());
883
        $this->assertEquals(2, $this->secondLevelCacheLogger->getMissCount());
884
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount('bar_region'));
885
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount('bar_region'));
886
887
        $query3     = clone $query;
888
        $result3    = $query3->setCacheable(true)
889
            ->setCacheRegion('foo_region')
890
            ->getResult();
891
892
        $this->assertNotEmpty($result3);
893
        $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
894
        $this->assertEquals(3, $this->secondLevelCacheLogger->getHitCount());
895
        $this->assertEquals(2, $this->secondLevelCacheLogger->getPutCount());
896
        $this->assertEquals(2, $this->secondLevelCacheLogger->getMissCount());
897
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionHitCount('foo_region'));
898
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount('foo_region'));
899
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount('foo_region'));
900
901
        $query4     = clone $query;
902
        $result4    = $query4->setCacheable(true)
0 ignored issues
show
Unused Code introduced by
The assignment to $result4 is dead and can be removed.
Loading history...
903
            ->setCacheRegion('bar_region')
904
            ->getResult();
905
906
        $this->assertNotEmpty($result3);
907
        $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
908
        $this->assertEquals(6, $this->secondLevelCacheLogger->getHitCount());
909
        $this->assertEquals(2, $this->secondLevelCacheLogger->getPutCount());
910
        $this->assertEquals(2, $this->secondLevelCacheLogger->getMissCount());
911
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionHitCount('bar_region'));
912
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionPutCount('bar_region'));
913
        $this->assertEquals(1, $this->secondLevelCacheLogger->getRegionMissCount('bar_region'));
914
    }
915
916
    public function testResolveAssociationCacheEntry()
917
    {
918
        $this->evictRegions();
919
        $this->loadFixturesCountries();
920
        $this->loadFixturesStates();
921
922
        $this->_em->clear();
923
924
        $stateId     = $this->states[0]->getId();
925
        $countryName = $this->states[0]->getCountry()->getName();
926
        $dql         = 'SELECT s FROM Doctrine\Tests\Models\Cache\State s WHERE s.id = :id';
927
        $query       = $this->_em->createQuery($dql);
928
        $queryCount  = $this->getCurrentQueryCount();
929
930
        $query1 = clone $query;
931
        $state1 = $query1
932
            ->setParameter('id', $stateId)
933
            ->setCacheable(true)
934
            ->setMaxResults(1)
935
            ->getSingleResult();
936
937
        $this->assertNotNull($state1);
938
        $this->assertNotNull($state1->getCountry());
939
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
940
        $this->assertInstanceOf(State::class, $state1);
941
        $this->assertInstanceOf(Proxy::class, $state1->getCountry());
942
        $this->assertEquals($countryName, $state1->getCountry()->getName());
943
        $this->assertEquals($stateId, $state1->getId());
944
945
        $this->_em->clear();
946
947
        $queryCount = $this->getCurrentQueryCount();
948
        $query2     = clone $query;
949
        $state2     = $query2
950
            ->setParameter('id', $stateId)
951
            ->setCacheable(true)
952
            ->setMaxResults(1)
953
            ->getSingleResult();
954
955
        $this->assertNotNull($state2);
956
        $this->assertNotNull($state2->getCountry());
957
        $this->assertEquals($queryCount, $this->getCurrentQueryCount());
958
        $this->assertInstanceOf(State::class, $state2);
959
        $this->assertInstanceOf(Proxy::class, $state2->getCountry());
960
        $this->assertEquals($countryName, $state2->getCountry()->getName());
961
        $this->assertEquals($stateId, $state2->getId());
962
    }
963
964
    public function testResolveToOneAssociationCacheEntry()
965
    {
966
        $this->evictRegions();
967
        $this->loadFixturesCountries();
968
        $this->loadFixturesStates();
969
        $this->loadFixturesCities();
970
        $this->evictRegions();
971
972
        $this->_em->clear();
973
974
        $cityId      = $this->cities[0]->getId();
975
        $dql         = 'SELECT c, s FROM Doctrine\Tests\Models\Cache\City c JOIN c.state s WHERE c.id = :id';
976
        $query       = $this->_em->createQuery($dql);
977
        $queryCount  = $this->getCurrentQueryCount();
978
979
        $query1 = clone $query;
980
        $city1 = $query1
981
            ->setParameter('id', $cityId)
982
            ->setCacheable(true)
983
            ->setMaxResults(1)
984
            ->getSingleResult();
985
986
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
987
        $this->assertInstanceOf(City::class, $city1);
988
        $this->assertInstanceOf(State::class, $city1->getState());
989
        $this->assertInstanceOf(City::class, $city1->getState()->getCities()->get(0));
990
        $this->assertInstanceOf(State::class, $city1->getState()->getCities()->get(0)->getState());
991
992
        $this->_em->clear();
993
994
        $queryCount = $this->getCurrentQueryCount();
995
        $query2     = clone $query;
996
        $city2      = $query2
997
            ->setParameter('id', $cityId)
998
            ->setCacheable(true)
999
            ->setMaxResults(1)
1000
            ->getSingleResult();
1001
1002
        $this->assertEquals($queryCount, $this->getCurrentQueryCount());
1003
        $this->assertInstanceOf(City::class, $city2);
1004
        $this->assertInstanceOf(State::class, $city2->getState());
1005
        $this->assertInstanceOf(City::class, $city2->getState()->getCities()->get(0));
1006
        $this->assertInstanceOf(State::class, $city2->getState()->getCities()->get(0)->getState());
1007
    }
1008
1009
    public function testResolveToManyAssociationCacheEntry()
1010
    {
1011
        $this->evictRegions();
1012
        $this->loadFixturesCountries();
1013
        $this->loadFixturesStates();
1014
        $this->loadFixturesCities();
1015
        $this->evictRegions();
1016
1017
        $this->_em->clear();
1018
1019
        $stateId     = $this->states[0]->getId();
1020
        $dql         = 'SELECT s, c FROM Doctrine\Tests\Models\Cache\State s JOIN s.cities c WHERE s.id = :id';
1021
        $query       = $this->_em->createQuery($dql);
1022
        $queryCount  = $this->getCurrentQueryCount();
1023
1024
        $query1 = clone $query;
1025
        $state1 = $query1
1026
            ->setParameter('id', $stateId)
1027
            ->setCacheable(true)
1028
            ->setMaxResults(1)
1029
            ->getSingleResult();
1030
1031
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
1032
        $this->assertInstanceOf(State::class, $state1);
1033
        $this->assertInstanceOf(Proxy::class, $state1->getCountry());
1034
        $this->assertInstanceOf(City::class, $state1->getCities()->get(0));
1035
        $this->assertInstanceOf(State::class, $state1->getCities()->get(0)->getState());
1036
        $this->assertSame($state1, $state1->getCities()->get(0)->getState());
1037
1038
        $this->_em->clear();
1039
1040
        $queryCount = $this->getCurrentQueryCount();
1041
        $query2     = clone $query;
1042
        $state2     = $query2
1043
            ->setParameter('id', $stateId)
1044
            ->setCacheable(true)
1045
            ->setMaxResults(1)
1046
            ->getSingleResult();
1047
1048
        $this->assertEquals($queryCount, $this->getCurrentQueryCount());
1049
        $this->assertInstanceOf(State::class, $state2);
1050
        $this->assertInstanceOf(Proxy::class, $state2->getCountry());
1051
        $this->assertInstanceOf(City::class, $state2->getCities()->get(0));
1052
        $this->assertInstanceOf(State::class, $state2->getCities()->get(0)->getState());
1053
        $this->assertSame($state2, $state2->getCities()->get(0)->getState());
1054
    }
1055
1056
    public function testHintClearEntityRegionUpdateStatement()
1057
    {
1058
        $this->evictRegions();
1059
        $this->loadFixturesCountries();
1060
1061
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
1062
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
1063
1064
        $this->_em->createQuery('DELETE Doctrine\Tests\Models\Cache\Country u WHERE u.id = 4')
1065
            ->setHint(Query::HINT_CACHE_EVICT, true)
1066
            ->execute();
1067
1068
        $this->assertFalse($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
1069
        $this->assertFalse($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
1070
    }
1071
1072
    public function testHintClearEntityRegionDeleteStatement()
1073
    {
1074
        $this->evictRegions();
1075
        $this->loadFixturesCountries();
1076
1077
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
1078
        $this->assertTrue($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
1079
1080
        $this->_em->createQuery("UPDATE Doctrine\Tests\Models\Cache\Country u SET u.name = 'foo' WHERE u.id = 1")
1081
            ->setHint(Query::HINT_CACHE_EVICT, true)
1082
            ->execute();
1083
1084
        $this->assertFalse($this->cache->containsEntity(Country::class, $this->countries[0]->getId()));
1085
        $this->assertFalse($this->cache->containsEntity(Country::class, $this->countries[1]->getId()));
1086
    }
1087
1088
    /**
1089
     * @expectedException \Doctrine\ORM\Cache\CacheException
1090
     * @expectedExceptionMessage Second level cache does not support partial entities.
1091
     */
1092
    public function testCacheablePartialQueryException()
1093
    {
1094
        $this->evictRegions();
1095
        $this->loadFixturesCountries();
1096
1097
        $this->_em->createQuery("SELECT PARTIAL c.{id} FROM Doctrine\Tests\Models\Cache\Country c")
1098
            ->setCacheable(true)
1099
            ->getResult();
1100
    }
1101
1102
    /**
1103
     * @expectedException \Doctrine\ORM\Cache\CacheException
1104
     * @expectedExceptionMessage Second level cache does not support partial entities.
1105
     */
1106
    public function testCacheableForcePartialLoadHintQueryException()
1107
    {
1108
        $this->evictRegions();
1109
        $this->loadFixturesCountries();
1110
1111
        $this->_em->createQuery('SELECT c FROM Doctrine\Tests\Models\Cache\Country c')
1112
            ->setCacheable(true)
1113
            ->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
1114
            ->getResult();
1115
    }
1116
1117
    /**
1118
     * @expectedException \Doctrine\ORM\Cache\CacheException
1119
     * @expectedExceptionMessage Second-level cache query supports only select statements.
1120
     */
1121
    public function testNonCacheableQueryDeleteStatementException()
1122
    {
1123
        $this->_em->createQuery("DELETE Doctrine\Tests\Models\Cache\Country u WHERE u.id = 4")
1124
            ->setCacheable(true)
1125
            ->getResult();
1126
    }
1127
1128
    /**
1129
     * @expectedException \Doctrine\ORM\Cache\CacheException
1130
     * @expectedExceptionMessage Second-level cache query supports only select statements.
1131
     */
1132
    public function testNonCacheableQueryUpdateStatementException()
1133
    {
1134
        $this->_em->createQuery("UPDATE Doctrine\Tests\Models\Cache\Country u SET u.name = 'foo' WHERE u.id = 4")
1135
            ->setCacheable(true)
1136
            ->getResult();
1137
    }
1138
1139
    public function testQueryCacheShouldBeEvictedOnTimestampUpdate()
1140
    {
1141
        $this->loadFixturesCountries();
1142
        $this->_em->clear();
1143
1144
        $queryCount = $this->getCurrentQueryCount();
1145
        $dql        = 'SELECT country FROM Doctrine\Tests\Models\Cache\Country country';
1146
1147
        $result1    = $this->_em->createQuery($dql)
1148
            ->setCacheable(true)
1149
            ->getResult();
1150
1151
        $this->assertCount(2, $result1);
1152
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
1153
1154
        $this->_em->persist(new Country('France'));
1155
        $this->_em->flush();
1156
        $this->_em->clear();
1157
1158
        $queryCount = $this->getCurrentQueryCount();
1159
1160
        $result2 = $this->_em->createQuery($dql)
1161
            ->setCacheable(true)
1162
            ->getResult();
1163
1164
        $this->assertCount(3, $result2);
1165
        $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
1166
1167
        foreach ($result2 as $entity) {
1168
            $this->assertInstanceOf(Country::class, $entity);
1169
        }
1170
    }
1171
}
1172