Completed
Pull Request — master (#1023)
by Asmir
02:45 queued 16s
created

DependencyFactory::getEntityManagerLoader()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

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