Passed
Pull Request — master (#6709)
by Sergey
12:37
created

testAddNamedNativeQueryResultClass()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
nc 1
nop 0
dl 0
loc 26
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Hydration;
6
7
use Doctrine\DBAL\Types\Type;
8
use Doctrine\ORM\Mapping\ClassMetadata;
9
use Doctrine\ORM\Mapping\ClassMetadataBuildingContext;
10
use Doctrine\ORM\Mapping\ClassMetadataFactory;
11
use Doctrine\ORM\Mapping\JoinColumnMetadata;
12
use Doctrine\ORM\Mapping\OneToOneAssociationMetadata;
13
use Doctrine\ORM\Mapping\TableMetadata;
14
use Doctrine\ORM\Query\ResultSetMapping;
15
use Doctrine\ORM\Reflection\RuntimeReflectionService;
16
use Doctrine\Tests\Models\CMS\CmsEmail;
17
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
18
use Doctrine\Tests\Models\CMS\CmsUser;
19
use Doctrine\Tests\Models\Legacy\LegacyUser;
20
use Doctrine\Tests\Models\Legacy\LegacyUserReference;
21
22
/**
23
 * Description of ResultSetMappingTest
24
 *
25
 * @author robo
26
 */
27
class ResultSetMappingTest extends \Doctrine\Tests\OrmTestCase
28
{
29
    /**
30
     * @var \Doctrine\ORM\EntityManagerInterface
31
     */
32
    private $em;
33
34
    /**
35
     * @var ResultSetMapping
36
     */
37
    private $rsm;
38
39
    /**
40
     * @var ClassMetadataBuildingContext
41
     */
42
    private $metadataBuildingContext;
43
44
    protected function setUp()
45
    {
46
        parent::setUp();
47
48
        $this->metadataBuildingContext = new ClassMetadataBuildingContext(
49
            $this->createMock(ClassMetadataFactory::class),
50
            new RuntimeReflectionService()
51
        );
52
53
        $this->em  = $this->getTestEntityManager();
54
        $this->rsm = new ResultSetMapping;
55
    }
56
57
    /**
58
     * For SQL: SELECT id, status, username, name FROM cms_users
59
     */
60
    public function testBasicResultSetMapping()
61
    {
62
        $this->rsm->addEntityResult(
63
            CmsUser::class,
64
            'u'
65
        );
66
        $this->rsm->addFieldResult('u', 'id', 'id');
67
        $this->rsm->addFieldResult('u', 'status', 'status');
68
        $this->rsm->addFieldResult('u', 'username', 'username');
69
        $this->rsm->addFieldResult('u', 'name', 'name');
70
71
        self::assertFalse($this->rsm->isScalarResult('id'));
72
        self::assertFalse($this->rsm->isScalarResult('status'));
73
        self::assertFalse($this->rsm->isScalarResult('username'));
74
        self::assertFalse($this->rsm->isScalarResult('name'));
75
76
        self::assertEquals($this->rsm->getClassName('u'), CmsUser::class);
77
        $class = $this->rsm->getDeclaringClass('id');
78
        self::assertEquals($class, CmsUser::class);
79
80
        self::assertEquals('u', $this->rsm->getEntityAlias('id'));
81
        self::assertEquals('u', $this->rsm->getEntityAlias('status'));
82
        self::assertEquals('u', $this->rsm->getEntityAlias('username'));
83
        self::assertEquals('u', $this->rsm->getEntityAlias('name'));
84
85
        self::assertEquals('id', $this->rsm->getFieldName('id'));
86
        self::assertEquals('status', $this->rsm->getFieldName('status'));
87
        self::assertEquals('username', $this->rsm->getFieldName('username'));
88
        self::assertEquals('name', $this->rsm->getFieldName('name'));
89
    }
90
91
    /**
92
     * @group DDC-1057
93
     *
94
     * Fluent interface test, not a real result set mapping
95
     */
96
    public function testFluentInterface()
97
    {
98
        $rms = $this->rsm;
99
100
        $this->rsm->addEntityResult(CmsUser::class, 'u');
101
        $this->rsm->addJoinedEntityResult(CmsPhonenumber::class, 'p', 'u', 'phonenumbers');
102
        $this->rsm->addFieldResult('u', 'id', 'id');
103
        $this->rsm->addFieldResult('u', 'name', 'name');
104
        $this->rsm->setDiscriminatorColumn('name', 'name');
105
        $this->rsm->addIndexByColumn('id', 'id');
106
        $this->rsm->addIndexBy('username', 'username');
107
        $this->rsm->addIndexByScalar('sclr0');
108
        $this->rsm->addScalarResult('sclr0', 'numPhones', Type::getType('integer'));
109
        $this->rsm->addMetaResult('a', 'user_id', 'user_id', false, Type::getType('integer'));
110
111
        self::assertTrue($rms->hasIndexBy('id'));
112
        self::assertTrue($rms->isFieldResult('id'));
113
        self::assertTrue($rms->isFieldResult('name'));
114
        self::assertTrue($rms->isScalarResult('sclr0'));
115
        self::assertTrue($rms->isRelation('p'));
116
        self::assertTrue($rms->hasParentAlias('p'));
117
        self::assertTrue($rms->isMixedResult());
118
    }
119
120
    /**
121
     * @group DDC-1663
122
     */
123
    public function testAddNamedNativeQueryResultSetMapping()
124
    {
125
        $cm = new ClassMetadata(CmsUser::class, $this->metadataBuildingContext);
126
        $cm->setTable(new TableMetadata("cms_users"));
127
128
        $joinColumn = new JoinColumnMetadata();
129
        $joinColumn->setReferencedColumnName('id');
130
        $joinColumn->setNullable(true);
131
132
        $association = new OneToOneAssociationMetadata('email');
133
        $association->setTargetEntity(CmsEmail::class);
134
        $association->setInversedBy('user');
135
        $association->setCascade(['persist']);
136
        $association->addJoinColumn($joinColumn);
137
138
        $cm->addProperty($association);
139
140
        $cm->addNamedNativeQuery(
141
            'find-all',
142
            'SELECT u.id AS user_id, e.id AS email_id, u.name, e.email, u.id + e.id AS scalarColumn FROM cms_users u INNER JOIN cms_emails e ON e.id = u.email_id',
143
            [
144
                'resultSetMapping' => 'find-all',
145
            ]
146
        );
147
148
        $cm->addSqlResultSetMapping(
149
            [
150
                'name'      => 'find-all',
151
                'entities'  => [
152
                    [
153
                        'entityClass'   => '__CLASS__',
154
                        'fields'        => [
155
                            [
156
                                'name'  => 'id',
157
                                'column'=> 'user_id'
158
                            ],
159
                            [
160
                                'name'  => 'name',
161
                                'column'=> 'name'
162
                            ]
163
                        ]
164
                    ],
165
                    [
166
                        'entityClass'   => CmsEmail::class,
167
                        'fields'        => [
168
                            [
169
                                'name'  => 'id',
170
                                'column'=> 'email_id'
171
                            ],
172
                            [
173
                                'name'  => 'email',
174
                                'column'=> 'email'
175
                            ]
176
                        ]
177
                    ]
178
                ],
179
                'columns'   => [
180
                    [
181
                        'name' => 'scalarColumn'
182
                    ]
183
                ]
184
            ]
185
        );
186
187
        $queryMapping = $cm->getNamedNativeQuery('find-all');
188
189
        $rsm = new \Doctrine\ORM\Query\ResultSetMappingBuilder($this->em);
190
        $rsm->addNamedNativeQueryMapping($cm, $queryMapping);
191
192
        self::assertEquals('scalarColumn', $rsm->getScalarAlias('scalarColumn'));
193
194
        self::assertEquals('e0', $rsm->getEntityAlias('user_id'));
195
        self::assertEquals('e0', $rsm->getEntityAlias('name'));
196
        self::assertEquals(CmsUser::class, $rsm->getClassName('e0'));
197
        self::assertEquals(CmsUser::class, $rsm->getDeclaringClass('name'));
198
        self::assertEquals(CmsUser::class, $rsm->getDeclaringClass('user_id'));
199
200
201
        self::assertEquals('e1', $rsm->getEntityAlias('email_id'));
202
        self::assertEquals('e1', $rsm->getEntityAlias('email'));
203
        self::assertEquals(CmsEmail::class, $rsm->getClassName('e1'));
204
        self::assertEquals(CmsEmail::class, $rsm->getDeclaringClass('email'));
205
        self::assertEquals(CmsEmail::class, $rsm->getDeclaringClass('email_id'));
206
    }
207
208
    /**
209
     * @group DDC-1663
210
     */
211
    public function testAddNamedNativeQueryResultSetMappingWithoutFields()
212
    {
213
        $cm = new ClassMetadata(CmsUser::class, $this->metadataBuildingContext);
214
        $cm->setTable(new TableMetadata("cms_users"));
215
216
        $cm->addNamedNativeQuery(
217
            'find-all',
218
            'SELECT u.id AS user_id, e.id AS email_id, u.name, e.email, u.id + e.id AS scalarColumn FROM cms_users u INNER JOIN cms_emails e ON e.id = u.email_id',
219
            [
220
                'resultSetMapping' => 'find-all',
221
            ]
222
        );
223
224
        $cm->addSqlResultSetMapping(
225
            [
226
            'name'      => 'find-all',
227
            'entities'  => [
228
                [
229
                    'entityClass'   => '__CLASS__',
230
                ]
231
            ],
232
            'columns'   => [
233
                [
234
                    'name' => 'scalarColumn'
235
                ]
236
            ]
237
            ]
238
        );
239
240
        $queryMapping = $cm->getNamedNativeQuery('find-all');
241
        $rsm          = new \Doctrine\ORM\Query\ResultSetMappingBuilder($this->em);
242
243
        $rsm->addNamedNativeQueryMapping($cm, $queryMapping);
244
245
        self::assertEquals('scalarColumn', $rsm->getScalarAlias('scalarColumn'));
246
        self::assertEquals('e0', $rsm->getEntityAlias('id'));
247
        self::assertEquals('e0', $rsm->getEntityAlias('name'));
248
        self::assertEquals('e0', $rsm->getEntityAlias('status'));
249
        self::assertEquals('e0', $rsm->getEntityAlias('username'));
250
        self::assertEquals(CmsUser::class, $rsm->getClassName('e0'));
251
        self::assertEquals(CmsUser::class, $rsm->getDeclaringClass('id'));
252
        self::assertEquals(CmsUser::class, $rsm->getDeclaringClass('name'));
253
        self::assertEquals(CmsUser::class, $rsm->getDeclaringClass('status'));
254
        self::assertEquals(CmsUser::class, $rsm->getDeclaringClass('username'));
255
    }
256
257
    /**
258
     * @group DDC-1663
259
     */
260
    public function testAddNamedNativeQueryResultClass()
261
    {
262
        $cm = $this->em->getClassMetadata(CmsUser::class);
263
264
        $cm->addNamedNativeQuery(
265
            'find-all',
266
            'SELECT * FROM cms_users',
267
            [
268
                'resultClass' => '__CLASS__',
269
            ]
270
        );
271
272
        $queryMapping = $cm->getNamedNativeQuery('find-all');
273
        $rsm          = new \Doctrine\ORM\Query\ResultSetMappingBuilder($this->em);
274
275
        $rsm->addNamedNativeQueryMapping($cm, $queryMapping);
276
277
        self::assertEquals('e0', $rsm->getEntityAlias('id'));
278
        self::assertEquals('e0', $rsm->getEntityAlias('name'));
279
        self::assertEquals('e0', $rsm->getEntityAlias('status'));
280
        self::assertEquals('e0', $rsm->getEntityAlias('username'));
281
        self::assertEquals(CmsUser::class, $rsm->getClassName('e0'));
282
        self::assertEquals(CmsUser::class, $rsm->getDeclaringClass('id'));
283
        self::assertEquals(CmsUser::class, $rsm->getDeclaringClass('name'));
284
        self::assertEquals(CmsUser::class, $rsm->getDeclaringClass('status'));
285
        self::assertEquals(CmsUser::class, $rsm->getDeclaringClass('username'));
286
    }
287
    /**
288
     * @group DDC-117
289
     */
290
    public function testIndexByMetadataColumn()
291
    {
292
        $this->rsm->addEntityResult(LegacyUser::class, 'u');
293
        $this->rsm->addJoinedEntityResult(LegacyUserReference::class, 'lu', 'u', '_references');
294
        $this->rsm->addMetaResult('lu', '_source',  '_source', true, Type::getType('integer'));
295
        $this->rsm->addMetaResult('lu', '_target',  '_target', true, Type::getType('integer'));
296
        $this->rsm->addIndexBy('lu', '_source');
297
298
        self::assertTrue($this->rsm->hasIndexBy('lu'));
299
    }
300
301
    public function testNewObjectNestedArgumentsDeepestLeavesShouldComeFirst()
302
    {
303
        $this->rsm->addNewObjectAsArgument('objALevel2', 'objALevel1', 0);
304
        $this->rsm->addNewObjectAsArgument('objALevel3', 'objALevel2', 1);
305
        $this->rsm->addNewObjectAsArgument('objBLevel3', 'objBLevel2', 0);
306
        $this->rsm->addNewObjectAsArgument('objBLevel2', 'objBLevel1', 1);
307
308
        $expectedArgumentMapping = [
309
            'objALevel3' => ['ownerIndex' => 'objALevel2', 'argIndex' => 1],
310
            'objALevel2' => ['ownerIndex' => 'objALevel1', 'argIndex' => 0],
311
            'objBLevel3' => ['ownerIndex' => 'objBLevel2', 'argIndex' => 0],
312
            'objBLevel2' => ['ownerIndex' => 'objBLevel1', 'argIndex' => 1],
313
        ];
314
315
        $this->assertEquals($expectedArgumentMapping, $this->rsm->nestedNewObjectArguments);
316
    }
317
}
318