Failed Conditions
Pull Request — 2.6 (#7875)
by
unknown
07:53
created

PostgreSqlSchemaToolTest::testGetCreateSchemaSql()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 37
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 31
nc 1
nop 0
dl 0
loc 37
rs 9.424
c 0
b 0
f 0
1
<?php
2
3
namespace Doctrine\Tests\ORM\Functional\SchemaTool;
4
5
use Doctrine\ORM\Tools\SchemaTool;
6
use Doctrine\Tests\Models;
7
use Doctrine\Tests\OrmFunctionalTestCase;
8
use Doctrine\DBAL\Configuration;
9
10
class PostgreSqlSchemaToolTest extends OrmFunctionalTestCase
11
{
12
    protected function setUp()
13
    {
14
        parent::setUp();
15
16
        if ($this->_em->getConnection()->getDatabasePlatform()->getName() !== 'postgresql') {
17
            $this->markTestSkipped('The ' . __CLASS__ .' requires the use of postgresql.');
18
        }
19
    }
20
21
    public function testPostgresMetadataSequenceIncrementedBy10()
22
    {
23
        $address = $this->_em->getClassMetadata(Models\CMS\CmsAddress::class);
24
25
        $this->assertEquals(1, $address->sequenceGeneratorDefinition['allocationSize']);
26
    }
27
28
    public function testGetCreateSchemaSql()
29
    {
30
        $classes = [
31
            $this->_em->getClassMetadata(Models\CMS\CmsAddress::class),
32
            $this->_em->getClassMetadata(Models\CMS\CmsUser::class),
33
            $this->_em->getClassMetadata(Models\CMS\CmsPhonenumber::class),
34
        ];
35
36
        $tool = new SchemaTool($this->_em);
37
        $sql = $tool->getCreateSchemaSql($classes);
38
        $sqlCount = count($sql);
39
40
        $this->assertEquals("CREATE TABLE cms_addresses (id INT NOT NULL, user_id INT DEFAULT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, PRIMARY KEY(id))", array_shift($sql));
41
        $this->assertEquals("CREATE UNIQUE INDEX UNIQ_ACAC157BA76ED395 ON cms_addresses (user_id)", array_shift($sql));
42
        $this->assertEquals("CREATE TABLE cms_users (id INT NOT NULL, email_id INT DEFAULT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))", array_shift($sql));
43
        $this->assertEquals("CREATE UNIQUE INDEX UNIQ_3AF03EC5F85E0677 ON cms_users (username)", array_shift($sql));
44
        $this->assertEquals("CREATE UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 ON cms_users (email_id)", array_shift($sql));
45
        $this->assertEquals("CREATE TABLE cms_users_groups (user_id INT NOT NULL, group_id INT NOT NULL, PRIMARY KEY(user_id, group_id))", array_shift($sql));
46
        $this->assertEquals("CREATE INDEX IDX_7EA9409AA76ED395 ON cms_users_groups (user_id)", array_shift($sql));
47
        $this->assertEquals("CREATE INDEX IDX_7EA9409AFE54D947 ON cms_users_groups (group_id)", array_shift($sql));
48
        $this->assertEquals("CREATE TABLE cms_users_tags (user_id INT NOT NULL, tag_id INT NOT NULL, PRIMARY KEY(user_id, tag_id))", array_shift($sql));
49
        $this->assertEquals("CREATE INDEX IDX_93F5A1ADA76ED395 ON cms_users_tags (user_id)", array_shift($sql));
50
        $this->assertEquals("CREATE INDEX IDX_93F5A1ADBAD26311 ON cms_users_tags (tag_id)", array_shift($sql));
51
        $this->assertEquals("CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, PRIMARY KEY(phonenumber))", array_shift($sql));
52
        $this->assertEquals("CREATE INDEX IDX_F21F790FA76ED395 ON cms_phonenumbers (user_id)", array_shift($sql));
53
        $this->assertEquals("CREATE SEQUENCE cms_addresses_id_seq INCREMENT BY 1 MINVALUE 1 START 1", array_shift($sql));
54
        $this->assertEquals("CREATE SEQUENCE cms_users_id_seq INCREMENT BY 1 MINVALUE 1 START 1", array_shift($sql));
55
        $this->assertEquals("ALTER TABLE cms_addresses ADD CONSTRAINT FK_ACAC157BA76ED395 FOREIGN KEY (user_id) REFERENCES cms_users (id) NOT DEFERRABLE INITIALLY IMMEDIATE", array_shift($sql));
56
        $this->assertEquals("ALTER TABLE cms_users ADD CONSTRAINT FK_3AF03EC5A832C1C9 FOREIGN KEY (email_id) REFERENCES cms_emails (id) NOT DEFERRABLE INITIALLY IMMEDIATE", array_shift($sql));
57
        $this->assertEquals("ALTER TABLE cms_users_groups ADD CONSTRAINT FK_7EA9409AA76ED395 FOREIGN KEY (user_id) REFERENCES cms_users (id) NOT DEFERRABLE INITIALLY IMMEDIATE", array_shift($sql));
58
        $this->assertEquals("ALTER TABLE cms_users_groups ADD CONSTRAINT FK_7EA9409AFE54D947 FOREIGN KEY (group_id) REFERENCES cms_groups (id) NOT DEFERRABLE INITIALLY IMMEDIATE", array_shift($sql));
59
        $this->assertEquals("ALTER TABLE cms_users_tags ADD CONSTRAINT FK_93F5A1ADA76ED395 FOREIGN KEY (user_id) REFERENCES cms_users (id) NOT DEFERRABLE INITIALLY IMMEDIATE", array_shift($sql));
60
        $this->assertEquals("ALTER TABLE cms_users_tags ADD CONSTRAINT FK_93F5A1ADBAD26311 FOREIGN KEY (tag_id) REFERENCES cms_tags (id) NOT DEFERRABLE INITIALLY IMMEDIATE", array_shift($sql));
61
        $this->assertEquals("ALTER TABLE cms_phonenumbers ADD CONSTRAINT FK_F21F790FA76ED395 FOREIGN KEY (user_id) REFERENCES cms_users (id) NOT DEFERRABLE INITIALLY IMMEDIATE", array_shift($sql));
62
63
        $this->assertEquals([], $sql, "SQL Array should be empty now.");
64
        $this->assertEquals(22, $sqlCount, "Total of 22 queries should be executed");
65
    }
66
67
    public function testGetCreateSchemaSql2()
68
    {
69
        $classes = [
70
            $this->_em->getClassMetadata(Models\Generic\DecimalModel::class)
71
        ];
72
73
        $tool = new SchemaTool($this->_em);
74
        $sql = $tool->getCreateSchemaSql($classes);
75
76
        $this->assertEquals(2, count($sql));
77
78
        $this->assertEquals('CREATE TABLE decimal_model (id INT NOT NULL, "decimal" NUMERIC(5, 2) NOT NULL, "high_scale" NUMERIC(14, 4) NOT NULL, PRIMARY KEY(id))', $sql[0]);
79
        $this->assertEquals("CREATE SEQUENCE decimal_model_id_seq INCREMENT BY 1 MINVALUE 1 START 1", $sql[1]);
80
    }
81
82
    public function testGetCreateSchemaSql3()
83
    {
84
        $classes = [
85
            $this->_em->getClassMetadata(Models\Generic\BooleanModel::class)
86
        ];
87
88
        $tool = new SchemaTool($this->_em);
89
        $sql = $tool->getCreateSchemaSql($classes);
90
91
        $this->assertEquals(2, count($sql));
92
        $this->assertEquals("CREATE TABLE boolean_model (id INT NOT NULL, booleanField BOOLEAN NOT NULL, PRIMARY KEY(id))", $sql[0]);
93
        $this->assertEquals("CREATE SEQUENCE boolean_model_id_seq INCREMENT BY 1 MINVALUE 1 START 1", $sql[1]);
94
    }
95
96
    public function testGetDropSchemaSql()
97
    {
98
        $classes = [
99
            $this->_em->getClassMetadata(Models\CMS\CmsAddress::class),
100
            $this->_em->getClassMetadata(Models\CMS\CmsUser::class),
101
            $this->_em->getClassMetadata(Models\CMS\CmsPhonenumber::class),
102
        ];
103
104
        $tool = new SchemaTool($this->_em);
105
        $sql = $tool->getDropSchemaSQL($classes);
106
107
        $this->assertEquals(17, count($sql));
108
109
        $dropSequenceSQLs = 0;
110
111
        foreach ($sql AS $stmt) {
112
            if (strpos($stmt, "DROP SEQUENCE") === 0) {
113
                $dropSequenceSQLs++;
114
            }
115
        }
116
        $this->assertEquals(4, $dropSequenceSQLs, "Expect 4 sequences to be dropped.");
117
    }
118
119
    /**
120
     * @group DDC-1657
121
     */
122
    public function testUpdateSchemaWithPostgreSQLSchema()
123
    {
124
        $classes = [
125
            $this->_em->getClassMetadata(DDC1657Screen::class),
126
            $this->_em->getClassMetadata(DDC1657Avatar::class),
127
        ];
128
129
        $tool = new SchemaTool($this->_em);
130
        $tool->createSchema($classes);
131
132
        $sql = $tool->getUpdateSchemaSql($classes);
133
        $sql = array_filter($sql, function($sql) { return (strpos($sql, "DROP SEQUENCE stonewood.") === 0); });
134
135
        $this->assertCount(0, $sql, implode("\n", $sql));
136
    }
137
138
    public function provideUpdateSchemaSqlWithSchemaAssetFilter(): array
139
    {
140
        return [
141
            ['/^(?!pg_entity_to_r)/', null],
142
            [null, function ($assetName): bool {
143
                return $assetName != 'pg_entity_to_remove';
144
            }]
145
        ];
146
    }
147
148
    /**
149
     * @dataProvider provideUpdateSchemaSqlWithSchemaAssetFilter
150
     */
151
    public function testUpdateSchemaSqlWithSchemaAssetFilter(?string $filterRegex, ?callable $filterCallback): void
152
    {
153
        if ($filterRegex && !method_exists(Configuration::class, 'setFilterSchemaAssetsExpression')) {
154
            $this->markTestSkipped(sprintf("Test require %s::setFilterSchemaAssetsExpression method", Configuration::class));
155
        }
156
157
        if ($filterCallback && !method_exists(Configuration::class, 'setSchemaAssetsFilter')) {
158
            $this->markTestSkipped(sprintf("Test require %s::setSchemaAssetsFilter method", Configuration::class));
159
        }
160
161
        $classes = [
162
            $this->_em->getClassMetadata(PgMyEntityToRemove::class)
163
        ];
164
165
        $tool = new SchemaTool($this->_em);
166
        $tool->createSchema($classes);
167
168
        $config = $this->_em->getConnection()->getConfiguration();
169
        if ($filterRegex) {
170
            $config->setFilterSchemaAssetsExpression($filterRegex);
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Configurat...chemaAssetsExpression() has been deprecated: Use Configuration::setSchemaAssetsFilter() instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

170
            /** @scrutinizer ignore-deprecated */ $config->setFilterSchemaAssetsExpression($filterRegex);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
171
        } else {
172
            $config->setSchemaAssetsFilter($filterCallback);
173
        }
174
175
        $sqls = $tool->getUpdateSchemaSql($classes);
176
        $sqls = array_filter($sqls, function($sql) { return (strpos($sql, "pg_entity_to_remove") !== false); });
177
        $this->assertCount(0, $sqls);
178
179
        if ($filterRegex) {
180
            $this->assertEquals($filterRegex, $config->getFilterSchemaAssetsExpression());
181
        } else {
182
            $this->assertSame($filterCallback, $config->getSchemaAssetsFilter());
183
        }
184
    }
185
186
    protected function tearDown(): void
187
    {
188
        $this->_em->getConnection()->exec("DROP TABLE IF EXISTS pg_entity_to_remove");
189
        $this->_em->getConnection()->exec("DROP SEQUENCE IF EXISTS pg_entity_to_remove_id_seq");
190
        parent::tearDown();
191
    }
192
}
193
194
/**
195
 * @Entity
196
 * @Table(name="stonewood.screen")
197
 */
198
class DDC1657Screen
199
{
200
    /**
201
     * Identifier
202
     * @var int
203
     *
204
     * @Id
205
     * @GeneratedValue(strategy="IDENTITY")
206
     * @Column(name="pk", type="integer", nullable=false)
207
     */
208
    private $pk;
0 ignored issues
show
introduced by
The private property $pk is not used, and could be removed.
Loading history...
209
210
    /**
211
     * Title
212
     * @var string
213
     *
214
     * @Column(name="title", type="string", length=255, nullable=false)
215
     */
216
    private $title;
0 ignored issues
show
introduced by
The private property $title is not used, and could be removed.
Loading history...
217
218
    /**
219
     * Path
220
     * @var string
221
     *
222
     * @Column(name="path", type="string", length=255, nullable=false)
223
     */
224
    private $path;
0 ignored issues
show
introduced by
The private property $path is not used, and could be removed.
Loading history...
225
226
    /**
227
     * Register date
228
     * @var Date
0 ignored issues
show
Bug introduced by
The type Doctrine\Tests\ORM\Functional\SchemaTool\Date was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
229
     *
230
     * @Column(name="ddate", type="date", nullable=false)
231
     */
232
    private $ddate;
0 ignored issues
show
introduced by
The private property $ddate is not used, and could be removed.
Loading history...
233
234
    /**
235
     * Avatar
236
     * @var Stonewood\Model\Entity\Avatar
0 ignored issues
show
Bug introduced by
The type Doctrine\Tests\ORM\Funct...ood\Model\Entity\Avatar was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
237
     *
238
     * @ManyToOne(targetEntity="DDC1657Avatar")
239
     * @JoinColumn(name="pk_avatar", referencedColumnName="pk", nullable=true, onDelete="CASCADE")
240
     */
241
    private $avatar;
0 ignored issues
show
introduced by
The private property $avatar is not used, and could be removed.
Loading history...
242
}
243
244
/**
245
 * @Entity
246
 * @Table(name="stonewood.avatar")
247
 */
248
class DDC1657Avatar
249
{
250
    /**
251
     * Identifier
252
     * @var int
253
     *
254
     * @Id
255
     * @GeneratedValue(strategy="IDENTITY")
256
     * @Column(name="pk", type="integer", nullable=false)
257
     */
258
    private $pk;
259
}
260
261
/**
262
 * @Entity
263
 * @Table(name="pg_entity_to_remove")
264
 */
265
class PgMyEntityToRemove
266
{
267
    /**
268
     * @Id @Column(type="integer")
269
     * @GeneratedValue(strategy="AUTO")
270
     */
271
    public $id;
272
}
273