@param SQLMigration $migration

@throws InvalidMigrationType
515070
public function addMigration(SQLMigration $migration) {
		if (!$migration instanceof MySQLMigration) {
			throw new InvalidMigrationType(\get_class($migration));
		}
		$this->migrations[\get_class($migration)] = $migration;
	}
457335
protected function hasMigrationApplied(AbstractMigration $migration)
    {
        // if the "applied-flow-migrations" section doesn't exist, we fall back to checking the git log for applied migrations for backwards compatibility
        if (!isset($this->currentPackageData['composerManifest']['extra']['applied-flow-migrations'])) {
            return Git::logContains($this->currentPackageData['path'], 'Migration: ' . $migration->getIdentifier());
        }
        return in_array($migration->getIdentifier(), $this->currentPackageData['composerManifest']['extra']['applied-flow-migrations']);
    }
391244
private function updateMigrationStatus($migration, $batch)
    {
        $table = $this->getMigrationTable();

        return $table->where('migration', $migration)->update([
            'migration' => $migration,
            'batch' => $batch
        ]);
    }
1226887
protected function recordMigration(AbstractMigration $migration)
    {
        $query = 'INSERT INTO `app_migrations` (`timestamp`, `description`) VALUES ("%s", "%s")';
        $query = sprintf($query, $migration->getTimestamp(), $migration->getDescription());

        $this->db->query($query, DbAdapter::QUERY_MODE_EXECUTE);
    }
589729
private function createMigrationsTable(OutputInterface $output = null)
    {
        if (!is_null($output)) {
            $output->writeln('<info>Creating migrations table</info>');
        }
        $m = new CreateMigrationsTable();
        $m->up();
    }
708702
public function init( $config = NULL )
    {
        parent::init( $config );
        
        if ( !isset( $config[ 'migration_path' ] ) )
        {
            throw new \InvalidArgumentException( 'Missing migration_path parameter' );
        }
        
        foreach ( $config as $key => $value )
        {
            switch( $key )
            {
                case 'migration_path':
                    $this->migrationPath = $value;
                    break;
                
                case 'migration_namespace':
                    $this->migrationNamespace = $value;
                    break;
                
                case 'namespaces':
                    $this->namespaces = $value;
                    break;
                
                case 'class_prefix':
                    $this->classPrefix = $value;
                    break;
                
                case 'migration_table':
                    $this->migrationTable = $value;
                    break;
                
                case 'class_name_style':
                    $this->migrationClassStyle = $value;
                    break;
                
                case 'overwrite':
                    $this->overwrite = $value;
                    break;
                
                case 'levels':
                    $this->levels = $value;
                    break;
                
                case 'name':
                    $this->migrationClass = $value;
                    break;
                
                case 'verbose':
                    $this->verbose = $value === 'true' ? TRUE : FALSE;
                    break;
                
                default:
                    // Do nothing
                    break;
            }
        }
        
        $this->doAction( self::ON_INIT_ACTION );
    }
1227280
private function createMigration($migration, $manifest = array(), $migrationName = '')
    {
        $empty = is_null($migration);
        $date = new DateTime();
        $name = 'm%s_migration';
        $description = [];

        if ($migrationName == '') {

            foreach ($manifest as $key => $value) {
                $description[] = $key;
                foreach ($value as $item) {
                    $description[] = $item;
                }
            }
        } else {
            $description[] = $migrationName;
        }

        if (!$empty || count($description)>0) {
            $description = implode('_', $description);
            $name .= '_' . MigrationManagerHelper::slugify($description);
        }

        $filename = sprintf($name, $date->format('ymd_His'));
        $filename = substr($filename, 0, 250);
        $filename = str_replace('-', '_', $filename);

        $migrator = Craft::$app->getContentMigrator();
        $migrationPath = $migrator->migrationPath;

        $path = sprintf($migrationPath . '/%s.php', $filename);

        $pathLen = strlen($path);
        if ($pathLen > 255) {
            $migrationPathLen = strlen($migrationPath);
            $filename = substr($filename, 0, 250 - $migrationPathLen);
            $path = sprintf($migrationPath . '/%s.php', $filename);
        }

        $migration = json_encode($migration, JSON_HEX_APOS | JSON_HEX_QUOT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        //escape backslashes
        //$migration = str_replace('\\', '\\\\', $migration);

        $content = Craft::$app->view->renderTemplate('migrationmanager/_migration', array('empty' => $empty, 'migration' => $migration, 'className' => $filename, 'manifest' => $manifest, true));

        FileHelper::writeToFile($path, $content);

        // mark the migration as completed if it's not a blank one
        if (!$empty) {
            $migrator->addMigrationHistory($filename);
        }
    }
545581
private function changeMigrationTable($migration)
    {
        $table = $this->_cap->table('migrations');

        $dbm = $table->where('migration', '=', $migration);

        if ($dbm->count() > 0) {
            $item = $dbm->first();
            $item->updated_at = date('Y-m-d h:i:s');
            $item->migrated = 1;
            $table->update((array) $item);
        } else {
            $options['migration'] = $migration;
            $options['created_at'] = date('Y-m-d h:i:s');
            $options['updated_at'] = $options['created_at'];
            $options['migrated'] = 1;
            $table->insert($options);
        }
    }
721609
public function unmigrate($migrationName) {
		$this->createTable();
		$this->db->dal()->from('_migrations')->where('name', $migrationName)->delete();
	}
563559
protected function deleteMigrations(array $migrations)
	{
		if ( !$migrations ) {
			return;
		}

		$sql = 'DELETE FROM Migrations
				WHERE Name IN (:names)';
		$this->_context->getDatabase()->perform($sql, array('names' => $migrations));
	}
1476
public function insert(Migration $migration)
    {
        $sql = sprintf("INSERT INTO {$this->tableName} (name, data) VALUES ('%s', '%s')",
            $this->adapter->escape($migration->getName()),
            $this->adapter->escape($migration->getSql())
        );
        $this->getAdapter()->execute($sql);
    }
1213358
public function check($migration)
    {
        if (!$this->isChecked($migration)) {
            $class = $this->compileEntity();
            $result = $class::add([
                'UF_MIGRATION_NAME' => $migration,
                'UF_MIGRATION_DATE' => date('d.m.Y H:i'),
            ]);
            if (!$result->isSuccess()) {
                throw new Exception(
                    "Can't check migration in HL: "
                    . implode(', ', $result->getErrorMessages())
                );
            }
        }
    }
1314907
protected function runDown($file, $migration)
    {
        $file     = $this->migrator->getMigrationName($file);
        $instance = $this->migrator->resolve($file);

        $instance->down();

        $this->migrator->getRepository()->delete($migration);

        $this->info("Rolledback: ".$file);
    }
125842
protected function migrate()
    {
        if (! $this->container['migrator']->repositoryExists()) {
            throw new Exception('Migration table not found.');
        }

        $this->container['migrator']->run($this->getAttribute('path').'/database/migrations');
    }
967916
protected function _execute(AbstractMigration $migration)
    {
        $time          = Time::parse('now');
        $version       = $migration->getVersion();
        $migrationName = $this->_plugin . '::' . get_class($migration);

        $sqlInsert = sprintf(
            'INSERT INTO %s ('
            . 'version,'
            . 'migration_name,'
            . 'start_time'
            . ') VALUES ('
            . '\'%s\','
            . '\'%s\','
            . '\'%s\''
            . ');',
            self::SCHEMA_TABLE,
            $version,
            $migrationName,
            $time->toDateTimeString()
        );

        $this->_adapter->query($sqlInsert);

        $sqlCheck = sprintf(
            'SELECT version FROM %s WHERE version=\'%s\'',
            self::SCHEMA_TABLE,
            $version
        );

        $versionResult = $this->_adapter->fetchRow($sqlCheck);
        if (count((array) $versionResult) > 0) {
            return __d(
                'extensions',
                'The version «{0}» of plugin «{1}» has bin success migrated.',
                sprintf('<strong>%s</strong>', $version),
                sprintf('<strong>%s</strong>', __d(Str::low($this->_plugin), $this->_plugin))
            );
        }

        return false;
    }
890332
protected function markRolledBackWithConfirmation($migration)
    {
        $helper = $this->getHelper('question');
        $question = new ConfirmationQuestion("<error>Migration $migration was not found.\r\nDo you want to mark it as rolled back? (y/n)</error>\r\n", false);

        if (!$helper->ask($this->input, $this->output, $question)) {
            $this->abort();
        }

        $this->migrator->removeSuccessfulMigrationFromLog($migration);
    }
29440
public function execute(InputInterface $input, OutputInterface $output)
    {
        $this->setOutput($output);
        $this->setVerbosity($output->getVerbosity());

        if ($input->getOption('list-types')) {
            $this->listAvailableTypes($output);
            return 0;
        }

        $bundleName = $input->getArgument('bundle');
        if ($bundleName === null) {
            // throw same exception as SF would when declaring 'bundle' as mandatory arg
            throw new \RuntimeException('Not enough arguments (missing: "bundle").');
        }
        $name = $input->getArgument('name');
        $fileType = $input->getOption('format');
        $migrationType = $input->getOption('type');
        $matchType = $input->getOption('match-type');
        $matchValue = $input->getOption('match-value');
        $matchExcept = $input->getOption('match-except');
        $mode = $input->getOption('mode');
        $dbServer = $input->getOption('dbserver');

        if ($bundleName == $this->thisBundle) {
            throw new \InvalidArgumentException("It is not allowed to create migrations in bundle '$bundleName'");
        }

        // be kind to lazy users
        if ($migrationType == '') {
            if ($fileType == 'sql') {
                $migrationType = 'db';
            } elseif ($fileType == 'php') {
                $migrationType = 'php';
            } else {
                $migrationType = 'generic';
            }
        }

        if (!in_array($fileType, $this->availableMigrationFormats)) {
            throw new \InvalidArgumentException('Unsupported migration file format ' . $fileType);
        }

        if (!in_array($mode, $this->availableModes)) {
            throw new \InvalidArgumentException('Unsupported migration mode ' . $mode);
        }

        $migrationDirectory = $this->getMigrationDirectory($bundleName);

        if (!is_dir($migrationDirectory)) {
            $output->writeln(sprintf(
                "Migrations directory <info>%s</info> does not exist. I will create it now....",
                $migrationDirectory
            ));

            if (mkdir($migrationDirectory, self::DIR_CREATE_PERMISSIONS, true)) {
                $output->writeln(sprintf(
                    "Migrations directory <info>%s</info> has been created",
                    $migrationDirectory
                ));
            } else {
                throw new FileException(sprintf(
                    "Failed to create migrations directory %s.",
                    $migrationDirectory
                ));
            }
        }

        // allow to generate migrations for many entities
        if (strpos($matchValue, ',') !== false ) {
            $matchValue = explode(',', $matchValue);
        }

        $parameters = array(
            'dbserver' => $dbServer,
            'matchType' => $matchType,
            'matchValue' => $matchValue,
            'matchExcept' => $matchExcept,
            'mode' => $mode,
            'lang' => $input->getOption('lang'),
            'adminLogin' => $input->getOption('admin-login')
            /// @todo should we allow users to specify this ?
            //'forceSigchildEnabled' => null
        );

        $date = date('YmdHis');

        switch ($fileType) {
            case 'sql':
                /// @todo this logic should come from the DefinitionParser, really
                if ($name != '') {
                    $name = '_' . ltrim($name, '_');
                }
                $fileName = $date . '_' . $dbServer . $name . '.sql';
                break;

            case 'php':
                /// @todo this logic should come from the DefinitionParser, really
                $className = ltrim($name, '_');
                if ($className == '') {
                    $className = 'Migration';
                }
                // Make sure that php class names are unique, not only migration definition file names
                $existingMigrations = count(glob($migrationDirectory . '/*_' . $className . '*.php'));
                if ($existingMigrations) {
                    $className = $className . sprintf('%03d', $existingMigrations + 1);
                }
                $parameters = array_merge($parameters, array(
                    'class_name' => $className
                ));
                $fileName = $date . '_' . $className . '.php';
                break;

            default:
                if ($name == '') {
                    $name = 'placeholder';
                }
                $fileName = $date . '_' . $name . '.' . $fileType;
        }

        $path = $migrationDirectory . '/' . $fileName;

        $warning = $this->generateMigrationFile($path, $fileType, $migrationType, $parameters);

        $output->writeln(sprintf("Generated new migration file: <info>%s</info>", $path));

        if ($warning != '') {
            $output->writeln("<comment>$warning</comment>");
        }

        return 0;
    }