Completed
Push — checkout-consistent-prices ( af49ca )
by Kamil
13:24
created

ands()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 3
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Sylius\Bundle\CoreBundle\Installer\Provider;
15
16
use Doctrine\Bundle\DoctrineBundle\Registry;
17
use Doctrine\DBAL\Schema\AbstractSchemaManager;
18
use Doctrine\ORM\EntityManagerInterface;
19
use Symfony\Component\Console\Helper\QuestionHelper;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Output\OutputInterface;
22
use Symfony\Component\Console\Question\ConfirmationQuestion;
23
use Symfony\Component\Console\Style\SymfonyStyle;
24
25
final class DatabaseSetupCommandsProvider implements DatabaseSetupCommandsProviderInterface
26
{
27
    /** @var Registry */
28
    private $doctrineRegistry;
29
30
    public function __construct(Registry $doctrineRegistry)
31
    {
32
        $this->doctrineRegistry = $doctrineRegistry;
33
    }
34
35
    /**
36
     * {@inheritdoc}
37
     */
38
    public function getCommands(InputInterface $input, OutputInterface $output, QuestionHelper $questionHelper): array
39
    {
40
        if (!$this->isDatabasePresent()) {
41
            return [
42
                'doctrine:database:create',
43
                'doctrine:migrations:migrate' => ['--no-interaction' => true],
44
            ];
45
        }
46
47
        return array_merge($this->setupDatabase($input, $output, $questionHelper), [
48
            'doctrine:migrations:version' => [
49
                '--add' => true,
50
                '--all' => true,
51
                '--no-interaction' => true,
52
            ],
53
        ]);
54
    }
55
56
    /**
57
     * @throws \Exception
58
     */
59
    private function isDatabasePresent(): bool
60
    {
61
        $databaseName = $this->getDatabaseName();
62
63
        try {
64
            $schemaManager = $this->getSchemaManager();
65
66
            return in_array($databaseName, $schemaManager->listDatabases());
67
        } catch (\Exception $exception) {
68
            $message = $exception->getMessage();
69
70
            $mysqlDatabaseError = false !== strpos($message, sprintf("Unknown database '%s'", $databaseName));
71
            $postgresDatabaseError = false !== strpos($message, sprintf('database "%s" does not exist', $databaseName));
72
73
            if ($mysqlDatabaseError || $postgresDatabaseError) {
74
                return false;
75
            }
76
77
            throw $exception;
78
        }
79
    }
80
81
    private function setupDatabase(InputInterface $input, OutputInterface $output, QuestionHelper $questionHelper): array
82
    {
83
        $outputStyle = new SymfonyStyle($input, $output);
84
        $outputStyle->writeln('It appears that your database already exists.');
85
        $outputStyle->writeln('<error>Warning! This action will erase your database.</error>');
86
87
        $question = new ConfirmationQuestion('Would you like to reset it? (y/N) ', false);
88
        if ($questionHelper->ask($input, $output, $question)) {
89
            return [
90
                'doctrine:database:drop' => ['--force' => true],
91
                'doctrine:database:create',
92
                'doctrine:migrations:migrate' => ['--no-interaction' => true],
93
            ];
94
        }
95
96
        if (!$this->isSchemaPresent()) {
97
            return ['doctrine:migrations:migrate' => ['--no-interaction' => true]];
98
        }
99
100
        $outputStyle->writeln('Seems like your database contains schema.');
101
        $outputStyle->writeln('<error>Warning! This action will erase your database.</error>');
102
        $question = new ConfirmationQuestion('Do you want to reset it? (y/N) ', false);
103
        if ($questionHelper->ask($input, $output, $question)) {
104
            return [
105
                'doctrine:schema:drop' => ['--force' => true],
106
                'doctrine:migrations:migrate' => ['--no-interaction' => true],
107
            ];
108
        }
109
110
        return [];
111
    }
112
113
    private function isSchemaPresent(): bool
114
    {
115
        return 0 !== count($this->getSchemaManager()->listTableNames());
116
    }
117
118
    private function getDatabaseName(): string
119
    {
120
        return (string) $this->getEntityManager()->getConnection()->getDatabase();
121
    }
122
123
    private function getSchemaManager(): AbstractSchemaManager
124
    {
125
        return $this->getEntityManager()->getConnection()->getSchemaManager();
126
    }
127
128
    private function getEntityManager(): EntityManagerInterface
129
    {
130
        return $this->doctrineRegistry->getManager();
131
    }
132
}
133