Passed
Pull Request — master (#7778)
by Саша
09:35
created

testPutToOneAssociationQueryResult()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 36
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

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