Propojení Mango tester s Doctrine Migrations (Nettrine)

Petr Parolek
Člen | 455
+
0
-

Ahoj,

poradil by mi někdo prosím, jak implementovat doctrine migrations do DatabaseCreator?

Koukám, jak je implementované nextras https://github.com/…nsDriver.php a https://github.com/…lAdapter.php .

Nejsem z toho vůbec moudrý.

Díky za pomoc.

Jan Tvrdík
Nette guru | 2595
+
0
-

A která z těch 3 metod je ti nejasná?

Petr Parolek
Člen | 455
+
0
-

Posunul jsem se dál:

MySqlNettrineMigrationsDbalAdapter vypadá ok

<?php
declare(strict_types=1);

namespace AppTests;

use DateTime;
use Doctrine;
use Mangoweb\Tester\DatabaseCreator\IDbal;

class MySqlNettrineMigrationsDbalAdapter implements IDbal
{

	/** @var Doctrine\DBAL\Connection */
	private $conn;

	public function __construct(Doctrine\DBAL\Connection $conn)
	{
		$this->conn = $conn;
	}

	public function query($sql): array
	{
		return $this->conn->fetchAll($sql);
	}

	public function exec($sql): int
	{
		return $this->conn->exec($sql);
	}

	public function escapeString($value): string
	{
		return $this->conn->quote($value, Doctrine\DBAL\Types\Type::STRING);
	}

	public function escapeInt($value): string
	{
		return $this->conn->quote($value, Doctrine\DBAL\Types\Type::INTEGER);
	}

	public function escapeBool($value): string
	{
		return $this->conn->quote($value, Doctrine\DBAL\Types\Type::BOOLEAN);
	}

	public function escapeDateTime(DateTime $value): string
	{
		return $this->conn->quote($value, Doctrine\DBAL\Types\Type::DATETIME);
	}

	public function escapeIdentifier($value): string
	{
		return $this->conn->quoteIdentifier($value);
	}

	public function connectToDatabase(string $name): void
	{
		$this->conn->exec(sprintf(
				'USE %s',
				$this->escapeIdentifier($name)
		));
	}
}
<?php
declare(strict_types=1);

namespace AppTests;

use Doctrine\Migrations\Version\Direction;
use Doctrine\Migrations\Migrator;
use Mangoweb\Tester\DatabaseCreator\CannotContinueMigrationException;
use Mangoweb\Tester\DatabaseCreator\IMigrationsDriver;
use Nettrine\Migrations\ContainerAwareConfiguration;

class NettrineMigrationsDriver implements IMigrationsDriver
{

	/** @var ContainerAwareConfiguration */
	private $containerAwareConfiguration;

	/** @var Migrator */
	private $migrator;

	public function __construct(ContainerAwareConfiguration $containerAwareConfiguration, Migrator $migrator)
	{
		$this->containerAwareConfiguration = $containerAwareConfiguration;
		$this->migrator = $migrator;
	}

	public function continue(): void
	{
		dump('continue');
	}

	public function getMigrationsHash(): string
	{
		return '';
	}

	public function reset(): void
	{
		$this->migrator->migrate();
	}
}

Ale v NettrineMigrationsDriver nevím, co dát do metody reset. Kod vyhazuje vyjímku Nette\DI\ServiceCreationException: Service 'mango.tester.databaseCreator.migrationsDriver' (type of AppTests\NettrineMigrationsDriver): Service of type Doctrine\Migrations\Migrator needed by $migrator in __construct() not found. Did you register it in configuration file?

Petr Parolek
Člen | 455
+
0
-

Půl dne tu nad tím sedím a před chvílí jsem našel řešení – vykopíroval jsem od z Testbench:

public function reset(): void
	{
		$migrationsConfig = $this->container->getByType(\Nettrine\Migrations\ContainerAwareConfiguration::class);

		$migrationsConfig->__construct($migrationsConfig->getConnection());
		$migrationsConfig->registerMigrationsFromDirectory($migrationsConfig->getMigrationsDirectory());
		$migration = new \Doctrine\DBAL\Migrations\Migration($migrationsConfig);
		$migration->migrate($migrationsConfig->getLatestVersion());
	}

Akorát to má mouchu – funguje na starší verzi doctrine migrations verze 1.8.1, ve 2.x už zmizela třída Doctrine\DBAL\Migrations\Migration. V doc https://github.com/…0/UPGRADE.md#… jsem se dočetl, že mám použít:

$migration = new Migrator($configuration, $migrationRepository, $outputWriter, $stopwatch);

Nevím, kde mám vzít jakýsi repozitář, outputWritter a stopWatch v proměnných.

EDIT

Vyřešeno, stačilo se kouknout, jak vnitřně fungují doctrine migrace a podle toho jsem kod vytvořil:

	public function reset(): void
	{
		$migrationsConfig = $this->container->getByType(\Nettrine\Migrations\ContainerAwareConfiguration::class);

		$migrationsConfig->__construct($migrationsConfig->getConnection());
		$migrationsConfig->registerMigrationsFromDirectory($migrationsConfig->getMigrationsDirectory());
		$dependencyFactory = new \Doctrine\Migrations\DependencyFactory($migrationsConfig);
		$migration = $dependencyFactory->getMigrator();
		$migration->migrate($migrationsConfig->getLatestVersion());
	}

Editoval ppar (3. 10. 2019 22:14)