Skip to content

Commit ca841a2

Browse files
committed
implement forward compatibility layer for v3.x
1 parent 1ac5511 commit ca841a2

File tree

4 files changed

+151
-9
lines changed

4 files changed

+151
-9
lines changed

DependencyInjection/Configuration.php

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
99
use Symfony\Component\Config\Definition\ConfigurationInterface;
1010
use function constant;
11+
use function count;
1112
use function in_array;
1213
use function is_string;
1314
use function method_exists;
@@ -41,14 +42,75 @@ public function getConfigTreeBuilder() : TreeBuilder
4142

4243
$rootNode
4344
->children()
44-
->scalarNode('dir_name')->defaultValue('%kernel.root_dir%/DoctrineMigrations')->cannotBeEmpty()->end()
45-
->scalarNode('namespace')->defaultValue('Application\Migrations')->cannotBeEmpty()->end()
46-
->scalarNode('table_name')->defaultValue('migration_versions')->cannotBeEmpty()->end()
47-
->scalarNode('column_name')->defaultValue('version')->end()
48-
->scalarNode('column_length')->defaultValue(14)->end()
49-
->scalarNode('executed_at_column_name')->defaultValue('executed_at')->end()
50-
->scalarNode('all_or_nothing')->defaultValue(false)->end()
5145
->scalarNode('name')->defaultValue('Application Migrations')->end()
46+
47+
// 3.x forward compatibility layer
48+
->arrayNode('migrations_paths')
49+
->info('A list of pairs namespace/path where to look for migrations.')
50+
->useAttributeAsKey('name')
51+
->defaultValue([])
52+
->prototype('scalar')->end()
53+
->validate()
54+
->ifTrue(static function ($v) {
55+
return count($v) === 0;
56+
})
57+
->thenInvalid('At least one migrations path must be specified.')
58+
59+
->ifTrue(static function ($v) {
60+
return count($v) > 1;
61+
})
62+
->thenInvalid('Maximum one migration path can be specified with the 2.x version.')
63+
->end()
64+
->end()
65+
66+
->arrayNode('storage')
67+
->info('Storage to use for migration status metadata.')
68+
->children()
69+
->arrayNode('table_storage')
70+
->info('The default metadata storage, implemented as table in the database.')
71+
->children()
72+
->scalarNode('table_name')->defaultValue(null)->cannotBeEmpty()->end()
73+
->scalarNode('version_column_name')->defaultValue(null)->end()
74+
->scalarNode('version_column_length')
75+
->defaultValue(null)
76+
->validate()
77+
->ifTrue(static function ($v) {
78+
return $v< 1024;
79+
})
80+
->thenInvalid('The minimum length for the version column is 1024.')
81+
->end()
82+
->end()
83+
->scalarNode('executed_at_column_name')->defaultValue(null)->end()
84+
->end()
85+
->end()
86+
->end()
87+
->end()
88+
89+
->scalarNode('dir_name')
90+
->defaultValue('%kernel.root_dir%/DoctrineMigrations')->cannotBeEmpty()
91+
->setDeprecated('The "%node%" option is deprecated. Use "migrations_paths" instead.')
92+
->end()
93+
->scalarNode('namespace')
94+
->defaultValue('Application\Migrations')->cannotBeEmpty()
95+
->setDeprecated('The "%node%" option is deprecated. Use "migrations_paths" instead.')
96+
->end()
97+
->scalarNode('table_name')
98+
->defaultValue('migration_versions')->cannotBeEmpty()
99+
->setDeprecated('The "%node%" option is deprecated. Use "storage.table_storage.table_name" instead.')
100+
->end()
101+
->scalarNode('column_name')
102+
->defaultValue('version')
103+
->setDeprecated('The "%node%" option is deprecated. Use "storage.table_storage.version_column_name" instead.')
104+
->end()
105+
->scalarNode('column_length')
106+
->defaultValue(14)
107+
->setDeprecated('The "%node%" option is deprecated. Use "storage.table_storage.version_column_length" instead.')
108+
->end()
109+
->scalarNode('executed_at_column_name')
110+
->defaultValue('executed_at')
111+
->setDeprecated('The "%node%" option is deprecated. Use "storage.table_storage.executed_at_column_name" instead.')
112+
->end()
113+
->scalarNode('all_or_nothing')->defaultValue(false)->end()
52114
->scalarNode('custom_template')->defaultValue(null)->end()
53115
->scalarNode('organize_migrations')->defaultValue(false)
54116
->info('Organize migrations mode. Possible values are: "BY_YEAR", "BY_YEAR_AND_MONTH", false')

DependencyInjection/DoctrineMigrationsExtension.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
use Symfony\Component\DependencyInjection\ContainerBuilder;
99
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
1010
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
11+
use function count;
12+
use function current;
13+
use function key;
1114

1215
/**
1316
* DoctrineMigrationsExtension.
@@ -25,6 +28,30 @@ public function load(array $configs, ContainerBuilder $container) : void
2528

2629
$config = $this->processConfiguration($configuration, $configs);
2730

31+
// 3.x forward compatibility layer
32+
if (isset($config['migrations_paths']) && count($config['migrations_paths'])>0) {
33+
$config['namespace'] = key($config['migrations_paths']);
34+
$config['dir_name'] = current($config['migrations_paths']);
35+
unset($config['migrations_paths']);
36+
}
37+
38+
if (isset($config['storage']['table_storage'])) {
39+
$storageConfig = $config['storage']['table_storage'];
40+
if (isset($storageConfig['table_name'])) {
41+
$config['table_name'] = $storageConfig['table_name'];
42+
}
43+
if (isset($storageConfig['version_column_name'])) {
44+
$config['column_name'] = $storageConfig['version_column_name'];
45+
}
46+
if (isset($storageConfig['version_column_length'])) {
47+
$config['column_length'] = $storageConfig['version_column_length'];
48+
}
49+
if (isset($storageConfig['executed_at_column_name'])) {
50+
$config['executed_at_column_name'] = $storageConfig['executed_at_column_name'];
51+
}
52+
unset($config['storage']);
53+
}
54+
2855
foreach ($config as $key => $value) {
2956
$container->setParameter($this->getAlias() . '.' . $key, $value);
3057
}

Resources/doc/index.rst

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,36 @@ application:
4141
4242
# config/packages/doctrine_migrations.yaml
4343
doctrine_migrations:
44+
name: 'Application Migrations'
45+
46+
# Namespace/path to search for migrations
47+
migrations_paths:
48+
'DoctrineMigrations': '%kernel.project_dir%/src/Migrations'
49+
50+
# Deprecated since v2.2, use "migrations_paths" instead (array value)
4451
dir_name: '%kernel.project_dir%/src/Migrations'
52+
53+
# Deprecated since v2.2, use "migrations_paths" instead (array key)
4554
namespace: DoctrineMigrations
55+
56+
storage:
57+
# Default (SQL table) metadata storage configuration
58+
table_storage:
59+
table_name: 'migration_versions'
60+
version_column_name: 'version'
61+
version_column_length: 1024
62+
executed_at_column_name: 'executed_at'
63+
execution_time_column_name: 'execution_time'
64+
65+
# Deprecated since v2.2, use "storage.table_storage.table_name" instead
4666
table_name: 'migration_versions'
67+
# Deprecated since v2.2, use "storage.table_storage.version_column_name" instead
4768
column_name: 'version'
69+
# Deprecated since v2.2, use "storage.table_storage.version_column_length" instead (minimum value has to be at least 1024)
4870
column_length: 14
71+
# Deprecated since v2.2, use "storage.table_storage.execution_time_column_name" instead
4972
executed_at_column_name: 'executed_at'
50-
name: 'Application Migrations'
73+
5174
# available in version >= 1.2. Possible values: "BY_YEAR", "BY_YEAR_AND_MONTH", false
5275
organize_migrations: false
5376
# available in version >= 1.3. Path to your custom migrations template
@@ -192,7 +215,7 @@ fill in the ``up()`` and ``down()`` methods), see the official Doctrine Migratio
192215

193216
.. tip::
194217

195-
If you need to use another database connection to execute migrations you may use option ``--db="doctrine-connection-name"``
218+
If you need to use another database connection to execute migrations you may use option ``--db="doctrine-connection-name"``
196219
where ``doctrine-connection-name`` is valid Doctrine connection defined in doctrine.yaml
197220

198221
Running Migrations during Deployment

Tests/DependencyInjection/DoctrineMigrationsExtensionTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,36 @@ public function testOrganizeMigrations() : void
2828
);
2929
}
3030

31+
public function testForwardCompatibilityLayer() : void
32+
{
33+
$container = $this->getContainer();
34+
$extension = new DoctrineMigrationsExtension();
35+
36+
$config = [
37+
'storage' => [
38+
'table_storage' => [
39+
'table_name' => 'doctrine_migration_versions_test',
40+
'version_column_name' => 'doctrine_migration_column_test',
41+
'version_column_length' => 2000,
42+
'executed_at_column_name' => 'doctrine_migration_executed_at_column_test',
43+
],
44+
],
45+
46+
'migrations_paths' => ['DoctrineMigrationsTest' => 'a'],
47+
48+
];
49+
50+
$extension->load(['doctrine_migrations' => $config], $container);
51+
52+
$this->assertEquals('a', $container->getParameter('doctrine_migrations.dir_name'));
53+
$this->assertEquals('DoctrineMigrationsTest', $container->getParameter('doctrine_migrations.namespace'));
54+
$this->assertEquals('doctrine_migration_versions_test', $container->getParameter('doctrine_migrations.table_name'));
55+
$this->assertEquals('doctrine_migration_column_test', $container->getParameter('doctrine_migrations.column_name'));
56+
$this->assertEquals(2000, $container->getParameter('doctrine_migrations.column_length'));
57+
$this->assertEquals(2000, $container->getParameter('doctrine_migrations.column_length'));
58+
$this->assertEquals('doctrine_migration_executed_at_column_test', $container->getParameter('doctrine_migrations.executed_at_column_name'));
59+
}
60+
3161
private function getContainer() : ContainerBuilder
3262
{
3363
return new ContainerBuilder(new ParameterBag([

0 commit comments

Comments
 (0)