From f78fa58cf1889abdf0d992177dc87be952fe49ce Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 5 Aug 2019 10:08:59 +0200 Subject: [PATCH] Updated CreateDatabaseCommand to create the empty database if it does not exist --- config/autoload/installer.global.php | 9 ++++ module/CLI/config/dependencies.config.php | 2 + .../Command/Db/AbstractDatabaseCommand.php | 33 +++++++++++++ .../src/Command/Db/CreateDatabaseCommand.php | 47 ++++++++++--------- module/Common/config/doctrine.config.php | 2 + .../Common/src/Doctrine/ConnectionFactory.php | 17 +++++++ .../test/Doctrine/ConnectionFactoryTest.php | 44 +++++++++++++++++ 7 files changed, 132 insertions(+), 22 deletions(-) create mode 100644 module/CLI/src/Command/Db/AbstractDatabaseCommand.php create mode 100644 module/Common/src/Doctrine/ConnectionFactory.php create mode 100644 module/Common/test/Doctrine/ConnectionFactoryTest.php diff --git a/config/autoload/installer.global.php b/config/autoload/installer.global.php index b258585e..7739ae4c 100644 --- a/config/autoload/installer.global.php +++ b/config/autoload/installer.global.php @@ -36,4 +36,13 @@ return [ ], ], + 'installation_commands' => [ + 'db_create_schema' => [ + 'command' => 'bin/cli db:create', + ], +// 'db_migrate' => [ +// 'command' => 'bin/cli db:migrate', +// ], + ], + ]; diff --git a/module/CLI/config/dependencies.config.php b/module/CLI/config/dependencies.config.php index b71598a9..5df6ea4d 100644 --- a/module/CLI/config/dependencies.config.php +++ b/module/CLI/config/dependencies.config.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI; +use Doctrine\DBAL\Connection; use GeoIp2\Database\Reader; use Shlinkio\Shlink\CLI\Util\GeolocationDbUpdater; use Shlinkio\Shlink\Common\IpGeolocation\GeoLite2\DbUpdater; @@ -83,6 +84,7 @@ return [ Locker::class, SymfonyCli\Helper\ProcessHelper::class, PhpExecutableFinder::class, + Connection::class, ], ], diff --git a/module/CLI/src/Command/Db/AbstractDatabaseCommand.php b/module/CLI/src/Command/Db/AbstractDatabaseCommand.php new file mode 100644 index 00000000..99eb5c36 --- /dev/null +++ b/module/CLI/src/Command/Db/AbstractDatabaseCommand.php @@ -0,0 +1,33 @@ +processHelper = $processHelper; + $this->phpBinary = $phpFinder->find(false) ?: 'php'; + } + + protected function runPhpCommand(OutputInterface $output, array $command): void + { + array_unshift($command, $this->phpBinary); + $this->processHelper->run($output, $command); + } +} diff --git a/module/CLI/src/Command/Db/CreateDatabaseCommand.php b/module/CLI/src/Command/Db/CreateDatabaseCommand.php index 188e2e68..4b4202a0 100644 --- a/module/CLI/src/Command/Db/CreateDatabaseCommand.php +++ b/module/CLI/src/Command/Db/CreateDatabaseCommand.php @@ -3,7 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\Db; -use Shlinkio\Shlink\CLI\Command\Util\AbstractLockedCommand; +use Doctrine\DBAL\Connection; use Shlinkio\Shlink\CLI\Command\Util\LockedCommandConfig; use Shlinkio\Shlink\CLI\Util\ExitCodes; use Symfony\Component\Console\Helper\ProcessHelper; @@ -13,22 +13,25 @@ use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Lock\Factory as Locker; use Symfony\Component\Process\PhpExecutableFinder; -class CreateDatabaseCommand extends AbstractLockedCommand +use function Functional\contains; + +class CreateDatabaseCommand extends AbstractDatabaseCommand { public const NAME = 'db:create'; private const DOCTRINE_HELPER_SCRIPT = 'vendor/doctrine/orm/bin/doctrine.php'; private const DOCTRINE_HELPER_COMMAND = 'orm:schema-tool:create'; - /** @var ProcessHelper */ - private $processHelper; - /** @var string */ - private $phpBinary; + /** @var Connection */ + private $conn; - public function __construct(Locker $locker, ProcessHelper $processHelper, PhpExecutableFinder $phpFinder) - { - parent::__construct($locker); - $this->processHelper = $processHelper; - $this->phpBinary = $phpFinder->find(false) ?: 'php'; + public function __construct( + Locker $locker, + ProcessHelper $processHelper, + PhpExecutableFinder $phpFinder, + Connection $conn + ) { + parent::__construct($locker, $processHelper, $phpFinder); + $this->conn = $conn; } protected function configure(): void @@ -44,34 +47,34 @@ class CreateDatabaseCommand extends AbstractLockedCommand { $io = new SymfonyStyle($input, $output); - if ($this->dbExistsAndIsPopulated()) { + $this->checkDbExists(); + + if ($this->schemaExists()) { $io->success('Database already exists.'); return ExitCodes::EXIT_SUCCESS; } - if (! $this->schemaExists()) { - // TODO Create empty database - } - // Create database $io->writeln('Creating database tables...'); - $command = [$this->phpBinary, self::DOCTRINE_HELPER_SCRIPT, self::DOCTRINE_HELPER_COMMAND]; - $this->processHelper->run($output, $command); + $this->runPhpCommand($output, [self::DOCTRINE_HELPER_SCRIPT, self::DOCTRINE_HELPER_COMMAND]); $io->success('Database properly created!'); return ExitCodes::EXIT_SUCCESS; } - private function dbExistsAndIsPopulated(): bool + private function checkDbExists(): void { - // TODO Implement - return false; + $schemaManager = $this->conn->getSchemaManager(); + $databases = $schemaManager->listDatabases(); + if (! contains($databases, '')) { + $schemaManager->createDatabase($this->conn->getDatabase()); + } } private function schemaExists(): bool { // TODO Implement - return true; + return false; } protected function getLockConfig(): LockedCommandConfig diff --git a/module/Common/config/doctrine.config.php b/module/Common/config/doctrine.config.php index 66d678af..547724f2 100644 --- a/module/Common/config/doctrine.config.php +++ b/module/Common/config/doctrine.config.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Common; +use Doctrine\DBAL\Connection; use Doctrine\ORM\EntityManager; return [ @@ -18,6 +19,7 @@ return [ 'dependencies' => [ 'factories' => [ EntityManager::class => Doctrine\EntityManagerFactory::class, + Connection::class => Doctrine\ConnectionFactory::class, ], 'aliases' => [ 'em' => EntityManager::class, diff --git a/module/Common/src/Doctrine/ConnectionFactory.php b/module/Common/src/Doctrine/ConnectionFactory.php new file mode 100644 index 00000000..f0c1a561 --- /dev/null +++ b/module/Common/src/Doctrine/ConnectionFactory.php @@ -0,0 +1,17 @@ +get(EntityManager::class); + return $em->getConnection(); + } +} diff --git a/module/Common/test/Doctrine/ConnectionFactoryTest.php b/module/Common/test/Doctrine/ConnectionFactoryTest.php new file mode 100644 index 00000000..a89ef79c --- /dev/null +++ b/module/Common/test/Doctrine/ConnectionFactoryTest.php @@ -0,0 +1,44 @@ +container = $this->prophesize(ContainerInterface::class); + $this->em = $this->prophesize(EntityManagerInterface::class); + $this->container->get(EntityManager::class)->willReturn($this->em->reveal()); + + $this->factory = new ConnectionFactory(); + } + + /** @test */ + public function properServiceFallbackOccursWhenInvoked(): void + { + $connection = $this->prophesize(Connection::class)->reveal(); + $getConnection = $this->em->getConnection()->willReturn($connection); + + $result = ($this->factory)($this->container->reveal()); + + $this->assertSame($connection, $result); + $getConnection->shouldHaveBeenCalledOnce(); + $this->container->get(EntityManager::class)->shouldHaveBeenCalledOnce(); + } +}