Passed
Pull Request — 2.6 (#7778)
by Luís
06:51
created

testGetWithAssociationCacheMiss()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 13
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 26
rs 9.8333
1
<?php
2
3
namespace Doctrine\Tests\ORM\Cache;
4
5
use Doctrine\Common\Collections\Collection;
6
use Doctrine\ORM\Cache\EntityCacheKey;
7
use Doctrine\ORM\Cache\QueryCache;
8
use Doctrine\Tests\Mocks\TimestampRegionMock;
9
use Doctrine\Tests\OrmTestCase;
10
use Doctrine\Tests\Mocks\CacheRegionMock;
11
use Doctrine\ORM\Cache\DefaultQueryCache;
12
use Doctrine\ORM\Cache\QueryCacheKey;
13
use Doctrine\ORM\Cache\QueryCacheEntry;
14
use Doctrine\ORM\Query\ResultSetMappingBuilder;
15
use Doctrine\Tests\Models\Cache\Country;
16
use Doctrine\Tests\Models\Cache\City;
17
use Doctrine\Tests\Models\Cache\State;
18
use Doctrine\Tests\Models\Cache\Restaurant;
19
use Doctrine\ORM\EntityManagerInterface;
20
use Doctrine\Tests\Models\Generic\BooleanModel;
21
use Doctrine\ORM\Cache\EntityCacheEntry;
22
use Doctrine\ORM\Cache;
23
24
/**
25
 * @group DDC-2183
26
 */
27
class DefaultQueryCacheTest extends OrmTestCase
28
{
29
    /**
30
     * @var \Doctrine\ORM\Cache\DefaultQueryCache
31
     */
32
    private $queryCache;
33
34
    /**
35
     * @var \Doctrine\ORM\EntityManager
36
     */
37
    private $em;
38
39
    /**
40
     * @var \Doctrine\Tests\Mocks\CacheRegionMock
41
     */
42
    private $region;
43
44
    /**
45
     * @var \Doctrine\Tests\ORM\Cache\CacheFactoryDefaultQueryCacheTest
46
     */
47
    private $cacheFactory;
48
49
    protected function setUp()
50
    {
51
        parent::setUp();
52
53
        $this->enableSecondLevelCache();
54
55
        $this->em           = $this->_getTestEntityManager();
56
        $this->region       = new CacheRegionMock();
57
        $this->queryCache   = new DefaultQueryCache($this->em, $this->region);
58
        $this->cacheFactory = new CacheFactoryDefaultQueryCacheTest($this->queryCache, $this->region);
59
60
        $this->em->getConfiguration()
61
            ->getSecondLevelCacheConfiguration()
62
            ->setCacheFactory($this->cacheFactory);
63
    }
64
65
    public function testImplementQueryCache()
66
    {
67
        $this->assertInstanceOf(QueryCache::class, $this->queryCache);
68
    }
69
70
    public function testGetRegion()
71
    {
72
        $this->assertSame($this->region, $this->queryCache->getRegion());
73
    }
74
75
    public function testClearShouldEvictRegion()
76
    {
77
        $this->queryCache->clear();
78
79
        $this->assertArrayHasKey('evictAll', $this->region->calls);
80
        $this->assertCount(1, $this->region->calls['evictAll']);
81
    }
82
83
    public function testPutBasicQueryResult()
84
    {
85
        $result   = [];
86
        $key      = new QueryCacheKey('query.key1', 0);
87
        $rsm      = new ResultSetMappingBuilder($this->em);
88
        $metadata = $this->em->getClassMetadata(Country::class);
89
90
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
91
92
        for ($i = 0; $i < 4; $i++) {
93
            $name       = "Country $i";
94
            $entity     = new Country($name);
95
            $result[]   = $entity;
96
97
            $metadata->setFieldValue($entity, 'id', $i);
98
            $this->em->getUnitOfWork()->registerManaged($entity, ['id' => $i], ['name' => $name]);
99
        }
100
101
        $this->assertTrue($this->queryCache->put($key, $rsm, $result));
102
        $this->assertArrayHasKey('put', $this->region->calls);
103
        $this->assertCount(5, $this->region->calls['put']);
104
105
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][0]['key']);
106
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][1]['key']);
107
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][2]['key']);
108
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][3]['key']);
109
        $this->assertInstanceOf(QueryCacheKey::class, $this->region->calls['put'][4]['key']);
110
111
        $this->assertInstanceOf(EntityCacheEntry::class, $this->region->calls['put'][0]['entry']);
112
        $this->assertInstanceOf(EntityCacheEntry::class, $this->region->calls['put'][1]['entry']);
113
        $this->assertInstanceOf(EntityCacheEntry::class, $this->region->calls['put'][2]['entry']);
114
        $this->assertInstanceOf(EntityCacheEntry::class, $this->region->calls['put'][3]['entry']);
115
        $this->assertInstanceOf(QueryCacheEntry::class, $this->region->calls['put'][4]['entry']);
116
    }
117
118
    public function testPutToOneAssociationQueryResult()
119
    {
120
        $result     = [];
121
        $uow        = $this->em->getUnitOfWork();
122
        $key        = new QueryCacheKey('query.key1', 0);
123
        $rsm        = new ResultSetMappingBuilder($this->em);
124
        $cityClass  = $this->em->getClassMetadata(City::class);
125
        $stateClass = $this->em->getClassMetadata(State::class);
126
127
        $rsm->addRootEntityFromClassMetadata(City::class, 'c');
128
        $rsm->addJoinedEntityFromClassMetadata(State::class, 's', 'c', 'state', ['id'=>'state_id', 'name'=>'state_name']);
129
130
        for ($i = 0; $i < 4; $i++) {
131
            $state    = new State("State $i");
132
            $city     = new City("City $i", $state);
133
            $result[] = $city;
134
135
            $cityClass->setFieldValue($city, 'id', $i);
136
            $stateClass->setFieldValue($state, 'id', $i*2);
137
138
            $uow->registerManaged($state, ['id' => $state->getId()], ['name' => $city->getName()]);
139
            $uow->registerManaged($city, ['id' => $city->getId()], ['name' => $city->getName(), 'state' => $state]);
140
        }
141
142
        $this->assertTrue($this->queryCache->put($key, $rsm, $result));
143
        $this->assertArrayHasKey('put', $this->region->calls);
144
        $this->assertCount(9, $this->region->calls['put']);
145
146
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][0]['key']);
147
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][1]['key']);
148
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][2]['key']);
149
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][3]['key']);
150
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][4]['key']);
151
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][5]['key']);
152
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][6]['key']);
153
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][7]['key']);
154
        $this->assertInstanceOf(QueryCacheKey::class, $this->region->calls['put'][8]['key']);
155
    }
156
157
    public function testPutToOneAssociation2LevelsQueryResult()
158
    {
159
        $result     = [];
160
        $uow        = $this->em->getUnitOfWork();
161
        $key        = new QueryCacheKey('query.key1', 0);
162
        $rsm        = new ResultSetMappingBuilder($this->em);
163
        $cityClass  = $this->em->getClassMetadata(City::class);
164
        $stateClass = $this->em->getClassMetadata(State::class);
165
        $countryClass = $this->em->getClassMetadata(Country::class);
166
167
        $rsm->addRootEntityFromClassMetadata(City::class, 'c');
168
        $rsm->addJoinedEntityFromClassMetadata(State::class, 's', 'c', 'state', ['id'=>'state_id', 'name'=>'state_name']
169
        );
170
        $rsm->addJoinedEntityFromClassMetadata(Country::class, 'co', 's', 'country', ['id'=>'country_id', 'name'=>'country_name']
171
        );
172
173
        for ($i = 0; $i < 4; $i++) {
174
            $country  = new Country("Country $i");
175
            $state    = new State("State $i", $country);
176
            $city     = new City("City $i", $state);
177
178
            $result[] = $city;
179
180
            $cityClass->setFieldValue($city, 'id', $i);
181
            $stateClass->setFieldValue($state, 'id', $i*2);
182
            $countryClass->setFieldValue($country, 'id', $i*3);
183
184
            $uow->registerManaged($country, ['id' => $country->getId()], ['name' => $country->getName()]);
185
            $uow->registerManaged($state, ['id' => $state->getId()], ['name' => $state->getName(), 'country' => $country]
186
            );
187
            $uow->registerManaged($city, ['id' => $city->getId()], ['name' => $city->getName(), 'state' => $state]);
188
        }
189
190
        $this->assertTrue($this->queryCache->put($key, $rsm, $result));
191
        $this->assertArrayHasKey('put', $this->region->calls);
192
        $this->assertCount(13, $this->region->calls['put']);
193
194
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][0]['key']);
195
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][1]['key']);
196
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][2]['key']);
197
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][3]['key']);
198
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][4]['key']);
199
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][5]['key']);
200
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][6]['key']);
201
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][7]['key']);
202
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][8]['key']);
203
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][9]['key']);
204
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][10]['key']);
205
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][11]['key']);
206
        $this->assertInstanceOf(QueryCacheKey::class, $this->region->calls['put'][12]['key']);
207
    }
208
209
    public function testPutToOneAssociationNullQueryResult()
210
    {
211
        $result     = [];
212
        $uow        = $this->em->getUnitOfWork();
213
        $key        = new QueryCacheKey('query.key1', 0);
214
        $rsm        = new ResultSetMappingBuilder($this->em);
215
        $cityClass  = $this->em->getClassMetadata(City::class);
216
217
        $rsm->addRootEntityFromClassMetadata(City::class, 'c');
218
        $rsm->addJoinedEntityFromClassMetadata(State::class, 's', 'c', 'state', ['id'=>'state_id', 'name'=>'state_name']
219
        );
220
221
        for ($i = 0; $i < 4; $i++) {
222
            $city     = new City("City $i", null);
223
            $result[] = $city;
224
225
            $cityClass->setFieldValue($city, 'id', $i);
226
227
            $uow->registerManaged($city, ['id' => $city->getId()], ['name' => $city->getName(), 'state' => null]);
228
        }
229
230
        $this->assertTrue($this->queryCache->put($key, $rsm, $result));
231
        $this->assertArrayHasKey('put', $this->region->calls);
232
        $this->assertCount(5, $this->region->calls['put']);
233
234
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][0]['key']);
235
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][1]['key']);
236
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][2]['key']);
237
        $this->assertInstanceOf(EntityCacheKey::class, $this->region->calls['put'][3]['key']);
238
        $this->assertInstanceOf(QueryCacheKey::class, $this->region->calls['put'][4]['key']);
239
    }
240
241
    public function testPutToManyAssociationQueryResult()
242
    {
243
        $result     = [];
244
        $uow        = $this->em->getUnitOfWork();
245
        $key        = new QueryCacheKey('query.key1', 0);
246
        $rsm        = new ResultSetMappingBuilder($this->em);
247
        $cityClass  = $this->em->getClassMetadata(City::class);
248
        $stateClass = $this->em->getClassMetadata(State::class);
249
250
        $rsm->addRootEntityFromClassMetadata(State::class, 's');
251
        $rsm->addJoinedEntityFromClassMetadata(City::class, 'c', 's', 'cities', ['id'=>'c_id', 'name'=>'c_name']);
252
253
        for ($i = 0; $i < 4; $i++) {
254
            $state    = new State("State $i");
255
            $city1    = new City("City 1", $state);
256
            $city2    = new City("City 2", $state);
257
            $result[] = $state;
258
259
            $cityClass->setFieldValue($city1, 'id', $i + 11);
260
            $cityClass->setFieldValue($city2, 'id', $i + 22);
261
            $stateClass->setFieldValue($state, 'id', $i);
262
263
            $state->addCity($city1);
264
            $state->addCity($city2);
265
266
            $uow->registerManaged($city1, ['id' => $city1->getId()], ['name' => $city1->getName(), 'state' => $state]
267
            );
268
            $uow->registerManaged($city2, ['id' => $city2->getId()], ['name' => $city2->getName(), 'state' => $state]
269
            );
270
            $uow->registerManaged($state, ['id' => $state->getId()], ['name' => $state->getName(), 'cities' => $state->getCities()]
271
            );
272
        }
273
274
        $this->assertTrue($this->queryCache->put($key, $rsm, $result));
275
        $this->assertArrayHasKey('put', $this->region->calls);
276
        $this->assertCount(13, $this->region->calls['put']);
277
    }
278
279
    public function testGetBasicQueryResult()
280
    {
281
        $rsm   = new ResultSetMappingBuilder($this->em);
282
        $key   = new QueryCacheKey('query.key1', 0);
283
        $entry = new QueryCacheEntry(
284
            [
285
                ['identifier' => ['id' => 1]],
286
                ['identifier' => ['id' => 2]]
287
            ]
288
        );
289
290
        $data = [
291
            ['id'=>1, 'name' => 'Foo'],
292
            ['id'=>2, 'name' => 'Bar']
293
        ];
294
295
        $this->region->addReturn('get', $entry);
296
297
        $this->region->addReturn(
298
            'getMultiple',
299
            [
300
                new EntityCacheEntry(Country::class, $data[0]),
301
                new EntityCacheEntry(Country::class, $data[1])
302
            ]
303
        );
304
305
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
306
307
        $result = $this->queryCache->get($key, $rsm);
308
309
        $this->assertCount(2, $result);
310
        $this->assertInstanceOf(Country::class, $result[0]);
311
        $this->assertInstanceOf(Country::class, $result[1]);
312
        $this->assertEquals(1, $result[0]->getId());
313
        $this->assertEquals(2, $result[1]->getId());
314
        $this->assertEquals('Foo', $result[0]->getName());
315
        $this->assertEquals('Bar', $result[1]->getName());
316
    }
317
318
    public function testGetWithAssociation()
319
    {
320
        $rsm   = new ResultSetMappingBuilder($this->em);
321
        $key   = new QueryCacheKey('query.key1', 0);
322
        $entry = new QueryCacheEntry(
323
            [
324
                ['identifier' => ['id' => 1]],
325
                ['identifier' => ['id' => 2]]
326
            ]
327
        );
328
329
        $data = [
330
            ['id'=>1, 'name' => 'Foo'],
331
            ['id'=>2, 'name' => 'Bar']
332
        ];
333
334
        $this->region->addReturn('get', $entry);
335
336
        $this->region->addReturn(
337
            'getMultiple',
338
            [
339
                new EntityCacheEntry(Country::class, $data[0]),
340
                new EntityCacheEntry(Country::class, $data[1])
341
            ]
342
        );
343
344
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
345
346
        $result = $this->queryCache->get($key, $rsm);
347
348
        $this->assertCount(2, $result);
349
        $this->assertInstanceOf(Country::class, $result[0]);
350
        $this->assertInstanceOf(Country::class, $result[1]);
351
        $this->assertEquals(1, $result[0]->getId());
352
        $this->assertEquals(2, $result[1]->getId());
353
        $this->assertEquals('Foo', $result[0]->getName());
354
        $this->assertEquals('Bar', $result[1]->getName());
355
    }
356
357
    public function testGetWithAssociationCacheMiss() : void
358
    {
359
        $rsm   = new ResultSetMappingBuilder($this->em);
360
        $key   = new QueryCacheKey('query.key1', 0);
361
        $entry = new QueryCacheEntry(
362
            [
363
                ['identifier' => ['id' => 1]],
364
                ['identifier' => ['id' => 2]],
365
            ]
366
        );
367
368
        $this->region->addReturn('get', $entry);
369
370
        $this->region->addReturn(
371
            'getMultiple',
372
            [
373
                new EntityCacheEntry(Country::class, ['id' => 1, 'name' => 'Foo']),
374
                false,
375
            ]
376
        );
377
378
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
379
380
        $result = $this->queryCache->get($key, $rsm);
381
382
        self::assertNull($result);
383
    }
384
385
    public function testCancelPutResultIfEntityPutFails()
386
    {
387
        $result   = [];
388
        $key      = new QueryCacheKey('query.key1', 0);
389
        $rsm      = new ResultSetMappingBuilder($this->em);
390
        $metadata = $this->em->getClassMetadata(Country::class);
391
392
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
393
394
        for ($i = 0; $i < 4; $i++) {
395
            $name       = "Country $i";
396
            $entity     = new Country($name);
397
            $result[]   = $entity;
398
399
            $metadata->setFieldValue($entity, 'id', $i);
400
            $this->em->getUnitOfWork()->registerManaged($entity, ['id' => $i], ['name' => $name]);
401
        }
402
403
        $this->region->addReturn('put', false);
404
405
        $this->assertFalse($this->queryCache->put($key, $rsm, $result));
406
        $this->assertArrayHasKey('put', $this->region->calls);
407
        $this->assertCount(1, $this->region->calls['put']);
408
    }
409
410
    public function testCancelPutResultIfAssociationEntityPutFails()
411
    {
412
        $result     = [];
413
        $uow        = $this->em->getUnitOfWork();
414
        $key        = new QueryCacheKey('query.key1', 0);
415
        $rsm        = new ResultSetMappingBuilder($this->em);
416
        $cityClass  = $this->em->getClassMetadata(City::class);
417
        $stateClass = $this->em->getClassMetadata(State::class);
418
419
        $rsm->addRootEntityFromClassMetadata(City::class, 'c');
420
        $rsm->addJoinedEntityFromClassMetadata(State::class, 's', 'c', 'state', ['id'=>'state_id', 'name'=>'state_name']
421
        );
422
423
        $state    = new State("State 1");
424
        $city     = new City("City 2", $state);
425
        $result[] = $city;
426
427
        $cityClass->setFieldValue($city, 'id', 1);
428
        $stateClass->setFieldValue($state, 'id', 11);
429
430
        $uow->registerManaged($state, ['id' => $state->getId()], ['name' => $city->getName()]);
431
        $uow->registerManaged($city, ['id' => $city->getId()], ['name' => $city->getName(), 'state' => $state]);
432
433
        $this->region->addReturn('put', true);  // put root entity
434
        $this->region->addReturn('put', false); // association fails
435
436
        $this->assertFalse($this->queryCache->put($key, $rsm, $result));
437
    }
438
439
    public function testCancelPutToManyAssociationQueryResult()
440
    {
441
        $result     = [];
442
        $uow        = $this->em->getUnitOfWork();
443
        $key        = new QueryCacheKey('query.key1', 0);
444
        $rsm        = new ResultSetMappingBuilder($this->em);
445
        $cityClass  = $this->em->getClassMetadata(City::class);
446
        $stateClass = $this->em->getClassMetadata(State::class);
447
448
        $rsm->addRootEntityFromClassMetadata(State::class, 's');
449
        $rsm->addJoinedEntityFromClassMetadata(City::class, 'c', 's', 'cities', ['id'=>'c_id', 'name'=>'c_name']);
450
451
        $state    = new State("State");
452
        $city1    = new City("City 1", $state);
453
        $city2    = new City("City 2", $state);
454
        $result[] = $state;
455
456
        $stateClass->setFieldValue($state, 'id', 1);
457
        $cityClass->setFieldValue($city1, 'id', 11);
458
        $cityClass->setFieldValue($city2, 'id', 22);
459
460
        $state->addCity($city1);
461
        $state->addCity($city2);
462
463
        $uow->registerManaged($city1, ['id' => $city1->getId()], ['name' => $city1->getName(), 'state' => $state]);
464
        $uow->registerManaged($city2, ['id' => $city2->getId()], ['name' => $city2->getName(), 'state' => $state]);
465
        $uow->registerManaged($state, ['id' => $state->getId()], ['name' => $state->getName(), 'cities' => $state->getCities()]
466
        );
467
468
        $this->region->addReturn('put', true);  // put root entity
469
        $this->region->addReturn('put', false); // collection association fails
470
471
        $this->assertFalse($this->queryCache->put($key, $rsm, $result));
472
        $this->assertArrayHasKey('put', $this->region->calls);
473
        $this->assertCount(2, $this->region->calls['put']);
474
    }
475
476
    public function testIgnoreCacheNonGetMode()
477
    {
478
        $rsm   = new ResultSetMappingBuilder($this->em);
479
        $key   = new QueryCacheKey('query.key1', 0, Cache::MODE_PUT);
480
        $entry = new QueryCacheEntry(
481
            [
482
            ['identifier' => ['id' => 1]],
483
            ['identifier' => ['id' => 2]]
484
            ]
485
        );
486
487
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
488
489
        $this->region->addReturn('get', $entry);
490
491
        $this->assertNull($this->queryCache->get($key, $rsm));
492
    }
493
494
    public function testIgnoreCacheNonPutMode()
495
    {
496
        $result   = [];
497
        $rsm      = new ResultSetMappingBuilder($this->em);
498
        $metadata = $this->em->getClassMetadata(Country::class);
499
        $key      = new QueryCacheKey('query.key1', 0, Cache::MODE_GET);
500
501
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
502
503
        for ($i = 0; $i < 4; $i++) {
504
            $name       = "Country $i";
505
            $entity     = new Country($name);
506
            $result[]   = $entity;
507
508
            $metadata->setFieldValue($entity, 'id', $i);
509
            $this->em->getUnitOfWork()->registerManaged($entity, ['id' => $i], ['name' => $name]);
510
        }
511
512
        $this->assertFalse($this->queryCache->put($key, $rsm, $result));
513
    }
514
515
    public function testGetShouldIgnoreOldQueryCacheEntryResult()
516
    {
517
        $rsm   = new ResultSetMappingBuilder($this->em);
518
        $key   = new QueryCacheKey('query.key1', 50);
519
        $entry = new QueryCacheEntry(
520
            [
521
            ['identifier' => ['id' => 1]],
522
            ['identifier' => ['id' => 2]]
523
            ]
524
        );
525
        $entities = [
526
            ['id'=>1, 'name' => 'Foo'],
527
            ['id'=>2, 'name' => 'Bar']
528
        ];
529
530
        $entry->time = microtime(true) - 100;
531
532
        $this->region->addReturn('get', $entry);
533
534
        $this->region->addReturn(
535
            'getMultiple',
536
            [
537
                new EntityCacheEntry(Country::class, $entities[0]),
538
                new EntityCacheEntry(Country::class, $entities[1])
539
            ]
540
        );
541
542
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
543
544
        $this->assertNull($this->queryCache->get($key, $rsm));
545
    }
546
547
    public function testGetShouldIgnoreNonQueryCacheEntryResult()
548
    {
549
        $rsm   = new ResultSetMappingBuilder($this->em);
550
        $key   = new QueryCacheKey('query.key1', 0);
551
        $entry = new \ArrayObject(
552
            [
553
            ['identifier' => ['id' => 1]],
554
            ['identifier' => ['id' => 2]]
555
            ]
556
        );
557
558
        $data = [
559
            ['id'=>1, 'name' => 'Foo'],
560
            ['id'=>2, 'name' => 'Bar']
561
        ];
562
563
        $this->region->addReturn('get', $entry);
564
565
        $this->region->addReturn(
566
            'getMultiple',
567
            [
568
                new EntityCacheEntry(Country::class, $data[0]),
569
                new EntityCacheEntry(Country::class, $data[1])
570
            ]
571
        );
572
573
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
574
575
        $this->assertNull($this->queryCache->get($key, $rsm));
576
    }
577
578
    public function testGetShouldIgnoreMissingEntityQueryCacheEntry()
579
    {
580
        $rsm   = new ResultSetMappingBuilder($this->em);
581
        $key   = new QueryCacheKey('query.key1', 0);
582
        $entry = new QueryCacheEntry(
583
            [
584
            ['identifier' => ['id' => 1]],
585
            ['identifier' => ['id' => 2]]
586
            ]
587
        );
588
589
        $this->region->addReturn('get', $entry);
590
        $this->region->addReturn('getMultiple', [null]);
591
592
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
593
594
        $this->assertNull($this->queryCache->get($key, $rsm));
595
    }
596
597
    public function testGetAssociationValue()
598
    {
599
        $reflection = new \ReflectionMethod($this->queryCache, 'getAssociationValue');
600
        $rsm        = new ResultSetMappingBuilder($this->em);
601
        $key        = new QueryCacheKey('query.key1', 0);
0 ignored issues
show
Unused Code introduced by
The assignment to $key is dead and can be removed.
Loading history...
602
603
        $reflection->setAccessible(true);
604
605
        $germany  = new Country("Germany");
606
        $bavaria  = new State("Bavaria", $germany);
607
        $wurzburg = new City("Würzburg", $bavaria);
608
        $munich   = new City("Munich", $bavaria);
609
610
        $bavaria->addCity($munich);
611
        $bavaria->addCity($wurzburg);
612
613
        $munich->addAttraction(new Restaurant('Reinstoff', $munich));
614
        $munich->addAttraction(new Restaurant('Schneider Weisse', $munich));
615
        $wurzburg->addAttraction(new Restaurant('Fischers Fritz', $wurzburg));
616
617
        $rsm->addRootEntityFromClassMetadata(State::class, 's');
618
        $rsm->addJoinedEntityFromClassMetadata(City::class, 'c', 's', 'cities', [
619
            'id'   => 'c_id',
620
            'name' => 'c_name'
621
        ]
622
        );
623
        $rsm->addJoinedEntityFromClassMetadata(Restaurant::class, 'a', 'c', 'attractions', [
624
            'id'   => 'a_id',
625
            'name' => 'a_name'
626
        ]
627
        );
628
629
        $cities      = $reflection->invoke($this->queryCache, $rsm, 'c', $bavaria);
630
        $attractions = $reflection->invoke($this->queryCache, $rsm, 'a', $bavaria);
631
632
        $this->assertCount(2, $cities);
633
        $this->assertCount(2,  $attractions);
634
635
        $this->assertInstanceOf(Collection::class, $cities);
636
        $this->assertInstanceOf(Collection::class, $attractions[0]);
637
        $this->assertInstanceOf(Collection::class, $attractions[1]);
638
639
        $this->assertCount(2, $attractions[0]);
640
        $this->assertCount(1, $attractions[1]);
641
    }
642
643
    /**
644
     * @expectedException Doctrine\ORM\Cache\CacheException
645
     * @expectedExceptionMessage Second level cache does not support scalar results.
646
     */
647
    public function testScalarResultException()
648
    {
649
        $result   = [];
650
        $key      = new QueryCacheKey('query.key1', 0);
651
        $rsm      = new ResultSetMappingBuilder($this->em);
652
653
        $rsm->addScalarResult('id', 'u', 'integer');
654
655
        $this->queryCache->put($key, $rsm, $result);
656
    }
657
658
    /**
659
     * @expectedException Doctrine\ORM\Cache\CacheException
660
     * @expectedExceptionMessage Second level cache does not support multiple root entities.
661
     */
662
    public function testSupportMultipleRootEntitiesException()
663
    {
664
        $result   = [];
665
        $key      = new QueryCacheKey('query.key1', 0);
666
        $rsm      = new ResultSetMappingBuilder($this->em);
667
668
        $rsm->addEntityResult(City::class, 'e1');
669
        $rsm->addEntityResult(State::class, 'e2');
670
671
        $this->queryCache->put($key, $rsm, $result);
672
    }
673
674
    /**
675
     * @expectedException Doctrine\ORM\Cache\CacheException
676
     * @expectedExceptionMessage Entity "Doctrine\Tests\Models\Generic\BooleanModel" not configured as part of the second-level cache.
677
     */
678
    public function testNotCacheableEntityException()
679
    {
680
        $result    = [];
681
        $key       = new QueryCacheKey('query.key1', 0);
682
        $rsm       = new ResultSetMappingBuilder($this->em);
683
        $rsm->addRootEntityFromClassMetadata(BooleanModel::class, 'c');
684
685
        for ($i = 0; $i < 4; $i++) {
686
            $entity  = new BooleanModel();
687
            $boolean = ($i % 2 === 0);
688
689
            $entity->id             = $i;
690
            $entity->booleanField   = $boolean;
691
            $result[]               = $entity;
692
693
            $this->em->getUnitOfWork()->registerManaged($entity, ['id' => $i], ['booleanField' => $boolean]);
694
        }
695
696
        $this->assertFalse($this->queryCache->put($key, $rsm, $result));
697
    }
698
699
}
700
701
class CacheFactoryDefaultQueryCacheTest extends Cache\DefaultCacheFactory
702
{
703
    private $queryCache;
704
    private $region;
705
706
    public function __construct(DefaultQueryCache $queryCache, CacheRegionMock $region)
707
    {
708
        $this->queryCache = $queryCache;
709
        $this->region     = $region;
710
    }
711
712
    public function buildQueryCache(EntityManagerInterface $em, $regionName = null)
713
    {
714
        return $this->queryCache;
715
    }
716
717
    public function getRegion(array $cache)
718
    {
719
        return $this->region;
720
    }
721
722
    public function getTimestampRegion()
723
    {
724
        return new TimestampRegionMock();
725
    }
726
}
727