Failed Conditions
Push — master ( ac0e13...24dbc4 )
by Sergei
22s queued 15s
created

testOnlyOwnCommentIsParsed()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 13
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\DBAL\Tests\Functional\Schema;
6
7
use Doctrine\DBAL\DBALException;
8
use Doctrine\DBAL\Driver\Statement;
9
use Doctrine\DBAL\Schema;
10
use Doctrine\DBAL\Schema\Table;
11
use Doctrine\DBAL\Types\BlobType;
12
use Doctrine\DBAL\Types\Type;
13
use Doctrine\DBAL\Types\Types;
14
use SQLite3;
15
use function array_map;
16
use function assert;
17
use function dirname;
18
use function extension_loaded;
19
use function version_compare;
20
21
class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase
22
{
23
    /**
24
     * SQLITE does not support databases.
25
     */
26
    public function testListDatabases() : void
27
    {
28
        $this->expectException(DBALException::class);
29
30
        $this->schemaManager->listDatabases();
31
    }
32
33
    public function testCreateAndDropDatabase() : void
34
    {
35
        $path = dirname(__FILE__) . '/test_create_and_drop_sqlite_database.sqlite';
36
37
        $this->schemaManager->createDatabase($path);
38
        self::assertFileExists($path);
39
        $this->schemaManager->dropDatabase($path);
40
        self::assertFileNotExists($path);
41
    }
42
43
    /**
44
     * @group DBAL-1220
45
     */
46
    public function testDropsDatabaseWithActiveConnections() : void
47
    {
48
        $this->schemaManager->dropAndCreateDatabase('test_drop_database');
49
50
        self::assertFileExists('test_drop_database');
51
52
        $params           = $this->connection->getParams();
53
        $params['dbname'] = 'test_drop_database';
54
55
        $user     = $params['user'] ?? '';
56
        $password = $params['password'] ?? '';
57
58
        $connection = $this->connection->getDriver()->connect($params, $user, $password);
59
60
        $this->schemaManager->dropDatabase('test_drop_database');
61
62
        self::assertFileNotExists('test_drop_database');
63
64
        unset($connection);
65
    }
66
67
    public function testRenameTable() : void
68
    {
69
        $this->createTestTable('oldname');
70
        $this->schemaManager->renameTable('oldname', 'newname');
71
72
        $tables = $this->schemaManager->listTableNames();
73
        self::assertContains('newname', $tables);
74
        self::assertNotContains('oldname', $tables);
75
    }
76
77
    public function createListTableColumns() : Table
78
    {
79
        $table = parent::createListTableColumns();
80
        $table->getColumn('id')->setAutoincrement(true);
81
82
        return $table;
83
    }
84
85
    public function testListForeignKeysFromExistingDatabase() : void
86
    {
87
        $this->connection->exec(<<<EOS
88
CREATE TABLE user (
89
    id INTEGER PRIMARY KEY AUTOINCREMENT,
90
    page INTEGER CONSTRAINT FK_1 REFERENCES page (key) DEFERRABLE INITIALLY DEFERRED,
91
    parent INTEGER REFERENCES user(id) ON DELETE CASCADE,
92
    log INTEGER,
93
    CONSTRAINT FK_3 FOREIGN KEY (log) REFERENCES log ON UPDATE SET NULL NOT DEFERRABLE
94
)
95
EOS
96
        );
97
98
        $expected = [
99
            new Schema\ForeignKeyConstraint(
100
                ['log'],
101
                'log',
102
                [''],
103
                'FK_3',
104
                ['onUpdate' => 'SET NULL', 'onDelete' => 'NO ACTION', 'deferrable' => false, 'deferred' => false]
105
            ),
106
            new Schema\ForeignKeyConstraint(
107
                ['parent'],
108
                'user',
109
                ['id'],
110
                '1',
111
                ['onUpdate' => 'NO ACTION', 'onDelete' => 'CASCADE', 'deferrable' => false, 'deferred' => false]
112
            ),
113
            new Schema\ForeignKeyConstraint(
114
                ['page'],
115
                'page',
116
                ['key'],
117
                'FK_1',
118
                ['onUpdate' => 'NO ACTION', 'onDelete' => 'NO ACTION', 'deferrable' => true, 'deferred' => true]
119
            ),
120
        ];
121
122
        self::assertEquals($expected, $this->schemaManager->listTableForeignKeys('user'));
123
    }
124
125
    public function testColumnCollation() : void
126
    {
127
        $table = new Schema\Table('test_collation');
128
        $table->addColumn('id', 'integer');
129
        $table->addColumn('text', 'text');
130
        $table->addColumn('foo', 'text')->setPlatformOption('collation', 'BINARY');
131
        $table->addColumn('bar', 'text')->setPlatformOption('collation', 'NOCASE');
132
        $this->schemaManager->dropAndCreateTable($table);
133
134
        $columns = $this->schemaManager->listTableColumns('test_collation');
135
136
        self::assertArrayNotHasKey('collation', $columns['id']->getPlatformOptions());
137
        self::assertEquals('BINARY', $columns['text']->getPlatformOption('collation'));
138
        self::assertEquals('BINARY', $columns['foo']->getPlatformOption('collation'));
139
        self::assertEquals('NOCASE', $columns['bar']->getPlatformOption('collation'));
140
    }
141
142
    public function testListTableWithBinary() : void
143
    {
144
        $tableName = 'test_binary_table';
145
146
        $table = new Table($tableName);
147
        $table->addColumn('id', 'integer');
148
        $table->addColumn('column_varbinary', 'binary', []);
149
        $table->addColumn('column_binary', 'binary', ['fixed' => true]);
150
        $table->setPrimaryKey(['id']);
151
152
        $this->schemaManager->createTable($table);
153
154
        $table = $this->schemaManager->listTableDetails($tableName);
155
156
        self::assertInstanceOf(BlobType::class, $table->getColumn('column_varbinary')->getType());
157
        self::assertFalse($table->getColumn('column_varbinary')->getFixed());
158
159
        self::assertInstanceOf(BlobType::class, $table->getColumn('column_binary')->getType());
160
        self::assertFalse($table->getColumn('column_binary')->getFixed());
161
    }
162
163
    public function testNonDefaultPKOrder() : void
164
    {
165
        if (! extension_loaded('sqlite3')) {
166
            self::markTestSkipped('This test requires the SQLite3 extension.');
167
        }
168
169
        $version = SQLite3::version();
170
        if (version_compare($version['versionString'], '3.7.16', '<')) {
171
            self::markTestSkipped('This version of sqlite doesn\'t return the order of the Primary Key.');
172
        }
173
174
        $this->connection->exec(<<<EOS
175
CREATE TABLE non_default_pk_order (
176
    id INTEGER,
177
    other_id INTEGER,
178
    PRIMARY KEY(other_id, id)
179
)
180
EOS
181
        );
182
183
        $tableIndexes = $this->schemaManager->listTableIndexes('non_default_pk_order');
184
185
         self::assertCount(1, $tableIndexes);
186
187
        self::assertArrayHasKey('primary', $tableIndexes, 'listTableIndexes() has to return a "primary" array key.');
188
        self::assertEquals(['other_id', 'id'], array_map('strtolower', $tableIndexes['primary']->getColumns()));
189
    }
190
191
    /**
192
     * @group DBAL-1779
193
     */
194
    public function testListTableColumnsWithWhitespacesInTypeDeclarations() : void
195
    {
196
        $sql = <<<SQL
197
CREATE TABLE dbal_1779 (
198
    foo VARCHAR (64) ,
199
    bar TEXT (100)
200
)
201
SQL;
202
203
        $this->connection->exec($sql);
204
205
        $columns = $this->schemaManager->listTableColumns('dbal_1779');
206
207
        self::assertCount(2, $columns);
208
209
        self::assertArrayHasKey('foo', $columns);
210
        self::assertArrayHasKey('bar', $columns);
211
212
        self::assertSame(Type::getType(Types::STRING), $columns['foo']->getType());
213
        self::assertSame(Type::getType(Types::TEXT), $columns['bar']->getType());
214
215
        self::assertSame(64, $columns['foo']->getLength());
216
        self::assertSame(100, $columns['bar']->getLength());
217
    }
218
219
    /**
220
     * @dataProvider getDiffListIntegerAutoincrementTableColumnsData
221
     * @group DBAL-924
222
     */
223
    public function testDiffListIntegerAutoincrementTableColumns(string $integerType, bool $unsigned, bool $expectedComparatorDiff) : void
224
    {
225
        $tableName = 'test_int_autoincrement_table';
226
227
        $offlineTable = new Table($tableName);
228
        $offlineTable->addColumn('id', $integerType, ['autoincrement' => true, 'unsigned' => $unsigned]);
229
        $offlineTable->setPrimaryKey(['id']);
230
231
        $this->schemaManager->dropAndCreateTable($offlineTable);
232
233
        $onlineTable = $this->schemaManager->listTableDetails($tableName);
234
        $comparator  = new Schema\Comparator();
235
        $diff        = $comparator->diffTable($offlineTable, $onlineTable);
236
237
        if ($expectedComparatorDiff) {
238
            self::assertNotNull($diff);
239
240
            self::assertEmpty($this->schemaManager->getDatabasePlatform()->getAlterTableSQL($diff));
241
        } else {
242
            self::assertNull($diff);
243
        }
244
    }
245
246
    /**
247
     * @return mixed[][]
248
     */
249
    public static function getDiffListIntegerAutoincrementTableColumnsData() : iterable
250
    {
251
        return [
252
            ['smallint', false, true],
253
            ['smallint', true, true],
254
            ['integer', false, false],
255
            ['integer', true, true],
256
            ['bigint', false, true],
257
            ['bigint', true, true],
258
        ];
259
    }
260
261
    /**
262
     * @group DBAL-2921
263
     */
264
    public function testPrimaryKeyNoAutoIncrement() : void
265
    {
266
        $table = new Schema\Table('test_pk_auto_increment');
267
        $table->addColumn('id', 'integer');
268
        $table->addColumn('text', 'text');
269
        $table->setPrimaryKey(['id']);
270
        $this->schemaManager->dropAndCreateTable($table);
271
272
        $this->connection->insert('test_pk_auto_increment', ['text' => '1']);
273
274
        $this->connection->query('DELETE FROM test_pk_auto_increment');
275
276
        $this->connection->insert('test_pk_auto_increment', ['text' => '2']);
277
278
        $query = $this->connection->query('SELECT id FROM test_pk_auto_increment WHERE text = "2"');
279
        assert($query instanceof Statement);
280
281
        $query->execute();
282
        $lastUsedIdAfterDelete = (int) $query->fetchColumn();
283
284
        // with an empty table, non autoincrement rowid is always 1
285
        self::assertEquals(1, $lastUsedIdAfterDelete);
286
    }
287
288
    public function testOnlyOwnCommentIsParsed() : void
289
    {
290
        $table = new Table('own_column_comment');
291
        $table->addColumn('col1', 'string', ['length' => 16]);
292
        $table->addColumn('col2', 'string', ['length' => 16, 'comment' => 'Column #2']);
293
        $table->addColumn('col3', 'string', ['length' => 16]);
294
295
        $sm = $this->connection->getSchemaManager();
296
        $sm->createTable($table);
297
298
        self::assertNull($sm->listTableDetails('own_column_comment')
299
            ->getColumn('col1')
300
            ->getComment());
301
    }
302
}
303