1 | <?php |
||||||
2 | |||||||
3 | declare(strict_types=1); |
||||||
4 | |||||||
5 | namespace Doctrine\Tests\DBAL\Functional\Schema; |
||||||
6 | |||||||
7 | use DateTime; |
||||||
8 | use Doctrine\DBAL\DriverManager; |
||||||
9 | use Doctrine\DBAL\Exception\DatabaseRequired; |
||||||
10 | use Doctrine\DBAL\Platforms\MariaDb1027Platform; |
||||||
11 | use Doctrine\DBAL\Platforms\MySqlPlatform; |
||||||
12 | use Doctrine\DBAL\Schema\Comparator; |
||||||
13 | use Doctrine\DBAL\Schema\Schema; |
||||||
14 | use Doctrine\DBAL\Schema\Table; |
||||||
15 | use Doctrine\DBAL\Types\BlobType; |
||||||
16 | use Doctrine\DBAL\Types\Type; |
||||||
17 | use Doctrine\DBAL\Types\Types; |
||||||
18 | use Doctrine\Tests\TestUtil; |
||||||
19 | use Doctrine\Tests\Types\MySqlPointType; |
||||||
20 | |||||||
21 | class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase |
||||||
22 | { |
||||||
23 | protected function setUp() : void |
||||||
24 | { |
||||||
25 | parent::setUp(); |
||||||
26 | |||||||
27 | if (Type::hasType('point')) { |
||||||
28 | return; |
||||||
29 | } |
||||||
30 | |||||||
31 | $this->resetSharedConn(); |
||||||
32 | |||||||
33 | Type::addType('point', MySqlPointType::class); |
||||||
34 | } |
||||||
35 | |||||||
36 | public function testSwitchPrimaryKeyColumns() : void |
||||||
37 | { |
||||||
38 | $tableOld = new Table('switch_primary_key_columns'); |
||||||
39 | $tableOld->addColumn('foo_id', 'integer'); |
||||||
40 | $tableOld->addColumn('bar_id', 'integer'); |
||||||
41 | |||||||
42 | $this->schemaManager->createTable($tableOld); |
||||||
43 | $tableFetched = $this->schemaManager->listTableDetails('switch_primary_key_columns'); |
||||||
44 | $tableNew = clone $tableFetched; |
||||||
45 | $tableNew->setPrimaryKey(['bar_id', 'foo_id']); |
||||||
46 | |||||||
47 | $comparator = new Comparator(); |
||||||
48 | |||||||
49 | $diff = $comparator->diffTable($tableFetched, $tableNew); |
||||||
50 | |||||||
51 | self::assertNotNull($diff); |
||||||
52 | |||||||
53 | $this->schemaManager->alterTable($diff); |
||||||
54 | |||||||
55 | $table = $this->schemaManager->listTableDetails('switch_primary_key_columns'); |
||||||
56 | $primaryKey = $table->getPrimaryKeyColumns(); |
||||||
57 | |||||||
58 | self::assertCount(2, $primaryKey); |
||||||
59 | self::assertContains('bar_id', $primaryKey); |
||||||
60 | self::assertContains('foo_id', $primaryKey); |
||||||
61 | } |
||||||
62 | |||||||
63 | public function testFulltextIndex() : void |
||||||
64 | { |
||||||
65 | $table = new Table('fulltext_index'); |
||||||
66 | $table->addColumn('text', 'text'); |
||||||
67 | $table->addIndex(['text'], 'f_index'); |
||||||
68 | $table->addOption('engine', 'MyISAM'); |
||||||
69 | |||||||
70 | $index = $table->getIndex('f_index'); |
||||||
71 | $index->addFlag('fulltext'); |
||||||
72 | |||||||
73 | $this->schemaManager->dropAndCreateTable($table); |
||||||
74 | |||||||
75 | $indexes = $this->schemaManager->listTableIndexes('fulltext_index'); |
||||||
76 | self::assertArrayHasKey('f_index', $indexes); |
||||||
77 | self::assertTrue($indexes['f_index']->hasFlag('fulltext')); |
||||||
78 | } |
||||||
79 | |||||||
80 | public function testSpatialIndex() : void |
||||||
81 | { |
||||||
82 | $table = new Table('spatial_index'); |
||||||
83 | $table->addColumn('point', 'point'); |
||||||
84 | $table->addIndex(['point'], 's_index'); |
||||||
85 | $table->addOption('engine', 'MyISAM'); |
||||||
86 | |||||||
87 | $index = $table->getIndex('s_index'); |
||||||
88 | $index->addFlag('spatial'); |
||||||
89 | |||||||
90 | $this->schemaManager->dropAndCreateTable($table); |
||||||
91 | |||||||
92 | $indexes = $this->schemaManager->listTableIndexes('spatial_index'); |
||||||
93 | self::assertArrayHasKey('s_index', $indexes); |
||||||
94 | self::assertTrue($indexes['s_index']->hasFlag('spatial')); |
||||||
95 | } |
||||||
96 | |||||||
97 | public function testIndexWithLength() : void |
||||||
98 | { |
||||||
99 | $table = new Table('index_length'); |
||||||
100 | $table->addColumn('text', 'string', ['length' => 255]); |
||||||
101 | $table->addIndex(['text'], 'text_index', [], ['lengths' => [128]]); |
||||||
102 | |||||||
103 | $this->schemaManager->dropAndCreateTable($table); |
||||||
104 | |||||||
105 | $indexes = $this->schemaManager->listTableIndexes('index_length'); |
||||||
106 | self::assertArrayHasKey('text_index', $indexes); |
||||||
107 | self::assertSame([128], $indexes['text_index']->getOption('lengths')); |
||||||
108 | } |
||||||
109 | |||||||
110 | /** |
||||||
111 | * @group DBAL-400 |
||||||
112 | */ |
||||||
113 | public function testAlterTableAddPrimaryKey() : void |
||||||
114 | { |
||||||
115 | $table = new Table('alter_table_add_pk'); |
||||||
116 | $table->addColumn('id', 'integer'); |
||||||
117 | $table->addColumn('foo', 'integer'); |
||||||
118 | $table->addIndex(['id'], 'idx_id'); |
||||||
119 | |||||||
120 | $this->schemaManager->createTable($table); |
||||||
121 | |||||||
122 | $comparator = new Comparator(); |
||||||
123 | $diffTable = clone $table; |
||||||
124 | |||||||
125 | $diffTable->dropIndex('idx_id'); |
||||||
126 | $diffTable->setPrimaryKey(['id']); |
||||||
127 | |||||||
128 | $diff = $comparator->diffTable($table, $diffTable); |
||||||
129 | |||||||
130 | self::assertNotNull($diff); |
||||||
131 | |||||||
132 | $this->schemaManager->alterTable($diff); |
||||||
133 | |||||||
134 | $table = $this->schemaManager->listTableDetails('alter_table_add_pk'); |
||||||
135 | |||||||
136 | self::assertFalse($table->hasIndex('idx_id')); |
||||||
137 | self::assertTrue($table->hasPrimaryKey()); |
||||||
138 | } |
||||||
139 | |||||||
140 | /** |
||||||
141 | * @group DBAL-464 |
||||||
142 | */ |
||||||
143 | public function testDropPrimaryKeyWithAutoincrementColumn() : void |
||||||
144 | { |
||||||
145 | $table = new Table('drop_primary_key'); |
||||||
146 | $table->addColumn('id', 'integer', ['autoincrement' => true]); |
||||||
147 | $table->addColumn('foo', 'integer'); |
||||||
148 | $table->setPrimaryKey(['id', 'foo']); |
||||||
149 | |||||||
150 | $this->schemaManager->dropAndCreateTable($table); |
||||||
151 | |||||||
152 | $diffTable = clone $table; |
||||||
153 | |||||||
154 | $diffTable->dropPrimaryKey(); |
||||||
155 | |||||||
156 | $comparator = new Comparator(); |
||||||
157 | |||||||
158 | $diff = $comparator->diffTable($table, $diffTable); |
||||||
159 | |||||||
160 | self::assertNotNull($diff); |
||||||
161 | |||||||
162 | $this->schemaManager->alterTable($diff); |
||||||
163 | |||||||
164 | $table = $this->schemaManager->listTableDetails('drop_primary_key'); |
||||||
165 | |||||||
166 | self::assertFalse($table->hasPrimaryKey()); |
||||||
167 | self::assertFalse($table->getColumn('id')->getAutoincrement()); |
||||||
168 | } |
||||||
169 | |||||||
170 | /** |
||||||
171 | * @group DBAL-789 |
||||||
172 | */ |
||||||
173 | public function testDoesNotPropagateDefaultValuesForUnsupportedColumnTypes() : void |
||||||
174 | { |
||||||
175 | if ($this->schemaManager->getDatabasePlatform() instanceof MariaDb1027Platform) { |
||||||
176 | $this->markTestSkipped( |
||||||
177 | 'MariaDb102Platform supports default values for BLOB and TEXT columns and will propagate values' |
||||||
178 | ); |
||||||
179 | } |
||||||
180 | |||||||
181 | $table = new Table('text_blob_default_value'); |
||||||
182 | $table->addColumn('def_text', 'text', ['default' => 'def']); |
||||||
183 | $table->addColumn('def_text_null', 'text', ['notnull' => false, 'default' => 'def']); |
||||||
184 | $table->addColumn('def_blob', 'blob', ['default' => 'def']); |
||||||
185 | $table->addColumn('def_blob_null', 'blob', ['notnull' => false, 'default' => 'def']); |
||||||
186 | |||||||
187 | $this->schemaManager->dropAndCreateTable($table); |
||||||
188 | |||||||
189 | $onlineTable = $this->schemaManager->listTableDetails('text_blob_default_value'); |
||||||
190 | |||||||
191 | self::assertNull($onlineTable->getColumn('def_text')->getDefault()); |
||||||
192 | self::assertNull($onlineTable->getColumn('def_text_null')->getDefault()); |
||||||
193 | self::assertFalse($onlineTable->getColumn('def_text_null')->getNotnull()); |
||||||
194 | self::assertNull($onlineTable->getColumn('def_blob')->getDefault()); |
||||||
195 | self::assertNull($onlineTable->getColumn('def_blob_null')->getDefault()); |
||||||
196 | self::assertFalse($onlineTable->getColumn('def_blob_null')->getNotnull()); |
||||||
197 | |||||||
198 | $comparator = new Comparator(); |
||||||
199 | |||||||
200 | $diff = $comparator->diffTable($table, $onlineTable); |
||||||
201 | |||||||
202 | self::assertNotNull($diff); |
||||||
203 | |||||||
204 | $this->schemaManager->alterTable($diff); |
||||||
205 | |||||||
206 | $onlineTable = $this->schemaManager->listTableDetails('text_blob_default_value'); |
||||||
207 | |||||||
208 | self::assertNull($onlineTable->getColumn('def_text')->getDefault()); |
||||||
209 | self::assertNull($onlineTable->getColumn('def_text_null')->getDefault()); |
||||||
210 | self::assertFalse($onlineTable->getColumn('def_text_null')->getNotnull()); |
||||||
211 | self::assertNull($onlineTable->getColumn('def_blob')->getDefault()); |
||||||
212 | self::assertNull($onlineTable->getColumn('def_blob_null')->getDefault()); |
||||||
213 | self::assertFalse($onlineTable->getColumn('def_blob_null')->getNotnull()); |
||||||
214 | } |
||||||
215 | |||||||
216 | public function testColumnCharset() : void |
||||||
217 | { |
||||||
218 | $table = new Table('test_column_charset'); |
||||||
219 | $table->addColumn('id', 'integer'); |
||||||
220 | $table->addColumn('no_charset', 'text'); |
||||||
221 | $table->addColumn('foo', 'text')->setPlatformOption('charset', 'ascii'); |
||||||
222 | $table->addColumn('bar', 'text')->setPlatformOption('charset', 'latin1'); |
||||||
223 | $this->schemaManager->dropAndCreateTable($table); |
||||||
224 | |||||||
225 | $columns = $this->schemaManager->listTableColumns('test_column_charset'); |
||||||
226 | |||||||
227 | self::assertFalse($columns['id']->hasPlatformOption('charset')); |
||||||
228 | self::assertEquals('utf8', $columns['no_charset']->getPlatformOption('charset')); |
||||||
229 | self::assertEquals('ascii', $columns['foo']->getPlatformOption('charset')); |
||||||
230 | self::assertEquals('latin1', $columns['bar']->getPlatformOption('charset')); |
||||||
231 | } |
||||||
232 | |||||||
233 | public function testAlterColumnCharset() : void |
||||||
234 | { |
||||||
235 | $tableName = 'test_alter_column_charset'; |
||||||
236 | |||||||
237 | $table = new Table($tableName); |
||||||
238 | $table->addColumn('col_text', 'text')->setPlatformOption('charset', 'utf8'); |
||||||
239 | |||||||
240 | $this->schemaManager->dropAndCreateTable($table); |
||||||
241 | |||||||
242 | $diffTable = clone $table; |
||||||
243 | $diffTable->getColumn('col_text')->setPlatformOption('charset', 'ascii'); |
||||||
244 | |||||||
245 | $comparator = new Comparator(); |
||||||
246 | |||||||
247 | $diff = $comparator->diffTable($table, $diffTable); |
||||||
248 | |||||||
249 | self::assertNotNull($diff); |
||||||
250 | |||||||
251 | $this->schemaManager->alterTable($diff); |
||||||
252 | |||||||
253 | $table = $this->schemaManager->listTableDetails($tableName); |
||||||
254 | |||||||
255 | self::assertEquals('ascii', $table->getColumn('col_text')->getPlatformOption('charset')); |
||||||
256 | } |
||||||
257 | |||||||
258 | public function testColumnCharsetChange() : void |
||||||
259 | { |
||||||
260 | $table = new Table('test_column_charset_change'); |
||||||
261 | $table->addColumn('col_string', 'string')->setLength(100)->setNotnull(true)->setPlatformOption('charset', 'utf8'); |
||||||
262 | |||||||
263 | $diffTable = clone $table; |
||||||
264 | $diffTable->getColumn('col_string')->setPlatformOption('charset', 'ascii'); |
||||||
265 | |||||||
266 | $fromSchema = new Schema([$table]); |
||||||
267 | $toSchema = new Schema([$diffTable]); |
||||||
268 | |||||||
269 | $diff = $fromSchema->getMigrateToSql($toSchema, $this->connection->getDatabasePlatform()); |
||||||
270 | self::assertContains('ALTER TABLE test_column_charset_change CHANGE col_string col_string VARCHAR(100) CHARACTER SET ascii NOT NULL', $diff); |
||||||
271 | } |
||||||
272 | |||||||
273 | public function testColumnCollation() : void |
||||||
274 | { |
||||||
275 | $table = new Table('test_collation'); |
||||||
276 | $table->addOption('collate', $collation = 'latin1_swedish_ci'); |
||||||
277 | $table->addOption('charset', 'latin1'); |
||||||
278 | $table->addColumn('id', 'integer'); |
||||||
279 | $table->addColumn('text', 'text'); |
||||||
280 | $table->addColumn('foo', 'text')->setPlatformOption('collation', 'latin1_swedish_ci'); |
||||||
281 | $table->addColumn('bar', 'text')->setPlatformOption('collation', 'utf8_general_ci'); |
||||||
282 | $table->addColumn('baz', 'text')->setPlatformOption('collation', 'binary'); |
||||||
283 | $this->schemaManager->dropAndCreateTable($table); |
||||||
284 | |||||||
285 | $columns = $this->schemaManager->listTableColumns('test_collation'); |
||||||
286 | |||||||
287 | self::assertArrayNotHasKey('collation', $columns['id']->getPlatformOptions()); |
||||||
288 | self::assertEquals('latin1_swedish_ci', $columns['text']->getPlatformOption('collation')); |
||||||
289 | self::assertEquals('latin1_swedish_ci', $columns['foo']->getPlatformOption('collation')); |
||||||
290 | self::assertEquals('utf8_general_ci', $columns['bar']->getPlatformOption('collation')); |
||||||
291 | self::assertInstanceOf(BlobType::class, $columns['baz']->getType()); |
||||||
292 | } |
||||||
293 | |||||||
294 | /** |
||||||
295 | * @group DBAL-843 |
||||||
296 | */ |
||||||
297 | public function testListLobTypeColumns() : void |
||||||
298 | { |
||||||
299 | $tableName = 'lob_type_columns'; |
||||||
300 | $table = new Table($tableName); |
||||||
301 | |||||||
302 | $table->addColumn('col_tinytext', 'text', ['length' => MySqlPlatform::LENGTH_LIMIT_TINYTEXT]); |
||||||
303 | $table->addColumn('col_text', 'text', ['length' => MySqlPlatform::LENGTH_LIMIT_TEXT]); |
||||||
304 | $table->addColumn('col_mediumtext', 'text', ['length' => MySqlPlatform::LENGTH_LIMIT_MEDIUMTEXT]); |
||||||
305 | $table->addColumn('col_longtext', 'text'); |
||||||
306 | |||||||
307 | $table->addColumn('col_tinyblob', 'text', ['length' => MySqlPlatform::LENGTH_LIMIT_TINYBLOB]); |
||||||
308 | $table->addColumn('col_blob', 'blob', ['length' => MySqlPlatform::LENGTH_LIMIT_BLOB]); |
||||||
309 | $table->addColumn('col_mediumblob', 'blob', ['length' => MySqlPlatform::LENGTH_LIMIT_MEDIUMBLOB]); |
||||||
310 | $table->addColumn('col_longblob', 'blob'); |
||||||
311 | |||||||
312 | $this->schemaManager->dropAndCreateTable($table); |
||||||
313 | |||||||
314 | $platform = $this->schemaManager->getDatabasePlatform(); |
||||||
315 | $offlineColumns = $table->getColumns(); |
||||||
316 | $onlineColumns = $this->schemaManager->listTableColumns($tableName); |
||||||
317 | |||||||
318 | self::assertSame( |
||||||
319 | $platform->getClobTypeDeclarationSQL($offlineColumns['col_tinytext']->toArray()), |
||||||
320 | $platform->getClobTypeDeclarationSQL($onlineColumns['col_tinytext']->toArray()) |
||||||
321 | ); |
||||||
322 | self::assertSame( |
||||||
323 | $platform->getClobTypeDeclarationSQL($offlineColumns['col_text']->toArray()), |
||||||
324 | $platform->getClobTypeDeclarationSQL($onlineColumns['col_text']->toArray()) |
||||||
325 | ); |
||||||
326 | self::assertSame( |
||||||
327 | $platform->getClobTypeDeclarationSQL($offlineColumns['col_mediumtext']->toArray()), |
||||||
328 | $platform->getClobTypeDeclarationSQL($onlineColumns['col_mediumtext']->toArray()) |
||||||
329 | ); |
||||||
330 | self::assertSame( |
||||||
331 | $platform->getClobTypeDeclarationSQL($offlineColumns['col_longtext']->toArray()), |
||||||
332 | $platform->getClobTypeDeclarationSQL($onlineColumns['col_longtext']->toArray()) |
||||||
333 | ); |
||||||
334 | |||||||
335 | self::assertSame( |
||||||
336 | $platform->getBlobTypeDeclarationSQL($offlineColumns['col_tinyblob']->toArray()), |
||||||
337 | $platform->getBlobTypeDeclarationSQL($onlineColumns['col_tinyblob']->toArray()) |
||||||
338 | ); |
||||||
339 | self::assertSame( |
||||||
340 | $platform->getBlobTypeDeclarationSQL($offlineColumns['col_blob']->toArray()), |
||||||
341 | $platform->getBlobTypeDeclarationSQL($onlineColumns['col_blob']->toArray()) |
||||||
342 | ); |
||||||
343 | self::assertSame( |
||||||
344 | $platform->getBlobTypeDeclarationSQL($offlineColumns['col_mediumblob']->toArray()), |
||||||
345 | $platform->getBlobTypeDeclarationSQL($onlineColumns['col_mediumblob']->toArray()) |
||||||
346 | ); |
||||||
347 | self::assertSame( |
||||||
348 | $platform->getBlobTypeDeclarationSQL($offlineColumns['col_longblob']->toArray()), |
||||||
349 | $platform->getBlobTypeDeclarationSQL($onlineColumns['col_longblob']->toArray()) |
||||||
350 | ); |
||||||
351 | } |
||||||
352 | |||||||
353 | /** |
||||||
354 | * @group DBAL-423 |
||||||
355 | */ |
||||||
356 | public function testDiffListGuidTableColumn() : void |
||||||
357 | { |
||||||
358 | $offlineTable = new Table('list_guid_table_column'); |
||||||
359 | $offlineTable->addColumn('col_guid', 'guid'); |
||||||
360 | |||||||
361 | $this->schemaManager->dropAndCreateTable($offlineTable); |
||||||
362 | |||||||
363 | $onlineTable = $this->schemaManager->listTableDetails('list_guid_table_column'); |
||||||
364 | |||||||
365 | $comparator = new Comparator(); |
||||||
366 | |||||||
367 | self::assertNull( |
||||||
368 | $comparator->diffTable($offlineTable, $onlineTable), |
||||||
369 | 'No differences should be detected with the offline vs online schema.' |
||||||
370 | ); |
||||||
371 | } |
||||||
372 | |||||||
373 | /** |
||||||
374 | * @group DBAL-1082 |
||||||
375 | */ |
||||||
376 | public function testListDecimalTypeColumns() : void |
||||||
377 | { |
||||||
378 | $tableName = 'test_list_decimal_columns'; |
||||||
379 | $table = new Table($tableName); |
||||||
380 | |||||||
381 | $table->addColumn('col', 'decimal'); |
||||||
382 | $table->addColumn('col_unsigned', 'decimal', ['unsigned' => true]); |
||||||
383 | |||||||
384 | $this->schemaManager->dropAndCreateTable($table); |
||||||
385 | |||||||
386 | $columns = $this->schemaManager->listTableColumns($tableName); |
||||||
387 | |||||||
388 | self::assertArrayHasKey('col', $columns); |
||||||
389 | self::assertArrayHasKey('col_unsigned', $columns); |
||||||
390 | self::assertFalse($columns['col']->getUnsigned()); |
||||||
391 | self::assertTrue($columns['col_unsigned']->getUnsigned()); |
||||||
392 | } |
||||||
393 | |||||||
394 | /** |
||||||
395 | * @group DBAL-1082 |
||||||
396 | */ |
||||||
397 | public function testListFloatTypeColumns() : void |
||||||
398 | { |
||||||
399 | $tableName = 'test_list_float_columns'; |
||||||
400 | $table = new Table($tableName); |
||||||
401 | |||||||
402 | $table->addColumn('col', 'float'); |
||||||
403 | $table->addColumn('col_unsigned', 'float', ['unsigned' => true]); |
||||||
404 | |||||||
405 | $this->schemaManager->dropAndCreateTable($table); |
||||||
406 | |||||||
407 | $columns = $this->schemaManager->listTableColumns($tableName); |
||||||
408 | |||||||
409 | self::assertArrayHasKey('col', $columns); |
||||||
410 | self::assertArrayHasKey('col_unsigned', $columns); |
||||||
411 | self::assertFalse($columns['col']->getUnsigned()); |
||||||
412 | self::assertTrue($columns['col_unsigned']->getUnsigned()); |
||||||
413 | } |
||||||
414 | |||||||
415 | public function testJsonColumnType() : void |
||||||
416 | { |
||||||
417 | $table = new Table('test_mysql_json'); |
||||||
418 | $table->addColumn('col_json', 'json'); |
||||||
419 | $this->schemaManager->dropAndCreateTable($table); |
||||||
420 | |||||||
421 | $columns = $this->schemaManager->listTableColumns('test_mysql_json'); |
||||||
422 | |||||||
423 | self::assertSame(Types::JSON, $columns['col_json']->getType()->getName()); |
||||||
424 | } |
||||||
425 | |||||||
426 | public function testColumnDefaultCurrentTimestamp() : void |
||||||
427 | { |
||||||
428 | $platform = $this->schemaManager->getDatabasePlatform(); |
||||||
429 | |||||||
430 | $table = new Table('test_column_defaults_current_timestamp'); |
||||||
431 | |||||||
432 | $currentTimeStampSql = $platform->getCurrentTimestampSQL(); |
||||||
433 | |||||||
434 | $table->addColumn('col_datetime', 'datetime', ['notnull' => true, 'default' => $currentTimeStampSql]); |
||||||
435 | $table->addColumn('col_datetime_nullable', 'datetime', ['default' => $currentTimeStampSql]); |
||||||
436 | |||||||
437 | $this->schemaManager->dropAndCreateTable($table); |
||||||
438 | |||||||
439 | $onlineTable = $this->schemaManager->listTableDetails('test_column_defaults_current_timestamp'); |
||||||
440 | self::assertSame($currentTimeStampSql, $onlineTable->getColumn('col_datetime')->getDefault()); |
||||||
441 | self::assertSame($currentTimeStampSql, $onlineTable->getColumn('col_datetime_nullable')->getDefault()); |
||||||
442 | |||||||
443 | $comparator = new Comparator(); |
||||||
444 | |||||||
445 | $diff = $comparator->diffTable($table, $onlineTable); |
||||||
446 | self::assertNull($diff, 'Tables should be identical with column defaults.'); |
||||||
447 | } |
||||||
448 | |||||||
449 | public function testColumnDefaultsAreValid() : void |
||||||
450 | { |
||||||
451 | $table = new Table('test_column_defaults_are_valid'); |
||||||
452 | |||||||
453 | $currentTimeStampSql = $this->schemaManager->getDatabasePlatform()->getCurrentTimestampSQL(); |
||||||
454 | $table->addColumn('col_datetime', 'datetime', ['default' => $currentTimeStampSql]); |
||||||
455 | $table->addColumn('col_datetime_null', 'datetime', ['notnull' => false, 'default' => null]); |
||||||
456 | $table->addColumn('col_int', 'integer', ['default' => 1]); |
||||||
457 | $table->addColumn('col_neg_int', 'integer', ['default' => -1]); |
||||||
458 | $table->addColumn('col_string', 'string', [ |
||||||
459 | 'length' => 1, |
||||||
460 | 'default' => 'A', |
||||||
461 | ]); |
||||||
462 | $table->addColumn('col_decimal', 'decimal', ['scale' => 3, 'precision' => 6, 'default' => -2.3]); |
||||||
463 | $table->addColumn('col_date', 'date', ['default' => '2012-12-12']); |
||||||
464 | |||||||
465 | $this->schemaManager->dropAndCreateTable($table); |
||||||
466 | |||||||
467 | $this->connection->executeUpdate( |
||||||
468 | 'INSERT INTO test_column_defaults_are_valid () VALUES()' |
||||||
469 | ); |
||||||
470 | |||||||
471 | $row = $this->connection->fetchAssoc( |
||||||
472 | 'SELECT *, DATEDIFF(CURRENT_TIMESTAMP(), col_datetime) as diff_seconds FROM test_column_defaults_are_valid' |
||||||
473 | ); |
||||||
474 | |||||||
475 | self::assertInstanceOf(DateTime::class, DateTime::createFromFormat('Y-m-d H:i:s', $row['col_datetime'])); |
||||||
476 | self::assertNull($row['col_datetime_null']); |
||||||
477 | self::assertSame('2012-12-12', $row['col_date']); |
||||||
478 | self::assertSame('A', $row['col_string']); |
||||||
479 | self::assertEquals(1, $row['col_int']); |
||||||
480 | self::assertEquals(-1, $row['col_neg_int']); |
||||||
481 | self::assertEquals('-2.300', $row['col_decimal']); |
||||||
482 | self::assertLessThan(5, $row['diff_seconds']); |
||||||
483 | } |
||||||
484 | |||||||
485 | /** |
||||||
486 | * MariaDB 10.2+ does support CURRENT_TIME and CURRENT_DATE as |
||||||
487 | * column default values for time and date columns. |
||||||
488 | * (Not supported on Mysql as of 5.7.19) |
||||||
489 | * |
||||||
490 | * Note that MariaDB 10.2+, when storing default in information_schema, |
||||||
491 | * silently change CURRENT_TIMESTAMP as 'current_timestamp()', |
||||||
492 | * CURRENT_TIME as 'currtime()' and CURRENT_DATE as 'currdate()'. |
||||||
493 | * This test also ensure proper aliasing to not trigger a table diff. |
||||||
494 | */ |
||||||
495 | public function testColumnDefaultValuesCurrentTimeAndDate() : void |
||||||
496 | { |
||||||
497 | if (! $this->schemaManager->getDatabasePlatform() instanceof MariaDb1027Platform) { |
||||||
498 | $this->markTestSkipped('Only relevant for MariaDb102Platform.'); |
||||||
499 | } |
||||||
500 | |||||||
501 | $platform = $this->schemaManager->getDatabasePlatform(); |
||||||
502 | |||||||
503 | $table = new Table('test_column_defaults_current_time_and_date'); |
||||||
504 | |||||||
505 | $currentTimestampSql = $platform->getCurrentTimestampSQL(); |
||||||
506 | $currentTimeSql = $platform->getCurrentTimeSQL(); |
||||||
507 | $currentDateSql = $platform->getCurrentDateSQL(); |
||||||
508 | |||||||
509 | $table->addColumn('col_datetime', 'datetime', ['default' => $currentTimestampSql]); |
||||||
510 | $table->addColumn('col_date', 'date', ['default' => $currentDateSql]); |
||||||
511 | $table->addColumn('col_time', 'time', ['default' => $currentTimeSql]); |
||||||
512 | |||||||
513 | $this->schemaManager->dropAndCreateTable($table); |
||||||
514 | |||||||
515 | $onlineTable = $this->schemaManager->listTableDetails('test_column_defaults_current_time_and_date'); |
||||||
516 | |||||||
517 | self::assertSame($currentTimestampSql, $onlineTable->getColumn('col_datetime')->getDefault()); |
||||||
518 | self::assertSame($currentDateSql, $onlineTable->getColumn('col_date')->getDefault()); |
||||||
519 | self::assertSame($currentTimeSql, $onlineTable->getColumn('col_time')->getDefault()); |
||||||
520 | |||||||
521 | $comparator = new Comparator(); |
||||||
522 | |||||||
523 | $diff = $comparator->diffTable($table, $onlineTable); |
||||||
524 | self::assertNull($diff, 'Tables should be identical with column defauts time and date.'); |
||||||
525 | } |
||||||
526 | |||||||
527 | public function testEnsureTableOptionsAreReflectedInMetadata() : void |
||||||
528 | { |
||||||
529 | $this->connection->query('DROP TABLE IF EXISTS test_table_metadata'); |
||||||
530 | |||||||
531 | $sql = <<<'SQL' |
||||||
532 | CREATE TABLE test_table_metadata( |
||||||
533 | col1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY |
||||||
534 | ) |
||||||
535 | COLLATE utf8_general_ci |
||||||
536 | ENGINE InnoDB |
||||||
537 | ROW_FORMAT COMPRESSED |
||||||
538 | COMMENT 'This is a test' |
||||||
539 | AUTO_INCREMENT=42 |
||||||
540 | PARTITION BY HASH (col1) |
||||||
541 | SQL; |
||||||
542 | |||||||
543 | $this->connection->query($sql); |
||||||
544 | $onlineTable = $this->schemaManager->listTableDetails('test_table_metadata'); |
||||||
545 | |||||||
546 | self::assertEquals('InnoDB', $onlineTable->getOption('engine')); |
||||||
547 | self::assertEquals('utf8_general_ci', $onlineTable->getOption('collation')); |
||||||
548 | self::assertEquals(42, $onlineTable->getOption('autoincrement')); |
||||||
549 | self::assertEquals('This is a test', $onlineTable->getOption('comment')); |
||||||
550 | self::assertEquals([ |
||||||
551 | 'row_format' => 'COMPRESSED', |
||||||
552 | 'partitioned' => true, |
||||||
553 | ], $onlineTable->getOption('create_options')); |
||||||
554 | } |
||||||
555 | |||||||
556 | public function testEnsureTableWithoutOptionsAreReflectedInMetadata() : void |
||||||
557 | { |
||||||
558 | $this->connection->query('DROP TABLE IF EXISTS test_table_empty_metadata'); |
||||||
559 | |||||||
560 | $this->connection->query('CREATE TABLE test_table_empty_metadata(col1 INT NOT NULL)'); |
||||||
561 | $onlineTable = $this->schemaManager->listTableDetails('test_table_empty_metadata'); |
||||||
562 | |||||||
563 | self::assertNotEmpty($onlineTable->getOption('engine')); |
||||||
564 | // collation could be set to default or not set, information_schema indicate a possibly null value |
||||||
565 | self::assertFalse($onlineTable->hasOption('autoincrement')); |
||||||
566 | self::assertEquals('', $onlineTable->getOption('comment')); |
||||||
567 | self::assertEquals([], $onlineTable->getOption('create_options')); |
||||||
568 | } |
||||||
569 | |||||||
570 | public function testParseNullCreateOptions() : void |
||||||
571 | { |
||||||
572 | $table = $this->schemaManager->listTableDetails('sys.processlist'); |
||||||
573 | |||||||
574 | self::assertEquals([], $table->getOption('create_options')); |
||||||
575 | } |
||||||
576 | |||||||
577 | public function testListTableColumnsThrowsDatabaseRequired() : void |
||||||
578 | { |
||||||
579 | $params = TestUtil::getConnectionParams(); |
||||||
580 | unset($params['dbname']); |
||||||
581 | |||||||
582 | $connection = DriverManager::getConnection($params); |
||||||
583 | $schemaManager = $connection->getSchemaManager(); |
||||||
584 | |||||||
585 | self::expectException(DatabaseRequired::class); |
||||||
0 ignored issues
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||||||
586 | self::expectExceptionMessage('A database is required for the method: Doctrine\DBAL\Schema\AbstractSchemaManager::listTableColumns'); |
||||||
0 ignored issues
–
show
The method
PHPUnit\Framework\TestCa...xpectExceptionMessage() is not static, but was called statically.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
587 | |||||||
588 | $schemaManager->listTableColumns('users'); |
||||||
589 | } |
||||||
590 | } |
||||||
591 |