Passed
Pull Request — master (#2921)
by Robin
63:46
created

testPrimaryKeyAutoIncrement()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 27
rs 8.8571
c 1
b 0
f 0
cc 1
eloc 18
nc 1
nop 0
1
<?php
2
3
namespace Doctrine\Tests\DBAL\Functional\Schema;
4
5
use Doctrine\DBAL\Schema;
6
use Doctrine\DBAL\Types\Type;
7
8
class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase
9
{
10
    /**
11
     * SQLITE does not support databases.
12
     *
13
     * @expectedException \Doctrine\DBAL\DBALException
14
     */
15
    public function testListDatabases()
16
    {
17
        $this->_sm->listDatabases();
18
    }
19
20
    public function testCreateAndDropDatabase()
21
    {
22
        $path = dirname(__FILE__).'/test_create_and_drop_sqlite_database.sqlite';
23
24
        $this->_sm->createDatabase($path);
25
        self::assertEquals(true, file_exists($path));
26
        $this->_sm->dropDatabase($path);
27
        self::assertEquals(false, file_exists($path));
28
    }
29
30
    /**
31
     * @group DBAL-1220
32
     */
33
    public function testDropsDatabaseWithActiveConnections()
34
    {
35
        $this->_sm->dropAndCreateDatabase('test_drop_database');
36
37
        self::assertFileExists('test_drop_database');
38
39
        $params = $this->_conn->getParams();
40
        $params['dbname'] = 'test_drop_database';
41
42
        $user = $params['user'] ?? null;
43
        $password = $params['password'] ?? null;
44
45
        $connection = $this->_conn->getDriver()->connect($params, $user, $password);
46
47
        self::assertInstanceOf('Doctrine\DBAL\Driver\Connection', $connection);
48
49
        $this->_sm->dropDatabase('test_drop_database');
50
51
        self::assertFileNotExists('test_drop_database');
52
53
        unset($connection);
54
    }
55
56
    public function testRenameTable()
57
    {
58
        $this->createTestTable('oldname');
59
        $this->_sm->renameTable('oldname', 'newname');
60
61
        $tables = $this->_sm->listTableNames();
62
        self::assertContains('newname', $tables);
63
        self::assertNotContains('oldname', $tables);
64
    }
65
66
    public function createListTableColumns()
67
    {
68
        $table = parent::createListTableColumns();
69
        $table->getColumn('id')->setAutoincrement(true);
70
71
        return $table;
72
    }
73
74
    public function testListForeignKeysFromExistingDatabase()
75
    {
76
        $this->_conn->exec(<<<EOS
77
CREATE TABLE user (
78
    id INTEGER PRIMARY KEY AUTOINCREMENT,
79
    page INTEGER CONSTRAINT FK_1 REFERENCES page (key) DEFERRABLE INITIALLY DEFERRED,
80
    parent INTEGER REFERENCES user(id) ON DELETE CASCADE,
81
    log INTEGER,
82
    CONSTRAINT FK_3 FOREIGN KEY (log) REFERENCES log ON UPDATE SET NULL NOT DEFERRABLE
83
)
84
EOS
85
        );
86
87
        $expected = array(
88
            new Schema\ForeignKeyConstraint(array('log'), 'log', array(null), 'FK_3',
89
                array('onUpdate' => 'SET NULL', 'onDelete' => 'NO ACTION', 'deferrable' => false, 'deferred' => false)),
90
            new Schema\ForeignKeyConstraint(array('parent'), 'user', array('id'), '1',
91
                array('onUpdate' => 'NO ACTION', 'onDelete' => 'CASCADE', 'deferrable' => false, 'deferred' => false)),
92
            new Schema\ForeignKeyConstraint(array('page'), 'page', array('key'), 'FK_1',
93
                array('onUpdate' => 'NO ACTION', 'onDelete' => 'NO ACTION', 'deferrable' => true, 'deferred' => true)),
94
        );
95
96
        self::assertEquals($expected, $this->_sm->listTableForeignKeys('user'));
97
    }
98
99
    public function testColumnCollation()
100
    {
101
        $table = new Schema\Table('test_collation');
102
        $table->addColumn('id', 'integer');
103
        $table->addColumn('text', 'text');
104
        $table->addColumn('foo', 'text')->setPlatformOption('collation', 'BINARY');
105
        $table->addColumn('bar', 'text')->setPlatformOption('collation', 'NOCASE');
106
        $this->_sm->dropAndCreateTable($table);
107
108
        $columns = $this->_sm->listTableColumns('test_collation');
109
110
        self::assertArrayNotHasKey('collation', $columns['id']->getPlatformOptions());
111
        self::assertEquals('BINARY', $columns['text']->getPlatformOption('collation'));
112
        self::assertEquals('BINARY', $columns['foo']->getPlatformOption('collation'));
113
        self::assertEquals('NOCASE', $columns['bar']->getPlatformOption('collation'));
114
    }
115
116 View Code Duplication
    public function testListTableWithBinary()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
    {
118
        $tableName = 'test_binary_table';
119
120
        $table = new \Doctrine\DBAL\Schema\Table($tableName);
121
        $table->addColumn('id', 'integer');
122
        $table->addColumn('column_varbinary', 'binary', array());
123
        $table->addColumn('column_binary', 'binary', array('fixed' => true));
124
        $table->setPrimaryKey(array('id'));
125
126
        $this->_sm->createTable($table);
127
128
        $table = $this->_sm->listTableDetails($tableName);
129
130
        self::assertInstanceOf('Doctrine\DBAL\Types\BlobType', $table->getColumn('column_varbinary')->getType());
131
        self::assertFalse($table->getColumn('column_varbinary')->getFixed());
132
133
        self::assertInstanceOf('Doctrine\DBAL\Types\BlobType', $table->getColumn('column_binary')->getType());
134
        self::assertFalse($table->getColumn('column_binary')->getFixed());
135
    }
136
137
    public function testNonDefaultPKOrder()
138
    {
139
        if ( ! extension_loaded('sqlite3')) {
140
            $this->markTestSkipped('This test requires the SQLite3 extension.');
141
        }
142
143
        $version = \SQLite3::version();
144
        if(version_compare($version['versionString'], '3.7.16', '<')) {
145
            $this->markTestSkipped('This version of sqlite doesn\'t return the order of the Primary Key.');
146
        }
147
        $this->_conn->exec(<<<EOS
148
CREATE TABLE non_default_pk_order (
149
    id INTEGER,
150
    other_id INTEGER,
151
    PRIMARY KEY(other_id, id)
152
)
153
EOS
154
        );
155
156
        $tableIndexes = $this->_sm->listTableIndexes('non_default_pk_order');
157
158
         self::assertEquals(1, count($tableIndexes));
159
160
        self::assertArrayHasKey('primary', $tableIndexes, 'listTableIndexes() has to return a "primary" array key.');
161
        self::assertEquals(array('other_id', 'id'), array_map('strtolower', $tableIndexes['primary']->getColumns()));
162
    }
163
164
    /**
165
     * @group DBAL-1779
166
     */
167
    public function testListTableColumnsWithWhitespacesInTypeDeclarations()
168
    {
169
        $sql = <<<SQL
170
CREATE TABLE dbal_1779 (
171
    foo VARCHAR (64) ,
172
    bar TEXT (100)
173
)
174
SQL;
175
176
        $this->_conn->exec($sql);
177
178
        $columns = $this->_sm->listTableColumns('dbal_1779');
179
180
        self::assertCount(2, $columns);
181
182
        self::assertArrayHasKey('foo', $columns);
183
        self::assertArrayHasKey('bar', $columns);
184
185
        self::assertSame(Type::getType(Type::STRING), $columns['foo']->getType());
186
        self::assertSame(Type::getType(Type::TEXT), $columns['bar']->getType());
187
188
        self::assertSame(64, $columns['foo']->getLength());
189
        self::assertSame(100, $columns['bar']->getLength());
190
    }
191
192
    /**
193
     * @dataProvider getDiffListIntegerAutoincrementTableColumnsData
194
     * @group DBAL-924
195
     */
196
    public function testDiffListIntegerAutoincrementTableColumns($integerType, $unsigned, $expectedComparatorDiff)
197
    {
198
        $tableName = 'test_int_autoincrement_table';
199
200
        $offlineTable = new \Doctrine\DBAL\Schema\Table($tableName);
201
        $offlineTable->addColumn('id', $integerType, array('autoincrement' => true, 'unsigned' => $unsigned));
202
        $offlineTable->setPrimaryKey(array('id'));
203
204
        $this->_sm->dropAndCreateTable($offlineTable);
205
206
        $onlineTable = $this->_sm->listTableDetails($tableName);
207
        $comparator = new Schema\Comparator();
208
        $diff = $comparator->diffTable($offlineTable, $onlineTable);
209
210
        if ($expectedComparatorDiff) {
211
            self::assertEmpty($this->_sm->getDatabasePlatform()->getAlterTableSQL($diff));
0 ignored issues
show
Bug introduced by
It seems like $diff can also be of type boolean; however, parameter $diff of Doctrine\DBAL\Platforms\...orm::getAlterTableSQL() does only seem to accept Doctrine\DBAL\Schema\TableDiff, maybe add an additional type check? ( Ignorable by Annotation )

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

211
            self::assertEmpty($this->_sm->getDatabasePlatform()->getAlterTableSQL(/** @scrutinizer ignore-type */ $diff));
Loading history...
212
        } else {
213
            self::assertFalse($diff);
214
        }
215
    }
216
217
    /**
218
     * @return array
219
     */
220
    public function getDiffListIntegerAutoincrementTableColumnsData()
221
    {
222
        return array(
223
            array('smallint', false, true),
224
            array('smallint', true, true),
225
            array('integer', false, false),
226
            array('integer', true, true),
227
            array('bigint', false, true),
228
            array('bigint', true, true),
229
        );
230
    }
231
232
    /**
233
     * @group DBAL-2921
234
     */
235
    public function testPrimaryKeyAutoIncrement()
236
    {
237
        $table = new Schema\Table('test_pk_auto_increment');
238
        $table->addColumn('id', 'integer', [
239
            'autoincrement' => true
240
        ]);
241
        $table->addColumn('text', 'text');
242
        $table->setPrimaryKey(['id']);
243
        $this->_sm->dropAndCreateTable($table);
244
245
        $this->_conn->insert('test_pk_auto_increment', ['text' => '1']);
246
        $this->_conn->insert('test_pk_auto_increment', ['text' => '2']);
247
        $this->_conn->insert('test_pk_auto_increment', ['text' => '3']);
248
249
        $query = $this->_conn->query('SELECT id FROM test_pk_auto_increment WHERE text = "3"');
250
        $query->execute();
251
        $lastUsedIdBeforeDelete = (int)$query->fetchColumn();
252
253
        $this->_conn->query('DELETE FROM test_pk_auto_increment');
254
255
        $this->_conn->insert('test_pk_auto_increment', ['text' => '4']);
256
257
        $query = $this->_conn->query('SELECT id FROM test_pk_auto_increment WHERE text = "4"');
258
        $query->execute();
259
        $lastUsedIdAfterDelete = (int)$query->fetchColumn();
260
261
        $this->assertGreaterThan($lastUsedIdBeforeDelete, $lastUsedIdAfterDelete);
262
    }
263
264
    /**
265
     * @group DBAL-2921
266
     */
267
    public function testPrimaryKeyNoAutoIncrement()
268
    {
269
        $table = new Schema\Table('test_pk_auto_increment');
270
        $table->addColumn('id', 'integer');
271
        $table->addColumn('text', 'text');
272
        $table->setPrimaryKey(['id']);
273
        $this->_sm->dropAndCreateTable($table);
274
275
        $this->_conn->insert('test_pk_auto_increment', ['text' => '1']);
276
        $this->_conn->insert('test_pk_auto_increment', ['text' => '2']);
277
        $this->_conn->insert('test_pk_auto_increment', ['text' => '3']);
278
279
        $this->_conn->query('DELETE FROM test_pk_auto_increment');
280
281
        $this->_conn->insert('test_pk_auto_increment', ['text' => '4']);
282
283
        $query = $this->_conn->query('SELECT id FROM test_pk_auto_increment WHERE text = "4"');
284
        $query->execute();
285
        $lastUsedIdAfterDelete = (int)$query->fetchColumn();
286
287
        // with an empty table, non autoincrement rowid is always 1
288
        $this->assertEquals(1, $lastUsedIdAfterDelete);
289
    }
290
}
291