Skip to content

Commit 7359c99

Browse files
committed
Fix up decimal migration_diff
1 parent 6469345 commit 7359c99

File tree

5 files changed

+139
-3
lines changed

5 files changed

+139
-3
lines changed

src/Command/BakeMigrationDiffCommand.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,38 @@ protected function getColumns(): void
300300
}
301301
}
302302

303-
if (isset($changedAttributes['length'])) {
303+
// For decimal columns, handle CakePHP schema -> migration attribute mapping
304+
if ($column['type'] === 'decimal') {
305+
// In CakePHP schema: 'length' = precision, 'precision' = scale
306+
// In migrations: 'precision' = precision, 'scale' = scale
307+
308+
// Convert CakePHP schema's 'precision' (which is scale) to migration's 'scale'
309+
if (isset($changedAttributes['precision'])) {
310+
$changedAttributes['scale'] = $changedAttributes['precision'];
311+
unset($changedAttributes['precision']);
312+
}
313+
314+
// Convert CakePHP schema's 'length' (which is precision) to migration's 'precision'
315+
if (isset($changedAttributes['length'])) {
316+
$changedAttributes['precision'] = $changedAttributes['length'];
317+
unset($changedAttributes['length']);
318+
}
319+
320+
// Ensure both precision and scale are always set for decimal columns
321+
if (!isset($changedAttributes['precision']) && isset($column['length'])) {
322+
$changedAttributes['precision'] = $column['length'];
323+
}
324+
if (!isset($changedAttributes['scale']) && isset($column['precision'])) {
325+
$changedAttributes['scale'] = $column['precision'];
326+
}
327+
328+
// Remove 'limit' for decimal columns as they use precision/scale instead
329+
unset($changedAttributes['limit']);
330+
} elseif (isset($changedAttributes['length'])) {
331+
// For non-decimal columns, convert 'length' to 'limit'
304332
if (!isset($changedAttributes['limit'])) {
305333
$changedAttributes['limit'] = $changedAttributes['length'];
306334
}
307-
308335
unset($changedAttributes['length']);
309336
}
310337

tests/TestCase/Command/BakeMigrationDiffCommandTest.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,19 @@ public function tearDown(): void
5757
unlink($file);
5858
}
5959
}
60+
61+
$defaultMigrationsPath = ROOT . DS . 'config' . DS . 'Migrations' . DS;
62+
$migrationFiles = glob($defaultMigrationsPath . '*TheDiff*.php') ?: [];
63+
foreach ($migrationFiles as $file) {
64+
if (file_exists($file)) {
65+
unlink($file);
66+
}
67+
}
68+
6069
if (env('DB_URL_COMPARE')) {
6170
// Clean up the comparison database each time. Table order is important.
6271
$connection = ConnectionManager::get('test_comparisons');
63-
$tables = ['articles', 'categories', 'comments', 'users', 'orphan_table', 'phinxlog', 'tags', 'test_blog_phinxlog'];
72+
$tables = ['articles', 'categories', 'comments', 'users', 'orphan_table', 'phinxlog', 'tags', 'test_blog_phinxlog', 'test_decimal_types'];
6473
foreach ($tables as $table) {
6574
$connection->execute("DROP TABLE IF EXISTS $table");
6675
}
@@ -240,6 +249,17 @@ public function testBakingDiffWithAutoIdIncompatibleUnsignedPrimaryKeys(): void
240249
$this->runDiffBakingTest('WithAutoIdIncompatibleUnsignedPrimaryKeys');
241250
}
242251

252+
/**
253+
* Tests baking a diff with decimal column changes
254+
* Regression test for issue #659
255+
*/
256+
public function testBakingDiffDecimalChange(): void
257+
{
258+
$this->skipIf(!env('DB_URL_COMPARE'));
259+
260+
$this->runDiffBakingTest('DecimalChange');
261+
}
262+
243263
/**
244264
* Tests that baking a diff with --plugin option only includes tables with Table classes
245265
*/
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
use Migrations\BaseMigration;
5+
6+
class TheDiffDecimalChange extends BaseMigration
7+
{
8+
/**
9+
* Up Method.
10+
*
11+
* More information on this method is available here:
12+
* https://book.cakephp.org/migrations/5/en/migrations.html#the-up-method
13+
*
14+
* @return void
15+
*/
16+
public function up(): void
17+
{
18+
$this->table('test_decimal_types')
19+
->changeColumn('amount', 'decimal', [
20+
'default' => null,
21+
'null' => false,
22+
'precision' => 10,
23+
'scale' => 2,
24+
'signed' => true,
25+
])
26+
->update();
27+
}
28+
29+
/**
30+
* Down Method.
31+
*
32+
* More information on this method is available here:
33+
* https://book.cakephp.org/migrations/5/en/migrations.html#the-down-method
34+
*
35+
* @return void
36+
*/
37+
public function down(): void
38+
{
39+
$this->table('test_decimal_types')
40+
->changeColumn('amount', 'decimal', [
41+
'default' => null,
42+
'null' => false,
43+
'precision' => 5,
44+
'scale' => 2,
45+
'signed' => true,
46+
])
47+
->update();
48+
}
49+
}
Binary file not shown.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
use Migrations\BaseMigration;
5+
6+
class TheDiffDecimalChangeMysql extends BaseMigration
7+
{
8+
/**
9+
* Up Method.
10+
*
11+
* More information on this method is available here:
12+
* https://book.cakephp.org/migrations/5/en/migrations.html#the-up-method
13+
*
14+
* @return void
15+
*/
16+
public function up(): void
17+
{
18+
$this->table('test_decimal_types')
19+
->addColumn('amount', 'decimal', [
20+
'default' => null,
21+
'null' => false,
22+
'precision' => 5,
23+
'scale' => 2,
24+
])
25+
->create();
26+
}
27+
28+
/**
29+
* Down Method.
30+
*
31+
* More information on this method is available here:
32+
* https://book.cakephp.org/migrations/5/en/migrations.html#the-down-method
33+
*
34+
* @return void
35+
*/
36+
public function down(): void
37+
{
38+
$this->table('test_decimal_types')->drop()->save();
39+
}
40+
}

0 commit comments

Comments
 (0)