Completed
Pull Request — master (#6245)
by Luís
10:01
created

DefaultQueryCacheTest::testGetWithAssociation()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 38
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 38
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 23
nc 1
nop 0
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 testCancelPutResultIfEntityPutFails()
358
    {
359
        $result   = [];
360
        $key      = new QueryCacheKey('query.key1', 0);
361
        $rsm      = new ResultSetMappingBuilder($this->em);
362
        $metadata = $this->em->getClassMetadata(Country::class);
363
364
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
365
366
        for ($i = 0; $i < 4; $i++) {
367
            $name       = "Country $i";
368
            $entity     = new Country($name);
369
            $result[]   = $entity;
370
371
            $metadata->setFieldValue($entity, 'id', $i);
372
            $this->em->getUnitOfWork()->registerManaged($entity, ['id' => $i], ['name' => $name]);
373
        }
374
375
        $this->region->addReturn('put', false);
376
377
        $this->assertFalse($this->queryCache->put($key, $rsm, $result));
378
        $this->assertArrayHasKey('put', $this->region->calls);
379
        $this->assertCount(1, $this->region->calls['put']);
380
    }
381
382
    public function testCancelPutResultIfAssociationEntityPutFails()
383
    {
384
        $result     = [];
385
        $uow        = $this->em->getUnitOfWork();
386
        $key        = new QueryCacheKey('query.key1', 0);
387
        $rsm        = new ResultSetMappingBuilder($this->em);
388
        $cityClass  = $this->em->getClassMetadata(City::class);
389
        $stateClass = $this->em->getClassMetadata(State::class);
390
391
        $rsm->addRootEntityFromClassMetadata(City::class, 'c');
392
        $rsm->addJoinedEntityFromClassMetadata(State::class, 's', 'c', 'state', ['id'=>'state_id', 'name'=>'state_name']
393
        );
394
395
        $state    = new State("State 1");
396
        $city     = new City("City 2", $state);
397
        $result[] = $city;
398
399
        $cityClass->setFieldValue($city, 'id', 1);
400
        $stateClass->setFieldValue($state, 'id', 11);
401
402
        $uow->registerManaged($state, ['id' => $state->getId()], ['name' => $city->getName()]);
403
        $uow->registerManaged($city, ['id' => $city->getId()], ['name' => $city->getName(), 'state' => $state]);
404
405
        $this->region->addReturn('put', true);  // put root entity
406
        $this->region->addReturn('put', false); // association fails
407
408
        $this->assertFalse($this->queryCache->put($key, $rsm, $result));
409
    }
410
411
    public function testCancelPutToManyAssociationQueryResult()
412
    {
413
        $result     = [];
414
        $uow        = $this->em->getUnitOfWork();
415
        $key        = new QueryCacheKey('query.key1', 0);
416
        $rsm        = new ResultSetMappingBuilder($this->em);
417
        $cityClass  = $this->em->getClassMetadata(City::class);
418
        $stateClass = $this->em->getClassMetadata(State::class);
419
420
        $rsm->addRootEntityFromClassMetadata(State::class, 's');
421
        $rsm->addJoinedEntityFromClassMetadata(City::class, 'c', 's', 'cities', ['id'=>'c_id', 'name'=>'c_name']);
422
423
        $state    = new State("State");
424
        $city1    = new City("City 1", $state);
425
        $city2    = new City("City 2", $state);
426
        $result[] = $state;
427
428
        $stateClass->setFieldValue($state, 'id', 1);
429
        $cityClass->setFieldValue($city1, 'id', 11);
430
        $cityClass->setFieldValue($city2, 'id', 22);
431
432
        $state->addCity($city1);
433
        $state->addCity($city2);
434
435
        $uow->registerManaged($city1, ['id' => $city1->getId()], ['name' => $city1->getName(), 'state' => $state]);
436
        $uow->registerManaged($city2, ['id' => $city2->getId()], ['name' => $city2->getName(), 'state' => $state]);
437
        $uow->registerManaged($state, ['id' => $state->getId()], ['name' => $state->getName(), 'cities' => $state->getCities()]
438
        );
439
440
        $this->region->addReturn('put', true);  // put root entity
441
        $this->region->addReturn('put', false); // collection association fails
442
443
        $this->assertFalse($this->queryCache->put($key, $rsm, $result));
444
        $this->assertArrayHasKey('put', $this->region->calls);
445
        $this->assertCount(2, $this->region->calls['put']);
446
    }
447
448
    public function testIgnoreCacheNonGetMode()
449
    {
450
        $rsm   = new ResultSetMappingBuilder($this->em);
451
        $key   = new QueryCacheKey('query.key1', 0, Cache::MODE_PUT);
452
        $entry = new QueryCacheEntry(
453
            [
454
            ['identifier' => ['id' => 1]],
455
            ['identifier' => ['id' => 2]]
456
            ]
457
        );
458
459
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
460
461
        $this->region->addReturn('get', $entry);
462
463
        $this->assertNull($this->queryCache->get($key, $rsm));
464
    }
465
466
    public function testIgnoreCacheNonPutMode()
467
    {
468
        $result   = [];
469
        $rsm      = new ResultSetMappingBuilder($this->em);
470
        $metadata = $this->em->getClassMetadata(Country::class);
471
        $key      = new QueryCacheKey('query.key1', 0, Cache::MODE_GET);
472
473
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
474
475
        for ($i = 0; $i < 4; $i++) {
476
            $name       = "Country $i";
477
            $entity     = new Country($name);
478
            $result[]   = $entity;
479
480
            $metadata->setFieldValue($entity, 'id', $i);
481
            $this->em->getUnitOfWork()->registerManaged($entity, ['id' => $i], ['name' => $name]);
482
        }
483
484
        $this->assertFalse($this->queryCache->put($key, $rsm, $result));
485
    }
486
487
    public function testGetShouldIgnoreOldQueryCacheEntryResult()
488
    {
489
        $rsm   = new ResultSetMappingBuilder($this->em);
490
        $key   = new QueryCacheKey('query.key1', 50);
491
        $entry = new QueryCacheEntry(
492
            [
493
            ['identifier' => ['id' => 1]],
494
            ['identifier' => ['id' => 2]]
495
            ]
496
        );
497
        $entities = [
498
            ['id'=>1, 'name' => 'Foo'],
499
            ['id'=>2, 'name' => 'Bar']
500
        ];
501
502
        $entry->time = microtime(true) - 100;
503
504
        $this->region->addReturn('get', $entry);
505
506
        $this->region->addReturn(
507
            'getMultiple',
508
            [
509
                new EntityCacheEntry(Country::class, $entities[0]),
510
                new EntityCacheEntry(Country::class, $entities[1])
511
            ]
512
        );
513
514
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
515
516
        $this->assertNull($this->queryCache->get($key, $rsm));
517
    }
518
519
    public function testGetShouldIgnoreNonQueryCacheEntryResult()
520
    {
521
        $rsm   = new ResultSetMappingBuilder($this->em);
522
        $key   = new QueryCacheKey('query.key1', 0);
523
        $entry = new \ArrayObject(
524
            [
525
            ['identifier' => ['id' => 1]],
526
            ['identifier' => ['id' => 2]]
527
            ]
528
        );
529
530
        $data = [
531
            ['id'=>1, 'name' => 'Foo'],
532
            ['id'=>2, 'name' => 'Bar']
533
        ];
534
535
        $this->region->addReturn('get', $entry);
536
537
        $this->region->addReturn(
538
            'getMultiple',
539
            [
540
                new EntityCacheEntry(Country::class, $data[0]),
541
                new EntityCacheEntry(Country::class, $data[1])
542
            ]
543
        );
544
545
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
546
547
        $this->assertNull($this->queryCache->get($key, $rsm));
548
    }
549
550
    public function testGetShouldIgnoreMissingEntityQueryCacheEntry()
551
    {
552
        $rsm   = new ResultSetMappingBuilder($this->em);
553
        $key   = new QueryCacheKey('query.key1', 0);
554
        $entry = new QueryCacheEntry(
555
            [
556
            ['identifier' => ['id' => 1]],
557
            ['identifier' => ['id' => 2]]
558
            ]
559
        );
560
561
        $this->region->addReturn('get', $entry);
562
        $this->region->addReturn('getMultiple', [null]);
563
564
        $rsm->addRootEntityFromClassMetadata(Country::class, 'c');
565
566
        $this->assertNull($this->queryCache->get($key, $rsm));
567
    }
568
569
    public function testGetAssociationValue()
570
    {
571
        $reflection = new \ReflectionMethod($this->queryCache, 'getAssociationValue');
572
        $rsm        = new ResultSetMappingBuilder($this->em);
573
        $key        = new QueryCacheKey('query.key1', 0);
574
575
        $reflection->setAccessible(true);
576
577
        $germany  = new Country("Germany");
578
        $bavaria  = new State("Bavaria", $germany);
579
        $wurzburg = new City("Würzburg", $bavaria);
580
        $munich   = new City("Munich", $bavaria);
581
582
        $bavaria->addCity($munich);
583
        $bavaria->addCity($wurzburg);
584
585
        $munich->addAttraction(new Restaurant('Reinstoff', $munich));
586
        $munich->addAttraction(new Restaurant('Schneider Weisse', $munich));
587
        $wurzburg->addAttraction(new Restaurant('Fischers Fritz', $wurzburg));
588
589
        $rsm->addRootEntityFromClassMetadata(State::class, 's');
590
        $rsm->addJoinedEntityFromClassMetadata(City::class, 'c', 's', 'cities', [
591
            'id'   => 'c_id',
592
            'name' => 'c_name'
593
        ]
594
        );
595
        $rsm->addJoinedEntityFromClassMetadata(Restaurant::class, 'a', 'c', 'attractions', [
596
            'id'   => 'a_id',
597
            'name' => 'a_name'
598
        ]
599
        );
600
601
        $cities      = $reflection->invoke($this->queryCache, $rsm, 'c', $bavaria);
602
        $attractions = $reflection->invoke($this->queryCache, $rsm, 'a', $bavaria);
603
604
        $this->assertCount(2, $cities);
605
        $this->assertCount(2,  $attractions);
606
607
        $this->assertInstanceOf(Collection::class, $cities);
608
        $this->assertInstanceOf(Collection::class, $attractions[0]);
609
        $this->assertInstanceOf(Collection::class, $attractions[1]);
610
611
        $this->assertCount(2, $attractions[0]);
612
        $this->assertCount(1, $attractions[1]);
613
    }
614
615
    /**
616
     * @expectedException Doctrine\ORM\Cache\CacheException
617
     * @expectedExceptionMessage Second level cache does not support scalar results.
618
     */
619
    public function testScalarResultException()
620
    {
621
        $result   = [];
622
        $key      = new QueryCacheKey('query.key1', 0);
623
        $rsm      = new ResultSetMappingBuilder($this->em);
624
625
        $rsm->addScalarResult('id', 'u', 'integer');
626
627
        $this->queryCache->put($key, $rsm, $result);
628
    }
629
630
    /**
631
     * @expectedException Doctrine\ORM\Cache\CacheException
632
     * @expectedExceptionMessage Second level cache does not support multiple root entities.
633
     */
634
    public function testSupportMultipleRootEntitiesException()
635
    {
636
        $result   = [];
637
        $key      = new QueryCacheKey('query.key1', 0);
638
        $rsm      = new ResultSetMappingBuilder($this->em);
639
640
        $rsm->addEntityResult(City::class, 'e1');
641
        $rsm->addEntityResult(State::class, 'e2');
642
643
        $this->queryCache->put($key, $rsm, $result);
644
    }
645
646
    /**
647
     * @expectedException Doctrine\ORM\Cache\CacheException
648
     * @expectedExceptionMessage Entity "Doctrine\Tests\Models\Generic\BooleanModel" not configured as part of the second-level cache.
649
     */
650
    public function testNotCacheableEntityException()
651
    {
652
        $result    = [];
653
        $key       = new QueryCacheKey('query.key1', 0);
654
        $rsm       = new ResultSetMappingBuilder($this->em);
655
        $rsm->addRootEntityFromClassMetadata(BooleanModel::class, 'c');
656
657
        for ($i = 0; $i < 4; $i++) {
658
            $entity  = new BooleanModel();
659
            $boolean = ($i % 2 === 0);
660
661
            $entity->id             = $i;
662
            $entity->booleanField   = $boolean;
663
            $result[]               = $entity;
664
665
            $this->em->getUnitOfWork()->registerManaged($entity, ['id' => $i], ['booleanField' => $boolean]);
666
        }
667
668
        $this->assertFalse($this->queryCache->put($key, $rsm, $result));
669
    }
670
671
}
672
673
class CacheFactoryDefaultQueryCacheTest extends Cache\DefaultCacheFactory
674
{
675
    private $queryCache;
676
    private $region;
677
678
    public function __construct(DefaultQueryCache $queryCache, CacheRegionMock $region)
679
    {
680
        $this->queryCache = $queryCache;
681
        $this->region     = $region;
682
    }
683
684
    public function buildQueryCache(EntityManagerInterface $em, $regionName = null)
685
    {
686
        return $this->queryCache;
687
    }
688
689
    public function getRegion(array $cache)
690
    {
691
        return $this->region;
692
    }
693
694
    public function getTimestampRegion()
695
    {
696
        return new TimestampRegionMock();
697
    }
698
}
699