Completed
Push — master ( 19bd7c...c28f13 )
by Asmir
04:59 queued 02:14
created

DependencyFactory::getMigrationStatusCalculator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations;
6
7
use Doctrine\DBAL\Connection;
8
use Doctrine\Migrations\Configuration\Configuration;
9
use Doctrine\Migrations\Exception\FrozenDependencies;
10
use Doctrine\Migrations\Exception\MissingDependency;
11
use Doctrine\Migrations\Finder\GlobFinder;
12
use Doctrine\Migrations\Finder\MigrationFinder;
13
use Doctrine\Migrations\Finder\RecursiveRegexFinder;
14
use Doctrine\Migrations\Generator\ClassNameGenerator;
15
use Doctrine\Migrations\Generator\ConcatenationFileBuilder;
16
use Doctrine\Migrations\Generator\DiffGenerator;
17
use Doctrine\Migrations\Generator\FileBuilder;
18
use Doctrine\Migrations\Generator\Generator;
19
use Doctrine\Migrations\Generator\SqlGenerator;
20
use Doctrine\Migrations\Metadata\Storage\MetadataStorage;
21
use Doctrine\Migrations\Metadata\Storage\MetadataStorageConfiguration;
22
use Doctrine\Migrations\Metadata\Storage\TableMetadataStorage;
23
use Doctrine\Migrations\Metadata\Storage\TableMetadataStorageConfiguration;
24
use Doctrine\Migrations\Provider\DBALSchemaDiffProvider;
25
use Doctrine\Migrations\Provider\LazySchemaDiffProvider;
26
use Doctrine\Migrations\Provider\OrmSchemaProvider;
27
use Doctrine\Migrations\Provider\SchemaDiffProvider;
28
use Doctrine\Migrations\Provider\SchemaProvider;
29
use Doctrine\Migrations\Tools\Console\ConsoleInputMigratorConfigurationFactory;
30
use Doctrine\Migrations\Tools\Console\Helper\MigrationStatusInfosHelper;
31
use Doctrine\Migrations\Tools\Console\MigratorConfigurationFactory;
32
use Doctrine\Migrations\Version\AliasResolver;
33
use Doctrine\Migrations\Version\CurrentMigrationStatusCalculator;
34
use Doctrine\Migrations\Version\DbalExecutor;
35
use Doctrine\Migrations\Version\DefaultAliasResolver;
36
use Doctrine\Migrations\Version\Executor;
37
use Doctrine\Migrations\Version\MigrationFactory;
38
use Doctrine\Migrations\Version\MigrationPlanCalculator;
39
use Doctrine\Migrations\Version\MigrationStatusCalculator;
40
use Doctrine\Migrations\Version\SortedMigrationPlanCalculator;
41
use Doctrine\ORM\EntityManagerInterface;
42
use Psr\Log\LoggerInterface;
43
use Psr\Log\NullLogger;
44
use Symfony\Component\Stopwatch\Stopwatch as SymfonyStopwatch;
45
use function array_key_exists;
46
use function preg_quote;
47
use function sprintf;
48
49
/**
50
 * The DependencyFactory is responsible for wiring up and managing internal class dependencies.
51
 *
52
 * @internal
53
 */
54
class DependencyFactory
55
{
56
    public const MIGRATIONS_SORTER = 'Doctrine\Migrations\MigrationsSorter';
57
58
    /** @var Configuration */
59
    private $configuration;
60
61
    /** @var object[]|callable[] */
62
    private $dependencies = [];
63
64
    /** @var LoggerInterface */
65
    private $logger;
66
67
    /** @var Connection */
68
    private $connection;
69
70
    /** @var EntityManagerInterface|null */
71
    private $em;
72
73
    /** @var bool */
74
    private $frozen = false;
75
76 39
    public function __construct(Configuration $configuration, Connection $connection, ?EntityManagerInterface $em = null, ?LoggerInterface $logger = null)
77
    {
78 39
        $this->configuration = $configuration;
79 39
        $this->logger        = $logger ?: new NullLogger();
80 39
        $this->connection    = $connection;
81 39
        $this->em            = $em;
82 39
    }
83
84 35
    public function freeze() : void
85
    {
86 35
        $this->frozen = true;
87 35
        $this->configuration->freeze();
88 35
    }
89
90 1
    private function assertNotFrozen() : void
91
    {
92 1
        if ($this->frozen) {
93 1
            throw FrozenDependencies::new();
94
        }
95
    }
96
97 37
    public function getConfiguration() : Configuration
98
    {
99 37
        return $this->configuration;
100
    }
101
102 35
    public function getConnection() : Connection
103
    {
104 35
        return $this->connection;
105
    }
106
107 34
    public function getSorter() : ?callable
108
    {
109
        return $this->getDependency(self::MIGRATIONS_SORTER, static function () {
110 34
            return null;
111 34
        });
112
    }
113
114
    public function getEventDispatcher() : EventDispatcher
115
    {
116
        return $this->getDependency(EventDispatcher::class, function () : EventDispatcher {
117
            return new EventDispatcher(
118
                $this->getConnection(),
119
                $this->getConnection()->getEventManager()
120
            );
121
        });
122
    }
123
124
    public function getClassNameGenerator() : ClassNameGenerator
125
    {
126
        return $this->getDependency(ClassNameGenerator::class, static function () : ClassNameGenerator {
127
            return new ClassNameGenerator();
128
        });
129
    }
130
131
    public function getSchemaDumper() : SchemaDumper
132
    {
133
        return $this->getDependency(SchemaDumper::class, function () : SchemaDumper {
134
            $excludedTables = [];
135
136
            $metadataConfig = $this->configuration->getMetadataStorageConfiguration();
137
            if ($metadataConfig instanceof TableMetadataStorageConfiguration) {
138
                $excludedTables[] = sprintf('/^%s$/', preg_quote($metadataConfig->getTableName(), '/'));
139
            }
140
141
            return new SchemaDumper(
142
                $this->getConnection()->getDatabasePlatform(),
143
                $this->getConnection()->getSchemaManager(),
144
                $this->getMigrationGenerator(),
145
                $this->getMigrationSqlGenerator(),
146
                $excludedTables
147
            );
148
        });
149
    }
150
151
    private function getSchemaProvider() : SchemaProvider
152
    {
153
        return $this->getDependency(SchemaProvider::class, function () : SchemaProvider {
154
            if ($this->em === null) {
155
                throw new MissingDependency('The doctrine entity manager should be provided in order to be able to instantiate SchemaProvider');
156
            }
157
158
            return new OrmSchemaProvider($this->em);
159
        });
160
    }
161
162
    public function getDiffGenerator() : DiffGenerator
163
    {
164
        return $this->getDependency(DiffGenerator::class, function () : DiffGenerator {
165
            return new DiffGenerator(
166
                $this->getConnection()->getConfiguration(),
167
                $this->getConnection()->getSchemaManager(),
168
                $this->getSchemaProvider(),
169
                $this->getConnection()->getDatabasePlatform(),
170
                $this->getMigrationGenerator(),
171
                $this->getMigrationSqlGenerator()
172
            );
173
        });
174
    }
175
176
    public function getSchemaDiffProvider() : SchemaDiffProvider
177
    {
178
        return $this->getDependency(SchemaDiffProvider::class, function () : LazySchemaDiffProvider {
179
            return LazySchemaDiffProvider::fromDefaultProxyFactoryConfiguration(
180
                new DBALSchemaDiffProvider(
181
                    $this->connection->getSchemaManager(),
182
                    $this->connection->getDatabasePlatform()
183
                )
184
            );
185
        });
186
    }
187
188
    public function getFileBuilder() : FileBuilder
189
    {
190
        return $this->getDependency(FileBuilder::class, static function () : FileBuilder {
191
            return new ConcatenationFileBuilder();
192
        });
193
    }
194
195
    public function getParameterFormatter() : ParameterFormatter
196
    {
197
        return $this->getDependency(ParameterFormatter::class, function () : ParameterFormatter {
198
            return new InlineParameterFormatter($this->connection);
199
        });
200
    }
201
202 37
    public function getMigrationsFinder() : MigrationFinder
203
    {
204
        return $this->getDependency(MigrationFinder::class, function () : MigrationFinder {
205 37
            $configs              = $this->getConfiguration();
206 37
            $needsRecursiveFinder = $configs->areMigrationsOrganizedByYear() || $configs->areMigrationsOrganizedByYearAndMonth();
207
208 37
            return $needsRecursiveFinder ? new RecursiveRegexFinder() : new GlobFinder();
209 37
        });
210
    }
211
212 34
    public function getMigrationRepository() : MigrationRepository
213
    {
214
        return $this->getDependency(MigrationRepository::class, function () : MigrationRepository {
215 34
            return new MigrationRepository(
216 34
                $this->getConfiguration()->getMigrationClasses(),
217 34
                $this->getConfiguration()->getMigrationDirectories(),
218 34
                $this->getMigrationsFinder(),
219 34
                new MigrationFactory($this->getConnection(), $this->getLogger()),
220 34
                $this->getSorter()
221
            );
222 34
        });
223
    }
224
225
    /**
226
     * @param object|callable $service
227
     */
228 1
    public function setService(string $id, $service) : void
229
    {
230 1
        $this->assertNotFrozen();
231
        $this->dependencies[$id] = $service;
232
    }
233
234 34
    private function getMetadataStorageConfiguration() : MetadataStorageConfiguration
235
    {
236
        return $this->getDependency(MetadataStorageConfiguration::class, static function () : MetadataStorageConfiguration {
237 34
            return new TableMetadataStorageConfiguration();
238 34
        });
239
    }
240
241 34
    public function getMetadataStorage() : MetadataStorage
242
    {
243
        return $this->getDependency(MetadataStorage::class, function () : MetadataStorage {
244 34
            return new TableMetadataStorage(
245 34
                $this->connection,
246 34
                $this->getMetadataStorageConfiguration()
247
            );
248 34
        });
249
    }
250
251
    public function getEntityManager() : ?EntityManagerInterface
252
    {
253
        return $this->em;
254
    }
255
256 34
    public function getLogger() : LoggerInterface
257
    {
258 34
        return $this->logger;
259
    }
260
261
    public function getVersionExecutor() : Executor
262
    {
263
        return $this->getDependency(Executor::class, function () : Executor {
264
            return new DbalExecutor(
265
                $this->getMetadataStorage(),
266
                $this->getEventDispatcher(),
267
                $this->connection,
268
                $this->getSchemaDiffProvider(),
269
                $this->getLogger(),
270
                $this->getParameterFormatter(),
271
                $this->getStopwatch()
272
            );
273
        });
274
    }
275
276
    public function getQueryWriter() : QueryWriter
277
    {
278
        return $this->getDependency(QueryWriter::class, function () : QueryWriter {
279
            return new FileQueryWriter(
280
                $this->getFileBuilder(),
281
                $this->logger
282
            );
283
        });
284
    }
285
286 15
    public function getVersionAliasResolver() : AliasResolver
287
    {
288
        return $this->getDependency(AliasResolver::class, function () : AliasResolver {
289 15
            return new DefaultAliasResolver(
290 15
                $this->getMigrationRepository(),
291 15
                $this->getMetadataStorage(),
292 15
                $this->getMigrationStatusCalculator()
293
            );
294 15
        });
295
    }
296
297 21
    public function getMigrationStatusCalculator() : MigrationStatusCalculator
298
    {
299
        return $this->getDependency(MigrationStatusCalculator::class, function () : MigrationStatusCalculator {
300 21
            return new CurrentMigrationStatusCalculator(
301 21
                $this->getMigrationRepository(),
302 21
                $this->getMetadataStorage()
303
            );
304 21
        });
305
    }
306
307 10
    public function getMigrationPlanCalculator() : MigrationPlanCalculator
308
    {
309
        return $this->getDependency(MigrationPlanCalculator::class, function () : MigrationPlanCalculator {
310 10
            return new SortedMigrationPlanCalculator(
311 10
                $this->getMigrationRepository(),
312 10
                $this->getMetadataStorage()
313
            );
314 10
        });
315
    }
316
317
    public function getMigrationGenerator() : Generator
318
    {
319
        return $this->getDependency(Generator::class, function () : Generator {
320
            return new Generator($this->getConfiguration());
321
        });
322
    }
323
324
    public function getMigrationSqlGenerator() : SqlGenerator
325
    {
326
        return $this->getDependency(SqlGenerator::class, function () : SqlGenerator {
327
            return new SqlGenerator(
328
                $this->getConfiguration(),
329
                $this->connection->getDatabasePlatform()
330
            );
331
        });
332
    }
333
334 13
    public function getConsoleInputMigratorConfigurationFactory() : MigratorConfigurationFactory
335
    {
336
        return $this->getDependency(MigratorConfigurationFactory::class, function () : MigratorConfigurationFactory {
337 13
            return new ConsoleInputMigratorConfigurationFactory(
338 13
                $this->getConfiguration()
339
            );
340 13
        });
341
    }
342
343 2
    public function getMigrationStatusInfosHelper() : MigrationStatusInfosHelper
344
    {
345
        return $this->getDependency(MigrationStatusInfosHelper::class, function () : MigrationStatusInfosHelper {
346 2
            return new MigrationStatusInfosHelper(
347 2
                $this->getConfiguration(),
348 2
                $this->connection,
349 2
                $this->getVersionAliasResolver()
350
            );
351 2
        });
352
    }
353
354
    public function getMigrator() : Migrator
355
    {
356
        return $this->getDependency(Migrator::class, function () : Migrator {
357
            return new DbalMigrator(
358
                $this->connection,
359
                $this->getEventDispatcher(),
360
                $this->getVersionExecutor(),
361
                $this->logger,
362
                $this->getStopwatch()
363
            );
364
        });
365
    }
366
367
    public function getStopwatch() : Stopwatch
368
    {
369
        return $this->getDependency(Stopwatch::class, static function () : Stopwatch {
370
            $symfonyStopwatch = new SymfonyStopwatch(true);
371
372
            return new Stopwatch($symfonyStopwatch);
373
        });
374
    }
375
376
    public function getRollup() : Rollup
377
    {
378
        return $this->getDependency(Rollup::class, function () : Rollup {
379
            return new Rollup(
380
                $this->getMetadataStorage(),
381
                $this->getMigrationRepository()
382
            );
383
        });
384
    }
385
386
    /**
387
     * @return mixed
388
     */
389 41
    private function getDependency(string $id, callable $callback)
390
    {
391 41
        if (! array_key_exists($id, $this->dependencies)) {
392 41
            $this->dependencies[$id] = $callback();
393
        }
394
395 41
        return $this->dependencies[$id];
396
    }
397
}
398