Completed
Pull Request — master (#6130)
by
unknown
10:40
created

AbstractMappingDriverTest   D

Complexity

Total Complexity 55

Size/Duplication

Total Lines 1038
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 55
lcom 1
cbo 8
dl 0
loc 1038
rs 4.8238
c 0
b 0
f 0

51 Methods

Rating   Name   Duplication   Size   Complexity  
_loadDriver() 0 1 ?
A createClassMetadata() 0 10 1
A createClassMetadataFactory() 0 10 2
A testLoadMapping() 0 5 1
A testEntityTableNameAndInheritance() 0 7 1
A testEntityIndexes() 0 10 1
A testEntityIndexFlagsAndPartialIndexes() 0 12 1
A testEntityUniqueConstraints() 0 11 1
A testEntityOptions() 0 10 1
A testEntitySequence() 0 12 1
A testEntityCustomGenerator() 0 11 1
A testFieldMappings() 0 10 1
A testVersionedField() 0 7 1
A testFieldMappingsColumnNames() 0 8 1
A testStringFieldMappings() 0 9 1
A testFieldOptions() 0 7 1
A testIdFieldOptions() 0 6 1
A testIdentifier() 0 8 1
A testBooleanValuesForOptionIsSetCorrectly() 0 10 1
A testAssociations() 0 6 1
A testOwningOneToOneAssociation() 0 14 1
A testInverseOneToManyAssociation() 0 16 1
A testManyToManyAssociationWithCascadeAll() 0 15 1
A testLifecycleCallbacks() 0 8 1
A testLifecycleCallbacksSupportMultipleMethodNames() 0 7 1
A testJoinColumnUniqueAndNullable() 0 8 1
A testColumnDefinition() 0 7 1
A testJoinColumnOnDelete() 0 6 1
A testDiscriminatorColumnDefaults() 0 13 2
B testMappedSuperclassWithRepository() 0 28 1
B testDefaultFieldType() 0 34 1
A testIdentifierColumnDefinition() 0 14 1
A testNamingStrategy() 0 16 1
A testDiscriminatorColumnDefinition() 0 10 1
A testInvalidEntityOrMappedSuperClassShouldMentionParentClasses() 0 7 1
A testIdentifierRequiredShouldMentionParentClasses() 0 9 1
A testNamedQuery() 0 7 1
A testNamedNativeQuery() 0 49 1
A testSqlResultSetMapping() 0 67 1
B testAssociationOverridesMapping() 0 79 1
A testInversedByOverrideMapping() 0 13 1
B testAttributeOverridesMapping() 0 35 1
B testEntityListeners() 0 27 1
B testEntityListenersOverride() 0 29 1
A testEntityListenersNamingConvention() 0 52 1
B testSecondLevelCacheMapping() 0 24 1
A testSchemaDefinitionViaExplicitTableSchemaAnnotationProperty() 0 8 1
A testSchemaDefinitionViaSchemaDefinedInTableNameInTableAnnotationProperty() 0 8 1
A testDiscriminatorColumnDefaultLength() 0 10 2
A testDiscriminatorColumnDefaultType() 0 10 2
A testDiscriminatorColumnDefaultName() 0 10 2

How to fix   Complexity   

Complex Class

Complex classes like AbstractMappingDriverTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AbstractMappingDriverTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Doctrine\Tests\ORM\Mapping;
4
5
use Doctrine\Common\Persistence\Mapping\RuntimeReflectionService;
6
use Doctrine\ORM\EntityManager;
7
use Doctrine\ORM\Events;
8
use Doctrine\ORM\Mapping\ClassMetadataFactory;
9
use Doctrine\ORM\Mapping\DiscriminatorColumn;
10
use Doctrine\ORM\Mapping\Id;
11
use Doctrine\ORM\Mapping\MappingException;
12
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
13
use Doctrine\Tests\Models\Cache\City;
14
use Doctrine\ORM\Mapping\ClassMetadata;
15
use Doctrine\ORM\Mapping\ClassMetadataInfo;
16
use Doctrine\Tests\Models\DDC2825\ExplicitSchemaAndTable;
17
use Doctrine\Tests\Models\DDC2825\SchemaAndTableInTableName;
18
use Doctrine\Tests\OrmTestCase;
19
20
abstract class AbstractMappingDriverTest extends OrmTestCase
21
{
22
    abstract protected function _loadDriver();
23
24
    public function createClassMetadata($entityClassName)
25
    {
26
        $mappingDriver = $this->_loadDriver();
27
28
        $class = new ClassMetadata($entityClassName);
29
        $class->initializeReflection(new RuntimeReflectionService());
30
        $mappingDriver->loadMetadataForClass($entityClassName, $class);
31
32
        return $class;
33
    }
34
35
    /**
36
     * @param \Doctrine\ORM\EntityManager $entityClassName
37
     * @return \Doctrine\ORM\Mapping\ClassMetadataFactory
38
     */
39
    protected function createClassMetadataFactory(EntityManager $em = null)
40
    {
41
        $driver     = $this->_loadDriver();
42
        $em         = $em ?: $this->_getTestEntityManager();
43
        $factory    = new ClassMetadataFactory();
44
        $em->getConfiguration()->setMetadataDriverImpl($driver);
45
        $factory->setEntityManager($em);
46
47
        return $factory;
48
    }
49
50
    public function testLoadMapping()
51
    {
52
        $entityClassName = 'Doctrine\Tests\ORM\Mapping\User';
53
        return $this->createClassMetadata($entityClassName);
54
    }
55
56
    /**
57
     * @depends testLoadMapping
58
     * @param ClassMetadata $class
59
     */
60
    public function testEntityTableNameAndInheritance($class)
61
    {
62
        $this->assertEquals('cms_users', $class->getTableName());
63
        $this->assertEquals(ClassMetadata::INHERITANCE_TYPE_NONE, $class->inheritanceType);
64
65
        return $class;
66
    }
67
68
    /**
69
     * @depends testEntityTableNameAndInheritance
70
     * @param ClassMetadata $class
71
     */
72
    public function testEntityIndexes($class)
73
    {
74
        $this->assertArrayHasKey('indexes', $class->table, 'ClassMetadata should have indexes key in table property.');
75
        $this->assertEquals(array(
76
            'name_idx' => array('columns' => array('name')),
77
            0 => array('columns' => array('user_email'))
78
        ), $class->table['indexes']);
79
80
        return $class;
81
    }
82
83
    public function testEntityIndexFlagsAndPartialIndexes()
84
    {
85
        $class = $this->createClassMetadata('Doctrine\Tests\ORM\Mapping\Comment');
86
87
        $this->assertEquals(array(
88
            0 => array(
89
                'columns' => array('content'),
90
                'flags' => array('fulltext'),
91
                'options' => array('where' => 'content IS NOT NULL'),
92
            )
93
        ), $class->table['indexes']);
94
    }
95
96
    /**
97
     * @depends testEntityTableNameAndInheritance
98
     * @param ClassMetadata $class
99
     */
100
    public function testEntityUniqueConstraints($class)
101
    {
102
        $this->assertArrayHasKey('uniqueConstraints', $class->table,
103
            'ClassMetadata should have uniqueConstraints key in table property when Unique Constraints are set.');
104
105
        $this->assertEquals(array(
106
            "search_idx" => array("columns" => array("name", "user_email"), 'options' => array('where' => 'name IS NOT NULL'))
107
        ), $class->table['uniqueConstraints']);
108
109
        return $class;
110
    }
111
112
    /**
113
     * @depends testEntityTableNameAndInheritance
114
     * @param ClassMetadata $class
115
     */
116
    public function testEntityOptions($class)
117
    {
118
        $this->assertArrayHasKey('options', $class->table, 'ClassMetadata should have options key in table property.');
119
120
        $this->assertEquals(array(
121
            'foo' => 'bar', 'baz' => array('key' => 'val')
122
        ), $class->table['options']);
123
124
        return $class;
125
    }
126
127
    /**
128
     * @depends testEntityOptions
129
     * @param ClassMetadata $class
130
     */
131
    public function testEntitySequence($class)
132
    {
133
        $this->assertInternalType('array', $class->sequenceGeneratorDefinition, 'No Sequence Definition set on this driver.');
134
        $this->assertEquals(
135
            array(
136
                'sequenceName' => 'tablename_seq',
137
                'allocationSize' => 100,
138
                'initialValue' => 1,
139
            ),
140
            $class->sequenceGeneratorDefinition
141
        );
142
    }
143
144
    public function testEntityCustomGenerator()
145
    {
146
        $class = $this->createClassMetadata('Doctrine\Tests\ORM\Mapping\Animal');
147
148
        $this->assertEquals(ClassMetadata::GENERATOR_TYPE_CUSTOM,
149
            $class->generatorType, "Generator Type");
150
        $this->assertEquals(
151
            array("class" => "stdClass"),
152
            $class->customGeneratorDefinition,
153
            "Custom Generator Definition");
154
    }
155
156
157
    /**
158
     * @depends testEntityTableNameAndInheritance
159
     * @param ClassMetadata $class
160
     */
161
    public function testFieldMappings($class)
162
    {
163
        $this->assertEquals(4, count($class->fieldMappings));
164
        $this->assertTrue(isset($class->fieldMappings['id']));
165
        $this->assertTrue(isset($class->fieldMappings['name']));
166
        $this->assertTrue(isset($class->fieldMappings['email']));
167
        $this->assertTrue(isset($class->fieldMappings['version']));
168
169
        return $class;
170
    }
171
172
    /**
173
     * @depends testFieldMappings
174
     * @param ClassMetadata $class
175
     */
176
    public function testVersionedField($class)
177
    {
178
        $this->assertTrue($class->isVersioned);
179
        $this->assertEquals("version", $class->versionField);
180
181
        $this->assertFalse(isset($class->fieldMappings['version']['version']));
182
    }
183
184
    /**
185
     * @depends testEntityTableNameAndInheritance
186
     * @param ClassMetadata $class
187
     */
188
    public function testFieldMappingsColumnNames($class)
189
    {
190
        $this->assertEquals("id", $class->fieldMappings['id']['columnName']);
191
        $this->assertEquals("name", $class->fieldMappings['name']['columnName']);
192
        $this->assertEquals("user_email", $class->fieldMappings['email']['columnName']);
193
194
        return $class;
195
    }
196
197
    /**
198
     * @depends testEntityTableNameAndInheritance
199
     * @param ClassMetadata $class
200
     */
201
    public function testStringFieldMappings($class)
202
    {
203
        $this->assertEquals('string', $class->fieldMappings['name']['type']);
204
        $this->assertEquals(50, $class->fieldMappings['name']['length']);
205
        $this->assertTrue($class->fieldMappings['name']['nullable']);
206
        $this->assertTrue($class->fieldMappings['name']['unique']);
207
208
        return $class;
209
    }
210
211
    /**
212
     * @depends testEntityTableNameAndInheritance
213
     *
214
     * @param ClassMetadata $class
215
     *
216
     * @return ClassMetadata
217
     */
218
    public function testFieldOptions(ClassMetadata $class)
219
    {
220
        $expected = ['foo' => 'bar', 'baz' => ['key' => 'val'], 'fixed' => false];
221
        $this->assertEquals($expected, $class->fieldMappings['name']['options']);
222
223
        return $class;
224
    }
225
226
    /**
227
     * @depends testEntityTableNameAndInheritance
228
     * @param ClassMetadata $class
229
     */
230
    public function testIdFieldOptions($class)
231
    {
232
        $this->assertEquals(['foo' => 'bar', 'unsigned' => false], $class->fieldMappings['id']['options']);
233
234
        return $class;
235
    }
236
237
    /**
238
     * @depends testFieldMappings
239
     * @param ClassMetadata $class
240
     */
241
    public function testIdentifier($class)
242
    {
243
        $this->assertEquals(array('id'), $class->identifier);
244
        $this->assertEquals('integer', $class->fieldMappings['id']['type']);
245
        $this->assertEquals(ClassMetadata::GENERATOR_TYPE_AUTO, $class->generatorType, "ID-Generator is not ClassMetadata::GENERATOR_TYPE_AUTO");
246
247
        return $class;
248
    }
249
250
    /**
251
     * @group #6129
252
     *
253
     * @depends testLoadMapping
254
     *
255
     * @param ClassMetadata $class
256
     *
257
     * @return ClassMetadata
258
     */
259
    public function testBooleanValuesForOptionIsSetCorrectly(ClassMetadata $class)
260
    {
261
        $this->assertInternalType('bool', $class->fieldMappings['id']['options']['unsigned']);
262
        $this->assertFalse($class->fieldMappings['id']['options']['unsigned']);
263
264
        $this->assertInternalType('bool', $class->fieldMappings['name']['options']['fixed']);
265
        $this->assertFalse($class->fieldMappings['name']['options']['fixed']);
266
267
        return $class;
268
    }
269
270
    /**
271
     * @depends testIdentifier
272
     * @param ClassMetadata $class
273
     */
274
    public function testAssociations($class)
275
    {
276
        $this->assertEquals(3, count($class->associationMappings));
277
278
        return $class;
279
    }
280
281
    /**
282
     * @depends testAssociations
283
     * @param ClassMetadata $class
284
     */
285
    public function testOwningOneToOneAssociation($class)
286
    {
287
        $this->assertTrue(isset($class->associationMappings['address']));
288
        $this->assertTrue($class->associationMappings['address']['isOwningSide']);
289
        $this->assertEquals('user', $class->associationMappings['address']['inversedBy']);
290
        // Check cascading
291
        $this->assertTrue($class->associationMappings['address']['isCascadeRemove']);
292
        $this->assertFalse($class->associationMappings['address']['isCascadePersist']);
293
        $this->assertFalse($class->associationMappings['address']['isCascadeRefresh']);
294
        $this->assertFalse($class->associationMappings['address']['isCascadeDetach']);
295
        $this->assertFalse($class->associationMappings['address']['isCascadeMerge']);
296
297
        return $class;
298
    }
299
300
    /**
301
     * @depends testOwningOneToOneAssociation
302
     * @param ClassMetadata $class
303
     */
304
    public function testInverseOneToManyAssociation($class)
305
    {
306
        $this->assertTrue(isset($class->associationMappings['phonenumbers']));
307
        $this->assertFalse($class->associationMappings['phonenumbers']['isOwningSide']);
308
        $this->assertTrue($class->associationMappings['phonenumbers']['isCascadePersist']);
309
        $this->assertTrue($class->associationMappings['phonenumbers']['isCascadeRemove']);
310
        $this->assertFalse($class->associationMappings['phonenumbers']['isCascadeRefresh']);
311
        $this->assertFalse($class->associationMappings['phonenumbers']['isCascadeDetach']);
312
        $this->assertFalse($class->associationMappings['phonenumbers']['isCascadeMerge']);
313
        $this->assertTrue($class->associationMappings['phonenumbers']['orphanRemoval']);
314
315
        // Test Order By
316
        $this->assertEquals(array('number' => 'ASC'), $class->associationMappings['phonenumbers']['orderBy']);
317
318
        return $class;
319
    }
320
321
    /**
322
     * @depends testInverseOneToManyAssociation
323
     * @param ClassMetadata $class
324
     */
325
    public function testManyToManyAssociationWithCascadeAll($class)
326
    {
327
        $this->assertTrue(isset($class->associationMappings['groups']));
328
        $this->assertTrue($class->associationMappings['groups']['isOwningSide']);
329
        // Make sure that cascade-all works as expected
330
        $this->assertTrue($class->associationMappings['groups']['isCascadeRemove']);
331
        $this->assertTrue($class->associationMappings['groups']['isCascadePersist']);
332
        $this->assertTrue($class->associationMappings['groups']['isCascadeRefresh']);
333
        $this->assertTrue($class->associationMappings['groups']['isCascadeDetach']);
334
        $this->assertTrue($class->associationMappings['groups']['isCascadeMerge']);
335
336
        $this->assertFalse(isset($class->associationMappings['groups']['orderBy']));
337
338
        return $class;
339
    }
340
341
    /**
342
     * @depends testManyToManyAssociationWithCascadeAll
343
     * @param ClassMetadata $class
344
     */
345
    public function testLifecycleCallbacks($class)
346
    {
347
        $this->assertEquals(count($class->lifecycleCallbacks), 2);
348
        $this->assertEquals($class->lifecycleCallbacks['prePersist'][0], 'doStuffOnPrePersist');
349
        $this->assertEquals($class->lifecycleCallbacks['postPersist'][0], 'doStuffOnPostPersist');
350
351
        return $class;
352
    }
353
354
    /**
355
     * @depends testManyToManyAssociationWithCascadeAll
356
     * @param ClassMetadata $class
357
     */
358
    public function testLifecycleCallbacksSupportMultipleMethodNames($class)
359
    {
360
        $this->assertEquals(count($class->lifecycleCallbacks['prePersist']), 2);
361
        $this->assertEquals($class->lifecycleCallbacks['prePersist'][1], 'doOtherStuffOnPrePersistToo');
362
363
        return $class;
364
    }
365
366
    /**
367
     * @depends testLifecycleCallbacksSupportMultipleMethodNames
368
     * @param ClassMetadata $class
369
     */
370
    public function testJoinColumnUniqueAndNullable($class)
371
    {
372
        // Non-Nullability of Join Column
373
        $this->assertFalse($class->associationMappings['groups']['joinTable']['joinColumns'][0]['nullable']);
374
        $this->assertFalse($class->associationMappings['groups']['joinTable']['joinColumns'][0]['unique']);
375
376
        return $class;
377
    }
378
379
    /**
380
     * @depends testJoinColumnUniqueAndNullable
381
     * @param ClassMetadata $class
382
     */
383
    public function testColumnDefinition($class)
384
    {
385
        $this->assertEquals("CHAR(32) NOT NULL", $class->fieldMappings['email']['columnDefinition']);
386
        $this->assertEquals("INT NULL", $class->associationMappings['groups']['joinTable']['inverseJoinColumns'][0]['columnDefinition']);
387
388
        return $class;
389
    }
390
391
    /**
392
     * @depends testColumnDefinition
393
     * @param ClassMetadata $class
394
     */
395
    public function testJoinColumnOnDelete($class)
396
    {
397
        $this->assertEquals('CASCADE', $class->associationMappings['address']['joinColumns'][0]['onDelete']);
398
399
        return $class;
400
    }
401
402
    /**
403
     * @group DDC-514
404
     */
405
    public function testDiscriminatorColumnDefaults()
406
    {
407
        if (strpos(get_class($this), 'PHPMappingDriver') !== false) {
408
            $this->markTestSkipped('PHP Mapping Drivers have no defaults.');
409
        }
410
411
        $class = $this->createClassMetadata('Doctrine\Tests\ORM\Mapping\Animal');
412
413
        $this->assertEquals(
414
            array('name' => 'discr', 'type' => 'string', 'length' => '32', 'fieldName' => 'discr', 'columnDefinition' => null),
415
            $class->discriminatorColumn
416
        );
417
    }
418
419
    /**
420
     * @group DDC-869
421
     */
422
    public function testMappedSuperclassWithRepository()
423
    {
424
        $em         = $this->_getTestEntityManager();
425
        $factory    = $this->createClassMetadataFactory($em);
426
427
428
        $class = $factory->getMetadataFor('Doctrine\Tests\Models\DDC869\DDC869CreditCardPayment');
429
430
        $this->assertTrue(isset($class->fieldMappings['id']));
431
        $this->assertTrue(isset($class->fieldMappings['value']));
432
        $this->assertTrue(isset($class->fieldMappings['creditCardNumber']));
433
        $this->assertEquals($class->customRepositoryClassName, "Doctrine\Tests\Models\DDC869\DDC869PaymentRepository");
434
        $this->assertInstanceOf("Doctrine\Tests\Models\DDC869\DDC869PaymentRepository",
435
             $em->getRepository("Doctrine\Tests\Models\DDC869\DDC869CreditCardPayment"));
436
        $this->assertTrue($em->getRepository("Doctrine\Tests\Models\DDC869\DDC869ChequePayment")->isTrue());
437
438
439
440
        $class = $factory->getMetadataFor('Doctrine\Tests\Models\DDC869\DDC869ChequePayment');
441
442
        $this->assertTrue(isset($class->fieldMappings['id']));
443
        $this->assertTrue(isset($class->fieldMappings['value']));
444
        $this->assertTrue(isset($class->fieldMappings['serialNumber']));
445
        $this->assertEquals($class->customRepositoryClassName, "Doctrine\Tests\Models\DDC869\DDC869PaymentRepository");
446
        $this->assertInstanceOf("Doctrine\Tests\Models\DDC869\DDC869PaymentRepository",
447
             $em->getRepository("Doctrine\Tests\Models\DDC869\DDC869ChequePayment"));
448
        $this->assertTrue($em->getRepository("Doctrine\Tests\Models\DDC869\DDC869ChequePayment")->isTrue());
449
    }
450
451
    /**
452
     * @group DDC-1476
453
     */
454
    public function testDefaultFieldType()
455
    {
456
        $factory    = $this->createClassMetadataFactory();
457
        $class      = $factory->getMetadataFor('Doctrine\Tests\Models\DDC1476\DDC1476EntityWithDefaultFieldType');
458
459
460
        $this->assertArrayHasKey('id', $class->fieldMappings);
461
        $this->assertArrayHasKey('name', $class->fieldMappings);
462
463
464
        $this->assertArrayHasKey('type', $class->fieldMappings['id']);
465
        $this->assertArrayHasKey('type', $class->fieldMappings['name']);
466
467
        $this->assertEquals('string', $class->fieldMappings['id']['type']);
468
        $this->assertEquals('string', $class->fieldMappings['name']['type']);
469
470
471
472
        $this->assertArrayHasKey('fieldName', $class->fieldMappings['id']);
473
        $this->assertArrayHasKey('fieldName', $class->fieldMappings['name']);
474
475
        $this->assertEquals('id', $class->fieldMappings['id']['fieldName']);
476
        $this->assertEquals('name', $class->fieldMappings['name']['fieldName']);
477
478
479
480
        $this->assertArrayHasKey('columnName', $class->fieldMappings['id']);
481
        $this->assertArrayHasKey('columnName', $class->fieldMappings['name']);
482
483
        $this->assertEquals('id', $class->fieldMappings['id']['columnName']);
484
        $this->assertEquals('name', $class->fieldMappings['name']['columnName']);
485
486
        $this->assertEquals(ClassMetadataInfo::GENERATOR_TYPE_NONE, $class->generatorType);
487
    }
488
489
    /**
490
     * @group DDC-1170
491
     */
492
    public function testIdentifierColumnDefinition()
493
    {
494
        $class = $this->createClassMetadata(__NAMESPACE__ . '\DDC1170Entity');
495
496
497
        $this->assertArrayHasKey('id', $class->fieldMappings);
498
        $this->assertArrayHasKey('value', $class->fieldMappings);
499
500
        $this->assertArrayHasKey('columnDefinition', $class->fieldMappings['id']);
501
        $this->assertArrayHasKey('columnDefinition', $class->fieldMappings['value']);
502
503
        $this->assertEquals("INT unsigned NOT NULL", $class->fieldMappings['id']['columnDefinition']);
504
        $this->assertEquals("VARCHAR(255) NOT NULL", $class->fieldMappings['value']['columnDefinition']);
505
    }
506
507
    /**
508
     * @group DDC-559
509
     */
510
    public function testNamingStrategy()
511
    {
512
        $em         = $this->_getTestEntityManager();
513
        $factory    = $this->createClassMetadataFactory($em);
514
515
516
        $this->assertInstanceOf('Doctrine\ORM\Mapping\DefaultNamingStrategy', $em->getConfiguration()->getNamingStrategy());
517
        $em->getConfiguration()->setNamingStrategy(new UnderscoreNamingStrategy(CASE_UPPER));
518
        $this->assertInstanceOf('Doctrine\ORM\Mapping\UnderscoreNamingStrategy', $em->getConfiguration()->getNamingStrategy());
519
520
        $class = $factory->getMetadataFor('Doctrine\Tests\Models\DDC1476\DDC1476EntityWithDefaultFieldType');
521
522
        $this->assertEquals('ID', $class->getColumnName('id'));
523
        $this->assertEquals('NAME', $class->getColumnName('name'));
524
        $this->assertEquals('DDC1476ENTITY_WITH_DEFAULT_FIELD_TYPE', $class->table['name']);
525
    }
526
527
    /**
528
     * @group DDC-807
529
     * @group DDC-553
530
     */
531
    public function testDiscriminatorColumnDefinition()
532
    {
533
        $class = $this->createClassMetadata(__NAMESPACE__ . '\DDC807Entity');
534
535
        $this->assertArrayHasKey('columnDefinition', $class->discriminatorColumn);
536
        $this->assertArrayHasKey('name', $class->discriminatorColumn);
537
538
        $this->assertEquals("ENUM('ONE','TWO')", $class->discriminatorColumn['columnDefinition']);
539
        $this->assertEquals("dtype", $class->discriminatorColumn['name']);
540
    }
541
542
    /**
543
     * @group DDC-889
544
     */
545
    public function testInvalidEntityOrMappedSuperClassShouldMentionParentClasses()
546
    {
547
        $this->expectException(MappingException::class);
548
        $this->expectExceptionMessage('Class "Doctrine\Tests\Models\DDC889\DDC889Class" sub class of "Doctrine\Tests\Models\DDC889\DDC889SuperClass" is not a valid entity or mapped super class.');
549
550
        $this->createClassMetadata('Doctrine\Tests\Models\DDC889\DDC889Class');
551
    }
552
553
    /**
554
     * @group DDC-889
555
     */
556
    public function testIdentifierRequiredShouldMentionParentClasses()
557
    {
558
        $factory = $this->createClassMetadataFactory();
559
560
        $this->expectException(MappingException::class);
561
        $this->expectExceptionMessage('No identifier/primary key specified for Entity "Doctrine\Tests\Models\DDC889\DDC889Entity" sub class of "Doctrine\Tests\Models\DDC889\DDC889SuperClass". Every Entity must have an identifier/primary key.');
562
563
        $factory->getMetadataFor('Doctrine\Tests\Models\DDC889\DDC889Entity');
564
    }
565
566
    public function testNamedQuery()
567
    {
568
        $driver = $this->_loadDriver();
569
        $class = $this->createClassMetadata(__NAMESPACE__.'\User');
570
571
        $this->assertCount(1, $class->getNamedQueries(), sprintf("Named queries not processed correctly by driver %s", get_class($driver)));
572
    }
573
574
    /**
575
     * @group DDC-1663
576
     */
577
    public function testNamedNativeQuery()
578
    {
579
580
        $class = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
581
582
        //named native query
583
        $this->assertCount(3, $class->namedNativeQueries);
584
        $this->assertArrayHasKey('find-all', $class->namedNativeQueries);
585
        $this->assertArrayHasKey('find-by-id', $class->namedNativeQueries);
586
587
588
        $findAllQuery = $class->getNamedNativeQuery('find-all');
589
        $this->assertEquals('find-all', $findAllQuery['name']);
590
        $this->assertEquals('mapping-find-all', $findAllQuery['resultSetMapping']);
591
        $this->assertEquals('SELECT id, country, city FROM cms_addresses', $findAllQuery['query']);
592
593
        $findByIdQuery = $class->getNamedNativeQuery('find-by-id');
594
        $this->assertEquals('find-by-id', $findByIdQuery['name']);
595
        $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddress',$findByIdQuery['resultClass']);
596
        $this->assertEquals('SELECT * FROM cms_addresses WHERE id = ?',  $findByIdQuery['query']);
597
598
        $countQuery = $class->getNamedNativeQuery('count');
599
        $this->assertEquals('count', $countQuery['name']);
600
        $this->assertEquals('mapping-count', $countQuery['resultSetMapping']);
601
        $this->assertEquals('SELECT COUNT(*) AS count FROM cms_addresses',  $countQuery['query']);
602
603
        // result set mapping
604
        $this->assertCount(3, $class->sqlResultSetMappings);
605
        $this->assertArrayHasKey('mapping-count', $class->sqlResultSetMappings);
606
        $this->assertArrayHasKey('mapping-find-all', $class->sqlResultSetMappings);
607
        $this->assertArrayHasKey('mapping-without-fields', $class->sqlResultSetMappings);
608
609
        $findAllMapping = $class->getSqlResultSetMapping('mapping-find-all');
610
        $this->assertEquals('mapping-find-all', $findAllMapping['name']);
611
        $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddress', $findAllMapping['entities'][0]['entityClass']);
612
        $this->assertEquals(array('name'=>'id','column'=>'id'), $findAllMapping['entities'][0]['fields'][0]);
613
        $this->assertEquals(array('name'=>'city','column'=>'city'), $findAllMapping['entities'][0]['fields'][1]);
614
        $this->assertEquals(array('name'=>'country','column'=>'country'), $findAllMapping['entities'][0]['fields'][2]);
615
616
        $withoutFieldsMapping = $class->getSqlResultSetMapping('mapping-without-fields');
617
        $this->assertEquals('mapping-without-fields', $withoutFieldsMapping['name']);
618
        $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddress', $withoutFieldsMapping['entities'][0]['entityClass']);
619
        $this->assertEquals(array(), $withoutFieldsMapping['entities'][0]['fields']);
620
621
        $countMapping = $class->getSqlResultSetMapping('mapping-count');
622
        $this->assertEquals('mapping-count', $countMapping['name']);
623
        $this->assertEquals(array('name'=>'count'), $countMapping['columns'][0]);
624
625
    }
626
627
    /**
628
     * @group DDC-1663
629
     */
630
    public function testSqlResultSetMapping()
631
    {
632
633
        $userMetadata   = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
634
        $personMetadata = $this->createClassMetadata('Doctrine\Tests\Models\Company\CompanyPerson');
635
636
        // user asserts
637
        $this->assertCount(4, $userMetadata->getSqlResultSetMappings());
638
639
        $mapping = $userMetadata->getSqlResultSetMapping('mappingJoinedAddress');
640
        $this->assertEquals(array(),$mapping['columns']);
641
        $this->assertEquals('mappingJoinedAddress', $mapping['name']);
642
        $this->assertNull($mapping['entities'][0]['discriminatorColumn']);
643
        $this->assertEquals(array('name'=>'id','column'=>'id'),                     $mapping['entities'][0]['fields'][0]);
644
        $this->assertEquals(array('name'=>'name','column'=>'name'),                 $mapping['entities'][0]['fields'][1]);
645
        $this->assertEquals(array('name'=>'status','column'=>'status'),             $mapping['entities'][0]['fields'][2]);
646
        $this->assertEquals(array('name'=>'address.zip','column'=>'zip'),           $mapping['entities'][0]['fields'][3]);
647
        $this->assertEquals(array('name'=>'address.city','column'=>'city'),         $mapping['entities'][0]['fields'][4]);
648
        $this->assertEquals(array('name'=>'address.country','column'=>'country'),   $mapping['entities'][0]['fields'][5]);
649
        $this->assertEquals(array('name'=>'address.id','column'=>'a_id'),           $mapping['entities'][0]['fields'][6]);
650
        $this->assertEquals($userMetadata->name,                                    $mapping['entities'][0]['entityClass']);
651
652
653
        $mapping = $userMetadata->getSqlResultSetMapping('mappingJoinedPhonenumber');
654
        $this->assertEquals(array(),$mapping['columns']);
655
        $this->assertEquals('mappingJoinedPhonenumber', $mapping['name']);
656
        $this->assertNull($mapping['entities'][0]['discriminatorColumn']);
657
        $this->assertEquals(array('name'=>'id','column'=>'id'),                             $mapping['entities'][0]['fields'][0]);
658
        $this->assertEquals(array('name'=>'name','column'=>'name'),                         $mapping['entities'][0]['fields'][1]);
659
        $this->assertEquals(array('name'=>'status','column'=>'status'),                     $mapping['entities'][0]['fields'][2]);
660
        $this->assertEquals(array('name'=>'phonenumbers.phonenumber','column'=>'number'),   $mapping['entities'][0]['fields'][3]);
661
        $this->assertEquals($userMetadata->name,                                            $mapping['entities'][0]['entityClass']);
662
663
        $mapping = $userMetadata->getSqlResultSetMapping('mappingUserPhonenumberCount');
664
        $this->assertEquals(array('name'=>'numphones'),$mapping['columns'][0]);
665
        $this->assertEquals('mappingUserPhonenumberCount', $mapping['name']);
666
        $this->assertNull($mapping['entities'][0]['discriminatorColumn']);
667
        $this->assertEquals(array('name'=>'id','column'=>'id'),         $mapping['entities'][0]['fields'][0]);
668
        $this->assertEquals(array('name'=>'name','column'=>'name'),     $mapping['entities'][0]['fields'][1]);
669
        $this->assertEquals(array('name'=>'status','column'=>'status'), $mapping['entities'][0]['fields'][2]);
670
        $this->assertEquals($userMetadata->name,                        $mapping['entities'][0]['entityClass']);
671
672
        $mapping = $userMetadata->getSqlResultSetMapping('mappingMultipleJoinsEntityResults');
673
        $this->assertEquals(array('name'=>'numphones'),$mapping['columns'][0]);
674
        $this->assertEquals('mappingMultipleJoinsEntityResults', $mapping['name']);
675
        $this->assertNull($mapping['entities'][0]['discriminatorColumn']);
676
        $this->assertEquals(array('name'=>'id','column'=>'u_id'),           $mapping['entities'][0]['fields'][0]);
677
        $this->assertEquals(array('name'=>'name','column'=>'u_name'),       $mapping['entities'][0]['fields'][1]);
678
        $this->assertEquals(array('name'=>'status','column'=>'u_status'),   $mapping['entities'][0]['fields'][2]);
679
        $this->assertEquals($userMetadata->name,                            $mapping['entities'][0]['entityClass']);
680
        $this->assertNull($mapping['entities'][1]['discriminatorColumn']);
681
        $this->assertEquals(array('name'=>'id','column'=>'a_id'),           $mapping['entities'][1]['fields'][0]);
682
        $this->assertEquals(array('name'=>'zip','column'=>'a_zip'),         $mapping['entities'][1]['fields'][1]);
683
        $this->assertEquals(array('name'=>'country','column'=>'a_country'), $mapping['entities'][1]['fields'][2]);
684
        $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddress',         $mapping['entities'][1]['entityClass']);
685
686
        //person asserts
687
        $this->assertCount(1, $personMetadata->getSqlResultSetMappings());
688
689
        $mapping = $personMetadata->getSqlResultSetMapping('mappingFetchAll');
690
        $this->assertEquals(array(),$mapping['columns']);
691
        $this->assertEquals('mappingFetchAll', $mapping['name']);
692
        $this->assertEquals('discriminator',                            $mapping['entities'][0]['discriminatorColumn']);
693
        $this->assertEquals(array('name'=>'id','column'=>'id'),         $mapping['entities'][0]['fields'][0]);
694
        $this->assertEquals(array('name'=>'name','column'=>'name'),     $mapping['entities'][0]['fields'][1]);
695
        $this->assertEquals($personMetadata->name,                      $mapping['entities'][0]['entityClass']);
696
    }
697
698
    /*
699
     * @group DDC-964
700
     */
701
    public function testAssociationOverridesMapping()
702
    {
703
704
        $factory        = $this->createClassMetadataFactory();
705
        $adminMetadata  = $factory->getMetadataFor('Doctrine\Tests\Models\DDC964\DDC964Admin');
706
        $guestMetadata  = $factory->getMetadataFor('Doctrine\Tests\Models\DDC964\DDC964Guest');
707
708
709
        // assert groups association mappings
710
        $this->assertArrayHasKey('groups', $guestMetadata->associationMappings);
711
        $this->assertArrayHasKey('groups', $adminMetadata->associationMappings);
712
713
        $guestGroups = $guestMetadata->associationMappings['groups'];
714
        $adminGroups = $adminMetadata->associationMappings['groups'];
715
716
        // assert not override attributes
717
        $this->assertEquals($guestGroups['fieldName'], $adminGroups['fieldName']);
718
        $this->assertEquals($guestGroups['type'], $adminGroups['type']);
719
        $this->assertEquals($guestGroups['mappedBy'], $adminGroups['mappedBy']);
720
        $this->assertEquals($guestGroups['inversedBy'], $adminGroups['inversedBy']);
721
        $this->assertEquals($guestGroups['isOwningSide'], $adminGroups['isOwningSide']);
722
        $this->assertEquals($guestGroups['fetch'], $adminGroups['fetch']);
723
        $this->assertEquals($guestGroups['isCascadeRemove'], $adminGroups['isCascadeRemove']);
724
        $this->assertEquals($guestGroups['isCascadePersist'], $adminGroups['isCascadePersist']);
725
        $this->assertEquals($guestGroups['isCascadeRefresh'], $adminGroups['isCascadeRefresh']);
726
        $this->assertEquals($guestGroups['isCascadeMerge'], $adminGroups['isCascadeMerge']);
727
        $this->assertEquals($guestGroups['isCascadeDetach'], $adminGroups['isCascadeDetach']);
728
729
         // assert not override attributes
730
        $this->assertEquals('ddc964_users_groups', $guestGroups['joinTable']['name']);
731
        $this->assertEquals('user_id', $guestGroups['joinTable']['joinColumns'][0]['name']);
732
        $this->assertEquals('group_id', $guestGroups['joinTable']['inverseJoinColumns'][0]['name']);
733
734
        $this->assertEquals(array('user_id'=>'id'), $guestGroups['relationToSourceKeyColumns']);
735
        $this->assertEquals(array('group_id'=>'id'), $guestGroups['relationToTargetKeyColumns']);
736
        $this->assertEquals(array('user_id','group_id'), $guestGroups['joinTableColumns']);
737
738
739
        $this->assertEquals('ddc964_users_admingroups', $adminGroups['joinTable']['name']);
740
        $this->assertEquals('adminuser_id', $adminGroups['joinTable']['joinColumns'][0]['name']);
741
        $this->assertEquals('admingroup_id', $adminGroups['joinTable']['inverseJoinColumns'][0]['name']);
742
743
        $this->assertEquals(array('adminuser_id'=>'id'), $adminGroups['relationToSourceKeyColumns']);
744
        $this->assertEquals(array('admingroup_id'=>'id'), $adminGroups['relationToTargetKeyColumns']);
745
        $this->assertEquals(array('adminuser_id','admingroup_id'), $adminGroups['joinTableColumns']);
746
747
748
        // assert address association mappings
749
        $this->assertArrayHasKey('address', $guestMetadata->associationMappings);
750
        $this->assertArrayHasKey('address', $adminMetadata->associationMappings);
751
752
        $guestAddress = $guestMetadata->associationMappings['address'];
753
        $adminAddress = $adminMetadata->associationMappings['address'];
754
755
        // assert not override attributes
756
        $this->assertEquals($guestAddress['fieldName'], $adminAddress['fieldName']);
757
        $this->assertEquals($guestAddress['type'], $adminAddress['type']);
758
        $this->assertEquals($guestAddress['mappedBy'], $adminAddress['mappedBy']);
759
        $this->assertEquals($guestAddress['inversedBy'], $adminAddress['inversedBy']);
760
        $this->assertEquals($guestAddress['isOwningSide'], $adminAddress['isOwningSide']);
761
        $this->assertEquals($guestAddress['fetch'], $adminAddress['fetch']);
762
        $this->assertEquals($guestAddress['isCascadeRemove'], $adminAddress['isCascadeRemove']);
763
        $this->assertEquals($guestAddress['isCascadePersist'], $adminAddress['isCascadePersist']);
764
        $this->assertEquals($guestAddress['isCascadeRefresh'], $adminAddress['isCascadeRefresh']);
765
        $this->assertEquals($guestAddress['isCascadeMerge'], $adminAddress['isCascadeMerge']);
766
        $this->assertEquals($guestAddress['isCascadeDetach'], $adminAddress['isCascadeDetach']);
767
768
        // assert override
769
        $this->assertEquals('address_id', $guestAddress['joinColumns'][0]['name']);
770
        $this->assertEquals(array('address_id'=>'id'), $guestAddress['sourceToTargetKeyColumns']);
771
        $this->assertEquals(array('address_id'=>'address_id'), $guestAddress['joinColumnFieldNames']);
772
        $this->assertEquals(array('id'=>'address_id'), $guestAddress['targetToSourceKeyColumns']);
773
774
775
        $this->assertEquals('adminaddress_id', $adminAddress['joinColumns'][0]['name']);
776
        $this->assertEquals(array('adminaddress_id'=>'id'), $adminAddress['sourceToTargetKeyColumns']);
777
        $this->assertEquals(array('adminaddress_id'=>'adminaddress_id'), $adminAddress['joinColumnFieldNames']);
778
        $this->assertEquals(array('id'=>'adminaddress_id'), $adminAddress['targetToSourceKeyColumns']);
779
    }
780
781
    /*
782
     * @group DDC-3579
783
     */
784
    public function testInversedByOverrideMapping()
785
    {
786
787
        $factory        = $this->createClassMetadataFactory();
788
        $adminMetadata  = $factory->getMetadataFor('Doctrine\Tests\Models\DDC3579\DDC3579Admin');
789
790
        // assert groups association mappings
791
        $this->assertArrayHasKey('groups', $adminMetadata->associationMappings);
792
        $adminGroups = $adminMetadata->associationMappings['groups'];
793
794
        // assert override
795
        $this->assertEquals('admins', $adminGroups['inversedBy']);
796
    }
797
798
    /**
799
     * @group DDC-964
800
     */
801
    public function testAttributeOverridesMapping()
802
    {
803
804
        $factory       = $this->createClassMetadataFactory();
805
        $guestMetadata = $factory->getMetadataFor('Doctrine\Tests\Models\DDC964\DDC964Guest');
806
        $adminMetadata = $factory->getMetadataFor('Doctrine\Tests\Models\DDC964\DDC964Admin');
807
808
        $this->assertTrue($adminMetadata->fieldMappings['id']['id']);
809
        $this->assertEquals('id', $adminMetadata->fieldMappings['id']['fieldName']);
810
        $this->assertEquals('user_id', $adminMetadata->fieldMappings['id']['columnName']);
811
        $this->assertEquals(array('user_id'=>'id','user_name'=>'name'), $adminMetadata->fieldNames);
812
        $this->assertEquals(array('id'=>'user_id','name'=>'user_name'), $adminMetadata->columnNames);
813
        $this->assertEquals(150, $adminMetadata->fieldMappings['id']['length']);
814
815
816
        $this->assertEquals('name', $adminMetadata->fieldMappings['name']['fieldName']);
817
        $this->assertEquals('user_name', $adminMetadata->fieldMappings['name']['columnName']);
818
        $this->assertEquals(250, $adminMetadata->fieldMappings['name']['length']);
819
        $this->assertTrue($adminMetadata->fieldMappings['name']['nullable']);
820
        $this->assertFalse($adminMetadata->fieldMappings['name']['unique']);
821
822
823
        $this->assertTrue($guestMetadata->fieldMappings['id']['id']);
824
        $this->assertEquals('guest_id', $guestMetadata->fieldMappings['id']['columnName']);
825
        $this->assertEquals('id', $guestMetadata->fieldMappings['id']['fieldName']);
826
        $this->assertEquals(array('guest_id'=>'id','guest_name'=>'name'), $guestMetadata->fieldNames);
827
        $this->assertEquals(array('id'=>'guest_id','name'=>'guest_name'), $guestMetadata->columnNames);
828
        $this->assertEquals(140, $guestMetadata->fieldMappings['id']['length']);
829
830
        $this->assertEquals('name', $guestMetadata->fieldMappings['name']['fieldName']);
831
        $this->assertEquals('guest_name', $guestMetadata->fieldMappings['name']['columnName']);
832
        $this->assertEquals(240, $guestMetadata->fieldMappings['name']['length']);
833
        $this->assertFalse($guestMetadata->fieldMappings['name']['nullable']);
834
        $this->assertTrue($guestMetadata->fieldMappings['name']['unique']);
835
    }
836
837
    /**
838
     * @group DDC-1955
839
     */
840
    public function testEntityListeners()
841
    {
842
        $em         = $this->_getTestEntityManager();
843
        $factory    = $this->createClassMetadataFactory($em);
844
        $superClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyContract');
845
        $flexClass  = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFixContract');
846
        $fixClass   = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexContract');
847
        $ultraClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexUltraContract');
848
849
        $this->assertArrayHasKey(Events::prePersist, $superClass->entityListeners);
850
        $this->assertArrayHasKey(Events::postPersist, $superClass->entityListeners);
851
852
        $this->assertCount(1, $superClass->entityListeners[Events::prePersist]);
853
        $this->assertCount(1, $superClass->entityListeners[Events::postPersist]);
854
855
        $postPersist = $superClass->entityListeners[Events::postPersist][0];
856
        $prePersist  = $superClass->entityListeners[Events::prePersist][0];
857
858
        $this->assertEquals('Doctrine\Tests\Models\Company\CompanyContractListener', $postPersist['class']);
859
        $this->assertEquals('Doctrine\Tests\Models\Company\CompanyContractListener', $prePersist['class']);
860
        $this->assertEquals('postPersistHandler', $postPersist['method']);
861
        $this->assertEquals('prePersistHandler', $prePersist['method']);
862
863
        //Inherited listeners
864
        $this->assertEquals($fixClass->entityListeners, $superClass->entityListeners);
865
        $this->assertEquals($flexClass->entityListeners, $superClass->entityListeners);
866
    }
867
868
    /**
869
     * @group DDC-1955
870
     */
871
    public function testEntityListenersOverride()
872
    {
873
        $em         = $this->_getTestEntityManager();
874
        $factory    = $this->createClassMetadataFactory($em);
875
        $ultraClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexUltraContract');
876
877
        //overridden listeners
878
        $this->assertArrayHasKey(Events::postPersist, $ultraClass->entityListeners);
879
        $this->assertArrayHasKey(Events::prePersist, $ultraClass->entityListeners);
880
881
        $this->assertCount(1, $ultraClass->entityListeners[Events::postPersist]);
882
        $this->assertCount(3, $ultraClass->entityListeners[Events::prePersist]);
883
884
        $postPersist = $ultraClass->entityListeners[Events::postPersist][0];
885
        $prePersist  = $ultraClass->entityListeners[Events::prePersist][0];
886
887
        $this->assertEquals('Doctrine\Tests\Models\Company\CompanyContractListener', $postPersist['class']);
888
        $this->assertEquals('Doctrine\Tests\Models\Company\CompanyContractListener', $prePersist['class']);
889
        $this->assertEquals('postPersistHandler', $postPersist['method']);
890
        $this->assertEquals('prePersistHandler', $prePersist['method']);
891
892
        $prePersist = $ultraClass->entityListeners[Events::prePersist][1];
893
        $this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener', $prePersist['class']);
894
        $this->assertEquals('prePersistHandler1', $prePersist['method']);
895
896
        $prePersist = $ultraClass->entityListeners[Events::prePersist][2];
897
        $this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener', $prePersist['class']);
898
        $this->assertEquals('prePersistHandler2', $prePersist['method']);
899
    }
900
901
902
    /**
903
     * @group DDC-1955
904
     */
905
    public function testEntityListenersNamingConvention()
906
    {
907
        $em         = $this->_getTestEntityManager();
908
        $factory    = $this->createClassMetadataFactory($em);
909
        $metadata   = $factory->getMetadataFor('Doctrine\Tests\Models\CMS\CmsAddress');
910
911
        $this->assertArrayHasKey(Events::postPersist, $metadata->entityListeners);
912
        $this->assertArrayHasKey(Events::prePersist, $metadata->entityListeners);
913
        $this->assertArrayHasKey(Events::postUpdate, $metadata->entityListeners);
914
        $this->assertArrayHasKey(Events::preUpdate, $metadata->entityListeners);
915
        $this->assertArrayHasKey(Events::postRemove, $metadata->entityListeners);
916
        $this->assertArrayHasKey(Events::preRemove, $metadata->entityListeners);
917
        $this->assertArrayHasKey(Events::postLoad, $metadata->entityListeners);
918
        $this->assertArrayHasKey(Events::preFlush, $metadata->entityListeners);
919
920
        $this->assertCount(1, $metadata->entityListeners[Events::postPersist]);
921
        $this->assertCount(1, $metadata->entityListeners[Events::prePersist]);
922
        $this->assertCount(1, $metadata->entityListeners[Events::postUpdate]);
923
        $this->assertCount(1, $metadata->entityListeners[Events::preUpdate]);
924
        $this->assertCount(1, $metadata->entityListeners[Events::postRemove]);
925
        $this->assertCount(1, $metadata->entityListeners[Events::preRemove]);
926
        $this->assertCount(1, $metadata->entityListeners[Events::postLoad]);
927
        $this->assertCount(1, $metadata->entityListeners[Events::preFlush]);
928
929
        $postPersist = $metadata->entityListeners[Events::postPersist][0];
930
        $prePersist  = $metadata->entityListeners[Events::prePersist][0];
931
        $postUpdate  = $metadata->entityListeners[Events::postUpdate][0];
932
        $preUpdate   = $metadata->entityListeners[Events::preUpdate][0];
933
        $postRemove  = $metadata->entityListeners[Events::postRemove][0];
934
        $preRemove   = $metadata->entityListeners[Events::preRemove][0];
935
        $postLoad    = $metadata->entityListeners[Events::postLoad][0];
936
        $preFlush    = $metadata->entityListeners[Events::preFlush][0];
937
938
939
        $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $postPersist['class']);
940
        $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $prePersist['class']);
941
        $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $postUpdate['class']);
942
        $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $preUpdate['class']);
943
        $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $postRemove['class']);
944
        $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $preRemove['class']);
945
        $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $postLoad['class']);
946
        $this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddressListener', $preFlush['class']);
947
948
        $this->assertEquals(Events::postPersist, $postPersist['method']);
949
        $this->assertEquals(Events::prePersist, $prePersist['method']);
950
        $this->assertEquals(Events::postUpdate, $postUpdate['method']);
951
        $this->assertEquals(Events::preUpdate, $preUpdate['method']);
952
        $this->assertEquals(Events::postRemove, $postRemove['method']);
953
        $this->assertEquals(Events::preRemove, $preRemove['method']);
954
        $this->assertEquals(Events::postLoad, $postLoad['method']);
955
        $this->assertEquals(Events::preFlush, $preFlush['method']);
956
    }
957
958
    /**
959
     * @group DDC-2183
960
     */
961
    public function testSecondLevelCacheMapping()
962
    {
963
        $em      = $this->_getTestEntityManager();
964
        $factory = $this->createClassMetadataFactory($em);
965
        $class   = $factory->getMetadataFor(City::CLASSNAME);
966
        $this->assertArrayHasKey('usage', $class->cache);
967
        $this->assertArrayHasKey('region', $class->cache);
968
        $this->assertEquals(ClassMetadata::CACHE_USAGE_READ_ONLY, $class->cache['usage']);
969
        $this->assertEquals('doctrine_tests_models_cache_city', $class->cache['region']);
970
971
        $this->assertArrayHasKey('state', $class->associationMappings);
972
        $this->assertArrayHasKey('cache', $class->associationMappings['state']);
973
        $this->assertArrayHasKey('usage', $class->associationMappings['state']['cache']);
974
        $this->assertArrayHasKey('region', $class->associationMappings['state']['cache']);
975
        $this->assertEquals(ClassMetadata::CACHE_USAGE_READ_ONLY, $class->associationMappings['state']['cache']['usage']);
976
        $this->assertEquals('doctrine_tests_models_cache_city__state', $class->associationMappings['state']['cache']['region']);
977
978
        $this->assertArrayHasKey('attractions', $class->associationMappings);
979
        $this->assertArrayHasKey('cache', $class->associationMappings['attractions']);
980
        $this->assertArrayHasKey('usage', $class->associationMappings['attractions']['cache']);
981
        $this->assertArrayHasKey('region', $class->associationMappings['attractions']['cache']);
982
        $this->assertEquals(ClassMetadata::CACHE_USAGE_READ_ONLY, $class->associationMappings['attractions']['cache']['usage']);
983
        $this->assertEquals('doctrine_tests_models_cache_city__attractions', $class->associationMappings['attractions']['cache']['region']);
984
    }
985
986
    /**
987
     * @group DDC-2825
988
     * @group 881
989
     */
990
    public function testSchemaDefinitionViaExplicitTableSchemaAnnotationProperty()
991
    {
992
        /* @var $metadata \Doctrine\ORM\Mapping\ClassMetadata */
993
        $metadata = $this->createClassMetadataFactory()->getMetadataFor(ExplicitSchemaAndTable::CLASSNAME);
994
995
        $this->assertSame('explicit_schema', $metadata->getSchemaName());
996
        $this->assertSame('explicit_table', $metadata->getTableName());
997
    }
998
999
    /**
1000
     * @group DDC-2825
1001
     * @group 881
1002
     */
1003
    public function testSchemaDefinitionViaSchemaDefinedInTableNameInTableAnnotationProperty()
1004
    {
1005
        /* @var $metadata \Doctrine\ORM\Mapping\ClassMetadata */
1006
        $metadata = $this->createClassMetadataFactory()->getMetadataFor(SchemaAndTableInTableName::CLASSNAME);
1007
1008
        $this->assertSame('implicit_schema', $metadata->getSchemaName());
1009
        $this->assertSame('implicit_table', $metadata->getTableName());
1010
    }
1011
1012
    /**
1013
     * @group DDC-514
1014
     * @group DDC-1015
1015
     */
1016
    public function testDiscriminatorColumnDefaultLength()
1017
    {
1018
        if (strpos(get_class($this), 'PHPMappingDriver') !== false) {
1019
            $this->markTestSkipped('PHP Mapping Drivers have no defaults.');
1020
        }
1021
        $class = $this->createClassMetadata(__NAMESPACE__ . '\SingleTableEntityNoDiscriminatorColumnMapping');
1022
        $this->assertEquals(255, $class->discriminatorColumn['length']);
1023
        $class = $this->createClassMetadata(__NAMESPACE__ . '\SingleTableEntityIncompleteDiscriminatorColumnMapping');
1024
        $this->assertEquals(255, $class->discriminatorColumn['length']);
1025
    }
1026
1027
    /**
1028
     * @group DDC-514
1029
     * @group DDC-1015
1030
     */
1031
    public function testDiscriminatorColumnDefaultType()
1032
    {
1033
        if (strpos(get_class($this), 'PHPMappingDriver') !== false) {
1034
            $this->markTestSkipped('PHP Mapping Drivers have no defaults.');
1035
        }
1036
        $class = $this->createClassMetadata(__NAMESPACE__ . '\SingleTableEntityNoDiscriminatorColumnMapping');
1037
        $this->assertEquals('string', $class->discriminatorColumn['type']);
1038
        $class = $this->createClassMetadata(__NAMESPACE__ . '\SingleTableEntityIncompleteDiscriminatorColumnMapping');
1039
        $this->assertEquals('string', $class->discriminatorColumn['type']);
1040
    }
1041
1042
    /**
1043
     * @group DDC-514
1044
     * @group DDC-1015
1045
     */
1046
    public function testDiscriminatorColumnDefaultName()
1047
    {
1048
        if (strpos(get_class($this), 'PHPMappingDriver') !== false) {
1049
            $this->markTestSkipped('PHP Mapping Drivers have no defaults.');
1050
        }
1051
        $class = $this->createClassMetadata(__NAMESPACE__ . '\SingleTableEntityNoDiscriminatorColumnMapping');
1052
        $this->assertEquals('dtype', $class->discriminatorColumn['name']);
1053
        $class = $this->createClassMetadata(__NAMESPACE__ . '\SingleTableEntityIncompleteDiscriminatorColumnMapping');
1054
        $this->assertEquals('dtype', $class->discriminatorColumn['name']);
1055
    }
1056
1057
}
1058
1059
/**
1060
 * @Entity
1061
 * @HasLifecycleCallbacks
1062
 * @Table(
1063
 *  name="cms_users",
1064
 *  uniqueConstraints={@UniqueConstraint(name="search_idx", columns={"name", "user_email"}, options={"where": "name IS NOT NULL"})},
1065
 *  indexes={@Index(name="name_idx", columns={"name"}), @Index(name="0", columns={"user_email"})},
1066
 *  options={"foo": "bar", "baz": {"key": "val"}}
1067
 * )
1068
 * @NamedQueries({@NamedQuery(name="all", query="SELECT u FROM __CLASS__ u")})
1069
 */
1070
class User
1071
{
1072
    /**
1073
     * @Id
1074
     * @Column(type="integer", options={"foo": "bar", "unsigned": false})
1075
     * @generatedValue(strategy="AUTO")
1076
     * @SequenceGenerator(sequenceName="tablename_seq", initialValue=1, allocationSize=100)
1077
     **/
1078
    public $id;
1079
1080
    /**
1081
     * @Column(length=50, nullable=true, unique=true, options={"foo": "bar", "baz": {"key": "val"}, "fixed": false})
1082
     */
1083
    public $name;
1084
1085
    /**
1086
     * @Column(name="user_email", columnDefinition="CHAR(32) NOT NULL")
1087
     */
1088
    public $email;
1089
1090
    /**
1091
     * @OneToOne(targetEntity="Address", cascade={"remove"}, inversedBy="user")
1092
     * @JoinColumn(onDelete="CASCADE")
1093
     */
1094
    public $address;
1095
1096
    /**
1097
     * @OneToMany(targetEntity="Phonenumber", mappedBy="user", cascade={"persist"}, orphanRemoval=true)
1098
     * @OrderBy({"number"="ASC"})
1099
     */
1100
    public $phonenumbers;
1101
1102
    /**
1103
     * @ManyToMany(targetEntity="Group", cascade={"all"})
1104
     * @JoinTable(name="cms_user_groups",
1105
     *    joinColumns={@JoinColumn(name="user_id", referencedColumnName="id", nullable=false, unique=false)},
1106
     *    inverseJoinColumns={@JoinColumn(name="group_id", referencedColumnName="id", columnDefinition="INT NULL")}
1107
     * )
1108
     */
1109
    public $groups;
1110
1111
    /**
1112
     * @Column(type="integer")
1113
     * @Version
1114
     */
1115
    public $version;
1116
1117
1118
    /**
1119
     * @PrePersist
1120
     */
1121
    public function doStuffOnPrePersist()
1122
    {
1123
    }
1124
1125
    /**
1126
     * @PrePersist
1127
     */
1128
    public function doOtherStuffOnPrePersistToo() {
1129
    }
1130
1131
    /**
1132
     * @PostPersist
1133
     */
1134
    public function doStuffOnPostPersist()
1135
    {
1136
1137
    }
1138
1139
    public static function loadMetadata(ClassMetadataInfo $metadata)
1140
    {
1141
        $metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_NONE);
1142
        $metadata->setPrimaryTable(array(
1143
           'name' => 'cms_users',
1144
           'options' => array('foo' => 'bar', 'baz' => array('key' => 'val')),
1145
          ));
1146
        $metadata->setChangeTrackingPolicy(ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT);
1147
        $metadata->addLifecycleCallback('doStuffOnPrePersist', 'prePersist');
1148
        $metadata->addLifecycleCallback('doOtherStuffOnPrePersistToo', 'prePersist');
1149
        $metadata->addLifecycleCallback('doStuffOnPostPersist', 'postPersist');
1150
        $metadata->mapField(array(
1151
           'id' => true,
1152
           'fieldName' => 'id',
1153
           'type' => 'integer',
1154
           'columnName' => 'id',
1155
           'options' => array('foo' => 'bar', 'unsigned' => false),
1156
          ));
1157
        $metadata->mapField(array(
1158
           'fieldName' => 'name',
1159
           'type' => 'string',
1160
           'length' => 50,
1161
           'unique' => true,
1162
           'nullable' => true,
1163
           'columnName' => 'name',
1164
           'options' => array('foo' => 'bar', 'baz' => array('key' => 'val'), 'fixed' => false),
1165
          ));
1166
        $metadata->mapField(array(
1167
           'fieldName' => 'email',
1168
           'type' => 'string',
1169
           'columnName' => 'user_email',
1170
           'columnDefinition' => 'CHAR(32) NOT NULL',
1171
          ));
1172
        $mapping = array('fieldName' => 'version', 'type' => 'integer');
1173
        $metadata->setVersionMapping($mapping);
1174
        $metadata->mapField($mapping);
1175
        $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
1176
        $metadata->mapOneToOne(array(
1177
           'fieldName' => 'address',
1178
           'targetEntity' => 'Doctrine\\Tests\\ORM\\Mapping\\Address',
1179
           'cascade' =>
1180
           array(
1181
           0 => 'remove',
1182
           ),
1183
           'mappedBy' => NULL,
1184
           'inversedBy' => 'user',
1185
           'joinColumns' =>
1186
           array(
1187
           0 =>
1188
           array(
1189
            'name' => 'address_id',
1190
            'referencedColumnName' => 'id',
1191
            'onDelete' => 'CASCADE',
1192
           ),
1193
           ),
1194
           'orphanRemoval' => false,
1195
          ));
1196
        $metadata->mapOneToMany(array(
1197
           'fieldName' => 'phonenumbers',
1198
           'targetEntity' => 'Doctrine\\Tests\\ORM\\Mapping\\Phonenumber',
1199
           'cascade' =>
1200
           array(
1201
           1 => 'persist',
1202
           ),
1203
           'mappedBy' => 'user',
1204
           'orphanRemoval' => true,
1205
           'orderBy' =>
1206
           array(
1207
           'number' => 'ASC',
1208
           ),
1209
          ));
1210
        $metadata->mapManyToMany(array(
1211
           'fieldName' => 'groups',
1212
           'targetEntity' => 'Doctrine\\Tests\\ORM\\Mapping\\Group',
1213
           'cascade' =>
1214
           array(
1215
           0 => 'remove',
1216
           1 => 'persist',
1217
           2 => 'refresh',
1218
           3 => 'merge',
1219
           4 => 'detach',
1220
           ),
1221
           'mappedBy' => NULL,
1222
           'joinTable' =>
1223
           array(
1224
           'name' => 'cms_users_groups',
1225
           'joinColumns' =>
1226
           array(
1227
            0 =>
1228
            array(
1229
            'name' => 'user_id',
1230
            'referencedColumnName' => 'id',
1231
            'unique' => false,
1232
            'nullable' => false,
1233
            ),
1234
           ),
1235
           'inverseJoinColumns' =>
1236
           array(
1237
            0 =>
1238
            array(
1239
            'name' => 'group_id',
1240
            'referencedColumnName' => 'id',
1241
            'columnDefinition' => 'INT NULL',
1242
            ),
1243
           ),
1244
           ),
1245
           'orderBy' => NULL,
1246
          ));
1247
        $metadata->table['uniqueConstraints'] = array(
1248
            'search_idx' => array('columns' => array('name', 'user_email'), 'options'=> array('where' => 'name IS NOT NULL')),
1249
        );
1250
        $metadata->table['indexes'] = array(
1251
            'name_idx' => array('columns' => array('name')), 0 => array('columns' => array('user_email'))
1252
        );
1253
        $metadata->setSequenceGeneratorDefinition(array(
1254
                'sequenceName' => 'tablename_seq',
1255
                'allocationSize' => 100,
1256
                'initialValue' => 1,
1257
            ));
1258
        $metadata->addNamedQuery(array(
1259
                'name' => 'all',
1260
                'query' => 'SELECT u FROM __CLASS__ u'
1261
            ));
1262
    }
1263
}
1264
1265
/**
1266
 * @Entity
1267
 * @InheritanceType("SINGLE_TABLE")
1268
 * @DiscriminatorMap({"cat" = "Cat", "dog" = "Dog"})
1269
 * @DiscriminatorColumn(name="discr", length=32, type="string")
1270
 */
1271
abstract class Animal
1272
{
1273
    /**
1274
     * @Id @Column(type="string") @GeneratedValue(strategy="CUSTOM")
1275
     * @CustomIdGenerator(class="stdClass")
1276
     */
1277
    public $id;
1278
1279
    public static function loadMetadata(ClassMetadataInfo $metadata)
1280
    {
1281
        $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_CUSTOM);
1282
        $metadata->setCustomGeneratorDefinition(array("class" => "stdClass"));
1283
    }
1284
}
1285
1286
/** @Entity */
1287
class Cat extends Animal
1288
{
1289
    public static function loadMetadata(ClassMetadataInfo $metadata)
1290
    {
1291
1292
    }
1293
}
1294
1295
/** @Entity */
1296
class Dog extends Animal
1297
{
1298
    public static function loadMetadata(ClassMetadataInfo $metadata)
1299
    {
1300
1301
    }
1302
}
1303
1304
1305
/**
1306
 * @Entity
1307
 */
1308
class DDC1170Entity
1309
{
1310
1311
    /**
1312
     * @param string $value
1313
     */
1314
    function __construct($value = null)
1315
    {
1316
        $this->value = $value;
1317
    }
1318
1319
    /**
1320
     * @Id
1321
     * @GeneratedValue(strategy="NONE")
1322
     * @Column(type="integer", columnDefinition = "INT unsigned NOT NULL")
1323
     **/
1324
    private $id;
1325
1326
    /**
1327
     * @Column(columnDefinition = "VARCHAR(255) NOT NULL")
1328
     */
1329
    private $value;
1330
1331
    /**
1332
     * @return int
1333
     */
1334
    public function getId()
1335
    {
1336
        return $this->id;
1337
    }
1338
1339
    /**
1340
     * @return string
1341
     */
1342
    public function getValue()
1343
    {
1344
        return $this->value;
1345
    }
1346
1347
    public static function loadMetadata(ClassMetadataInfo $metadata)
1348
    {
1349
        $metadata->mapField(array(
1350
           'id'                 => true,
1351
           'fieldName'          => 'id',
1352
           'columnDefinition'   => 'INT unsigned NOT NULL',
1353
        ));
1354
1355
        $metadata->mapField(array(
1356
            'fieldName'         => 'value',
1357
            'columnDefinition'  => 'VARCHAR(255) NOT NULL'
1358
        ));
1359
1360
        $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_NONE);
1361
    }
1362
1363
}
1364
1365
/**
1366
 * @Entity
1367
 * @InheritanceType("SINGLE_TABLE")
1368
 * @DiscriminatorMap({"ONE" = "DDC807SubClasse1", "TWO" = "DDC807SubClasse2"})
1369
 * @DiscriminatorColumn(name = "dtype", columnDefinition="ENUM('ONE','TWO')")
1370
 */
1371
class DDC807Entity
1372
{
1373
    /**
1374
     * @Id
1375
     * @Column(type="integer")
1376
     * @GeneratedValue(strategy="NONE")
1377
     **/
1378
   public $id;
1379
1380
   public static function loadMetadata(ClassMetadataInfo $metadata)
1381
    {
1382
         $metadata->mapField(array(
1383
           'id'                 => true,
1384
           'fieldName'          => 'id',
1385
        ));
1386
1387
        $metadata->setDiscriminatorColumn(array(
1388
            'name'              => "dtype",
1389
            'type'              => "string",
1390
            'columnDefinition'  => "ENUM('ONE','TWO')"
1391
        ));
1392
1393
        $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_NONE);
1394
    }
1395
}
1396
1397
class DDC807SubClasse1 {}
1398
class DDC807SubClasse2 {}
1399
1400
class Address {}
1401
class Phonenumber {}
1402
class Group {}
1403
1404
/**
1405
 * @Entity
1406
 * @Table(indexes={@Index(columns={"content"}, flags={"fulltext"}, options={"where": "content IS NOT NULL"})})
1407
 */
1408
class Comment
1409
{
1410
    /**
1411
     * @Column(type="text")
1412
     */
1413
    private $content;
1414
1415
    public static function loadMetadata(ClassMetadataInfo $metadata)
1416
    {
1417
        $metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_NONE);
1418
        $metadata->setPrimaryTable(array(
1419
            'indexes' => array(
1420
                array('columns' => array('content'), 'flags' => array('fulltext'), 'options' => array('where' => 'content IS NOT NULL'))
1421
            )
1422
        ));
1423
1424
        $metadata->mapField(array(
1425
            'fieldName' => 'content',
1426
            'type' => 'text',
1427
            'scale' => 0,
1428
            'length' => NULL,
1429
            'unique' => false,
1430
            'nullable' => false,
1431
            'precision' => 0,
1432
            'columnName' => 'content',
1433
        ));
1434
    }
1435
}
1436
1437
/**
1438
 * @Entity
1439
 * @InheritanceType("SINGLE_TABLE")
1440
 * @DiscriminatorMap({
1441
 *     "ONE" = "SingleTableEntityNoDiscriminatorColumnMappingSub1",
1442
 *     "TWO" = "SingleTableEntityNoDiscriminatorColumnMappingSub2"
1443
 * })
1444
 */
1445
class SingleTableEntityNoDiscriminatorColumnMapping
1446
{
1447
    /**
1448
     * @Id
1449
     * @Column(type="integer")
1450
     * @GeneratedValue(strategy="NONE")
1451
     */
1452
    public $id;
1453
1454
    public static function loadMetadata(ClassMetadataInfo $metadata)
1455
    {
1456
        $metadata->mapField(array(
1457
            'id' => true,
1458
            'fieldName' => 'id',
1459
        ));
1460
1461
        $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_NONE);
1462
    }
1463
}
1464
1465
class SingleTableEntityNoDiscriminatorColumnMappingSub1 extends SingleTableEntityNoDiscriminatorColumnMapping {}
1466
class SingleTableEntityNoDiscriminatorColumnMappingSub2 extends SingleTableEntityNoDiscriminatorColumnMapping {}
1467
1468
/**
1469
 * @Entity
1470
 * @InheritanceType("SINGLE_TABLE")
1471
 * @DiscriminatorMap({
1472
 *     "ONE" = "SingleTableEntityIncompleteDiscriminatorColumnMappingSub1",
1473
 *     "TWO" = "SingleTableEntityIncompleteDiscriminatorColumnMappingSub2"
1474
 * })
1475
 * @DiscriminatorColumn(name="dtype")
1476
 */
1477
class SingleTableEntityIncompleteDiscriminatorColumnMapping
1478
{
1479
    /**
1480
     * @Id
1481
     * @Column(type="integer")
1482
     * @GeneratedValue(strategy="NONE")
1483
     */
1484
    public $id;
1485
1486
    public static function loadMetadata(ClassMetadataInfo $metadata)
1487
    {
1488
        $metadata->mapField(array(
1489
            'id' => true,
1490
            'fieldName' => 'id',
1491
        ));
1492
1493
        $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_NONE);
1494
    }
1495
}
1496
1497
class SingleTableEntityIncompleteDiscriminatorColumnMappingSub1
1498
    extends SingleTableEntityIncompleteDiscriminatorColumnMapping {}
1499
class SingleTableEntityIncompleteDiscriminatorColumnMappingSub2
1500
    extends SingleTableEntityIncompleteDiscriminatorColumnMapping {}
1501