/**
  * Run migrations
  *
  * @param array $options
  *
  * @throws Exception
  * @throws ModelException
  * @throws ScriptException
  */
 public static function run(array $options)
 {
     $path = $options['directory'];
     $migrationsDir = $options['migrationsDir'];
     if (!file_exists($migrationsDir)) {
         throw new ModelException('Migrations directory could not found.');
     }
     $config = $options['config'];
     if (!$config instanceof Config) {
         throw new ModelException('Internal error. Config should be instance of \\Phalcon\\Config');
     }
     $finalVersion = null;
     if (isset($options['version']) && $options['version'] !== null) {
         $finalVersion = new VersionItem($options['version']);
     }
     $tableName = 'all';
     if (isset($options['tableName'])) {
         $tableName = $options['tableName'];
     }
     // read all versions
     $versions = array();
     $iterator = new \DirectoryIterator($migrationsDir);
     foreach ($iterator as $fileinfo) {
         if ($fileinfo->isDir() && preg_match('/[a-z0-9](\\.[a-z0-9]+)+/', $fileinfo->getFilename(), $matches)) {
             $versions[] = new VersionItem($matches[0], 3);
         }
     }
     if (count($versions) == 0) {
         throw new ModelException('Migrations were not found at ' . $migrationsDir);
     }
     // set default final version
     if ($finalVersion === null) {
         $finalVersion = VersionItem::maximum($versions);
     }
     // read current version
     if (is_file($path . '.phalcon')) {
         unlink($path . '.phalcon');
         mkdir($path . '.phalcon');
     }
     $migrationFid = $path . '.phalcon/migration-version';
     $initialVersion = new VersionItem(file_exists($migrationFid) ? file_get_contents($migrationFid) : null);
     if ($initialVersion->getStamp() == $finalVersion->getStamp()) {
         return;
         // nothing to do
     }
     // init ModelMigration
     if (!isset($config->database)) {
         throw new ScriptException('Cannot load database configuration');
     }
     ModelMigration::setup($config->database);
     ModelMigration::setMigrationPath($migrationsDir);
     // run migration
     $versionsBetween = VersionItem::between($initialVersion, $finalVersion, $versions);
     foreach ($versionsBetween as $k => $version) {
         /** @var \Phalcon\Version\Item $version */
         if ($tableName == 'all') {
             $iterator = new \DirectoryIterator($migrationsDir . '/' . $version);
             foreach ($iterator as $fileinfo) {
                 if (!$fileinfo->isFile() || !preg_match('/\\.php$/i', $fileinfo->getFilename())) {
                     continue;
                 }
                 ModelMigration::migrate($initialVersion, $version, $fileinfo->getBasename('.php'));
             }
         } else {
             ModelMigration::migrate($initialVersion, $version, $tableName);
         }
         file_put_contents($migrationFid, (string) $version);
         print Color::success('Version ' . $version . ' was successfully migrated');
         $initialVersion = $version;
     }
 }
 /**
  * Run migrations
  *
  * @param array $options
  *
  * @throws Exception
  * @throws ModelException
  * @throws ScriptException
  * @throws \Exception
  */
 public static function run(array $options)
 {
     $path = $options['directory'];
     $migrationsDir = $options['migrationsDir'];
     $config = $options['config'];
     $version = null;
     if (isset($options['version']) && $options['version'] !== null) {
         $version = new VersionItem($options['version']);
     }
     if (isset($options['tableName'])) {
         $tableName = $options['tableName'];
     } else {
         $tableName = 'all';
     }
     if (!file_exists($migrationsDir)) {
         throw new ModelException('Migrations directory could not found');
     }
     $versions = array();
     $iterator = new \DirectoryIterator($migrationsDir);
     foreach ($iterator as $fileinfo) {
         if ($fileinfo->isDir()) {
             if (preg_match('/[a-z0-9](\\.[a-z0-9]+)+/', $fileinfo->getFilename(), $matches)) {
                 $versions[] = new VersionItem($matches[0], 3);
             }
         }
     }
     if (count($versions) == 0) {
         throw new ModelException('Migrations were not found at ' . $migrationsDir);
     } else {
         if ($version === null) {
             $version = VersionItem::maximum($versions);
         }
     }
     if (is_file($path . '.phalcon')) {
         unlink($path . '.phalcon');
         mkdir($path . '.phalcon');
     }
     $migrationFid = $path . '.phalcon/migration-version';
     if (file_exists($migrationFid)) {
         $fromVersion = trim(file_get_contents($migrationFid));
     } else {
         $fromVersion = null;
     }
     if (isset($config->database)) {
         ModelMigration::setup($config->database);
     } else {
         throw new \Exception("Cannot load database configuration");
     }
     ModelMigration::setMigrationPath($migrationsDir . '/' . $version . '/');
     $versionsBetween = VersionItem::between($fromVersion, $version, $versions);
     // get rid of the current version, we don't want migrations to run for our
     // existing version.
     if (isset($versionsBetween[0]) && (string) $versionsBetween[0] == $fromVersion) {
         unset($versionsBetween[0]);
     }
     foreach ($versionsBetween as $version) {
         if ($tableName == 'all') {
             $iterator = new \DirectoryIterator($migrationsDir . '/' . $version);
             foreach ($iterator as $fileinfo) {
                 if ($fileinfo->isFile()) {
                     if (preg_match('/\\.php$/', $fileinfo->getFilename())) {
                         ModelMigration::migrateFile((string) $version, $migrationsDir . '/' . $version . '/' . $fileinfo->getFilename());
                     }
                 }
             }
         } else {
             $migrationPath = $migrationsDir . '/' . $version . '/' . $tableName . '.php';
             if (!file_exists($migrationPath)) {
                 throw new ScriptException('Migration class was not found ' . $migrationPath);
             }
             ModelMigration::migrateFile((string) $version, $migrationPath);
         }
         print Color::success('Version ' . $version . ' was successfully migrated') . PHP_EOL;
     }
     file_put_contents($migrationFid, (string) $version);
 }
 /**
  * Run migrations
  *
  * @param array $options
  *
  * @throws Exception
  * @throws ModelException
  * @throws ScriptException
  */
 public static function run(array $options)
 {
     $path = $options['directory'];
     $migrationsDir = $options['migrationsDir'];
     if (!file_exists($migrationsDir)) {
         throw new ModelException('Migrations directory could not found.');
     }
     self::$_config = $options['config'];
     if (!self::$_config instanceof Config) {
         throw new ModelException('Internal error. Config should be instance of \\Phalcon\\Config');
     }
     $finalVersion = null;
     if (isset($options['version']) && $options['version'] !== null) {
         $finalVersion = new VersionItem($options['version']);
     }
     $tableName = 'all';
     if (isset($options['tableName'])) {
         $tableName = $options['tableName'];
     }
     $versions = ModelMigration::scanForVersions($migrationsDir);
     if (!count($versions)) {
         throw new ModelException("Migrations were not found at {$migrationsDir}");
     }
     // set default final version
     if (!$finalVersion) {
         $finalVersion = VersionItem::maximum($versions);
     }
     // read current version
     if (is_file($path . '.phalcon')) {
         unlink($path . '.phalcon');
         mkdir($path . '.phalcon');
         chmod($path . '.phalcon', 0775);
     }
     self::$_migrationFid = $path . '.phalcon/migration-version';
     // init ModelMigration
     if (!is_null(self::$_config->get('database'))) {
         throw new ScriptException('Cannot load database configuration');
     }
     ModelMigration::setup(self::$_config->get('database'));
     ModelMigration::setMigrationPath($migrationsDir);
     $initialVersion = self::getCurrentVersion();
     if ($initialVersion->getStamp() == $finalVersion->getStamp()) {
         return;
         // nothing to do
     }
     $direction = ModelMigration::DIRECTION_FORWARD;
     if ($finalVersion->getStamp() < $initialVersion->getStamp()) {
         $direction = ModelMigration::DIRECTION_BACK;
     }
     // run migration
     $lastGoodVersion = $initialVersion;
     $versionsBetween = VersionItem::between($initialVersion, $finalVersion, $versions);
     foreach ($versionsBetween as $version) {
         if ($tableName == 'all') {
             $iterator = new DirectoryIterator($migrationsDir . DIRECTORY_SEPARATOR . $version);
             foreach ($iterator as $fileInfo) {
                 if (!$fileInfo->isFile() || 0 !== strcasecmp($fileInfo->getExtension(), 'php')) {
                     continue;
                 }
                 ModelMigration::migrate($initialVersion, $version, $fileInfo->getBasename('.php'), $direction);
             }
         } else {
             ModelMigration::migrate($initialVersion, $version, $tableName, $direction);
         }
         self::setCurrentVersion((string) $lastGoodVersion, (string) $version);
         $lastGoodVersion = $version;
         print Color::success('Version ' . $version . ' was successfully migrated');
         $initialVersion = $version;
     }
 }
 /**
  * List migrations along with statuses
  *
  * @param array $options
  *
  * @throws Exception
  * @throws ModelException
  * @throws ScriptException
  *
  */
 public static function listAll(array $options)
 {
     // Define versioning type to be used
     if (true === $options['tsBased']) {
         VersionCollection::setType(VersionCollection::TYPE_TIMESTAMPED);
     } else {
         VersionCollection::setType(VersionCollection::TYPE_INCREMENTAL);
     }
     $migrationsDir = rtrim($options['migrationsDir'], '/');
     if (!file_exists($migrationsDir)) {
         throw new ModelException('Migrations directory was not found.');
     }
     /** @var Config $config */
     $config = $options['config'];
     if (!$config instanceof Config) {
         throw new ModelException('Internal error. Config should be an instance of \\Phalcon\\Config');
     }
     // Init ModelMigration
     if (!isset($config->database)) {
         throw new ScriptException('Cannot load database configuration');
     }
     $finalVersion = null;
     if (isset($options['version']) && $options['version'] !== null) {
         $finalVersion = VersionCollection::createItem($options['version']);
     }
     $versionItems = ModelMigration::scanForVersions($migrationsDir);
     if (!isset($versionItems[0])) {
         throw new ModelException('Migrations were not found at ' . $migrationsDir);
     }
     // Set default final version
     if ($finalVersion === null) {
         $finalVersion = VersionCollection::maximum($versionItems);
     }
     ModelMigration::setup($config->database);
     ModelMigration::setMigrationPath($migrationsDir);
     self::connectionSetup($options);
     $initialVersion = self::getCurrentVersion($options);
     $completedVersions = self::getCompletedVersions($options);
     if ($finalVersion->getStamp() < $initialVersion->getStamp()) {
         $direction = ModelMigration::DIRECTION_BACK;
         $versionItems = VersionCollection::sortDesc($versionItems);
     } else {
         $direction = ModelMigration::DIRECTION_FORWARD;
         $versionItems = VersionCollection::sortAsc($versionItems);
     }
     foreach ($versionItems as $versionItem) {
         if (ModelMigration::DIRECTION_FORWARD === $direction && isset($completedVersions[(string) $versionItem])) {
             print Color::success('Version ' . (string) $versionItem . ' was already applied');
             continue;
         } elseif (ModelMigration::DIRECTION_BACK === $direction && !isset($completedVersions[(string) $versionItem])) {
             print Color::success('Version ' . (string) $versionItem . ' was already rolled back');
             continue;
         }
         if (ModelMigration::DIRECTION_FORWARD === $direction) {
             print Color::error('Version ' . (string) $versionItem . ' was not applied');
             continue;
         } elseif (ModelMigration::DIRECTION_BACK === $direction) {
             print Color::error('Version ' . (string) $versionItem . ' was not rolled back');
             continue;
         }
     }
 }