Completed
Push — master ( df5690...3e4b0c )
by Asmir
13s queued 10s
created

DependencyFactory::setService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1.037

Importance

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