Passed
Push — master ( d48ea9...7021bd )
by Sergei
24:21
created

getDiffListIntegerAutoincrementTableColumnsData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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