-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Port dump command to new migrations backend
Add test coverage based on what we had before.
- Loading branch information
Showing
9 changed files
with
241 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
/** | ||
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) | ||
* | ||
* Licensed under The MIT License | ||
* Redistributions of files must retain the above copyright notice. | ||
* | ||
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) | ||
* @link https://cakephp.org CakePHP(tm) Project | ||
* @license https://www.opensource.org/licenses/mit-license.php MIT License | ||
*/ | ||
namespace Migrations\Command; | ||
|
||
use Cake\Command\Command; | ||
use Cake\Console\Arguments; | ||
use Cake\Console\ConsoleIo; | ||
use Cake\Console\ConsoleOptionParser; | ||
use Cake\Database\Connection; | ||
use Cake\Datasource\ConnectionManager; | ||
use Migrations\Config\ConfigInterface; | ||
use Migrations\Migration\ManagerFactory; | ||
use Migrations\TableFinderTrait; | ||
|
||
/** | ||
* Dump command class. | ||
* A "dump" is a snapshot of a database at a given point in time. It is stored in a | ||
* .lock file in the same folder as migrations files. | ||
*/ | ||
class DumpCommand extends Command | ||
{ | ||
use TableFinderTrait; | ||
|
||
protected string $connection; | ||
|
||
/** | ||
* The default name added to the application command list | ||
* | ||
* @return string | ||
*/ | ||
public static function defaultName(): string | ||
{ | ||
return 'migrations dump'; | ||
} | ||
|
||
/** | ||
* Configure the option parser | ||
* | ||
* @param \Cake\Console\ConsoleOptionParser $parser The option parser to configure | ||
* @return \Cake\Console\ConsoleOptionParser | ||
*/ | ||
public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser | ||
{ | ||
$parser->setDescription([ | ||
'Dumps the current scheam of the database to be used while baking a diff', | ||
'', | ||
'<info>migrations dump -c secondary</info>', | ||
])->addOption('plugin', [ | ||
'short' => 'p', | ||
'help' => 'The plugin to dump migrations for', | ||
])->addOption('connection', [ | ||
'short' => 'c', | ||
'help' => 'The datasource connection to use', | ||
'default' => 'default', | ||
])->addOption('source', [ | ||
'short' => 's', | ||
'help' => 'The folder under src/Config that migrations are in', | ||
'default' => ConfigInterface::DEFAULT_MIGRATION_FOLDER, | ||
]); | ||
|
||
return $parser; | ||
} | ||
|
||
/** | ||
* Execute the command. | ||
* | ||
* @param \Cake\Console\Arguments $args The command arguments. | ||
* @param \Cake\Console\ConsoleIo $io The console io | ||
* @return int|null The exit code or null for success | ||
*/ | ||
public function execute(Arguments $args, ConsoleIo $io): ?int | ||
{ | ||
$factory = new ManagerFactory([ | ||
'plugin' => $args->getOption('plugin'), | ||
'source' => $args->getOption('source'), | ||
'connection' => $args->getOption('connection'), | ||
]); | ||
$config = $factory->createConfig(); | ||
$path = $config->getMigrationPaths()[0]; | ||
$connectionName = (string)$config->getConnection(); | ||
$connection = ConnectionManager::get($connectionName); | ||
assert($connection instanceof Connection); | ||
|
||
$collection = $connection->getSchemaCollection(); | ||
$options = [ | ||
'require-table' => false, | ||
'plugin' => $args->getOption('plugin'), | ||
]; | ||
// The connection property is used by the trait methods. | ||
$this->connection = $connectionName; | ||
$tables = $this->getTablesToBake($collection, $options); | ||
|
||
$dump = []; | ||
if ($tables) { | ||
foreach ($tables as $table) { | ||
$schema = $collection->describe($table); | ||
$dump[$table] = $schema; | ||
} | ||
} | ||
|
||
$filePath = $path . DS . 'schema-dump-' . $connectionName . '.lock'; | ||
$io->out("<info>Writing dump file `{$filePath}`...</info>"); | ||
if (file_put_contents($filePath, serialize($dump))) { | ||
$io->out("<info>Dump file `{$filePath}` was successfully written</info>"); | ||
|
||
return self::CODE_SUCCESS; | ||
} | ||
$io->out("<error>An error occurred while writing dump file `{$filePath}`</error>"); | ||
|
||
return self::CODE_ERROR; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Migrations\Test\TestCase\Command; | ||
|
||
use Cake\Console\TestSuite\ConsoleIntegrationTestTrait; | ||
use Cake\Core\Configure; | ||
use Cake\Core\Exception\MissingPluginException; | ||
use Cake\Core\Plugin; | ||
use Cake\Database\Connection; | ||
use Cake\Database\Schema\TableSchema; | ||
use Cake\Datasource\ConnectionManager; | ||
use Cake\TestSuite\TestCase; | ||
use RuntimeException; | ||
|
||
class DumpCommandTest extends TestCase | ||
{ | ||
use ConsoleIntegrationTestTrait; | ||
|
||
protected Connection $connection; | ||
protected string $_compareBasePath; | ||
protected string $dumpFile; | ||
|
||
public function setUp(): void | ||
{ | ||
parent::setUp(); | ||
Configure::write('Migrations.backend', 'builtin'); | ||
|
||
/** @var \Cake\Database\Connection $this->connection */ | ||
$this->connection = ConnectionManager::get('test'); | ||
$this->connection->execute('DROP TABLE IF EXISTS numbers'); | ||
$this->connection->execute('DROP TABLE IF EXISTS letters'); | ||
$this->connection->execute('DROP TABLE IF EXISTS parts'); | ||
$this->connection->execute('DROP TABLE IF EXISTS phinxlog'); | ||
|
||
$this->dumpFile = ROOT . DS . 'config/TestsMigrations/schema-dump-test.lock'; | ||
} | ||
|
||
public function tearDown(): void | ||
{ | ||
parent::tearDown(); | ||
|
||
$this->connection->execute('DROP TABLE IF EXISTS numbers'); | ||
$this->connection->execute('DROP TABLE IF EXISTS letters'); | ||
$this->connection->execute('DROP TABLE IF EXISTS parts'); | ||
$this->connection->execute('DROP TABLE IF EXISTS phinxlog'); | ||
if (file_exists($this->dumpFile)) { | ||
unlink($this->dumpFile); | ||
} | ||
} | ||
|
||
public function testExecuteIncorrectConnection(): void | ||
{ | ||
$this->expectException(RuntimeException::class); | ||
$this->exec('migrations dump --connection lolnope'); | ||
} | ||
|
||
public function testExecuteIncorrectPlugin(): void | ||
{ | ||
$this->expectException(MissingPluginException::class); | ||
$this->exec('migrations dump --plugin lolnope'); | ||
} | ||
|
||
public function testExecuteSuccess(): void | ||
{ | ||
// Run migrations | ||
$this->exec('migrations migrate --connection test --source TestsMigrations --no-lock'); | ||
$this->assertExitSuccess(); | ||
|
||
// Generate dump file. | ||
$this->exec('migrations dump --connection test --source TestsMigrations'); | ||
|
||
$this->assertExitSuccess(); | ||
$this->assertOutputContains('config/TestsMigrations/schema-dump-test.lock'); | ||
|
||
$this->assertFileExists($this->dumpFile); | ||
/** @var array<string, TableSchema> $generatedDump */ | ||
$generatedDump = unserialize(file_get_contents($this->dumpFile)); | ||
|
||
$this->assertArrayHasKey('letters', $generatedDump); | ||
$this->assertArrayHasKey('numbers', $generatedDump); | ||
$this->assertInstanceOf(TableSchema::class, $generatedDump['numbers']); | ||
$this->assertInstanceOf(TableSchema::class, $generatedDump['letters']); | ||
$this->assertEquals(['id', 'number', 'radix'], $generatedDump['numbers']->columns()); | ||
$this->assertEquals(['id', 'letter'], $generatedDump['letters']->columns()); | ||
} | ||
|
||
public function testExecutePlugin(): void | ||
{ | ||
$this->loadPlugins(['Migrator']); | ||
|
||
$this->exec('migrations dump --connection test --plugin Migrator'); | ||
|
||
$this->assertExitSuccess(); | ||
$this->assertOutputContains('Migrator/config/Migrations/schema-dump-test.lock'); | ||
|
||
$dumpFile = Plugin::path('Migrator') . '/config/Migrations/schema-dump-test.lock'; | ||
if (file_exists($dumpFile)) { | ||
unlink($dumpFile); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters