public async Task SelectMigrationsAsync_MigrationNeedNotExistIfAlreadyUpToDate_WithBaseline() { migrationProvider.GetMigrationHistoryAsync() .Returns(new[] { new FakeDatabaseMigrationRecord() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0") } }); migrationRegistry.Migrations.Returns(new List <IDatabaseMigration>() { new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.1"), IsBaseline = true } }); var migrations = await sut.SelectMigrationsAsync( new[] { new DatabaseMigrationSpecifier("appModule1", DatabaseVersion.Parse("1.0.0")) }, new string[0]); migrations.Should().BeEmpty(); }
public async Task SelectMigrationsAsync_NoopWhenVersionsMatch() { migrationProvider.GetMigrationHistoryAsync() .Returns(new[] { new FakeDatabaseMigrationRecord() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0") } }); migrationRegistry.Migrations.Returns(new List <IDatabaseMigration>() { new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0") } }); var migrations = await sut.SelectMigrationsAsync( new[] { new DatabaseMigrationSpecifier("appModule1", null) }, new string[0]); migrations.Should().BeEmpty(); }
public async Task SelectMigrationsAsync_AreInOrder() { migrationRegistry.Migrations.Returns(new List <IDatabaseMigration>() { new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0") }, new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.1") } }); var migrations = await sut.SelectMigrationsAsync( new[] { new DatabaseMigrationSpecifier("appModule1", null) }, new string[0]); migrations.Should().HaveCount(1); migrations.First().Specifier.Should().Be(new DatabaseMigrationSpecifier("appModule1", null)); migrations.First().Migrations.Should().Equal( migrationRegistry.Migrations.ElementAt(0), migrationRegistry.Migrations.ElementAt(1)); }
public async Task SelectMigrationsAsync_RepeatablesOnlyRunOnce() { migrationRegistry.Migrations.Returns(new List <IDatabaseMigration>() { new FakeDatabaseMigration() { ModuleName = "appModule1", Dependencies = new[] { new DatabaseMigrationSpecifier("baseModule1", null) }, Version = DatabaseVersion.Parse("1.0.0") }, new FakeDatabaseMigration() { ModuleName = "appModule1", Dependencies = new[] { new DatabaseMigrationSpecifier("baseModule1", null) }, Version = DatabaseVersion.Parse("1.0.1") }, new FakeDatabaseMigration() { ModuleName = "baseModule1", IsRepeatable = true, Checksum = "xyz" } }); var migrations = await sut.SelectMigrationsAsync( new[] { new DatabaseMigrationSpecifier("appModule1", null) }, new string[0]); migrations.Should().HaveCount(1); migrations.First().Specifier.Should().Be(new DatabaseMigrationSpecifier("appModule1", null)); migrations.First().Migrations.Should().Equal( migrationRegistry.Migrations.ElementAt(2), migrationRegistry.Migrations.ElementAt(0), migrationRegistry.Migrations.ElementAt(1)); }
public async Task SelectMigrationsAsync_BaselineThrowsWhenLatestVersionHasOnlyBaselineMigrationPath() { migrationProvider.GetMigrationHistoryAsync() .Returns(new[] { new FakeDatabaseMigrationRecord() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0") } }); migrationRegistry.Migrations.Returns(new List <IDatabaseMigration>() { new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.1"), IsBaseline = true } }); await sut.Awaiting(async x => await sut.SelectMigrationsAsync( new[] { new DatabaseMigrationSpecifier("appModule1", null) }, new string[0])) .Should() .ThrowAsync <DatabaseMigrationException>(); }
public async Task SelectMigrationsAsync_RepeatablesNotIfPreviouslyNotRunWhenDependenciesUpdated() { migrationProvider.GetMigrationHistoryAsync() .Returns(new IDatabaseMigrationRecord[] { }); migrationRegistry.Migrations.Returns(new List <IDatabaseMigration>() { new FakeDatabaseMigration() { ModuleName = "data", Version = DatabaseVersion.Parse("1") }, new FakeDatabaseMigration() { ModuleName = "view", IsRepeatable = true, Checksum = "xyz", Dependencies = new [] { new DatabaseMigrationSpecifier("data", null), } } }); var migrations = await sut.SelectMigrationsAsync( new[] { new DatabaseMigrationSpecifier("data", null) }, new string[0]); migrations.Should().HaveCount(1); migrations.First().Specifier.Should().Be(new DatabaseMigrationSpecifier("data", null)); migrations.First().Migrations.Should().Equal( migrationRegistry.Migrations.ElementAt(0)); }
public async Task SelectMigrationsAsync_MigrationsToCurrentDependencyVersionsNeedNotExist() { migrationProvider.GetMigrationHistoryAsync() .Returns(new[] { new FakeDatabaseMigrationRecord() { ModuleName = "baseModule1", Version = DatabaseVersion.Parse("1.0.0"), } }); migrationRegistry.Migrations.Returns(new List <IDatabaseMigration>() { new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0"), Dependencies = new [] { new DatabaseMigrationSpecifier("baseModule1", DatabaseVersion.Parse("1.0.0")), } } }); var migrations = await sut.SelectMigrationsAsync( new[] { new DatabaseMigrationSpecifier("appModule1", null) }, new string[0]); migrations.Should().HaveCount(1); migrations.First().Specifier.Should().Be(new DatabaseMigrationSpecifier("appModule1", null)); migrations.First().Migrations.Should().Equal( migrationRegistry.Migrations.ElementAt(0)); }
public void SearchModules_QuestionMarkWildcard() { sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "app-base", Version = DatabaseVersion.Parse("1.0.0") }); sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "app-base", Version = DatabaseVersion.Parse("1.0.1") }); sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "app-module1", Version = DatabaseVersion.Parse("1.0.0") }); sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "foo-another", Version = DatabaseVersion.Parse("1.0.0") }); var result = sut.SearchModules("ap?-base"); result.Should().BeEquivalentTo("app-base"); }
public async Task SelectMigrationsAsync_Tagged() { migrationRegistry.Migrations.Returns(new List <IDatabaseMigration>() { new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.1"), Tags = new [] { new [] { "DEV", "CI" }, new [] { "CUSTOMER2" } } }, new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0"), Tags = new [] { new [] { "DEV", "CI" }, new [] { "CUSTOMER3" } } }, new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0"), Tags = new [] { new [] { "DEV", "CI" }, new [] { "CUSTOMER1", "CUSTOMER2" } } }, new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0"), Tags = new [] { new [] { "PROD" } } } }); var migrations = await sut.SelectMigrationsAsync( new[] { new DatabaseMigrationSpecifier("appModule1", null) }, new[] { "CI", "CUSTOMER2" }); migrations.Should().HaveCount(1); migrations.First().Specifier.Should().Be(new DatabaseMigrationSpecifier("appModule1", null)); migrations.First().Migrations.Should().Equal( migrationRegistry.Migrations.ElementAt(2), migrationRegistry.Migrations.ElementAt(0)); }
private async Task InitializeAsync() { if (executor != null) { return; } LoadModules(); CreateMigrationProvider(); executionOptions.EnvironmentTags = Options.EnvironmentTags?.ToArray() ?? new string[0]; executionOptions.MigrateOnlySpecifiedModules = Options.Modules?.Count() > 0 ? Options.Modules.Select(x => { string[] parts = x.Split('@', 2); if (parts.Length > 1) { return(new DatabaseMigrationSearchSpecifier(parts[0], DatabaseVersion.Parse(parts[1]))); } else { return(new DatabaseMigrationSearchSpecifier(x, null)); } }).ToArray() : null; migrationSelector = new DatabaseMigrationSelector(migrationRegistry, migrationProvider, executionOptions.MigrationSelectorOptions); Regex fileNameRegex = Options.FileNameRegex != null ? new Regex(Options.FileNameRegex, RegexOptions.Compiled | RegexOptions.IgnoreCase) : null; foreach (string path in Options.DirectoryPaths) { kernel.Bind <FileDatabaseMigrationDiscoveryPath>() .ToConstant(new FileDatabaseMigrationDiscoveryPath(path, true, fileNameRegex)); } if (!Options.DirectoryPaths.Any() && !Options.Assemblies.Any()) { Logger.Error("You have not passed any --directoryPaths nor --assemblies to load the migrations from. No migrations will be performed."); } migrationDiscoveries = new IDatabaseMigrationDiscovery[] { new FileDatabaseMigrationDiscovery(kernel.GetBindings(typeof(FileDatabaseMigrationDiscoveryPath)).Count() > 0 ? kernel.GetAll <FileDatabaseMigrationDiscoveryPath>().ToArray() : new FileDatabaseMigrationDiscoveryPath[0]), new ResourceDatabaseMigrationDiscovery(kernel.GetBindings(typeof(ResourceDatabaseMigrationDiscoveryAssembly)).Count() > 0 ? kernel.GetAll <ResourceDatabaseMigrationDiscoveryAssembly>().ToArray() : new ResourceDatabaseMigrationDiscoveryAssembly[0]) }; executor = new DatabaseMigrationExecutor(new[] { migrationProvider }, migrationRegistry, migrationDiscoveries, migrationSelector, executionOptions); }
public async Task SelectMigrationsAsync_OverlappingLevelTwoDependencies() { migrationRegistry.Migrations.Returns(new List <IDatabaseMigration>() { new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0"), Dependencies = new [] { new DatabaseMigrationSpecifier("baseModule1", DatabaseVersion.Parse("1.0.0")), new DatabaseMigrationSpecifier("baseModule2", DatabaseVersion.Parse("1.0.0")), } }, new FakeDatabaseMigration() { ModuleName = "baseModule1", Version = DatabaseVersion.Parse("1.0.0"), Dependencies = new [] { new DatabaseMigrationSpecifier("baseModule3", DatabaseVersion.Parse("1.0.0")), } }, new FakeDatabaseMigration() { ModuleName = "baseModule2", Version = DatabaseVersion.Parse("1.0.0"), Dependencies = new [] { new DatabaseMigrationSpecifier("baseModule3", DatabaseVersion.Parse("1.0.1")), } }, new FakeDatabaseMigration() { ModuleName = "baseModule3", Version = DatabaseVersion.Parse("1.0.1") }, new FakeDatabaseMigration() { ModuleName = "baseModule3", Version = DatabaseVersion.Parse("1.0.0") } }); var migrations = await sut.SelectMigrationsAsync( new[] { new DatabaseMigrationSpecifier("appModule1", null) }, new string[0]); migrations.Should().HaveCount(1); migrations.First().Specifier.Should().Be(new DatabaseMigrationSpecifier("appModule1", null)); migrations.First().Migrations.Should().Equal( migrationRegistry.Migrations.ElementAt(4), migrationRegistry.Migrations.ElementAt(1), migrationRegistry.Migrations.ElementAt(3), migrationRegistry.Migrations.ElementAt(2), migrationRegistry.Migrations.ElementAt(0)); }
private IDatabaseMigrationRecord ParseMigrationRecord(IDataReader reader, Dictionary <string, int> columnDict) { return(new DatabaseMigrationRecord( reader.GetGuid(columnDict["id"]), reader.GetDateTime(columnDict["time_applied"]), reader.GetString(columnDict["module_name"]), reader.IsDBNull(columnDict["version"]) ? null : DatabaseVersion.Parse(reader.GetString(columnDict["version"])), reader.GetString(columnDict["checksum"]), reader.IsDBNull(columnDict["file_name"]) ? null : reader.GetString(columnDict["file_name"]))); }
public void AddMigration() { var migration = new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0") }; sut.AddMigration(migration); sut.Migrations.Should().Contain(migration); }
public void Validate_VersionedRepeatableThrows() { sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0"), IsRepeatable = true }); sut.Invoking(x => x.ValidateMigrations()) .Should().Throw <DatabaseMigrationException>(); }
public async Task SelectMigrationsAsync_TopModuleDependencies() { migrationRegistry.Migrations.Returns(new List <IDatabaseMigration>() { new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0"), Dependencies = new [] { new DatabaseMigrationSpecifier("baseModule1", DatabaseVersion.Parse("1.0.0")) } }, new FakeDatabaseMigration() { ModuleName = "appModule2", Version = DatabaseVersion.Parse("1.0.0"), Dependencies = new [] { new DatabaseMigrationSpecifier("baseModule1", DatabaseVersion.Parse("1.0.0")) } }, new FakeDatabaseMigration() { ModuleName = "baseModule1", Version = DatabaseVersion.Parse("1.0.0") } }); var migrations = await sut.SelectMigrationsAsync( new[] { new DatabaseMigrationSpecifier("appModule1", null), new DatabaseMigrationSpecifier("appModule2", null) }, new string[0]); migrations.Should().HaveCount(2); migrations.Should().Contain(x => x.Specifier.Equals(new DatabaseMigrationSpecifier("appModule1", null))); migrations.Should().Contain(x => x.Specifier.Equals(new DatabaseMigrationSpecifier("appModule2", null))); var a1 = migrations.First(x => x.Specifier.ModuleName == "appModule1"); a1.Migrations.Should().Equal( migrationRegistry.Migrations.ElementAt(2), migrationRegistry.Migrations.ElementAt(0)); var a2 = migrations.First(x => x.Specifier.ModuleName == "appModule2"); a2.Migrations.Should().Equal( migrationRegistry.Migrations.ElementAt(1)); }
public void Validate_VersionDuplicatesWithDifferentTagsNotThrows() { sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0"), Tags = new [] { new[] { "ABC" } } }); sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0"), Tags = new[] { new[] { "XYZ" } } }); sut.Invoking(x => x.ValidateMigrations()) .Should().NotThrow <DatabaseMigrationException>(); }
public void ParsesVersion() { var sql = @" -- Hello /* Multi line comment */ -- version: 1.5.0 CREATE TABLE abc ( id int ); DROP TABLE def; "; sut = new TestFileSqlDatabaseMigration("myapp.sql", sql); sut.Version.Should().Be(DatabaseVersion.Parse("1.5.0")); }
public async Task SelectMigrationsAsync_RepeatablesRunLast() { migrationProvider.GetMigrationHistoryAsync() .Returns(new IDatabaseMigrationRecord[] { }); migrationRegistry.Migrations.Returns(new List <IDatabaseMigration>() { new FakeDatabaseMigration() { ModuleName = "a", Version = DatabaseVersion.Parse("1") }, new FakeDatabaseMigration() { ModuleName = "b", IsRepeatable = true, Checksum = "xyz" }, new FakeDatabaseMigration() { ModuleName = "c", Version = DatabaseVersion.Parse("1") }, }); var migrations = await sut.SelectMigrationsAsync( new[] { new DatabaseMigrationSpecifier("a", null), new DatabaseMigrationSpecifier("b", null), new DatabaseMigrationSpecifier("c", null) }, new string[0]); migrations.Should().HaveCount(3); migrations.First().Specifier.Should().Be(new DatabaseMigrationSpecifier("a", null)); migrations.ElementAt(1).Specifier.Should().Be(new DatabaseMigrationSpecifier("c", null)); migrations.ElementAt(2).Specifier.Should().Be(new DatabaseMigrationSpecifier("b", null)); }
public async Task SelectMigrationsAsync_BaselineNotUsedOnExistingDBs() { migrationProvider.GetMigrationHistoryAsync() .Returns(new[] { new FakeDatabaseMigrationRecord() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0") } }); migrationRegistry.Migrations.Returns(new List <IDatabaseMigration>() { new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.1"), IsBaseline = true }, new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.1") }, new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0") } }); var migrations = await sut.SelectMigrationsAsync( new[] { new DatabaseMigrationSpecifier("appModule1", null) }, new string[0]); migrations.Should().HaveCount(1); migrations.First().Specifier.Should().Be(new DatabaseMigrationSpecifier("appModule1", null)); migrations.First().Migrations.Should().Equal( migrationRegistry.Migrations.ElementAt(1)); }
public void Validate_MultipleBaselinesDifferentTagsNotThrows() { sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0"), IsBaseline = true, Tags = new [] { new [] { "xyz" } } }); sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.1"), IsBaseline = true, Tags = new[] { new[] { "abc" } } }); sut.Invoking(x => x.ValidateMigrations()) .Should().NotThrow <DatabaseMigrationException>(); }
public void Validate_NotThrows() { sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0") }); sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.1") }); sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "appModule2", Version = DatabaseVersion.Parse("1.0.0") }); sut.Invoking(x => x.ValidateMigrations()) .Should().NotThrow <DatabaseMigrationException>(); }
public void GetAvailableModules() { sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0") }); sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.1") }); sut.AddMigration(new FakeDatabaseMigration() { ModuleName = "appModule2", Version = DatabaseVersion.Parse("1.0.0") }); var result = sut.GetAvailableModules(); result.Should().BeEquivalentTo("appModule1", "appModule2"); }
public async Task SelectMigrationsAsync_NonExistentTargetVersionThrows() { migrationRegistry.Migrations.Returns(new List <IDatabaseMigration>() { new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.2") }, new FakeDatabaseMigration() { ModuleName = "appModule1", Version = DatabaseVersion.Parse("1.0.0") } }); await sut.Awaiting(async x => await sut.SelectMigrationsAsync( new[] { new DatabaseMigrationSpecifier("appModule1", DatabaseVersion.Parse("1.0.1")) }, new string[0])) .Should() .ThrowAsync <DatabaseMigrationException>(); }
public void ParsesDependencies() { var sql = @" -- Hello /* Multi line comment */ -- dependency: [email protected] -- dependency: vendor-module CREATE TABLE abc ( id int ); DROP TABLE def; "; sut = new TestFileSqlDatabaseMigration("myapp_1.0.1.sql", sql); sut.Dependencies.Should() .BeEquivalentTo( new DatabaseMigrationSpecifier("myapp-base", DatabaseVersion.Parse("1.2.3")), new DatabaseMigrationSpecifier("vendor-module", null)); }