Completed
Pull Request — master (#440)
by Alejandro
17:40 queued 14:38
created

CreateDatabaseCommand   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 75
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 8
eloc 29
c 3
b 0
f 0
dl 0
loc 75
ccs 29
cts 29
cp 1
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getLockConfig() 0 3 1
A schemaExists() 0 6 1
A configure() 0 6 1
A checkDbExists() 0 10 2
A lockedExecute() 0 17 2
A __construct() 0 10 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\CLI\Command\Db;
5
6
use Doctrine\DBAL\Connection;
7
use Shlinkio\Shlink\CLI\Command\Util\LockedCommandConfig;
8
use Shlinkio\Shlink\CLI\Util\ExitCodes;
9
use Symfony\Component\Console\Helper\ProcessHelper;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Symfony\Component\Console\Style\SymfonyStyle;
13
use Symfony\Component\Lock\Factory as Locker;
14
use Symfony\Component\Process\PhpExecutableFinder;
15
16
use function Functional\contains;
17
18
class CreateDatabaseCommand extends AbstractDatabaseCommand
19
{
20
    public const NAME = 'db:create';
21
    public const DOCTRINE_HELPER_SCRIPT = 'vendor/doctrine/orm/bin/doctrine.php';
22
    public const DOCTRINE_HELPER_COMMAND = 'orm:schema-tool:create';
23
24
    /** @var Connection */
25
    private $regularConn;
26
    /** @var Connection */
27
    private $noDbNameConn;
28
29 3
    public function __construct(
30
        Locker $locker,
31
        ProcessHelper $processHelper,
32
        PhpExecutableFinder $phpFinder,
33
        Connection $conn,
34
        Connection $noDbNameConn
35
    ) {
36 3
        parent::__construct($locker, $processHelper, $phpFinder);
37 3
        $this->regularConn = $conn;
38 3
        $this->noDbNameConn = $noDbNameConn;
39
    }
40
41 3
    protected function configure(): void
42
    {
43
        $this
44 3
            ->setName(self::NAME)
45 3
            ->setDescription(
46 3
                'Creates the database needed for shlink to work. It will do nothing if the database already exists'
47
            );
48
    }
49
50 3
    protected function lockedExecute(InputInterface $input, OutputInterface $output): int
51
    {
52 3
        $io = new SymfonyStyle($input, $output);
53
54 3
        $this->checkDbExists();
55
56 3
        if ($this->schemaExists()) {
57 2
            $io->success('Database already exists. Run "db:migrate" command to make sure it is up to date.');
58 2
            return ExitCodes::EXIT_SUCCESS;
59
        }
60
61
        // Create database
62 1
        $io->writeln('<fg=blue>Creating database tables...</>');
63 1
        $this->runPhpCommand($output, [self::DOCTRINE_HELPER_SCRIPT, self::DOCTRINE_HELPER_COMMAND]);
64 1
        $io->success('Database properly created!');
65
66 1
        return ExitCodes::EXIT_SUCCESS;
67
    }
68
69 3
    private function checkDbExists(): void
70
    {
71
        // In order to create the new database, we have to use a connection where the dbname was not set.
72
        // Otherwise, it will fail to connect and will not be able to create the new database
73 3
        $schemaManager = $this->noDbNameConn->getSchemaManager();
74 3
        $databases = $schemaManager->listDatabases();
75 3
        $shlinkDatabase = $this->regularConn->getDatabase();
76
77 3
        if (! contains($databases, $shlinkDatabase)) {
78 1
            $schemaManager->createDatabase($shlinkDatabase);
79
        }
80
    }
81
82 3
    private function schemaExists(): bool
83
    {
84
        // If at least one of the shlink tables exist, we will consider the database exists somehow.
85
        // Any inconsistency will be taken care by the migrations
86 3
        $schemaManager = $this->regularConn->getSchemaManager();
87 3
        return ! empty($schemaManager->listTableNames());
88
    }
89
90 3
    protected function getLockConfig(): LockedCommandConfig
91
    {
92 3
        return new LockedCommandConfig($this->getName(), true);
93
    }
94
}
95