Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / orm / tests / Doctrine / Tests / ORM / Hydration / ArrayHydratorTest.php
1 <?php
2
3 namespace Doctrine\Tests\ORM\Hydration;
4
5 use Doctrine\Tests\Mocks\HydratorMockStatement;
6 use Doctrine\ORM\Query\ResultSetMapping;
7
8 require_once __DIR__ . '/../../TestInit.php';
9
10 class ArrayHydratorTest extends HydrationTestCase
11 {
12     public function provideDataForUserEntityResult()
13     {
14         return array(
15             array(0),
16             array('user'),
17         );
18     }
19
20     /**
21      * SELECT PARTIAL u.{id, name}
22      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
23      */
24     public function testSimpleEntityQuery()
25     {
26         $rsm = new ResultSetMapping;
27         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
28         $rsm->addFieldResult('u', 'u__id', 'id');
29         $rsm->addFieldResult('u', 'u__name', 'name');
30
31         // Faked result set
32         $resultSet = array(
33             array(
34                 'u__id' => '1',
35                 'u__name' => 'romanb'
36             ),
37             array(
38                 'u__id' => '2',
39                 'u__name' => 'jwage'
40             )
41         );
42
43         $stmt     = new HydratorMockStatement($resultSet);
44         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
45         $result   = $hydrator->hydrateAll($stmt, $rsm);
46
47         $this->assertEquals(2, count($result));
48
49         $this->assertTrue(is_array($result));
50
51         $this->assertEquals(1, $result[0]['id']);
52         $this->assertEquals('romanb', $result[0]['name']);
53
54         $this->assertEquals(2, $result[1]['id']);
55         $this->assertEquals('jwage', $result[1]['name']);
56     }
57
58     /**
59      * SELECT PARTIAL u.{id, name} AS user
60      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
61      */
62     public function testSimpleEntityQueryWithAliasedUserEntity()
63     {
64         $rsm = new ResultSetMapping;
65         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', 'user');
66         $rsm->addFieldResult('u', 'u__id', 'id');
67         $rsm->addFieldResult('u', 'u__name', 'name');
68
69         // Faked result set
70         $resultSet = array(
71             array(
72                 'u__id' => '1',
73                 'u__name' => 'romanb'
74             ),
75             array(
76                 'u__id' => '2',
77                 'u__name' => 'jwage'
78             )
79         );
80
81         $stmt     = new HydratorMockStatement($resultSet);
82         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
83         $result   = $hydrator->hydrateAll($stmt, $rsm);
84
85         $this->assertEquals(2, count($result));
86
87         $this->assertTrue(is_array($result));
88
89         $this->assertArrayHasKey('user', $result[0]);
90         $this->assertEquals(1, $result[0]['user']['id']);
91         $this->assertEquals('romanb', $result[0]['user']['name']);
92
93         $this->assertArrayHasKey('user', $result[1]);
94         $this->assertEquals(2, $result[1]['user']['id']);
95         $this->assertEquals('jwage', $result[1]['user']['name']);
96     }
97
98     /**
99      * SELECT PARTIAL u.{id, name}, PARTIAL a.{id, topic}
100      *   FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a
101      */
102     public function testSimpleMultipleRootEntityQuery()
103     {
104         $rsm = new ResultSetMapping;
105         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
106         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsArticle', 'a');
107         $rsm->addFieldResult('u', 'u__id', 'id');
108         $rsm->addFieldResult('u', 'u__name', 'name');
109         $rsm->addFieldResult('a', 'a__id', 'id');
110         $rsm->addFieldResult('a', 'a__topic', 'topic');
111
112         // Faked result set
113         $resultSet = array(
114             array(
115                 'u__id' => '1',
116                 'u__name' => 'romanb',
117                 'a__id' => '1',
118                 'a__topic' => 'Cool things.'
119             ),
120             array(
121                 'u__id' => '2',
122                 'u__name' => 'jwage',
123                 'a__id' => '2',
124                 'a__topic' => 'Cool things II.'
125             )
126         );
127
128         $stmt     = new HydratorMockStatement($resultSet);
129         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
130         $result   = $hydrator->hydrateAll($stmt, $rsm);
131
132         $this->assertEquals(4, count($result));
133
134         $this->assertEquals(1, $result[0]['id']);
135         $this->assertEquals('romanb', $result[0]['name']);
136
137         $this->assertEquals(1, $result[1]['id']);
138         $this->assertEquals('Cool things.', $result[1]['topic']);
139
140         $this->assertEquals(2, $result[2]['id']);
141         $this->assertEquals('jwage', $result[2]['name']);
142
143         $this->assertEquals(2, $result[3]['id']);
144         $this->assertEquals('Cool things II.', $result[3]['topic']);
145     }
146
147     /**
148      * SELECT PARTIAL u.{id, name} AS user, PARTIAL a.{id, topic}
149      *   FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a
150      */
151     public function testSimpleMultipleRootEntityQueryWithAliasedUserEntity()
152     {
153         $rsm = new ResultSetMapping;
154         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', 'user');
155         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsArticle', 'a');
156         $rsm->addFieldResult('u', 'u__id', 'id');
157         $rsm->addFieldResult('u', 'u__name', 'name');
158         $rsm->addFieldResult('a', 'a__id', 'id');
159         $rsm->addFieldResult('a', 'a__topic', 'topic');
160
161         // Faked result set
162         $resultSet = array(
163             array(
164                 'u__id' => '1',
165                 'u__name' => 'romanb',
166                 'a__id' => '1',
167                 'a__topic' => 'Cool things.'
168             ),
169             array(
170                 'u__id' => '2',
171                 'u__name' => 'jwage',
172                 'a__id' => '2',
173                 'a__topic' => 'Cool things II.'
174             )
175         );
176
177         $stmt     = new HydratorMockStatement($resultSet);
178         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
179         $result   = $hydrator->hydrateAll($stmt, $rsm);
180
181         $this->assertEquals(4, count($result));
182
183         $this->assertArrayHasKey('user', $result[0]);
184         $this->assertEquals(1, $result[0]['user']['id']);
185         $this->assertEquals('romanb', $result[0]['user']['name']);
186
187         $this->assertArrayHasKey(0, $result[1]);
188         $this->assertEquals(1, $result[1][0]['id']);
189         $this->assertEquals('Cool things.', $result[1][0]['topic']);
190
191         $this->assertArrayHasKey('user', $result[2]);
192         $this->assertEquals(2, $result[2]['user']['id']);
193         $this->assertEquals('jwage', $result[2]['user']['name']);
194
195         $this->assertArrayHasKey(0, $result[3]);
196         $this->assertEquals(2, $result[3][0]['id']);
197         $this->assertEquals('Cool things II.', $result[3][0]['topic']);
198     }
199
200     /**
201      * SELECT PARTIAL u.{id, name}, PARTIAL a.{id, topic} AS article
202      *   FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a
203      */
204     public function testSimpleMultipleRootEntityQueryWithAliasedArticleEntity()
205     {
206         $rsm = new ResultSetMapping;
207         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
208         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsArticle', 'a', 'article');
209         $rsm->addFieldResult('u', 'u__id', 'id');
210         $rsm->addFieldResult('u', 'u__name', 'name');
211         $rsm->addFieldResult('a', 'a__id', 'id');
212         $rsm->addFieldResult('a', 'a__topic', 'topic');
213
214         // Faked result set
215         $resultSet = array(
216             array(
217                 'u__id' => '1',
218                 'u__name' => 'romanb',
219                 'a__id' => '1',
220                 'a__topic' => 'Cool things.'
221             ),
222             array(
223                 'u__id' => '2',
224                 'u__name' => 'jwage',
225                 'a__id' => '2',
226                 'a__topic' => 'Cool things II.'
227             )
228         );
229
230         $stmt     = new HydratorMockStatement($resultSet);
231         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
232         $result   = $hydrator->hydrateAll($stmt, $rsm);
233
234         $this->assertEquals(4, count($result));
235
236         $this->assertArrayHasKey(0, $result[0]);
237         $this->assertEquals(1, $result[0][0]['id']);
238         $this->assertEquals('romanb', $result[0][0]['name']);
239
240         $this->assertArrayHasKey('article', $result[1]);
241         $this->assertEquals(1, $result[1]['article']['id']);
242         $this->assertEquals('Cool things.', $result[1]['article']['topic']);
243
244         $this->assertArrayHasKey(0, $result[2]);
245         $this->assertEquals(2, $result[2][0]['id']);
246         $this->assertEquals('jwage', $result[2][0]['name']);
247
248         $this->assertArrayHasKey('article', $result[3]);
249         $this->assertEquals(2, $result[3]['article']['id']);
250         $this->assertEquals('Cool things II.', $result[3]['article']['topic']);
251     }
252
253     /**
254      * SELECT PARTIAL u.{id, name} AS user, PARTIAL a.{id, topic} AS article
255      *   FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a
256      */
257     public function testSimpleMultipleRootEntityQueryWithAliasedEntities()
258     {
259         $rsm = new ResultSetMapping;
260         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', 'user');
261         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsArticle', 'a', 'article');
262         $rsm->addFieldResult('u', 'u__id', 'id');
263         $rsm->addFieldResult('u', 'u__name', 'name');
264         $rsm->addFieldResult('a', 'a__id', 'id');
265         $rsm->addFieldResult('a', 'a__topic', 'topic');
266
267         // Faked result set
268         $resultSet = array(
269             array(
270                 'u__id' => '1',
271                 'u__name' => 'romanb',
272                 'a__id' => '1',
273                 'a__topic' => 'Cool things.'
274             ),
275             array(
276                 'u__id' => '2',
277                 'u__name' => 'jwage',
278                 'a__id' => '2',
279                 'a__topic' => 'Cool things II.'
280             )
281         );
282
283         $stmt     = new HydratorMockStatement($resultSet);
284         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
285         $result   = $hydrator->hydrateAll($stmt, $rsm);
286
287         $this->assertEquals(4, count($result));
288
289         $this->assertArrayHasKey('user', $result[0]);
290         $this->assertEquals(1, $result[0]['user']['id']);
291         $this->assertEquals('romanb', $result[0]['user']['name']);
292
293         $this->assertArrayHasKey('article', $result[1]);
294         $this->assertEquals(1, $result[1]['article']['id']);
295         $this->assertEquals('Cool things.', $result[1]['article']['topic']);
296
297         $this->assertArrayHasKey('user', $result[2]);
298         $this->assertEquals(2, $result[2]['user']['id']);
299         $this->assertEquals('jwage', $result[2]['user']['name']);
300
301         $this->assertArrayHasKey('article', $result[3]);
302         $this->assertEquals(2, $result[3]['article']['id']);
303         $this->assertEquals('Cool things II.', $result[3]['article']['topic']);
304     }
305
306     /**
307      * SELECT PARTIAL u.{id, status}, COUNT(p.phonenumber) AS numPhones
308      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
309      *   JOIN u.phonenumbers p
310      *  GROUP BY u.status, u.id
311      *
312      * @dataProvider provideDataForUserEntityResult
313      */
314     public function testMixedQueryNormalJoin($userEntityKey)
315     {
316         $rsm = new ResultSetMapping;
317         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
318         $rsm->addFieldResult('u', 'u__id', 'id');
319         $rsm->addFieldResult('u', 'u__status', 'status');
320         $rsm->addScalarResult('sclr0', 'numPhones');
321
322         // Faked result set
323         $resultSet = array(
324             //row1
325             array(
326                 'u__id' => '1',
327                 'u__status' => 'developer',
328                 'sclr0' => '2',
329             ),
330             array(
331                 'u__id' => '2',
332                 'u__status' => 'developer',
333                 'sclr0' => '1',
334             )
335         );
336
337         $stmt     = new HydratorMockStatement($resultSet);
338         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
339         $result   = $hydrator->hydrateAll($stmt, $rsm);
340
341         $this->assertEquals(2, count($result));
342         $this->assertTrue(is_array($result));
343         $this->assertTrue(is_array($result[0]));
344         $this->assertTrue(is_array($result[1]));
345
346         // first user => 2 phonenumbers
347         $this->assertArrayHasKey($userEntityKey, $result[0]);
348         $this->assertEquals(2, $result[0]['numPhones']);
349
350         // second user => 1 phonenumber
351         $this->assertArrayHasKey($userEntityKey, $result[1]);
352         $this->assertEquals(1, $result[1]['numPhones']);
353     }
354
355     /**
356      * SELECT PARTIAL u.{id, status}, PARTIAL p.{phonenumber}, UPPER(u.name) AS nameUpper
357      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
358      *   JOIN u.phonenumbers p
359      *
360      * @dataProvider provideDataForUserEntityResult
361      */
362     public function testMixedQueryFetchJoin($userEntityKey)
363     {
364         $rsm = new ResultSetMapping;
365         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
366         $rsm->addJoinedEntityResult(
367             'Doctrine\Tests\Models\CMS\CmsPhonenumber',
368             'p',
369             'u',
370             'phonenumbers'
371         );
372         $rsm->addFieldResult('u', 'u__id', 'id');
373         $rsm->addFieldResult('u', 'u__status', 'status');
374         $rsm->addScalarResult('sclr0', 'nameUpper');
375         $rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
376
377         // Faked result set
378         $resultSet = array(
379             //row1
380             array(
381                 'u__id' => '1',
382                 'u__status' => 'developer',
383                 'sclr0' => 'ROMANB',
384                 'p__phonenumber' => '42',
385             ),
386             array(
387                 'u__id' => '1',
388                 'u__status' => 'developer',
389                 'sclr0' => 'ROMANB',
390                 'p__phonenumber' => '43',
391             ),
392             array(
393                 'u__id' => '2',
394                 'u__status' => 'developer',
395                 'sclr0' => 'JWAGE',
396                 'p__phonenumber' => '91'
397             )
398         );
399
400         $stmt     = new HydratorMockStatement($resultSet);
401         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
402         $result   = $hydrator->hydrateAll($stmt, $rsm);
403
404         $this->assertEquals(2, count($result));
405
406         $this->assertTrue(is_array($result));
407         $this->assertTrue(is_array($result[0]));
408         $this->assertTrue(is_array($result[1]));
409
410         // first user => 2 phonenumbers
411         $this->assertEquals(2, count($result[0][$userEntityKey]['phonenumbers']));
412         $this->assertEquals('ROMANB', $result[0]['nameUpper']);
413
414         // second user => 1 phonenumber
415         $this->assertEquals(1, count($result[1][$userEntityKey]['phonenumbers']));
416         $this->assertEquals('JWAGE', $result[1]['nameUpper']);
417
418         $this->assertEquals(42, $result[0][$userEntityKey]['phonenumbers'][0]['phonenumber']);
419         $this->assertEquals(43, $result[0][$userEntityKey]['phonenumbers'][1]['phonenumber']);
420         $this->assertEquals(91, $result[1][$userEntityKey]['phonenumbers'][0]['phonenumber']);
421     }
422
423     /**
424      * SELECT PARTIAL u.{id, status}, UPPER(u.name) nameUpper
425      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
426      *        INDEX BY u.id
427      *   JOIN u.phonenumbers p
428      *        INDEX BY p.phonenumber
429      *
430      * @dataProvider provideDataForUserEntityResult
431      */
432     public function testMixedQueryFetchJoinCustomIndex($userEntityKey)
433     {
434         $rsm = new ResultSetMapping;
435         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
436         $rsm->addJoinedEntityResult(
437             'Doctrine\Tests\Models\CMS\CmsPhonenumber',
438             'p',
439             'u',
440             'phonenumbers'
441         );
442         $rsm->addFieldResult('u', 'u__id', 'id');
443         $rsm->addFieldResult('u', 'u__status', 'status');
444         $rsm->addScalarResult('sclr0', 'nameUpper');
445         $rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
446         $rsm->addIndexBy('u', 'id');
447         $rsm->addIndexBy('p', 'phonenumber');
448
449         // Faked result set
450         $resultSet = array(
451             //row1
452             array(
453                 'u__id' => '1',
454                 'u__status' => 'developer',
455                 'sclr0' => 'ROMANB',
456                 'p__phonenumber' => '42',
457             ),
458             array(
459                 'u__id' => '1',
460                 'u__status' => 'developer',
461                 'sclr0' => 'ROMANB',
462                 'p__phonenumber' => '43',
463             ),
464             array(
465                 'u__id' => '2',
466                 'u__status' => 'developer',
467                 'sclr0' => 'JWAGE',
468                 'p__phonenumber' => '91'
469             )
470         );
471
472
473         $stmt     = new HydratorMockStatement($resultSet);
474         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
475         $result   = $hydrator->hydrateAll($stmt, $rsm);
476
477         $this->assertEquals(2, count($result));
478
479         $this->assertTrue(is_array($result));
480         $this->assertTrue(is_array($result[1]));
481         $this->assertTrue(is_array($result[2]));
482
483         // test the scalar values
484         $this->assertEquals('ROMANB', $result[1]['nameUpper']);
485         $this->assertEquals('JWAGE', $result[2]['nameUpper']);
486
487         // first user => 2 phonenumbers. notice the custom indexing by user id
488         $this->assertEquals(2, count($result[1][$userEntityKey]['phonenumbers']));
489
490         // second user => 1 phonenumber. notice the custom indexing by user id
491         $this->assertEquals(1, count($result[2][$userEntityKey]['phonenumbers']));
492
493         // test the custom indexing of the phonenumbers
494         $this->assertTrue(isset($result[1][$userEntityKey]['phonenumbers']['42']));
495         $this->assertTrue(isset($result[1][$userEntityKey]['phonenumbers']['43']));
496         $this->assertTrue(isset($result[2][$userEntityKey]['phonenumbers']['91']));
497     }
498
499     /**
500      * select u.id, u.status, p.phonenumber, upper(u.name) nameUpper, a.id, a.topic
501      * from User u
502      * join u.phonenumbers p
503      * join u.articles a
504      * =
505      * select u.id, u.status, p.phonenumber, upper(u.name) as u__0, a.id, a.topic
506      * from USERS u
507      * inner join PHONENUMBERS p ON u.id = p.user_id
508      * inner join ARTICLES a ON u.id = a.user_id
509      */
510     public function testMixedQueryMultipleFetchJoin()
511     {
512         $rsm = new ResultSetMapping;
513         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
514         $rsm->addJoinedEntityResult(
515             'Doctrine\Tests\Models\CMS\CmsPhonenumber',
516             'p',
517             'u',
518             'phonenumbers'
519         );
520         $rsm->addJoinedEntityResult(
521             'Doctrine\Tests\Models\CMS\CmsArticle',
522             'a',
523             'u',
524             'articles'
525         );
526         $rsm->addFieldResult('u', 'u__id', 'id');
527         $rsm->addFieldResult('u', 'u__status', 'status');
528         $rsm->addScalarResult('sclr0', 'nameUpper');
529         $rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
530         $rsm->addFieldResult('a', 'a__id', 'id');
531         $rsm->addFieldResult('a', 'a__topic', 'topic');
532
533         // Faked result set
534         $resultSet = array(
535             //row1
536             array(
537                 'u__id' => '1',
538                 'u__status' => 'developer',
539                 'sclr0' => 'ROMANB',
540                 'p__phonenumber' => '42',
541                 'a__id' => '1',
542                 'a__topic' => 'Getting things done!'
543             ),
544             array(
545                 'u__id' => '1',
546                 'u__status' => 'developer',
547                 'sclr0' => 'ROMANB',
548                 'p__phonenumber' => '43',
549                 'a__id' => '1',
550                 'a__topic' => 'Getting things done!'
551             ),
552             array(
553                 'u__id' => '1',
554                 'u__status' => 'developer',
555                 'sclr0' => 'ROMANB',
556                 'p__phonenumber' => '42',
557                 'a__id' => '2',
558                 'a__topic' => 'ZendCon'
559             ),
560             array(
561                 'u__id' => '1',
562                 'u__status' => 'developer',
563                 'sclr0' => 'ROMANB',
564                 'p__phonenumber' => '43',
565                 'a__id' => '2',
566                 'a__topic' => 'ZendCon'
567             ),
568             array(
569                 'u__id' => '2',
570                 'u__status' => 'developer',
571                 'sclr0' => 'JWAGE',
572                 'p__phonenumber' => '91',
573                 'a__id' => '3',
574                 'a__topic' => 'LINQ'
575             ),
576             array(
577                 'u__id' => '2',
578                 'u__status' => 'developer',
579                 'sclr0' => 'JWAGE',
580                 'p__phonenumber' => '91',
581                 'a__id' => '4',
582                 'a__topic' => 'PHP6'
583             ),
584         );
585
586         $stmt     = new HydratorMockStatement($resultSet);
587         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
588         $result   = $hydrator->hydrateAll($stmt, $rsm);
589
590         $this->assertEquals(2, count($result));
591         $this->assertTrue(is_array($result));
592         $this->assertTrue(is_array($result[0]));
593         $this->assertTrue(is_array($result[1]));
594         // first user => 2 phonenumbers, 2 articles
595         $this->assertEquals(2, count($result[0][0]['phonenumbers']));
596         $this->assertEquals(2, count($result[0][0]['articles']));
597         $this->assertEquals('ROMANB', $result[0]['nameUpper']);
598         // second user => 1 phonenumber, 2 articles
599         $this->assertEquals(1, count($result[1][0]['phonenumbers']));
600         $this->assertEquals(2, count($result[1][0]['articles']));
601         $this->assertEquals('JWAGE', $result[1]['nameUpper']);
602
603         $this->assertEquals(42, $result[0][0]['phonenumbers'][0]['phonenumber']);
604         $this->assertEquals(43, $result[0][0]['phonenumbers'][1]['phonenumber']);
605         $this->assertEquals(91, $result[1][0]['phonenumbers'][0]['phonenumber']);
606
607         $this->assertEquals('Getting things done!', $result[0][0]['articles'][0]['topic']);
608         $this->assertEquals('ZendCon', $result[0][0]['articles'][1]['topic']);
609         $this->assertEquals('LINQ', $result[1][0]['articles'][0]['topic']);
610         $this->assertEquals('PHP6', $result[1][0]['articles'][1]['topic']);
611     }
612
613     /**
614      * select u.id, u.status, p.phonenumber, upper(u.name) nameUpper, a.id, a.topic,
615      * c.id, c.topic
616      * from User u
617      * join u.phonenumbers p
618      * join u.articles a
619      * left join a.comments c
620      * =
621      * select u.id, u.status, p.phonenumber, upper(u.name) as u__0, a.id, a.topic,
622      * c.id, c.topic
623      * from USERS u
624      * inner join PHONENUMBERS p ON u.id = p.user_id
625      * inner join ARTICLES a ON u.id = a.user_id
626      * left outer join COMMENTS c ON a.id = c.article_id
627      */
628     public function testMixedQueryMultipleDeepMixedFetchJoin()
629     {
630
631         $rsm = new ResultSetMapping;
632         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
633         $rsm->addJoinedEntityResult(
634             'Doctrine\Tests\Models\CMS\CmsPhonenumber',
635             'p',
636             'u',
637             'phonenumbers'
638         );
639         $rsm->addJoinedEntityResult(
640             'Doctrine\Tests\Models\CMS\CmsArticle',
641             'a',
642             'u',
643             'articles'
644         );
645         $rsm->addJoinedEntityResult(
646             'Doctrine\Tests\Models\CMS\CmsComment',
647             'c',
648             'a',
649             'comments'
650         );
651         $rsm->addFieldResult('u', 'u__id', 'id');
652         $rsm->addFieldResult('u', 'u__status', 'status');
653         $rsm->addScalarResult('sclr0', 'nameUpper');
654         $rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
655         $rsm->addFieldResult('a', 'a__id', 'id');
656         $rsm->addFieldResult('a', 'a__topic', 'topic');
657         $rsm->addFieldResult('c', 'c__id', 'id');
658         $rsm->addFieldResult('c', 'c__topic', 'topic');
659
660         // Faked result set
661         $resultSet = array(
662             //row1
663             array(
664                 'u__id' => '1',
665                 'u__status' => 'developer',
666                 'sclr0' => 'ROMANB',
667                 'p__phonenumber' => '42',
668                 'a__id' => '1',
669                 'a__topic' => 'Getting things done!',
670                 'c__id' => '1',
671                 'c__topic' => 'First!'
672             ),
673             array(
674                 'u__id' => '1',
675                 'u__status' => 'developer',
676                 'sclr0' => 'ROMANB',
677                 'p__phonenumber' => '43',
678                 'a__id' => '1',
679                 'a__topic' => 'Getting things done!',
680                 'c__id' => '1',
681                 'c__topic' => 'First!'
682             ),
683             array(
684                 'u__id' => '1',
685                 'u__status' => 'developer',
686                 'sclr0' => 'ROMANB',
687                 'p__phonenumber' => '42',
688                 'a__id' => '2',
689                 'a__topic' => 'ZendCon',
690                 'c__id' => null,
691                 'c__topic' => null
692             ),
693             array(
694                 'u__id' => '1',
695                 'u__status' => 'developer',
696                 'sclr0' => 'ROMANB',
697                 'p__phonenumber' => '43',
698                 'a__id' => '2',
699                 'a__topic' => 'ZendCon',
700                 'c__id' => null,
701                 'c__topic' => null
702             ),
703             array(
704                 'u__id' => '2',
705                 'u__status' => 'developer',
706                 'sclr0' => 'JWAGE',
707                 'p__phonenumber' => '91',
708                 'a__id' => '3',
709                 'a__topic' => 'LINQ',
710                 'c__id' => null,
711                 'c__topic' => null
712             ),
713             array(
714                 'u__id' => '2',
715                 'u__status' => 'developer',
716                 'sclr0' => 'JWAGE',
717                 'p__phonenumber' => '91',
718                 'a__id' => '4',
719                 'a__topic' => 'PHP6',
720                 'c__id' => null,
721                 'c__topic' => null
722             ),
723         );
724
725         $stmt     = new HydratorMockStatement($resultSet);
726         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
727         $result   = $hydrator->hydrateAll($stmt, $rsm);
728
729         $this->assertEquals(2, count($result));
730         $this->assertTrue(is_array($result));
731         $this->assertTrue(is_array($result[0]));
732         $this->assertTrue(is_array($result[1]));
733
734         // first user => 2 phonenumbers, 2 articles, 1 comment on first article
735         $this->assertEquals(2, count($result[0][0]['phonenumbers']));
736         $this->assertEquals(2, count($result[0][0]['articles']));
737         $this->assertEquals(1, count($result[0][0]['articles'][0]['comments']));
738         $this->assertEquals('ROMANB', $result[0]['nameUpper']);
739         // second user => 1 phonenumber, 2 articles, no comments
740         $this->assertEquals(1, count($result[1][0]['phonenumbers']));
741         $this->assertEquals(2, count($result[1][0]['articles']));
742         $this->assertEquals('JWAGE', $result[1]['nameUpper']);
743
744         $this->assertEquals(42, $result[0][0]['phonenumbers'][0]['phonenumber']);
745         $this->assertEquals(43, $result[0][0]['phonenumbers'][1]['phonenumber']);
746         $this->assertEquals(91, $result[1][0]['phonenumbers'][0]['phonenumber']);
747
748         $this->assertEquals('Getting things done!', $result[0][0]['articles'][0]['topic']);
749         $this->assertEquals('ZendCon', $result[0][0]['articles'][1]['topic']);
750         $this->assertEquals('LINQ', $result[1][0]['articles'][0]['topic']);
751         $this->assertEquals('PHP6', $result[1][0]['articles'][1]['topic']);
752
753         $this->assertEquals('First!', $result[0][0]['articles'][0]['comments'][0]['topic']);
754
755         $this->assertTrue(isset($result[0][0]['articles'][0]['comments']));
756
757         // empty comment collections
758         $this->assertTrue(is_array($result[0][0]['articles'][1]['comments']));
759         $this->assertEquals(0, count($result[0][0]['articles'][1]['comments']));
760         $this->assertTrue(is_array($result[1][0]['articles'][0]['comments']));
761         $this->assertEquals(0, count($result[1][0]['articles'][0]['comments']));
762         $this->assertTrue(is_array($result[1][0]['articles'][1]['comments']));
763         $this->assertEquals(0, count($result[1][0]['articles'][1]['comments']));
764     }
765
766     /**
767      * Tests that the hydrator does not rely on a particular order of the rows
768      * in the result set.
769      *
770      * DQL:
771      * select c.id, c.position, c.name, b.id, b.position
772      * from \Doctrine\Tests\Models\Forum\ForumCategory c inner join c.boards b
773      * order by c.position asc, b.position asc
774      *
775      * Checks whether the boards are correctly assigned to the categories.
776      *
777      * The 'evil' result set that confuses the object population is displayed below.
778      *
779      * c.id  | c.position | c.name   | boardPos | b.id | b.category_id (just for clarity)
780      *  1    | 0          | First    | 0        |   1  | 1
781      *  2    | 0          | Second   | 0        |   2  | 2   <--
782      *  1    | 0          | First    | 1        |   3  | 1
783      *  1    | 0          | First    | 2        |   4  | 1
784      */
785     public function testEntityQueryCustomResultSetOrder()
786     {
787         $rsm = new ResultSetMapping;
788         $rsm->addEntityResult('Doctrine\Tests\Models\Forum\ForumCategory', 'c');
789         $rsm->addJoinedEntityResult(
790             'Doctrine\Tests\Models\Forum\ForumBoard',
791             'b',
792             'c',
793             'boards'
794         );
795
796         $rsm->addFieldResult('c', 'c__id', 'id');
797         $rsm->addFieldResult('c', 'c__position', 'position');
798         $rsm->addFieldResult('c', 'c__name', 'name');
799         $rsm->addFieldResult('b', 'b__id', 'id');
800         $rsm->addFieldResult('b', 'b__position', 'position');
801
802         // Faked result set
803         $resultSet = array(
804             array(
805                 'c__id' => '1',
806                 'c__position' => '0',
807                 'c__name' => 'First',
808                 'b__id' => '1',
809                 'b__position' => '0',
810                 //'b__category_id' => '1'
811             ),
812             array(
813                 'c__id' => '2',
814                 'c__position' => '0',
815                 'c__name' => 'Second',
816                 'b__id' => '2',
817                 'b__position' => '0',
818                 //'b__category_id' => '2'
819             ),
820             array(
821                 'c__id' => '1',
822                 'c__position' => '0',
823                 'c__name' => 'First',
824                 'b__id' => '3',
825                 'b__position' => '1',
826                 //'b__category_id' => '1'
827             ),
828             array(
829                 'c__id' => '1',
830                 'c__position' => '0',
831                 'c__name' => 'First',
832                 'b__id' => '4',
833                 'b__position' => '2',
834                 //'b__category_id' => '1'
835             )
836         );
837
838         $stmt     = new HydratorMockStatement($resultSet);
839         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
840         $result   = $hydrator->hydrateAll($stmt, $rsm);
841
842         $this->assertEquals(2, count($result));
843         $this->assertTrue(is_array($result));
844         $this->assertTrue(is_array($result[0]));
845         $this->assertTrue(is_array($result[1]));
846         $this->assertTrue(isset($result[0]['boards']));
847         $this->assertEquals(3, count($result[0]['boards']));
848         $this->assertTrue(isset($result[1]['boards']));
849         $this->assertEquals(1, count($result[1]['boards']));
850     }
851
852     /**
853      * SELECT PARTIAL u.{id,status}, a.id, a.topic, c.id as cid, c.topic as ctopic
854      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
855      *   LEFT JOIN u.articles a
856      *   LEFT JOIN a.comments c
857      *
858      * @dataProvider provideDataForUserEntityResult
859      */
860     public function testChainedJoinWithScalars($entityKey)
861     {
862         $rsm = new ResultSetMapping;
863         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $entityKey ?: null);
864         $rsm->addFieldResult('u', 'u__id', 'id');
865         $rsm->addFieldResult('u', 'u__status', 'status');
866         $rsm->addScalarResult('a__id', 'id');
867         $rsm->addScalarResult('a__topic', 'topic');
868         $rsm->addScalarResult('c__id', 'cid');
869         $rsm->addScalarResult('c__topic', 'ctopic');
870
871         // Faked result set
872         $resultSet = array(
873             //row1
874             array(
875                 'u__id' => '1',
876                 'u__status' => 'developer',
877                 'a__id' => '1',
878                 'a__topic' => 'The First',
879                 'c__id' => '1',
880                 'c__topic' => 'First Comment'
881             ),
882             array(
883                 'u__id' => '1',
884                 'u__status' => 'developer',
885                 'a__id' => '1',
886                 'a__topic' => 'The First',
887                 'c__id' => '2',
888                 'c__topic' => 'Second Comment'
889             ),
890             array(
891                 'u__id' => '1',
892                 'u__status' => 'developer',
893                 'a__id' => '42',
894                 'a__topic' => 'The Answer',
895                 'c__id' => null,
896                 'c__topic' => null
897             ),
898         );
899
900         $stmt     = new HydratorMockStatement($resultSet);
901         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
902         $result   = $hydrator->hydrateAll($stmt, $rsm);
903
904         $this->assertEquals(3, count($result));
905
906         $this->assertEquals(2, count($result[0][$entityKey])); // User array
907         $this->assertEquals(1, $result[0]['id']);
908         $this->assertEquals('The First', $result[0]['topic']);
909         $this->assertEquals(1, $result[0]['cid']);
910         $this->assertEquals('First Comment', $result[0]['ctopic']);
911
912         $this->assertEquals(2, count($result[1][$entityKey])); // User array, duplicated
913         $this->assertEquals(1, $result[1]['id']); // duplicated
914         $this->assertEquals('The First', $result[1]['topic']); // duplicated
915         $this->assertEquals(2, $result[1]['cid']);
916         $this->assertEquals('Second Comment', $result[1]['ctopic']);
917
918         $this->assertEquals(2, count($result[2][$entityKey])); // User array, duplicated
919         $this->assertEquals(42, $result[2]['id']);
920         $this->assertEquals('The Answer', $result[2]['topic']);
921         $this->assertNull($result[2]['cid']);
922         $this->assertNull($result[2]['ctopic']);
923     }
924
925     /**
926      * SELECT PARTIAL u.{id, status}
927      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
928      */
929     public function testResultIteration()
930     {
931         $rsm = new ResultSetMapping;
932         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
933         $rsm->addFieldResult('u', 'u__id', 'id');
934         $rsm->addFieldResult('u', 'u__name', 'name');
935
936         // Faked result set
937         $resultSet = array(
938             array(
939                 'u__id' => '1',
940                 'u__name' => 'romanb'
941             ),
942             array(
943                 'u__id' => '2',
944                 'u__name' => 'jwage'
945             )
946         );
947
948         $stmt     = new HydratorMockStatement($resultSet);
949         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
950         $iterator = $hydrator->iterate($stmt, $rsm);
951         $rowNum   = 0;
952
953         while (($row = $iterator->next()) !== false) {
954             $this->assertEquals(1, count($row));
955             $this->assertTrue(is_array($row[0]));
956
957             if ($rowNum == 0) {
958                 $this->assertEquals(1, $row[0]['id']);
959                 $this->assertEquals('romanb', $row[0]['name']);
960             } else if ($rowNum == 1) {
961                 $this->assertEquals(2, $row[0]['id']);
962                 $this->assertEquals('jwage', $row[0]['name']);
963             }
964
965             ++$rowNum;
966         }
967     }
968
969     /**
970      * SELECT PARTIAL u.{id, status}
971      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
972      */
973     public function testResultIterationWithAliasedUserEntity()
974     {
975         $rsm = new ResultSetMapping;
976         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', 'user');
977         $rsm->addFieldResult('u', 'u__id', 'id');
978         $rsm->addFieldResult('u', 'u__name', 'name');
979
980         // Faked result set
981         $resultSet = array(
982             array(
983                 'u__id' => '1',
984                 'u__name' => 'romanb'
985             ),
986             array(
987                 'u__id' => '2',
988                 'u__name' => 'jwage'
989             )
990         );
991
992         $stmt     = new HydratorMockStatement($resultSet);
993         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
994         $iterator = $hydrator->iterate($stmt, $rsm);
995         $rowNum   = 0;
996
997         while (($row = $iterator->next()) !== false) {
998             $this->assertEquals(1, count($row));
999             $this->assertArrayHasKey(0, $row);
1000             $this->assertArrayHasKey('user', $row[0]);
1001
1002             if ($rowNum == 0) {
1003                 $this->assertEquals(1, $row[0]['user']['id']);
1004                 $this->assertEquals('romanb', $row[0]['user']['name']);
1005             } else if ($rowNum == 1) {
1006                 $this->assertEquals(2, $row[0]['user']['id']);
1007                 $this->assertEquals('jwage', $row[0]['user']['name']);
1008             }
1009
1010             ++$rowNum;
1011         }
1012     }
1013
1014     /**
1015      * SELECT PARTIAL u.{id, name}
1016      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1017      *
1018      * @group DDC-644
1019      */
1020     public function testSkipUnknownColumns()
1021     {
1022         $rsm = new ResultSetMapping;
1023         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
1024         $rsm->addFieldResult('u', 'u__id', 'id');
1025         $rsm->addFieldResult('u', 'u__name', 'name');
1026
1027         // Faked result set
1028         $resultSet = array(
1029             array(
1030                 'u__id' => '1',
1031                 'u__name' => 'romanb',
1032                 'foo' => 'bar', // unknown!
1033             ),
1034         );
1035
1036         $stmt     = new HydratorMockStatement($resultSet);
1037         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
1038         $result   = $hydrator->hydrateAll($stmt, $rsm);
1039
1040         $this->assertEquals(1, count($result));
1041         $this->assertArrayHasKey('id', $result[0]);
1042         $this->assertArrayHasKey('name', $result[0]);
1043         $this->assertArrayNotHasKey('foo', $result[0]);
1044     }
1045
1046     /**
1047      * SELECT PARTIAL u.{id, status}, UPPER(u.name) AS nameUpper
1048      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1049      *
1050      * @group DDC-1358
1051      * @dataProvider provideDataForUserEntityResult
1052      */
1053     public function testMissingIdForRootEntity($userEntityKey)
1054     {
1055         $rsm = new ResultSetMapping;
1056         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
1057         $rsm->addFieldResult('u', 'u__id', 'id');
1058         $rsm->addFieldResult('u', 'u__status', 'status');
1059         $rsm->addScalarResult('sclr0', 'nameUpper');
1060
1061         // Faked result set
1062         $resultSet = array(
1063             //row1
1064             array(
1065                 'u__id' => '1',
1066                 'u__status' => 'developer',
1067                 'sclr0' => 'ROMANB',
1068             ),
1069             array(
1070                 'u__id' => null,
1071                 'u__status' => null,
1072                 'sclr0' => 'ROMANB',
1073             ),
1074             array(
1075                 'u__id' => '2',
1076                 'u__status' => 'developer',
1077                 'sclr0' => 'JWAGE',
1078             ),
1079             array(
1080                 'u__id' => null,
1081                 'u__status' => null,
1082                 'sclr0' => 'JWAGE',
1083             ),
1084         );
1085
1086         $stmt     = new HydratorMockStatement($resultSet);
1087         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
1088         $result   = $hydrator->hydrateAll($stmt, $rsm);
1089
1090         $this->assertEquals(4, count($result), "Should hydrate four results.");
1091
1092         $this->assertEquals('ROMANB', $result[0]['nameUpper']);
1093         $this->assertEquals('ROMANB', $result[1]['nameUpper']);
1094         $this->assertEquals('JWAGE', $result[2]['nameUpper']);
1095         $this->assertEquals('JWAGE', $result[3]['nameUpper']);
1096
1097         $this->assertEquals(array('id' => 1, 'status' => 'developer'), $result[0][$userEntityKey]);
1098         $this->assertNull($result[1][$userEntityKey]);
1099         $this->assertEquals(array('id' => 2, 'status' => 'developer'), $result[2][$userEntityKey]);
1100         $this->assertNull($result[3][$userEntityKey]);
1101     }
1102
1103     /**
1104      * SELECT PARTIAL u.{id, status}, UPPER(u.name) AS nameUpper
1105      *   FROM Doctrine\Tests\Models\CMS\CmsUser u
1106      *        INDEX BY u.id
1107      *
1108      * @group DDC-1385
1109      * @dataProvider provideDataForUserEntityResult
1110      */
1111     public function testIndexByAndMixedResult($userEntityKey)
1112     {
1113         $rsm = new ResultSetMapping;
1114         $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u', $userEntityKey ?: null);
1115         $rsm->addFieldResult('u', 'u__id', 'id');
1116         $rsm->addFieldResult('u', 'u__status', 'status');
1117         $rsm->addScalarResult('sclr0', 'nameUpper');
1118         $rsm->addIndexBy('u', 'id');
1119
1120         // Faked result set
1121         $resultSet = array(
1122             //row1
1123             array(
1124                 'u__id' => '1',
1125                 'u__status' => 'developer',
1126                 'sclr0' => 'ROMANB',
1127             ),
1128             array(
1129                 'u__id' => '2',
1130                 'u__status' => 'developer',
1131                 'sclr0' => 'JWAGE',
1132             ),
1133         );
1134
1135         $stmt     = new HydratorMockStatement($resultSet);
1136         $hydrator = new \Doctrine\ORM\Internal\Hydration\ArrayHydrator($this->_em);
1137         $result   = $hydrator->hydrateAll($stmt, $rsm);
1138
1139         $this->assertEquals(2, count($result));
1140
1141         $this->assertTrue(isset($result[1]));
1142         $this->assertEquals(1, $result[1][$userEntityKey]['id']);
1143
1144         $this->assertTrue(isset($result[2]));
1145         $this->assertEquals(2, $result[2][$userEntityKey]['id']);
1146     }
1147 }