@@ -8,19 +8,18 @@ namespace Revo.Infrastructure.DataAccess.Migrations
8
8
public class DatabaseMigrationSelector : IDatabaseMigrationSelector
9
9
{
10
10
private readonly IDatabaseMigrationRegistry migrationRegistry ;
11
- private readonly IDatabaseMigrationProvider migrationProvider ;
12
11
private readonly IDatabaseMigrationSelectorOptions selectorOptions ;
13
12
private IReadOnlyCollection < IDatabaseMigrationRecord > history ;
14
13
15
- public DatabaseMigrationSelector ( IDatabaseMigrationRegistry migrationRegistry , IDatabaseMigrationProvider migrationProvider ,
14
+ public DatabaseMigrationSelector ( IDatabaseMigrationRegistry migrationRegistry ,
16
15
IDatabaseMigrationSelectorOptions selectorOptions )
17
16
{
18
17
this . migrationRegistry = migrationRegistry ;
19
- this . migrationProvider = migrationProvider ;
20
18
this . selectorOptions = selectorOptions ;
21
19
}
22
20
23
- public async Task < IReadOnlyCollection < SelectedModuleMigrations > > SelectMigrationsAsync ( DatabaseMigrationSpecifier [ ] modules , string [ ] tags )
21
+ public async Task < IReadOnlyCollection < SelectedModuleMigrations > > SelectMigrationsAsync ( IDatabaseMigrationProvider migrationProvider ,
22
+ DatabaseMigrationSpecifier [ ] modules , string [ ] tags )
24
23
{
25
24
try
26
25
{
@@ -33,7 +32,7 @@ public async Task<IReadOnlyCollection<SelectedModuleMigrations>> SelectMigration
33
32
34
33
foreach ( var module in sortedModules )
35
34
{
36
- var migrations = await DoSelectMigrationsAsync ( module , tags , queuedMigrations ) ;
35
+ var migrations = await DoSelectMigrationsAsync ( module , tags , queuedMigrations , false ) ;
37
36
38
37
if ( migrations . Count > 0 )
39
38
{
@@ -58,10 +57,10 @@ private bool IsRepeatableMigration(DatabaseMigrationSpecifier specifier)
58
57
}
59
58
60
59
private async Task < IReadOnlyCollection < IDatabaseMigration > > DoSelectMigrationsAsync ( DatabaseMigrationSpecifier specifier , string [ ] tags ,
61
- List < DatabaseMigrationSpecifier > queuedMigrations )
60
+ List < DatabaseMigrationSpecifier > queuedMigrations , bool required )
62
61
{
63
- var result = await SelectModuleMigrationsNoDependenciesAsync ( specifier , tags , queuedMigrations ) ;
64
-
62
+ var result = await SelectModuleMigrationsNoDependenciesAsync ( specifier , tags , queuedMigrations , required ) ;
63
+
65
64
foreach ( var migration in result )
66
65
{
67
66
queuedMigrations . Add ( new DatabaseMigrationSpecifier ( migration . ModuleName , migration . Version ) ) ;
@@ -81,7 +80,7 @@ private async Task AddRequiredDependenciesAsync(List<IDatabaseMigration> migrati
81
80
var dependencySpecs = await GetRequiredMigrationDependenciesAsync ( migration , queuedMigrations , tags ) ;
82
81
foreach ( var dependencySpec in dependencySpecs )
83
82
{
84
- var dependencyMigrations = await DoSelectMigrationsAsync ( dependencySpec , tags , queuedMigrations ) ;
83
+ var dependencyMigrations = await DoSelectMigrationsAsync ( dependencySpec , tags , queuedMigrations , true ) ;
85
84
migrations . InsertRange ( i , dependencyMigrations ) ;
86
85
queuedMigrations . AddRange ( dependencyMigrations . Select ( x => new DatabaseMigrationSpecifier ( x . ModuleName , x . Version ) ) ) ;
87
86
i += dependencyMigrations . Count ;
@@ -96,7 +95,7 @@ private async Task<List<DatabaseMigrationSpecifier>> GetRequiredMigrationDepende
96
95
97
96
foreach ( var dependency in migration . Dependencies )
98
97
{
99
- var dependencyMigrations = await SelectModuleMigrationsNoDependenciesAsync ( dependency , tags , queuedMigrations ) ;
98
+ var dependencyMigrations = await SelectModuleMigrationsNoDependenciesAsync ( dependency , tags , queuedMigrations , true ) ;
100
99
if ( dependencyMigrations . Count > 0 )
101
100
{
102
101
dependencies . Add ( new DatabaseMigrationSpecifier (
@@ -109,18 +108,19 @@ private async Task<List<DatabaseMigrationSpecifier>> GetRequiredMigrationDepende
109
108
}
110
109
111
110
private async Task < List < IDatabaseMigration > > SelectModuleMigrationsNoDependenciesAsync ( DatabaseMigrationSpecifier specifier ,
112
- string [ ] tags , List < DatabaseMigrationSpecifier > queuedMigrations )
111
+ string [ ] tags , List < DatabaseMigrationSpecifier > queuedMigrations , bool required )
113
112
{
114
113
var moduleMigrations = migrationRegistry . Migrations
115
- . Where ( x => string . Equals ( x . ModuleName , specifier . ModuleName , StringComparison . InvariantCultureIgnoreCase ) )
114
+ . Where ( x => string . Equals ( x . ModuleName , specifier . ModuleName , StringComparison . InvariantCultureIgnoreCase ) ) ;
115
+ var providerModuleMigrations = moduleMigrations
116
116
. Where ( x => x . Tags . All ( tagGroup => tags . Any ( tagGroup . Contains ) ) ) ;
117
117
118
118
if ( specifier . Version != null )
119
119
{
120
- moduleMigrations = moduleMigrations . Where ( x => x . Version . CompareTo ( specifier . Version ) <= 0 ) ;
120
+ providerModuleMigrations = providerModuleMigrations . Where ( x => x . Version . CompareTo ( specifier . Version ) <= 0 ) ;
121
121
}
122
122
123
- moduleMigrations = moduleMigrations
123
+ providerModuleMigrations = providerModuleMigrations
124
124
. OrderBy ( x => x . Version )
125
125
. ToArray ( ) ;
126
126
@@ -131,14 +131,14 @@ private async Task<List<IDatabaseMigration>> SelectModuleMigrationsNoDependencie
131
131
132
132
if ( specifier . Version != null )
133
133
{
134
- if ( moduleMigrations . Any ( ) && moduleMigrations . Last ( ) . IsRepeatable )
134
+ if ( providerModuleMigrations . Any ( ) && providerModuleMigrations . Last ( ) . IsRepeatable )
135
135
{
136
136
throw new DatabaseMigrationException ( $ "Cannot select database migrations for module { specifier } because it is a repeatable migration module, which means it is versioned only by checksums") ;
137
137
}
138
138
}
139
- else if ( ! moduleMigrations . Any ( ) )
139
+ else if ( ! providerModuleMigrations . Any ( ) )
140
140
{
141
- if ( ! historyMigrations . Any ( ) )
141
+ if ( ! historyMigrations . Any ( ) && ( required || ! moduleMigrations . Any ( ) ) )
142
142
{
143
143
// TODO maybe return without errors if there are migrations for this module with different tags?
144
144
throw new DatabaseMigrationException ( $ "Cannot select database migrations for module { specifier } : no migrations for specified module were found") ;
@@ -147,10 +147,10 @@ private async Task<List<IDatabaseMigration>> SelectModuleMigrationsNoDependencie
147
147
return new List < IDatabaseMigration > ( ) ;
148
148
}
149
149
150
- if ( historyMigrations . Any ( ) && moduleMigrations . Any ( ) )
150
+ if ( historyMigrations . Any ( ) && providerModuleMigrations . Any ( ) )
151
151
{
152
152
bool wasRepeatable = historyMigrations . First ( ) . Version == null ;
153
- bool isRepeatable = moduleMigrations . First ( ) . IsRepeatable ;
153
+ bool isRepeatable = providerModuleMigrations . First ( ) . IsRepeatable ;
154
154
155
155
if ( wasRepeatable != isRepeatable )
156
156
{
@@ -166,7 +166,7 @@ private async Task<List<IDatabaseMigration>> SelectModuleMigrationsNoDependencie
166
166
}
167
167
168
168
// repeatable-migration modules
169
- if ( moduleMigrations . Any ( ) && moduleMigrations . First ( ) . IsRepeatable )
169
+ if ( providerModuleMigrations . Any ( ) && providerModuleMigrations . First ( ) . IsRepeatable )
170
170
{
171
171
if ( moduleQueuedMigrations . Any ( ) )
172
172
{
@@ -177,7 +177,7 @@ private async Task<List<IDatabaseMigration>> SelectModuleMigrationsNoDependencie
177
177
. OrderByDescending ( x => x . TimeApplied )
178
178
. FirstOrDefault ( ) ;
179
179
180
- var migration = moduleMigrations . SingleOrDefault ( )
180
+ var migration = providerModuleMigrations . SingleOrDefault ( )
181
181
?? throw new DatabaseMigrationException ( $ "Cannot select database migrations for repeatable module { specifier } : multiple migrations found") ;
182
182
183
183
// return if same and no dependencies got updated
@@ -214,21 +214,21 @@ private async Task<List<IDatabaseMigration>> SelectModuleMigrationsNoDependencie
214
214
215
215
if ( version == null )
216
216
{
217
- var baseline = moduleMigrations . FirstOrDefault ( x => x . IsBaseline ) ;
217
+ var baseline = providerModuleMigrations . FirstOrDefault ( x => x . IsBaseline ) ;
218
218
if ( baseline != null )
219
219
{
220
220
result . Add ( baseline ) ;
221
- result . AddRange ( moduleMigrations
221
+ result . AddRange ( providerModuleMigrations
222
222
. Where ( x => x . Version . CompareTo ( baseline . Version ) > 0 ) ) ;
223
223
}
224
224
else
225
225
{
226
- result . AddRange ( moduleMigrations ) ;
226
+ result . AddRange ( providerModuleMigrations ) ;
227
227
}
228
228
}
229
229
else
230
230
{
231
- result . AddRange ( moduleMigrations
231
+ result . AddRange ( providerModuleMigrations
232
232
. Where ( x => ! x . IsBaseline && x . Version . CompareTo ( version ) > 0 ) ) ;
233
233
}
234
234
@@ -242,7 +242,7 @@ private async Task<List<IDatabaseMigration>> SelectModuleMigrationsNoDependencie
242
242
}
243
243
else
244
244
{
245
- var maxVersion = moduleMigrations . Select ( x => x . Version ) . Max ( ) ;
245
+ var maxVersion = providerModuleMigrations . Select ( x => x . Version ) . Max ( ) ;
246
246
247
247
if ( ( ! result . Any ( ) && ( version == null || version . CompareTo ( maxVersion ) < 0 ) )
248
248
|| ( result . Any ( ) && ! result . Last ( ) . Version . Equals ( maxVersion ) ) )
0 commit comments