Roave / psr-container-doctrine

Doctrine Factories for PSR-11 Containers

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Migrations: Document how to use a custom version comparator

internalsystemerror opened this issue · comments

It's come up a couple of times in laminas' slack the question as to how to use a custom version comparator in doctrine migrations when using this library.

That should be documented, and the one I've been sharing is:

config/cli-config.php

<?php

declare(strict_types=1);

use Doctrine\Migrations\DependencyFactory;
use Doctrine\Migrations\Version\Comparator;
use Doctrine\Migrations\Version\Version;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider;
use Laminas\ServiceManager\ServiceManager;

require dirname(__DIR__) . '/vendor/autoload.php';

/** @var ServiceManager $container */
$container = require __DIR__ . '/container.php';

global $argv;
if (str_contains($argv[0], 'doctrine-migrations')) {
    /** @var DependencyFactory $factory */
    $factory = $container->get(DependencyFactory::class);
    $factory->setService(Comparator::class, new class() implements Comparator {
        public function compare(Version $a, Version $b): int
        {
            return strcmp(self::versionWithoutNamespace($a), self::versionWithoutNamespace($b));
        }
        private static function versionWithoutNamespace(Version $version): string
        {
            $parsed = strrchr($version->__toString(), '\\');
            if ($parsed === false) {
                throw new \RuntimeException('Unable to parse version ' . $version->__toString());
            }

            return $parsed;
        }
    });

    return $factory;
}

When run as: vendor/bin/doctrine-migrations ...

This example uses laminas service manager, and adds an anonymous class as the comparator, which compares version numbers regardless of their namespace, so that they can be run in order across different modules.

If no one beats me to it, I'll try to remember to create a PR for this if it would be welcome. I know its not just for this library, but everything else is pretty much available by configuration, so this comes up.