/** * Execute this migration version up or down and and return the SQL. * * @param string $direction The direction to execute the migration. * @param string $dryRun Whether to not actually execute the migration SQL and just do a dry run. * @return array $sql * @throws Exception when migration fails */ public function execute($direction, $dryRun = false) { $this->_sql = array(); $this->_connection->beginTransaction(); try { $start = microtime(true); $this->_state = self::STATE_PRE; $fromSchema = $this->_sm->createSchema(); $this->_migration->{'pre' . ucfirst($direction)}($fromSchema); if ($direction === 'up') { $this->_outputWriter->write("\n" . sprintf(' <info>++</info> migrating <comment>%s</comment>', $this->_version) . "\n"); } else { $this->_outputWriter->write("\n" . sprintf(' <info>--</info> reverting <comment>%s</comment>', $this->_version) . "\n"); } $this->_state = self::STATE_EXEC; $toSchema = clone $fromSchema; $this->_migration->{$direction}($toSchema); $this->addSql($fromSchema->getMigrateToSql($toSchema, $this->_platform)); if ($dryRun === false) { if ($this->_sql) { $count = count($this->_sql); foreach ($this->_sql as $query) { $this->_outputWriter->write(' <comment>-></comment> ' . $query); $this->_connection->executeQuery($query); } } else { $this->_outputWriter->write(sprintf('<error>Migration %s was executed but did not result in any SQL statements.</error>', $this->_version)); } if ($direction === 'up') { $this->markMigrated(); } else { $this->markNotMigrated(); } } else { foreach ($this->_sql as $query) { $this->_outputWriter->write(' <comment>-></comment> ' . $query); } } $this->_state = self::STATE_POST; $this->_migration->{'post' . ucfirst($direction)}($toSchema); $end = microtime(true); $this->_time = round($end - $start, 2); if ($direction === 'up') { $this->_outputWriter->write(sprintf("\n <info>++</info> migrated (%ss)", $this->_time)); } else { $this->_outputWriter->write(sprintf("\n <info>--</info> reverted (%ss)", $this->_time)); } $this->_connection->commit(); return $this->_sql; } catch (SkipMigrationException $e) { $this->_connection->rollback(); // now mark it as migrated if ($direction === 'up') { $this->markMigrated(); } else { $this->markNotMigrated(); } $this->_outputWriter->write(sprintf("\n <info>SS</info> skipped (Reason: %s)", $e->getMessage())); } catch (\Exception $e) { $this->_outputWriter->write(sprintf('<error>Migration %s failed during %s. Error %s</error>', $this->_version, $this->getExecutionState(), $e->getMessage())); $this->_connection->rollback(); $this->_state = self::STATE_NONE; throw $e; } $this->_state = self::STATE_NONE; }