1818use Cake \Core \Configure ;
1919use Cake \Core \Plugin ;
2020use Cake \Database \Driver \Mysql ;
21+ use Cake \Database \Driver \Postgres ;
22+ use Cake \Database \Driver \Sqlite ;
23+ use Cake \Database \Driver \Sqlserver ;
2124use Cake \Datasource \ConnectionManager ;
2225use Cake \TestSuite \StringCompareTrait ;
2326use Cake \Utility \Inflector ;
27+ use Exception ;
2428use Migrations \Migrations ;
2529use Migrations \Test \TestCase \TestCase ;
2630use function Cake \Core \env ;
@@ -47,6 +51,36 @@ public function setUp(): void
4751 parent ::setUp ();
4852
4953 $ this ->generatedFiles = [];
54+
55+ // Clean up any TheDiff migration files from all directories before test starts
56+ $ configPath = ROOT . DS . 'config ' . DS ;
57+ $ directories = glob ($ configPath . '* ' , GLOB_ONLYDIR ) ?: [];
58+ foreach ($ directories as $ dir ) {
59+ // Clean up TheDiff migration files
60+ $ migrationFiles = glob ($ dir . DS . '*TheDiff*.php ' ) ?: [];
61+ foreach ($ migrationFiles as $ file ) {
62+ if (file_exists ($ file )) {
63+ unlink ($ file );
64+ }
65+ }
66+ // Clean up Initial migration files
67+ $ initialMigrationFiles = glob ($ dir . DS . '*Initial*.php ' ) ?: [];
68+ foreach ($ initialMigrationFiles as $ file ) {
69+ if (file_exists ($ file )) {
70+ unlink ($ file );
71+ }
72+ }
73+ }
74+
75+ // Clean up test_decimal_types table if it exists
76+ if (env ('DB_URL_COMPARE ' )) {
77+ try {
78+ $ connection = ConnectionManager::get ('test_comparisons ' );
79+ $ connection ->execute ('DROP TABLE IF EXISTS test_decimal_types ' );
80+ } catch (Exception $ e ) {
81+ // Ignore errors if connection doesn't exist yet
82+ }
83+ }
5084 }
5185
5286 public function tearDown (): void
@@ -57,10 +91,29 @@ public function tearDown(): void
5791 unlink ($ file );
5892 }
5993 }
94+
95+ // Clean up any TheDiff migration files from all directories
96+ $ configPath = ROOT . DS . 'config ' . DS ;
97+ $ directories = glob ($ configPath . '* ' , GLOB_ONLYDIR ) ?: [];
98+ foreach ($ directories as $ dir ) {
99+ $ migrationFiles = glob ($ dir . DS . '*TheDiff*.php ' ) ?: [];
100+ foreach ($ migrationFiles as $ file ) {
101+ if (file_exists ($ file )) {
102+ unlink ($ file );
103+ }
104+ }
105+ $ initialMigrationFiles = glob ($ dir . DS . '*Initial*.php ' ) ?: [];
106+ foreach ($ initialMigrationFiles as $ file ) {
107+ if (file_exists ($ file )) {
108+ unlink ($ file );
109+ }
110+ }
111+ }
112+
60113 if (env ('DB_URL_COMPARE ' )) {
61114 // Clean up the comparison database each time. Table order is important.
62115 $ connection = ConnectionManager::get ('test_comparisons ' );
63- $ tables = ['articles ' , 'categories ' , 'comments ' , 'users ' , 'orphan_table ' , 'phinxlog ' , 'tags ' , 'test_blog_phinxlog ' ];
116+ $ tables = ['articles ' , 'categories ' , 'comments ' , 'users ' , 'orphan_table ' , 'phinxlog ' , 'tags ' , 'test_blog_phinxlog ' , ' test_decimal_types ' ];
64117 foreach ($ tables as $ table ) {
65118 $ connection ->execute ("DROP TABLE IF EXISTS $ table " );
66119 }
@@ -240,6 +293,17 @@ public function testBakingDiffWithAutoIdIncompatibleUnsignedPrimaryKeys(): void
240293 $ this ->runDiffBakingTest ('WithAutoIdIncompatibleUnsignedPrimaryKeys ' );
241294 }
242295
296+ /**
297+ * Tests baking a diff with decimal column changes
298+ * Regression test for issue #659
299+ */
300+ public function testBakingDiffDecimalChange (): void
301+ {
302+ $ this ->skipIf (!env ('DB_URL_COMPARE ' ));
303+
304+ $ this ->runDiffBakingTest ('DecimalChange ' );
305+ }
306+
243307 /**
244308 * Tests that baking a diff with --plugin option only includes tables with Table classes
245309 */
@@ -330,13 +394,21 @@ protected function runDiffBakingTest(string $scenario): void
330394 {
331395 $ this ->skipIf (!env ('DB_URL_COMPARE ' ));
332396
397+ // Detect database type from connection if DB env is not set
398+ $ db = env ('DB ' ) ?: $ this ->getDbType ();
399+
333400 $ diffConfigFolder = Plugin::path ('Migrations ' ) . 'tests ' . DS . 'comparisons ' . DS . 'Diff ' . DS . lcfirst ($ scenario ) . DS ;
334- $ diffMigrationsPath = $ diffConfigFolder . 'the_diff_ ' . Inflector::underscore ($ scenario ) . '_ ' . env ('DB ' ) . '.php ' ;
335- $ diffDumpPath = $ diffConfigFolder . 'schema-dump-test_comparisons_ ' . env ('DB ' ) . '.lock ' ;
401+
402+ // DecimalChange uses 'initial_' prefix to avoid class name conflicts
403+ $ prefix = $ scenario === 'DecimalChange ' ? 'initial_ ' : 'the_diff_ ' ;
404+ $ classPrefix = $ scenario === 'DecimalChange ' ? 'Initial ' : 'TheDiff ' ;
405+
406+ $ diffMigrationsPath = $ diffConfigFolder . $ prefix . Inflector::underscore ($ scenario ) . '_ ' . $ db . '.php ' ;
407+ $ diffDumpPath = $ diffConfigFolder . 'schema-dump-test_comparisons_ ' . $ db . '.lock ' ;
336408
337409 $ destinationConfigDir = ROOT . DS . 'config ' . DS . "MigrationsDiff {$ scenario }" . DS ;
338- $ destination = $ destinationConfigDir . "20160415220805_TheDiff { $ scenario }" . ucfirst (env ( ' DB ' ) ) . '.php ' ;
339- $ destinationDumpPath = $ destinationConfigDir . 'schema-dump-test_comparisons_ ' . env ( ' DB ' ) . '.lock ' ;
410+ $ destination = $ destinationConfigDir . "20160415220805_ { $ classPrefix }{ $ scenario }" . ucfirst ($ db ) . '.php ' ;
411+ $ destinationDumpPath = $ destinationConfigDir . 'schema-dump-test_comparisons_ ' . $ db . '.lock ' ;
340412 copy ($ diffMigrationsPath , $ destination );
341413
342414 $ this ->generatedFiles = [
@@ -387,6 +459,29 @@ protected function runDiffBakingTest(string $scenario): void
387459 $ this ->getMigrations ("MigrationsDiff {$ scenario }" )->rollback (['target ' => 'all ' ]);
388460 }
389461
462+ /**
463+ * Detect database type from connection
464+ *
465+ * @return string Database type (mysql, pgsql, sqlite, sqlserver)
466+ */
467+ protected function getDbType (): string
468+ {
469+ $ connection = ConnectionManager::get ('test_comparisons ' );
470+ $ driver = $ connection ->getDriver ();
471+
472+ if ($ driver instanceof Mysql) {
473+ return 'mysql ' ;
474+ } elseif ($ driver instanceof Postgres) {
475+ return 'pgsql ' ;
476+ } elseif ($ driver instanceof Sqlite) {
477+ return 'sqlite ' ;
478+ } elseif ($ driver instanceof Sqlserver) {
479+ return 'sqlserver ' ;
480+ }
481+
482+ return 'mysql ' ; // Default fallback
483+ }
484+
390485 /**
391486 * Get the baked filename based on the current db environment
392487 *
@@ -395,7 +490,11 @@ protected function runDiffBakingTest(string $scenario): void
395490 */
396491 public function getBakeName ($ name )
397492 {
398- $ name .= ucfirst (getenv ('DB ' ));
493+ $ db = getenv ('DB ' );
494+ if (!$ db ) {
495+ $ db = $ this ->getDbType ();
496+ }
497+ $ name .= ucfirst ($ db );
399498
400499 return $ name ;
401500 }
@@ -428,6 +527,9 @@ protected function getMigrations($source = 'MigrationsDiff')
428527 public function assertCorrectSnapshot ($ bakeName , $ result )
429528 {
430529 $ dbenv = getenv ('DB ' );
530+ if (!$ dbenv ) {
531+ $ dbenv = $ this ->getDbType ();
532+ }
431533 $ bakeName = Inflector::underscore ($ bakeName );
432534 if (file_exists ($ this ->_compareBasePath . $ dbenv . DS . $ bakeName . '.php ' )) {
433535 $ this ->assertSameAsFile ($ dbenv . DS . $ bakeName . '.php ' , $ result );
0 commit comments