public function run($options)
{
$targetVersion = $latestVersion = $this->getVersion($options['type']);
$mapping = $this->getMapping($options['type'], false);
$direction = 'up';
if (!empty($options['direction'])) {
$direction = $options['direction'];
}
if (isset($options['version'])) {
$targetVersion = $options['version'];
$direction = $targetVersion < $latestVersion ? 'down' : $direction;
if (isset($mapping[$targetVersion]) && empty($mapping[$targetVersion]['migrated'])) {
$direction = 'up';
}
}
if (!empty($this->skip) && is_string($this->skip)) {
$this->skip = explode(',', trim($this->skip));
}
if ($direction === 'up' && !isset($options['version'])) {
$keys = array_keys($mapping);
$flipped = array_flip($keys);
$next = $flipped[$targetVersion + 1];
$targetVersion = $keys[$next];
}
if ($direction === 'down') {
krsort($mapping);
}
foreach ($mapping as $version => $info) {
if ($direction === 'up' && $version > $targetVersion || $direction === 'down' && $version < $targetVersion) {
break;
} elseif ($direction === 'up' && $info['migrated'] === null || $direction === 'down' && $info['migrated'] !== null) {
$type = $info['type'];
$jumpVersion = $this->getVersionByName($mapping);
if ($version < $jumpVersion) {
$this->jump($version, $type);
continue;
}
if (in_array($mapping[$version]['name'], $this->skip)) {
$this->setVersion($version, $type);
continue;
}
$migration = $this->getMigration($info['name'], $info['class'], $type, $options);
$migration->Version = $this;
$migration->info = $info;
try {
$result = $migration->run($direction, $options);
$this->log[$info['name']] = $migration->getQueryLog();
} catch (MigrationException $migrationException) {
throw $migrationException;
// throw to MigrationShell::_execute
} catch (Exception $exception) {
$mapping = $this->getMapping($options['type']);
if (isset($mapping[$latestVersion]['version'])) {
$latestVersionName = '#' . sprintf("%'.03d", $mapping[$latestVersion]['version']) . ' ' . $mapping[$latestVersion]['name'];
} else {
$latestVersionName = null;
}
$errorMessage = __d('migrations', "There was an error during a migration. \n The error was: '%s' \n You must resolve the issue manually and try again.", $exception->getMessage(), $latestVersionName);
return $errorMessage;
}
$this->setVersion($version, $type, $direction === 'up');
}
}
if (isset($result)) {
return $result;
}
return true;
}