public Migrator( [NotNull] DbContextConfiguration contextConfiguration, [NotNull] HistoryRepository historyRepository, [NotNull] MigrationAssembly migrationAssembly, [NotNull] ModelDiffer modelDiffer, [NotNull] IMigrationOperationSqlGeneratorFactory ddlSqlGeneratorFactory, [NotNull] SqlGenerator dmlSqlGenerator, [NotNull] SqlStatementExecutor sqlExecutor) { Check.NotNull(contextConfiguration, "contextConfiguration"); Check.NotNull(historyRepository, "historyRepository"); Check.NotNull(migrationAssembly, "migrationAssembly"); Check.NotNull(modelDiffer, "modelDiffer"); Check.NotNull(ddlSqlGeneratorFactory, "ddlSqlGeneratorFactory"); Check.NotNull(dmlSqlGenerator, "dmlSqlGenerator"); Check.NotNull(sqlExecutor, "sqlExecutor"); _contextConfiguration = contextConfiguration; _historyRepository = historyRepository; _migrationAssembly = migrationAssembly; _modelDiffer = modelDiffer; _ddlSqlGeneratorFactory = ddlSqlGeneratorFactory; _dmlSqlGenerator = dmlSqlGenerator; _sqlExecutor = sqlExecutor; }
public Migrator( [NotNull] HistoryRepository historyRepository, [NotNull] MigrationAssembly migrationAssembly, [NotNull] ModelDiffer modelDiffer, [NotNull] IMigrationOperationSqlGeneratorFactory ddlSqlGeneratorFactory, [NotNull] SqlGenerator dmlSqlGenerator, [NotNull] SqlStatementExecutor sqlExecutor, [NotNull] RelationalDataStoreCreator storeCreator, [NotNull] RelationalConnection connection, [NotNull] ILoggerFactory loggerFactory) { Check.NotNull(historyRepository, "historyRepository"); Check.NotNull(migrationAssembly, "migrationAssembly"); Check.NotNull(modelDiffer, "modelDiffer"); Check.NotNull(ddlSqlGeneratorFactory, "ddlSqlGeneratorFactory"); Check.NotNull(dmlSqlGenerator, "dmlSqlGenerator"); Check.NotNull(sqlExecutor, "sqlExecutor"); Check.NotNull(storeCreator, "storeCreator"); Check.NotNull(connection, "connection"); Check.NotNull(loggerFactory, "loggerFactory"); _historyRepository = historyRepository; _migrationAssembly = migrationAssembly; _modelDiffer = modelDiffer; _ddlSqlGeneratorFactory = ddlSqlGeneratorFactory; _dmlSqlGenerator = dmlSqlGenerator; _sqlExecutor = sqlExecutor; _storeCreator = storeCreator; _connection = connection; _logger = new DbContextService <ILogger>(loggerFactory.Create <Migrator>); }
protected virtual IReadOnlyList <SqlStatement> GenerateUpdateDatabaseSql( IReadOnlyList <IMigrationMetadata> downgradeMigrations, IReadOnlyList <IMigrationMetadata> upgradeMigrations) { var sqlStatements = new List <SqlStatement>(); foreach (var migration in downgradeMigrations) { var database = DatabaseBuilder.GetDatabase(migration.TargetModel); var ddlSqlGenerator = DdlSqlGeneratorFactory.Create(database); sqlStatements.AddRange( ddlSqlGenerator.Generate( migration.DowngradeOperations, generateIdempotentSql: true)); sqlStatements.AddRange( HistoryRepository.GenerateDeleteMigrationSql(migration, DmlSqlGenerator)); } foreach (var migration in upgradeMigrations) { var database = DatabaseBuilder.GetDatabase(migration.TargetModel); var ddlSqlGenerator = DdlSqlGeneratorFactory.Create(database); sqlStatements.AddRange( ddlSqlGenerator.Generate( migration.UpgradeOperations, generateIdempotentSql: true)); sqlStatements.AddRange( HistoryRepository.GenerateInsertMigrationSql(migration, DmlSqlGenerator)); } return(sqlStatements); }
public void Get_table_name() { using (var context = new Context()) { var historyRepository = new HistoryRepository(context.Configuration); Assert.Equal("__MigrationHistory", historyRepository.TableName); } }
protected virtual IReadOnlyList <SqlStatement> GenerateUpdateDatabaseSql( IReadOnlyList <IMigrationMetadata> migrations, IReadOnlyList <int> downgradeIndexes, IReadOnlyList <int> upgradeIndexes, bool historyRepositoryExists, bool removeHistoryRepository) { var sqlStatements = new List <SqlStatement>(); if (!historyRepositoryExists && upgradeIndexes.Count > 0) { var targetDatabase = ModelDiffer.DatabaseBuilder.GetDatabase(HistoryRepository.HistoryModel); var ddlSqlGenerator = DdlSqlGeneratorFactory.Create(); sqlStatements.AddRange(ddlSqlGenerator.Generate(ModelDiffer.CreateSchema(targetDatabase))); } foreach (var index in downgradeIndexes) { var migration = migrations[index]; var sourceDatabase = ModelDiffer.DatabaseBuilder.GetDatabase(migration.TargetModel); var ddlSqlGenerator = DdlSqlGeneratorFactory.Create(sourceDatabase); sqlStatements.AddRange(ddlSqlGenerator.Generate(migration.DowngradeOperations)); sqlStatements.AddRange( HistoryRepository.GenerateDeleteMigrationSql(migration, DmlSqlGenerator)); } foreach (var index in upgradeIndexes) { var migration = migrations[index]; var sourceDatabase = ModelDiffer.DatabaseBuilder.GetDatabase(GetSourceModel(migrations, index)); var ddlSqlGenerator = DdlSqlGeneratorFactory.Create(sourceDatabase); sqlStatements.AddRange(ddlSqlGenerator.Generate(migration.UpgradeOperations)); sqlStatements.AddRange( HistoryRepository.GenerateInsertMigrationSql(migration, DmlSqlGenerator)); } if (historyRepositoryExists && removeHistoryRepository) { var sourceDatabase = ModelDiffer.DatabaseBuilder.GetDatabase(HistoryRepository.HistoryModel); var ddlSqlGenerator = DdlSqlGeneratorFactory.Create(sourceDatabase); sqlStatements.AddRange(ddlSqlGenerator.Generate(ModelDiffer.DropSchema(sourceDatabase))); } return(sqlStatements); }
protected virtual IReadOnlyList <SqlBatch> ApplyMigrations(int targetMigrationIndex, bool simulate) { bool historyTableExists; var migrationPairs = PairMigrations(MigrationAssembly.Migrations, HistoryRepository.GetRows(out historyTableExists)); var downgradeIndexes = MigrationAssembly.Migrations .Select((m, i) => i) .Skip(targetMigrationIndex + 1) .Where(i => migrationPairs[i].HistoryRow != null) .Reverse() .ToList(); var upgradeIndexes = MigrationAssembly.Migrations .Select((m, i) => i) .Take(targetMigrationIndex + 1) .Where(i => migrationPairs[i].HistoryRow == null) .ToList(); if (!simulate && !_storeCreator.Exists()) { _storeCreator.Create(); } var batches = new List <SqlBatch>(); if (upgradeIndexes.Any() && !historyTableExists) { batches.AddRange(CreateHistoryTable(simulate)); } batches.AddRange(downgradeIndexes.SelectMany(i => RevertMigration(i, simulate))); batches.AddRange(upgradeIndexes.SelectMany(i => ApplyMigration(i, simulate))); if (targetMigrationIndex == -1 && historyTableExists) { batches.AddRange(DropHistoryTable(simulate)); } if (batches.Count == 0) { Logger.UpToDate(); } return(batches); }
protected virtual IReadOnlyList <SqlStatement> ApplyMigrations(int targetMigrationIndex, bool simulate) { bool historyTableExists; var migrationPairs = PairMigrations(MigrationAssembly.Migrations, HistoryRepository.GetRows(out historyTableExists)); var downgradeIndexes = MigrationAssembly.Migrations .Select((m, i) => i) .Skip(targetMigrationIndex + 1) .Where(i => migrationPairs[i].HistoryRow != null) .Reverse() .ToArray(); var upgradeIndexes = MigrationAssembly.Migrations .Select((m, i) => i) .Take(targetMigrationIndex + 1) .Where(i => migrationPairs[i].HistoryRow == null) .ToArray(); var database = (RelationalDatabase)ContextConfiguration.Database; var statements = new List <SqlStatement>(); if (!simulate && !database.Exists()) { database.Create(); } if (upgradeIndexes.Any() && !historyTableExists) { statements.AddRange(CreateHistoryTable(simulate)); } statements.AddRange(downgradeIndexes.SelectMany(i => RevertMigration(i, simulate))); statements.AddRange(upgradeIndexes.SelectMany(i => ApplyMigration(i, simulate))); if (targetMigrationIndex == -1 && historyTableExists) { statements.AddRange(DropHistoryTable(simulate)); } if (statements.Count == 0) { Logger.UpToDate(); } return(statements); }
public void Create_and_cache_history_model() { using (var context = new Context()) { var historyRepository = new HistoryRepository(context.Configuration); var historyModel1 = historyRepository.HistoryModel; var historyModel2 = historyRepository.HistoryModel; Assert.Same(historyModel1, historyModel2); Assert.Equal(1, historyModel1.EntityTypes.Count); var entityType = historyModel1.EntityTypes[0]; Assert.Equal("HistoryRow", entityType.Name); Assert.Equal(2, entityType.Properties.Count); Assert.Equal(new[] { "ContextKey", "MigrationId" }, entityType.Properties.Select(p => p.Name)); } }
protected virtual IReadOnlyList <SqlBatch> RevertMigration(int index, bool simulate) { var migration = MigrationAssembly.Migrations[index]; var targetModel = GetSourceModel(index); var ddlSqlGenerator = DdlSqlGeneratorFactory.Create(targetModel); var batches = ddlSqlGenerator.Generate(migration.GetDowngradeOperations()) .Concat(HistoryRepository.GenerateDeleteMigrationSql(migration.GetMetadata(), DmlSqlGenerator)) .ToList(); if (simulate) { return(batches); } Logger.RevertingMigration(migration.GetMigrationId()); ExecuteSqlBatches(batches); return(batches); }
protected virtual IReadOnlyList <SqlBatch> ApplyMigration(int index, bool simulate) { var migration = MigrationAssembly.Migrations[index]; var targetModel = migration.GetTargetModel(); var ddlSqlGenerator = DdlSqlGeneratorFactory.Create(targetModel); var statements = ddlSqlGenerator.Generate(migration.GetUpgradeOperations()) .Concat(HistoryRepository.GenerateInsertMigrationSql(migration.GetMetadata(), DmlSqlGenerator)) .ToList(); if (simulate) { return(statements); } Logger.ApplyingMigration(migration.GetMigrationId()); ExecuteSqlBatches(statements); return(statements); }
protected virtual IReadOnlyList <SqlStatement> RevertMigration(int index, bool simulate) { var migration = MigrationAssembly.Migrations[index]; var sourceDatabase = ModelDiffer.DatabaseBuilder.GetDatabase(migration.GetTargetModel()); var ddlSqlGenerator = DdlSqlGeneratorFactory.Create(sourceDatabase); var statements = ddlSqlGenerator.Generate(migration.GetDowngradeOperations()) .Concat(HistoryRepository.GenerateDeleteMigrationSql(migration.GetMetadata(), DmlSqlGenerator)) .ToArray(); if (simulate) { return(statements); } Logger.RevertingMigration(migration.GetMigrationId()); ExecuteStatements(statements); return(statements); }
public void Create_history_context_from_user_context() { using (var context = new Context()) { var historyRepository = new HistoryRepository(context.Configuration); using (var historyContext = historyRepository.CreateHistoryContext()) { Assert.Same(historyRepository.HistoryModel, historyContext.Model); var extensions = context.Configuration.ContextOptions.Extensions; var historyExtensions = historyContext.Configuration.ContextOptions.Extensions; Assert.Equal(extensions.Count, historyExtensions.Count); for (var i = 0; i < extensions.Count; i++) { Assert.Same(extensions[i], historyExtensions[i]); } } } }
public void Get_migrations_query() { using (var context = new Context()) { var historyRepository = new HistoryRepository(context.Configuration); using (var historyContext = historyRepository.CreateHistoryContext()) { var query = historyRepository.GetMigrationsQuery(historyContext); var expression = (MethodCallExpression)query.Expression; Assert.Equal("Select", expression.Method.Name); Assert.Equal("h => new MigrationMetadata(h.MigrationId)", expression.Arguments[1].ToString()); expression = (MethodCallExpression)expression.Arguments[0]; Assert.Equal("OrderBy", expression.Method.Name); Assert.Equal("h => h.MigrationId", expression.Arguments[1].ToString()); expression = (MethodCallExpression)expression.Arguments[0]; Assert.Equal("Where", expression.Method.Name); Assert.Equal( "h => (h.ContextKey == value(Microsoft.Data.Entity.Migrations.Infrastructure.HistoryRepository).GetContextKey())", expression.Arguments[1].ToString()); var queryableType = expression.Arguments[0].Type; Assert.True(queryableType.IsGenericType); Assert.Equal("EntityQueryable", queryableType.Name.Remove(queryableType.Name.IndexOf("`", StringComparison.Ordinal))); Assert.Equal(1, queryableType.GenericTypeArguments.Length); Assert.Equal("HistoryRow", queryableType.GenericTypeArguments[0].Name); } } }
public void Generate_delete_migration_sql() { using (var context = new Context()) { var historyRepository = new HistoryRepository(context.Configuration); var sqlStatements = historyRepository.GenerateDeleteMigrationSql( new MigrationMetadata("000000000000001_Foo"), new DmlSqlGenerator()); Assert.Equal(1, sqlStatements.Count); Assert.Equal( @"DELETE FROM ""__MigrationHistory"" WHERE ""MigrationId"" = '000000000000001_Foo' AND ""ContextKey"" = 'Microsoft.Data.Entity.Migrations.Tests.Infrastructure.HistoryRepositoryTest+Context'", sqlStatements[0].Sql); } }
public void Generate_insert_migration_sql() { using (var context = new Context()) { var historyRepository = new HistoryRepository(context.Configuration); var sqlStatements = historyRepository.GenerateInsertMigrationSql( new MigrationMetadata("000000000000001_Foo"), new DmlSqlGenerator()); Assert.Equal(1, sqlStatements.Count); Assert.Equal( @"INSERT INTO ""__MigrationHistory"" (""MigrationId"", ""ContextKey"") VALUES ('000000000000001_Foo', 'Microsoft.Data.Entity.Migrations.Tests.Infrastructure.HistoryRepositoryTest+Context')", sqlStatements[0].Sql); } }