Passed
Pull Request — master (#6767)
by Tyler
14:13
created

SchemaToolTest::testDerivedCompositeKey()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 40
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 40
rs 8.5806
c 1
b 0
f 0
cc 4
eloc 30
nc 4
nop 0
1
<?php
2
3
namespace Doctrine\Tests\ORM\Tools;
4
5
use Doctrine\ORM\Mapping\ClassMetadata;
6
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
7
use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs;
8
use Doctrine\ORM\Tools\SchemaTool;
9
use Doctrine\ORM\Tools\ToolEvents;
10
use Doctrine\Tests\Models\CMS\CmsAddress;
11
use Doctrine\Tests\Models\CMS\CmsArticle;
12
use Doctrine\Tests\Models\CMS\CmsComment;
13
use Doctrine\Tests\Models\CMS\CmsEmployee;
14
use Doctrine\Tests\Models\CMS\CmsGroup;
15
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
16
use Doctrine\Tests\Models\CMS\CmsUser;
17
use Doctrine\Tests\Models\CompositeKeyInheritance\JoinedDerivedChildClass;
18
use Doctrine\Tests\Models\CompositeKeyInheritance\JoinedDerivedIdentityClass;
19
use Doctrine\Tests\Models\CompositeKeyInheritance\JoinedDerivedRootClass;
20
use Doctrine\Tests\Models\Forum\ForumAvatar;
21
use Doctrine\Tests\Models\Forum\ForumUser;
22
use Doctrine\Tests\Models\NullDefault\NullDefaultColumn;
23
use Doctrine\Tests\OrmTestCase;
24
25
class SchemaToolTest extends OrmTestCase
26
{
27
    public function testAddUniqueIndexForUniqueFieldAnnotation()
28
    {
29
        $em = $this->_getTestEntityManager();
30
        $schemaTool = new SchemaTool($em);
31
32
        $classes = [
33
            $em->getClassMetadata(CmsAddress::class),
34
            $em->getClassMetadata(CmsArticle::class),
35
            $em->getClassMetadata(CmsComment::class),
36
            $em->getClassMetadata(CmsEmployee::class),
37
            $em->getClassMetadata(CmsGroup::class),
38
            $em->getClassMetadata(CmsPhonenumber::class),
39
            $em->getClassMetadata(CmsUser::class),
40
        ];
41
42
        $schema = $schemaTool->getSchemaFromMetadata($classes);
43
44
        $this->assertTrue($schema->hasTable('cms_users'), "Table cms_users should exist.");
45
        $this->assertTrue($schema->getTable('cms_users')->columnsAreIndexed(['username']), "username column should be indexed.");
46
    }
47
48
    public function testAnnotationOptionsAttribute()
49
    {
50
        $em = $this->_getTestEntityManager();
51
        $schemaTool = new SchemaTool($em);
52
53
        $classes = [
54
            $em->getClassMetadata(TestEntityWithAnnotationOptionsAttribute::class),
55
        ];
56
57
        $schema = $schemaTool->getSchemaFromMetadata($classes);
58
59
        $expected = ['foo' => 'bar', 'baz' => ['key' => 'val']];
60
61
        $this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getOptions(), "options annotation are passed to the tables options");
62
        $this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getColumn('test')->getCustomSchemaOptions(), "options annotation are passed to the columns customSchemaOptions");
63
    }
64
65
    /**
66
     * @group DDC-200
67
     */
68
    public function testPassColumnDefinitionToJoinColumn()
69
    {
70
        $customColumnDef = "MEDIUMINT(6) UNSIGNED NOT NULL";
71
72
        $em = $this->_getTestEntityManager();
73
        $schemaTool = new SchemaTool($em);
74
75
        $avatar = $em->getClassMetadata(ForumAvatar::class);
76
        $avatar->fieldMappings['id']['columnDefinition'] = $customColumnDef;
77
        $user = $em->getClassMetadata(ForumUser::class);
78
79
        $classes = [$avatar, $user];
80
81
        $schema = $schemaTool->getSchemaFromMetadata($classes);
82
83
        $this->assertTrue($schema->hasTable('forum_users'));
84
        $table = $schema->getTable("forum_users");
85
        $this->assertTrue($table->hasColumn('avatar_id'));
86
        $this->assertEquals($customColumnDef, $table->getColumn('avatar_id')->getColumnDefinition());
87
    }
88
89
    /**
90
     * @group DDC-283
91
     */
92
    public function testPostGenerateEvents()
93
    {
94
        $listener = new GenerateSchemaEventListener();
95
96
        $em = $this->_getTestEntityManager();
97
        $em->getEventManager()->addEventListener(
98
            [ToolEvents::postGenerateSchemaTable, ToolEvents::postGenerateSchema], $listener
99
        );
100
        $schemaTool = new SchemaTool($em);
101
102
        $classes = [
103
            $em->getClassMetadata(CmsAddress::class),
104
            $em->getClassMetadata(CmsArticle::class),
105
            $em->getClassMetadata(CmsComment::class),
106
            $em->getClassMetadata(CmsEmployee::class),
107
            $em->getClassMetadata(CmsGroup::class),
108
            $em->getClassMetadata(CmsPhonenumber::class),
109
            $em->getClassMetadata(CmsUser::class),
110
        ];
111
112
        $schema = $schemaTool->getSchemaFromMetadata($classes);
0 ignored issues
show
Unused Code introduced by
$schema is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
113
114
        $this->assertEquals(count($classes), $listener->tableCalls);
115
        $this->assertTrue($listener->schemaCalled);
116
    }
117
118
    public function testNullDefaultNotAddedToCustomSchemaOptions()
119
    {
120
        $em = $this->_getTestEntityManager();
121
        $schemaTool = new SchemaTool($em);
122
123
        $customSchemaOptions = $schemaTool->getSchemaFromMetadata([$em->getClassMetadata(NullDefaultColumn::class)])
124
            ->getTable('NullDefaultColumn')
125
            ->getColumn('nullDefault')
126
            ->getCustomSchemaOptions();
127
128
        $this->assertSame([], $customSchemaOptions);
129
    }
130
131
    /**
132
     * @group DDC-3671
133
     */
134 View Code Duplication
    public function testSchemaHasProperIndexesFromUniqueConstraintAnnotation()
135
    {
136
        $em         = $this->_getTestEntityManager();
137
        $schemaTool = new SchemaTool($em);
138
        $classes    = [
139
            $em->getClassMetadata(UniqueConstraintAnnotationModel::class),
140
        ];
141
142
        $schema = $schemaTool->getSchemaFromMetadata($classes);
143
144
        $this->assertTrue($schema->hasTable('unique_constraint_annotation_table'));
145
        $table = $schema->getTable('unique_constraint_annotation_table');
146
147
        $this->assertEquals(2, count($table->getIndexes()));
148
        $this->assertTrue($table->hasIndex('primary'));
149
        $this->assertTrue($table->hasIndex('uniq_hash'));
150
    }
151
152 View Code Duplication
    public function testRemoveUniqueIndexOverruledByPrimaryKey()
153
    {
154
        $em         = $this->_getTestEntityManager();
155
        $schemaTool = new SchemaTool($em);
156
        $classes    = [
157
            $em->getClassMetadata(FirstEntity::class),
158
            $em->getClassMetadata(SecondEntity::class)
159
        ];
160
161
        $schema = $schemaTool->getSchemaFromMetadata($classes);
162
163
        $this->assertTrue($schema->hasTable('first_entity'), "Table first_entity should exist.");
164
165
        $indexes = $schema->getTable('first_entity')->getIndexes();
166
167
        $this->assertCount(1, $indexes, "there should be only one index");
168
        $this->assertTrue(current($indexes)->isPrimary(), "index should be primary");
169
    }
170
171
    public function testSetDiscriminatorColumnWithoutLength() : void
172
    {
173
        $em         = $this->_getTestEntityManager();
174
        $schemaTool = new SchemaTool($em);
175
        $metadata   = $em->getClassMetadata(FirstEntity::class);
176
177
        $metadata->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE);
178
        $metadata->setDiscriminatorColumn(['name' => 'discriminator', 'type' => 'string']);
179
180
        $schema = $schemaTool->getSchemaFromMetadata([$metadata]);
181
182
        $this->assertTrue($schema->hasTable('first_entity'));
183
        $table = $schema->getTable('first_entity');
184
185
        $this->assertTrue($table->hasColumn('discriminator'));
186
        $column = $table->getColumn('discriminator');
187
188
        $this->assertEquals(255, $column->getLength());
189
    }
190
191
    public function testDerivedCompositeKey() : void
192
    {
193
        $em = $this->_getTestEntityManager();
194
        $schemaTool = new SchemaTool($em);
195
        $classes = [
196
            $em->getClassMetadata(JoinedDerivedIdentityClass::class),
197
            $em->getClassMetadata(JoinedDerivedRootClass::class),
198
            $em->getClassMetadata(JoinedDerivedChildClass::class),
199
        ];
200
        $schema = $schemaTool->getSchemaFromMetadata($classes);
201
202
        $this->assertTrue($schema->hasTable('joined_derived_identity'));
203
        $this->assertTrue($schema->hasTable('joined_derived_root'));
204
        $this->assertTrue($schema->hasTable('joined_derived_child'));
205
206
        $rootTable = $schema->getTable('joined_derived_root');
207
        $this->assertNotNull($rootTable->getPrimaryKey());
208
        $this->assertEquals(['keyPart1_id', 'keyPart2'], $rootTable->getPrimaryKey()->getColumns());
209
210
        $childTable = $schema->getTable('joined_derived_child');
211
        $this->assertNotNull($childTable->getPrimaryKey());
212
        $this->assertEquals(['keyPart1_id', 'keyPart2'], $childTable->getPrimaryKey()->getColumns());
213
        foreach ($childTable->getForeignKeys() as $foreignKey) {
214
            switch ($foreignKey->getForeignTableName()) {
215
                case 'joined_derived_identity':
216
                    $this->assertEquals(['keyPart1_id'], $foreignKey->getLocalColumns());
217
                    $this->assertEquals(['id'], $foreignKey->getForeignColumns());
218
                    break;
219
220
                case 'joined_derived_root':
221
                    $this->assertEquals(['keyPart1_id', 'keyPart2'], $foreignKey->getLocalColumns());
222
                    $this->assertEquals(['keyPart1_id', 'keyPart2'], $foreignKey->getForeignColumns());
223
                    break;
224
225
                default:
226
                    $this->fail();
227
                    break;
228
            }
229
        }
230
    }
231
}
232
233
/**
234
 * @Entity
235
 * @Table(options={"foo": "bar", "baz": {"key": "val"}})
236
 */
237
class TestEntityWithAnnotationOptionsAttribute
238
{
239
    /** @Id @Column */
240
    private $id;
241
242
    /**
243
     * @Column(type="string", options={"foo": "bar", "baz": {"key": "val"}})
244
     */
245
    private $test;
246
}
247
248
class GenerateSchemaEventListener
249
{
250
    public $tableCalls = 0;
251
    public $schemaCalled = false;
252
253
    public function postGenerateSchemaTable(GenerateSchemaTableEventArgs $eventArgs)
0 ignored issues
show
Unused Code introduced by
The parameter $eventArgs is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
254
    {
255
        $this->tableCalls++;
256
    }
257
258
    public function postGenerateSchema(GenerateSchemaEventArgs $eventArgs)
0 ignored issues
show
Unused Code introduced by
The parameter $eventArgs is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
259
    {
260
        $this->schemaCalled = true;
261
    }
262
}
263
264
/**
265
 * @Entity
266
 * @Table(name="unique_constraint_annotation_table", uniqueConstraints={
267
 *   @UniqueConstraint(name="uniq_hash", columns={"hash"})
268
 * })
269
 */
270
class UniqueConstraintAnnotationModel
271
{
272
    /** @Id @Column */
273
    private $id;
274
275
    /**
276
     * @Column(name="hash", type="string", length=8, nullable=false, unique=true)
277
     */
278
    private $hash;
279
}
280
281
/**
282
 * @Entity
283
 * @Table(name="first_entity")
284
 */
285
class FirstEntity
286
{
287
    /**
288
     * @Id
289
     * @Column(name="id")
290
     */
291
    public $id;
292
293
    /**
294
     * @OneToOne(targetEntity="SecondEntity")
295
     * @JoinColumn(name="id", referencedColumnName="fist_entity_id")
296
     */
297
    public $secondEntity;
298
299
    /**
300
     * @Column(name="name")
301
     */
302
    public $name;
303
}
304
305
/**
306
 * @Entity
307
 * @Table(name="second_entity")
308
 */
309
class SecondEntity
310
{
311
    /**
312
     * @Id
313
     * @Column(name="fist_entity_id")
314
     */
315
    public $fist_entity_id;
316
317
    /**
318
     * @Column(name="name")
319
     */
320
    public $name;
321
}
322