src/RocknRoot/StrayFw/Database/Postgres/Migration.php
public static function migrate(array $mapping)
    {
        $database = Database::get($mapping['config']['database']);
        $database->beginTransaction();
        if (self::ensureTable($mapping) === false) {
            $database->rollBack();
            return;
        }
        $migrations = Config::get(rtrim($mapping['config']['migrations']['path'], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'migrations.yml');
        $select = new Select($mapping['config']['database'], true);
        $select->select('*')
            ->from('_stray_migration')
            ->orderBy('date DESC')
            ->limit(1);
        if ($select->execute() === false) {
            echo 'Can\'t fetch from _stray_migration (' . $select->getErrorMessage() . ')' . PHP_EOL;
            $database->rollBack();
            return;
        }
        $last = $select->fetch();
        $last['date'] = new \DateTime($last['date']);
        $last['date'] = $last['date']->getTimestamp();
        $migrations = array_values(array_filter($migrations, function (array $m) use ($last) {
            return (int) $m['timestamp'] > $last['date'];
        }));
        usort($migrations, function (array $a, array $b) {
            return $a['timestamp'] > $b['timestamp'];
        });
        $imax = count($migrations);
        for ($i = 0; $i < $imax; $i++) {
            echo 'Run ' . $migrations[$i]['name'] . PHP_EOL;
            $cl = '\\' . ltrim(rtrim($mapping['config']['migrations']['namespace'], '\\'), '\\') . '\\' . ucfirst($migrations[$i]['name']) . '\\' . ucfirst($migrations[$i]['name']);
            if ($i < $imax - 1) {
                $schema = Config::get(rtrim($mapping['config']['migrations']['path'], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . ucfirst($migrations[$i + 1]['name']) . DIRECTORY_SEPARATOR . 'schema.yml');
            } else {
                $schema = Config::get($mapping['config']['schema']);
            }
            $n = new $cl($schema, rtrim($mapping['config']['migrations']['path'], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . ucfirst($migrations[$i]['name']) . DIRECTORY_SEPARATOR);
            try {
                $n->up();
            } catch (Exception $e) {
                $database->rollBack();
                throw $e;
            }
            $insert = new Insert($mapping['config']['database']);
            $insert->into('_stray_migration');
            $insert->bind('migration', $migrations[$i]['name']);
            $insert->values([ 'migration' => ':migration' ]);
            if ($insert->execute() === false) {
                echo 'Can\'t insert into _stray_migration (' . $insert->getErrorMessage() . ')' . PHP_EOL;
                $database->rollBack();
                return;
            }
        }
        $database->commit();
    }
public static function migrate(array $mapping)
    {
        $database = Database::get($mapping['config']['database']);
        $database->beginTransaction();
        if (self::ensureTable($mapping) === false) {
            $database->rollBack();
            return;
        }
        $migrations = Config::get(rtrim($mapping['config']['migrations']['path'], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'migrations.yml');
        $select = new Select($mapping['config']['database'], true);
        $select->select('*')
            ->from('_stray_migration')
            ->orderBy('date DESC')
            ->limit(1);
        if ($select->execute() === false) {
            echo 'Can\'t fetch from _stray_migration (' . $select->getErrorMessage() . ')' . PHP_EOL;
            $database->rollBack();
            return;
        }
        $last = $select->fetch();
        $last['date'] = new \DateTime($last['date']);
        $last['date'] = $last['date']->getTimestamp();
        $migrations = array_values(array_filter($migrations, function (array $m) use ($last) {
            return (int) $m['timestamp'] > $last['date'];
        }));
        usort($migrations, function (array $a, array $b) {
            return $a['timestamp'] > $b['timestamp'];
        });
        $imax = count($migrations);
        for ($i = 0; $i < $imax; $i++) {
            echo 'Run ' . $migrations[$i]['name'] . PHP_EOL;
            $cl = '\\' . ltrim(rtrim($mapping['config']['migrations']['namespace'], '\\'), '\\') . '\\' . ucfirst($migrations[$i]['name']) . '\\' . ucfirst($migrations[$i]['name']);
            if ($i < $imax - 1) {
                $schema = Config::get(rtrim($mapping['config']['migrations']['path'], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . ucfirst($migrations[$i + 1]['name']) . DIRECTORY_SEPARATOR . 'schema.yml');
            } else {
                $schema = Config::get($mapping['config']['schema']);
            }
            $n = new $cl($schema, rtrim($mapping['config']['migrations']['path'], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . ucfirst($migrations[$i]['name']) . DIRECTORY_SEPARATOR);
            try {
                $n->up();
            } catch (Exception $e) {
                $database->rollBack();
                throw $e;
            }
            $insert = new Insert($mapping['config']['database']);
            $insert->into('_stray_migration');
            $insert->bind('migration', $migrations[$i]['name']);
            $insert->values([ 'migration' => ':migration' ]);
            if ($insert->execute() === false) {
                echo 'Can\'t insert into _stray_migration (' . $insert->getErrorMessage() . ')' . PHP_EOL;
                $database->rollBack();
                return;
            }
        }
        $database->commit();
    }
Run migration code for specified mapping.

@param array $mapping mapping definition