/** * 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; } }
/** * 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 * */ public static function run(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']); } $tableName = 'all'; if (isset($options['tableName'])) { $tableName = $options['tableName']; } $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); // Everything is up to date if ($initialVersion->getStamp() === $finalVersion->getStamp()) { print Color::info('Everything is up to date'); exit(0); } $direction = ModelMigration::DIRECTION_FORWARD; if ($finalVersion->getStamp() < $initialVersion->getStamp()) { $direction = ModelMigration::DIRECTION_BACK; } if (ModelMigration::DIRECTION_FORWARD === $direction) { // If we migrate up, we should go from the beginning to run some migrations which may have been missed $versionItemsTmp = VersionCollection::sortAsc(array_merge($versionItems, [$initialVersion])); $initialVersion = $versionItemsTmp[0]; } else { // If we migrate downs, we should go from the last migration to revert some migrations which may have been missed $versionItemsTmp = VersionCollection::sortDesc(array_merge($versionItems, [$initialVersion])); $initialVersion = $versionItemsTmp[0]; } // Run migration $versionsBetween = VersionCollection::between($initialVersion, $finalVersion, $versionItems); foreach ($versionsBetween as $versionItem) { if (ModelMigration::DIRECTION_FORWARD === $direction && isset($completedVersions[(string) $versionItem])) { print Color::info('Version ' . (string) $versionItem . ' was already applied'); continue; } elseif (ModelMigration::DIRECTION_BACK === $direction && !isset($completedVersions[(string) $versionItem])) { print Color::info('Version ' . (string) $versionItem . ' was already rolled back'); continue; } if ($versionItem->getVersion() === $finalVersion->getVersion() && ModelMigration::DIRECTION_BACK === $direction) { break; } $migrationStartTime = date("'Y-m-d H:i:s'"); if ($tableName === 'all') { $iterator = new DirectoryIterator($migrationsDir . DIRECTORY_SEPARATOR . $versionItem->getVersion()); foreach ($iterator as $fileInfo) { if (!$fileInfo->isFile() || 0 !== strcasecmp($fileInfo->getExtension(), 'php')) { continue; } ModelMigration::migrate($initialVersion, $versionItem, $fileInfo->getBasename('.php'), $direction); } } else { ModelMigration::migrate($initialVersion, $versionItem, $tableName, $direction); } if (ModelMigration::DIRECTION_FORWARD == $direction) { self::addCurrentVersion($options, (string) $versionItem, $migrationStartTime); print Color::success('Version ' . $versionItem . ' was successfully migrated'); } else { self::removeCurrentVersion($options, (string) $versionItem); print Color::success('Version ' . $versionItem . ' was successfully rolled back'); } $initialVersion = $versionItem; } }