Passed
Pull Request — master (#959)
by Asmir
02:24
created

DependencyFactory::setConfigurationLoader()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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