Completed
Push — master ( f95233...cf7f94 )
by Andreas
15s queued 10s
created

DiffGenerator   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Test Coverage

Coverage 97.73%

Importance

Changes 0
Metric Value
eloc 44
dl 0
loc 116
ccs 43
cts 44
cp 0.9773
rs 10
c 0
b 0
f 0
wmc 12

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 1
A resolveTableName() 0 5 2
A createFromSchema() 0 3 1
A createToSchema() 0 19 4
A generate() 0 37 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations\Generator;
6
7
use Doctrine\DBAL\Configuration as DBALConfiguration;
8
use Doctrine\DBAL\Platforms\AbstractPlatform;
9
use Doctrine\DBAL\Schema\AbstractSchemaManager;
10
use Doctrine\DBAL\Schema\Schema;
11
use Doctrine\Migrations\Generator\Exception\NoChangesDetected;
12
use Doctrine\Migrations\Provider\SchemaProviderInterface;
13
use function preg_match;
14
use function strpos;
15
use function substr;
16
17
/**
18
 * The DiffGenerator class is responsible for comparing two Doctrine\DBAL\Schema\Schema instances and generating a
19
 * migration class with the SQL statements needed to migrate from one schema to the other.
20
 *
21
 * @internal
22
 */
23
class DiffGenerator
24
{
25
    /** @var DBALConfiguration */
26
    private $dbalConfiguration;
27
28
    /** @var AbstractSchemaManager */
29
    private $schemaManager;
30
31
    /** @var SchemaProviderInterface */
32
    private $schemaProvider;
33
34
    /** @var AbstractPlatform */
35
    private $platform;
36
37
    /** @var Generator */
38
    private $migrationGenerator;
39
40
    /** @var SqlGenerator */
41
    private $migrationSqlGenerator;
42
43 6
    public function __construct(
44
        DBALConfiguration $dbalConfiguration,
45
        AbstractSchemaManager $schemaManager,
46
        SchemaProviderInterface $schemaProvider,
47
        AbstractPlatform $platform,
48
        Generator $migrationGenerator,
49
        SqlGenerator $migrationSqlGenerator
50
    ) {
51 6
        $this->dbalConfiguration     = $dbalConfiguration;
52 6
        $this->schemaManager         = $schemaManager;
53 6
        $this->schemaProvider        = $schemaProvider;
54 6
        $this->platform              = $platform;
55 6
        $this->migrationGenerator    = $migrationGenerator;
56 6
        $this->migrationSqlGenerator = $migrationSqlGenerator;
57 6
    }
58
59
    /**
60
     * @throws NoChangesDetected
61
     */
62 6
    public function generate(
63
        string $versionNumber,
64
        ?string $filterExpression,
65
        bool $formatted = false,
66
        int $lineLength = 120,
67
        bool $checkDbPlatform = true
68
    ) : string {
69 6
        if ($filterExpression !== null) {
70 1
            $this->dbalConfiguration->setFilterSchemaAssetsExpression($filterExpression);
71
        }
72
73 6
        $fromSchema = $this->createFromSchema();
74
75 6
        $toSchema = $this->createToSchema();
76
77 6
        $up = $this->migrationSqlGenerator->generate(
78 6
            $fromSchema->getMigrateToSql($toSchema, $this->platform),
79 6
            $formatted,
80 6
            $lineLength,
81 6
            $checkDbPlatform
82
        );
83
84 6
        $down = $this->migrationSqlGenerator->generate(
85 6
            $fromSchema->getMigrateFromSql($toSchema, $this->platform),
86 6
            $formatted,
87 6
            $lineLength,
88 6
            $checkDbPlatform
89
        );
90
91 6
        if ($up === '' && $down === '') {
92
            throw NoChangesDetected::new();
93
        }
94
95 6
        return $this->migrationGenerator->generateMigration(
96 6
            $versionNumber,
97 6
            $up,
98 6
            $down
99
        );
100
    }
101
102 6
    private function createFromSchema() : Schema
103
    {
104 6
        return $this->schemaManager->createSchema();
105
    }
106
107 6
    private function createToSchema() : Schema
108
    {
109 6
        $toSchema = $this->schemaProvider->createSchema();
110
111 6
        $filterExpression = $this->dbalConfiguration->getFilterSchemaAssetsExpression();
112
113 6
        if ($filterExpression !== null) {
114 3
            foreach ($toSchema->getTables() as $table) {
115 3
                $tableName = $table->getName();
116
117 3
                if (preg_match($filterExpression, $this->resolveTableName($tableName)) === 1) {
118 3
                    continue;
119
                }
120
121 2
                $toSchema->dropTable($tableName);
122
            }
123
        }
124
125 6
        return $toSchema;
126
    }
127
128
    /**
129
     * Resolve a table name from its fully qualified name. The `$name` argument
130
     * comes from Doctrine\DBAL\Schema\Table#getName which can sometimes return
131
     * a namespaced name with the form `{namespace}.{tableName}`. This extracts
132
     * the table name from that.
133
     */
134 3
    private function resolveTableName(string $name) : string
135
    {
136 3
        $pos = strpos($name, '.');
137
138 3
        return $pos === false ? $name : substr($name, $pos + 1);
139
    }
140
}
141