Passed
Push — master ( 5085bf...8511d7 )
by Kevin
04:52
created

DatabaseResetter::runCommand()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.0185

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 3
dl 0
loc 9
ccs 5
cts 6
cp 0.8333
crap 2.0185
rs 10
1
<?php
2
3
namespace Zenstruck\Foundry\Test;
4
5
use DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver;
6
use Doctrine\Persistence\ManagerRegistry;
7
use Symfony\Bundle\FrameworkBundle\Console\Application;
8
use Symfony\Component\Console\Input\ArrayInput;
9
use Symfony\Component\Console\Output\BufferedOutput;
10
use Symfony\Component\HttpKernel\KernelInterface;
11
use Zenstruck\Foundry\Factory;
12
13
/**
14
 * @internal
15
 *
16
 * @author Kevin Bond <[email protected]>
17
 */
18
final class DatabaseResetter
19
{
20
    /** @var bool */
21
    private static $hasBeenReset = false;
22
23
    public static function hasBeenReset(): bool
24
    {
25
        if (isset($_SERVER['FOUNDRY_DISABLE_DATABASE_RESET'])) {
26
            return true;
27
        }
28
29
        return self::$hasBeenReset;
30
    }
31
32 634
    public static function isDAMADoctrineTestBundleEnabled(): bool
33
    {
34 634
        return \class_exists(StaticDriver::class) && StaticDriver::isKeepStaticConnections();
35
    }
36
37
    public static function resetDatabase(KernelInterface $kernel): void
38
    {
39
        $application = self::createApplication($kernel);
40
        $registry = $kernel->getContainer()->get('doctrine');
41
42
        foreach (self::connectionsToReset($registry) as $connection) {
0 ignored issues
show
Bug introduced by
It seems like $registry can also be of type null; however, parameter $registry of Zenstruck\Foundry\Test\D...r::connectionsToReset() does only seem to accept Doctrine\Persistence\ManagerRegistry, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

42
        foreach (self::connectionsToReset(/** @scrutinizer ignore-type */ $registry) as $connection) {
Loading history...
43
            $dropParams = ['--connection' => $connection, '--force' => true];
44
45
            if ('sqlite' !== $registry->getConnection($connection)->getDatabasePlatform()->getName()) {
46
                // sqlite does not support "--if-exists" (ref: https://github.com/doctrine/dbal/pull/2402)
47
                $dropParams['--if-exists'] = true;
48
            }
49
50
            self::runCommand($application, 'doctrine:database:drop', $dropParams);
51
52
            self::runCommand($application, 'doctrine:database:create', [
53
                '--connection' => $connection,
54
            ]);
55
        }
56
57
        self::createSchema($application, $registry);
0 ignored issues
show
Bug introduced by
It seems like $registry can also be of type null; however, parameter $registry of Zenstruck\Foundry\Test\D...esetter::createSchema() does only seem to accept Doctrine\Persistence\ManagerRegistry, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

57
        self::createSchema($application, /** @scrutinizer ignore-type */ $registry);
Loading history...
58
59
        self::$hasBeenReset = true;
60
    }
61
62 381
    public static function resetSchema(KernelInterface $kernel): void
63
    {
64 381
        $application = self::createApplication($kernel);
65 381
        $registry = $kernel->getContainer()->get('doctrine');
66
67 381
        self::dropSchema($application, $registry);
0 ignored issues
show
Bug introduced by
It seems like $registry can also be of type null; however, parameter $registry of Zenstruck\Foundry\Test\D...eResetter::dropSchema() does only seem to accept Doctrine\Persistence\ManagerRegistry, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

67
        self::dropSchema($application, /** @scrutinizer ignore-type */ $registry);
Loading history...
68 381
        self::createSchema($application, $registry);
0 ignored issues
show
Bug introduced by
It seems like $registry can also be of type null; however, parameter $registry of Zenstruck\Foundry\Test\D...esetter::createSchema() does only seem to accept Doctrine\Persistence\ManagerRegistry, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

68
        self::createSchema($application, /** @scrutinizer ignore-type */ $registry);
Loading history...
69 381
    }
70
71 381
    private static function createSchema(Application $application, ManagerRegistry $registry): void
72
    {
73 381
        foreach (self::objectManagersToReset($registry) as $manager) {
74 381
            self::runCommand($application, 'doctrine:schema:create', [
75 381
                '--em' => $manager,
76
            ]);
77
        }
78
79 381
        if (!Factory::isBooted()) {
80 186
            TestState::bootFromContainer($application->getKernel()->getContainer());
81
        }
82
83 381
        TestState::flushGlobalState();
84 381
    }
85
86 381
    private static function dropSchema(Application $application, ManagerRegistry $registry): void
87
    {
88 381
        foreach (self::objectManagersToReset($registry) as $manager) {
89 381
            self::runCommand($application, 'doctrine:schema:drop', [
90 381
                '--em' => $manager,
91
                '--force' => true,
92
            ]);
93
        }
94 381
    }
95
96 381
    private static function runCommand(Application $application, string $command, array $parameters = []): void
97
    {
98 381
        $exit = $application->run(
99 381
            new ArrayInput(\array_merge(['command' => $command], $parameters)),
100 381
            $output = new BufferedOutput()
101
        );
102
103 381
        if (0 !== $exit) {
104
            throw new \RuntimeException(\sprintf('Error running "%s": %s', $command, $output->fetch()));
105
        }
106 381
    }
107
108 381
    private static function createApplication(KernelInterface $kernel): Application
109
    {
110 381
        $application = new Application($kernel);
111 381
        $application->setAutoExit(false);
112
113 381
        return $application;
114
    }
115
116
    private static function connectionsToReset(ManagerRegistry $registry): array
117
    {
118
        if (isset($_SERVER['FOUNDRY_RESET_CONNECTIONS'])) {
119
            return \explode(',', $_SERVER['FOUNDRY_RESET_CONNECTIONS']);
120
        }
121
122
        return [$registry->getDefaultConnectionName()];
123
    }
124
125 381
    private static function objectManagersToReset(ManagerRegistry $registry): array
126
    {
127 381
        if (isset($_SERVER['FOUNDRY_RESET_OBJECT_MANAGERS'])) {
128
            return \explode(',', $_SERVER['FOUNDRY_RESET_OBJECT_MANAGERS']);
129
        }
130
131 381
        return [$registry->getDefaultManagerName()];
132
    }
133
}
134