diff --git a/Migrate/Command/AbstractEnvCommand.php b/Migrate/Command/AbstractEnvCommand.php index 4ac7f42..d7ed7c1 100644 --- a/Migrate/Command/AbstractEnvCommand.php +++ b/Migrate/Command/AbstractEnvCommand.php @@ -69,7 +69,6 @@ protected function init(InputInterface $input, OutputInterface $output, $env = n $parser = $configLocator->locate($env); $conf = $parser->parse(); - $this->config = $conf; $driver = ArrayUtil::get($conf['connection'], 'driver'); @@ -79,9 +78,16 @@ protected function init(InputInterface $input, OutputInterface $output, $env = n $username = ArrayUtil::get($conf['connection'], 'username'); $password = ArrayUtil::get($conf['connection'], 'password'); $charset = ArrayUtil::get($conf['connection'], 'charset'); - + if (empty($host)) { + $host = "localhost"; + } + if (empty($dbname)) { + $dbname = $input->getOption('database'); + } + if (empty($driver)) { + $dbname = $input->getOption('driver'); + } $uri = $driver; - if ($driver == 'sqlite') { $uri .= ":$dbname"; } else { @@ -110,8 +116,10 @@ public function getLocalMigrations() $migrations = array(); foreach ($fileList as $file) { - $migration = Migration::createFromFile($file, $this->getMigrationDir()); - $migrations[$migration->getId()] = $migration; + if (substr($file, -4) == ".sql") { // Skip backup files, etc. + $migration = Migration::createFromFile($file, $this->getMigrationDir()); + $migrations[$migration->getId()] = $migration; + } } ksort($migrations); diff --git a/Migrate/Command/AddEnvCommand.php b/Migrate/Command/AddEnvCommand.php index e158d19..6a7651b 100644 --- a/Migrate/Command/AddEnvCommand.php +++ b/Migrate/Command/AddEnvCommand.php @@ -68,10 +68,11 @@ protected function execute(InputInterface $input, OutputInterface $output) throw new \InvalidArgumentException("environment [$envName] is already defined!"); } - $driverQuestion = new ChoiceQuestion("Please chose your pdo driver", $drivers); + $driverQuestion = new ChoiceQuestion("Please choose your pdo driver", $drivers); $driver = $questions->ask($input, $output, $driverQuestion); - $dbNameQuestion = new Question("Please enter the database name (or the database file location): ", "~"); + $dbNameQuestion = + new Question("Please enter the database name (or the database file location) (if needed): ", "~"); $dbName = $questions->ask($input, $output, $dbNameQuestion); $dbHostQuestion = new Question("Please enter the database host (if needed): ", "~"); diff --git a/Migrate/Command/CreateCommand.php b/Migrate/Command/CreateCommand.php index 458887d..72d560c 100644 --- a/Migrate/Command/CreateCommand.php +++ b/Migrate/Command/CreateCommand.php @@ -31,16 +31,23 @@ protected function execute(InputInterface $input, OutputInterface $output) $descriptionQuestion = new Question("Please enter a description: "); $description = $questions->ask($input, $output, $descriptionQuestion); - - $editorQuestion = new Question("Please chose which editor to use (default vim): ", "vim"); - $questions->ask($input, $output, $editorQuestion); + $editor=getenv("EDITOR"); + if (empty($editor)) { + $editor="vi"; + } + $editorQuestion = new Question("Please chose which editor to use (default $editor): ", "$editor"); + $editor=$questions->ask($input, $output, $editorQuestion); $slugger = new Slugify(); $filename = $slugger->slugify($description); $timestamp = str_pad(str_replace(".", "", microtime(true)), 14, "0"); $filename = $timestamp . '_' . $filename . '.sql'; - $templateFile = file_get_contents(__DIR__ . '/../../templates/migration.tpl'); + if (file_exists($this->getMigrationDir() . '/../' .'migration.tpl')) { + $templateFile = file_get_contents($this->getMigrationDir() . '/../' .'migration.tpl'); + } else { + $templateFile = file_get_contents(__DIR__ . '/../../templates/migration.tpl'); + } $templateFile = str_replace('{DESCRIPTION}', $description, $templateFile); $migrationFullPath = $this->getMigrationDir() . '/' . $filename; @@ -48,7 +55,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln("$migrationFullPath created"); if (!defined('PHPUNIT')) { - system("vim $migrationFullPath > `tty`"); + system("$editor $migrationFullPath > `tty`"); } } } diff --git a/Migrate/Command/DownCommand.php b/Migrate/Command/DownCommand.php index cba4989..fc9b920 100644 --- a/Migrate/Command/DownCommand.php +++ b/Migrate/Command/DownCommand.php @@ -44,6 +44,18 @@ protected function configure() null, InputOption::VALUE_NONE, 'Mark as applied without executing SQL ' + ) + ->addOption( + 'database', + null, + InputOption::VALUE_REQUIRED, + 'Database ' + ) + ->addOption( + 'driver', + null, + InputOption::VALUE_REQUIRED, + 'DB driver' ); } diff --git a/Migrate/Command/InitCommand.php b/Migrate/Command/InitCommand.php index 43d1201..35e0400 100644 --- a/Migrate/Command/InitCommand.php +++ b/Migrate/Command/InitCommand.php @@ -8,6 +8,7 @@ namespace Migrate\Command; use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -23,6 +24,16 @@ protected function configure() 'env', InputArgument::REQUIRED, 'Environment' + )->addOption( + 'database', + null, + InputOption::VALUE_REQUIRED, + 'Database ' + )->addOption( + 'driver', + null, + InputOption::VALUE_REQUIRED, + 'DB driver' ); } diff --git a/Migrate/Command/StatusCommand.php b/Migrate/Command/StatusCommand.php index 8492d82..720ac5f 100644 --- a/Migrate/Command/StatusCommand.php +++ b/Migrate/Command/StatusCommand.php @@ -10,6 +10,7 @@ use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -25,6 +26,16 @@ protected function configure() 'env', InputArgument::REQUIRED, 'Environment' + )->addOption( + 'database', + null, + InputOption::VALUE_REQUIRED, + 'Database ' + )->addOption( + 'driver', + null, + InputOption::VALUE_REQUIRED, + 'DB driver' ); } diff --git a/Migrate/Command/UpCommand.php b/Migrate/Command/UpCommand.php index 24f2ec9..2e6cad0 100644 --- a/Migrate/Command/UpCommand.php +++ b/Migrate/Command/UpCommand.php @@ -37,12 +37,21 @@ protected function configure() null, InputOption::VALUE_REQUIRED, 'If you need to up this migration id only' - ) - ->addOption( + )->addOption( 'changelog-only', null, InputOption::VALUE_NONE, 'Mark as applied without executing SQL ' + )->addOption( + 'database', + null, + InputOption::VALUE_REQUIRED, + 'Database ' + )->addOption( + 'driver', + null, + InputOption::VALUE_REQUIRED, + 'DB driver' ); } diff --git a/Migrate/Migration.php b/Migrate/Migration.php index 1efeef3..5f3bfed 100644 --- a/Migrate/Migration.php +++ b/Migrate/Migration.php @@ -159,7 +159,6 @@ public static function createFromRow(array $data, $migrationDir) $slugger = new Slugify(); $filename = $migration->getId() . '_' . $slugger->slugify($migration->getDescription()) . '.sql'; $migration->setFile($filename); - $migration->load($migrationDir); return $migration; @@ -177,11 +176,14 @@ public function toArray() public function load($migrationDir) { - $content = file_get_contents($migrationDir . '/' . $this->getFile()); - if ($content && strpos($content, '@UNDO') > 0) { - $sql = explode('-- @UNDO', $content); - $this->setSqlUp($sql[0]); - $this->setSqlDown($sql[1]); + $filePath=$migrationDir . '/' . $this->getFile(); + if (file_exists($filePath)) { + $content = file_get_contents($filePath); + if ($content && strpos($content, '@UNDO') > 0) { + $sql = explode('-- @UNDO', $content); + $this->setSqlUp($sql[0]); + $this->setSqlDown($sql[1]); + } } } } diff --git a/README.md b/README.md index ec51786..7eba200 100644 --- a/README.md +++ b/README.md @@ -72,8 +72,12 @@ The first thing to do before playing with SQL migrations is to add an environmen $ ./bin/migrate migrate:addenv ``` -You will be prompted to answer a series of questions about your environment, and then a config file will be saved -in `./.php-database-migration/environments/[env].yml`. +You will be prompted to answer a series of questions about your +environment, and then a config file will be saved in +`./.php-database-migration/environments/[env].yml`. You can skip all +questions except the database driver. But if you do not enter a database name, +then you have to suppy it as an option in the following commands ( +--database=foo ). This is useful for e.g. testing scripts that create and copy databases on the fly. Initialization -------------- @@ -81,7 +85,7 @@ Once the environment is added, you have to initialize it. This verifies that the creates a new database table for tracking the current database changes: ``` -$ ./bin/migrate migrate:init [env] +$ ./bin/migrate migrate:init env ``` Create a migration diff --git a/tests/Command/AbstractCommandTester.php b/tests/Command/AbstractCommandTester.php index 67de6c2..be0a52f 100644 --- a/tests/Command/AbstractCommandTester.php +++ b/tests/Command/AbstractCommandTester.php @@ -48,7 +48,9 @@ public function createEnv($format = 'yml') /* @var $question QuestionHelper */ $question = $command->getHelper('question'); $question->setInputStream(InputStreamUtil::type("testing\n$driverKey\ntest.sqlite\n\n\n\n\n\nchangelog\nvim\n")); - + $commandTester->execute(array('command' => $command->getName(), 'format' => $format)); + $question = $command->getHelper('question'); + $question->setInputStream(InputStreamUtil::type("minimal\nsqlite\n\n\n\n\n\n\nchangelog\n\n")); $commandTester->execute(array('command' => $command->getName(), 'format' => $format)); } @@ -64,6 +66,12 @@ public function initEnv() 'command' => $command->getName(), 'env' => 'testing' )); + $commandTester->execute(array( + 'command' => $command->getName(), + 'env' => 'minimal', + '--database' => 'migrate_test', + '--driver' => 'sqlite' + )); } public function createMigration($timestamp, $sqlUp, $sqlDown) @@ -83,4 +91,4 @@ public function createMigration($timestamp, $sqlUp, $sqlDown) file_put_contents($filename, $content); } -} \ No newline at end of file +} diff --git a/tests/Command/AddenvCommandTest.php b/tests/Command/AddenvCommandTest.php index e603f41..1a093d4 100644 --- a/tests/Command/AddenvCommandTest.php +++ b/tests/Command/AddenvCommandTest.php @@ -36,20 +36,20 @@ public function testExecute() $pdoDrivers = pdo_drivers(); $driverKey = array_search('sqlite', $pdoDrivers); - + if (empty($driverKey)) { + echo "install sqlite php driver (php-sqlite3)\n"; + exit(-1); + } $driverSelect = ''; foreach ($pdoDrivers as $key => $driver) { $driverSelect .= " [$key] $driver\n"; } - /* @var $question QuestionHelper */ $question = $command->getHelper('question'); $question->setInputStream(InputStreamUtil::type("testing\n$driverKey\nmigrate_test\nlocalhost\n5432\naguidet\naguidet\nutf8\nchangelog\nvim\n")); $commandTester->execute(array('command' => $command->getName())); - $expected = "Please enter the name of the new environment (default dev): Please chose your pdo driver\n$driverSelect > 0\nPlease enter the database name (or the database file location): Please enter the database host (if needed): Please enter the database port (if needed): Please enter the database user name (if needed): Please enter the database user password (if needed): Please enter the changelog table (default changelog): Please enter the text editor to use by default (default vim): "; - $this->assertRegExp('/Please enter the name of the new environment/', $commandTester->getDisplay()); $envDir = Directory::getEnvPath(); diff --git a/tests/Command/OptionTest.php b/tests/Command/OptionTest.php new file mode 100644 index 0000000..ae90987 --- /dev/null +++ b/tests/Command/OptionTest.php @@ -0,0 +1,99 @@ +cleanEnv(); + $this->createEnv(); + $this->initEnv(); + + $this->createMigration('0', "CREATE TABLE test (id INTEGER, thevalue TEXT);", "DROP TABLE test;"); + $this->createMigration('1', "SELECT 1", "DELETE FROM test WHERE id = 1;"); + $this->createMigration('2', "INSERT INTO test VALUES (2, 'two');", "DELETE FROM test WHERE id = 2;"); + + self::$application = new Application(); + self::$application->add(new UpCommand()); + self::$application->add(new DownCommand()); + self::$application->add(new StatusCommand()); + } + + public function tearDown() + { + $this->cleanEnv(); + } + + public function testUpAllPendingMigrationsInMinimal() + { + $command = self::$application->find('migrate:up'); + $commandTester = new CommandTester($command); + $commandTester->execute(array( + 'command' => $command->getName(), + 'env' => 'minimal', + '--database' => 'migrate_test', + '--driver' => 'sqlite' + )); + + $expected =<<---------------------------] 0 % [] +1/3 [=========>------------------] 33 % [migration] +2/3 [==================>---------] 66 % [migration] +3/3 [============================] 100 % [migration] + +EXPECTED; + + $this->assertEquals($expected, $commandTester->getDisplay()); + } + + + + public function testDownLastMigrationInMinimal() + { + + $command = self::$application->find('migrate:down'); + $commandTester = new CommandTester($command); + + /* @var $question QuestionHelper */ + $question = $command->getHelper('question'); + $question->setInputStream(InputStreamUtil::type("yes\n")); + + $commandTester->execute(array( + 'command' => $command->getName(), + 'env' => 'testing', + '--database' => 'migrate_test', + '--driver' => 'sqlite' + )); + + $expected =<<assertEquals($expected, $commandTester->getDisplay()); + } + + + + +} diff --git a/tests/Command/UpDownCommandTest.php b/tests/Command/UpDownCommandTest.php index 7fd7d60..2f65322 100644 --- a/tests/Command/UpDownCommandTest.php +++ b/tests/Command/UpDownCommandTest.php @@ -147,6 +147,7 @@ public function testUpOnly() { $command = self::$application->find('migrate:up'); $commandTester = new CommandTester($command); + $currentDate = date('Y-m-d H:i:s'); $commandTester->execute(array( 'command' => $command->getName(), @@ -166,7 +167,6 @@ public function testUpOnly() $command = self::$application->find('migrate:status'); $commandTester = new CommandTester($command); - $currentDate = date('Y-m-d H:i:s'); $commandTester->execute(array( 'command' => $command->getName(), @@ -257,6 +257,7 @@ public function testDownOnly() public function testUpTo() { + $time0 = time(); $command = self::$application->find('migrate:up'); $commandTester = new CommandTester($command); @@ -278,9 +279,7 @@ public function testUpTo() $command = self::$application->find('migrate:status'); $commandTester = new CommandTester($command); - - $currentDate = date('Y-m-d H:i:s'); - + $currentDate = date('Y-m-d H:i:s',$time0); $commandTester->execute(array( 'command' => $command->getName(), 'env' => 'testing' @@ -299,14 +298,17 @@ public function testUpTo() EXPECTED; + $testResult = $commandTester->getDisplay(); + $testResult = str_replace(date('Y-m-d H:i:s',$time0+1),$currentDate,$testResult); + $testResult = str_replace(date('Y-m-d H:i:s',$time0+2),$currentDate,$testResult); $this->assertEquals($expected, $commandTester->getDisplay()); } public function testDownTo() { + $time0=time(); $command = self::$application->find('migrate:up'); $commandTester = new CommandTester($command); - $commandTester->execute(array( 'command' => $command->getName(), 'env' => 'testing', @@ -334,18 +336,14 @@ public function testDownTo() EXPECTED; $this->assertEquals($expected, $commandTester->getDisplay()); - $command = self::$application->find('migrate:status'); $commandTester = new CommandTester($command); - - $currentDate = date('Y-m-d H:i:s'); - + $currentDate = date('Y-m-d H:i:s',$time0); $commandTester->execute(array( 'command' => $command->getName(), 'env' => 'testing' )); - - + $currentDate = date('Y-m-d H:i:s',$time0); $expected =<<assertEquals($expected, $commandTester->getDisplay()); + $testResult = $commandTester->getDisplay(); + $testResult = str_replace(date('Y-m-d H:i:s',$time0+1),$currentDate,$testResult); + $this->assertEquals($expected, $testResult); } /** @@ -412,4 +411,4 @@ public function testDownInANotInitializedDirectory() '--to' => '1' )); } -} \ No newline at end of file +}