1 | <?php |
||
21 | class MigrateCommand extends AbstractCommand |
||
22 | { |
||
23 | 18 | protected function configure() |
|
24 | { |
||
25 | $this |
||
26 | 18 | ->setName('migrations:migrate') |
|
27 | 18 | ->setDescription('Execute a migration to a specified version or the latest available version.') |
|
28 | 18 | ->addArgument('version', InputArgument::OPTIONAL, 'The version number (YYYYMMDDHHMMSS) or alias (first, prev, next, latest) to migrate to.', 'latest') |
|
29 | 18 | ->addOption('write-sql', null, InputOption::VALUE_OPTIONAL, 'The path to output the migration SQL file instead of executing it. Default to current working directory.') |
|
30 | 18 | ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Execute the migration as a dry run.') |
|
31 | 18 | ->addOption('query-time', null, InputOption::VALUE_NONE, 'Time all the queries individually.') |
|
32 | 18 | ->addOption('allow-no-migration', null, InputOption::VALUE_NONE, 'Don\'t throw an exception if no migration is available (CI).') |
|
33 | 18 | ->setHelp(<<<EOT |
|
34 | 18 | The <info>%command.name%</info> command executes a migration to a specified version or the latest available version: |
|
35 | |||
36 | <info>%command.full_name%</info> |
||
37 | |||
38 | You can optionally manually specify the version you wish to migrate to: |
||
39 | |||
40 | <info>%command.full_name% YYYYMMDDHHMMSS</info> |
||
41 | |||
42 | You can specify the version you wish to migrate to using an alias: |
||
43 | |||
44 | <info>%command.full_name% prev</info> |
||
45 | <info>These alias are defined : first, latest, prev, current and next</info> |
||
46 | |||
47 | You can specify the version you wish to migrate to using an number against the current version: |
||
48 | |||
49 | <info>%command.full_name% current+3</info> |
||
50 | |||
51 | You can also execute the migration as a <comment>--dry-run</comment>: |
||
52 | |||
53 | <info>%command.full_name% YYYYMMDDHHMMSS --dry-run</info> |
||
54 | |||
55 | You can output the would be executed SQL statements to a file with <comment>--write-sql</comment>: |
||
56 | |||
57 | <info>%command.full_name% YYYYMMDDHHMMSS --write-sql</info> |
||
58 | |||
59 | Or you can also execute the migration without a warning message which you need to interact with: |
||
60 | |||
61 | <info>%command.full_name% --no-interaction</info> |
||
62 | |||
63 | You can also time all the different queries if you wanna know which one is taking so long: |
||
64 | |||
65 | <info>%command.full_name% --query-time</info> |
||
66 | EOT |
||
67 | ); |
||
68 | |||
69 | 18 | parent::configure(); |
|
70 | 18 | } |
|
71 | |||
72 | 11 | public function execute(InputInterface $input, OutputInterface $output) |
|
73 | { |
||
74 | 11 | $configuration = $this->getMigrationConfiguration($input, $output); |
|
75 | 11 | $migration = $this->createMigration($configuration); |
|
76 | |||
77 | 11 | $this->outputHeader($configuration, $output); |
|
78 | |||
79 | 11 | $timeAllqueries = $input->getOption('query-time'); |
|
80 | |||
81 | 11 | $dryRun = (boolean) $input->getOption('dry-run'); |
|
82 | 11 | $configuration->setIsDryRun($dryRun); |
|
83 | |||
84 | 11 | $executedMigrations = $configuration->getMigratedVersions(); |
|
85 | 11 | $availableMigrations = $configuration->getAvailableVersions(); |
|
86 | |||
87 | 11 | $version = $this->getVersionNameFromAlias($input->getArgument('version'), $output, $configuration); |
|
88 | 11 | if ($version === false) { |
|
89 | 3 | return 1; |
|
90 | } |
||
91 | |||
92 | 8 | $executedUnavailableMigrations = array_diff($executedMigrations, $availableMigrations); |
|
93 | 8 | if ( ! empty($executedUnavailableMigrations)) { |
|
94 | 1 | $output->writeln(sprintf( |
|
95 | '<error>WARNING! You have %s previously executed migrations' |
||
96 | 1 | . ' in the database that are not registered migrations.</error>', |
|
97 | 1 | count($executedUnavailableMigrations) |
|
98 | )); |
||
99 | |||
100 | 1 | foreach ($executedUnavailableMigrations as $executedUnavailableMigration) { |
|
101 | 1 | $output->writeln(sprintf( |
|
102 | 1 | ' <comment>>></comment> %s (<comment>%s</comment>)', |
|
103 | 1 | $configuration->getDateTime($executedUnavailableMigration), |
|
104 | 1 | $executedUnavailableMigration |
|
105 | )); |
||
106 | } |
||
107 | |||
108 | 1 | $question = 'Are you sure you wish to continue? (y/n)'; |
|
109 | 1 | if ( ! $this->canExecute($question, $input, $output)) { |
|
110 | 1 | $output->writeln('<error>Migration cancelled!</error>'); |
|
111 | |||
112 | 1 | return 1; |
|
113 | } |
||
114 | } |
||
115 | |||
116 | 7 | if ($path = $input->getOption('write-sql')) { |
|
117 | 2 | $path = is_bool($path) ? getcwd() : $path; |
|
118 | 2 | $migration->writeSqlFile($path, $version); |
|
119 | 2 | return 0; |
|
120 | } |
||
121 | |||
122 | 5 | $cancelled = false; |
|
123 | 5 | $migration->setNoMigrationException($input->getOption('allow-no-migration')); |
|
124 | 5 | $result = $migration->migrate($version, $dryRun, $timeAllqueries, function () use ($input, $output, &$cancelled) { |
|
|
|||
125 | $question = 'WARNING! You are about to execute a database migration' |
||
126 | . ' that could result in schema changes and data lost.' |
||
127 | 4 | . ' Are you sure you wish to continue? (y/n)'; |
|
128 | 4 | $canContinue = $this->canExecute($question, $input, $output); |
|
129 | 4 | $cancelled = ! $canContinue; |
|
130 | |||
131 | 4 | return $canContinue; |
|
132 | 5 | }); |
|
133 | |||
134 | 5 | if ($cancelled) { |
|
135 | 1 | $output->writeln('<error>Migration cancelled!</error>'); |
|
136 | 1 | return 1; |
|
137 | } |
||
138 | 4 | } |
|
139 | |||
140 | /** |
||
141 | * Create a new migration instance to execute the migrations. |
||
142 | * |
||
143 | * @param Configuration $configuration The configuration with which the migrations will be executed |
||
144 | * @return Migration a new migration instance |
||
145 | */ |
||
146 | 1 | protected function createMigration(Configuration $configuration) |
|
147 | { |
||
148 | 1 | return new Migration($configuration); |
|
149 | } |
||
150 | |||
151 | /** |
||
152 | * @param string $question |
||
153 | * @param InputInterface $input |
||
154 | * @param OutputInterface $output |
||
155 | * @return bool |
||
156 | */ |
||
157 | 5 | private function canExecute($question, InputInterface $input, OutputInterface $output) |
|
165 | |||
166 | /** |
||
167 | * @param string $versionAlias |
||
168 | * @param OutputInterface $output |
||
169 | * @param Configuration $configuration |
||
170 | * @return bool|string |
||
171 | */ |
||
172 | 11 | private function getVersionNameFromAlias($versionAlias, OutputInterface $output, Configuration $configuration) |
|
198 | } |
||
199 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVar
assignment in line 1 and the$higher
assignment in line 2 are dead. The first because$myVar
is never used and the second because$higher
is always overwritten for every possible time line.