public async Task <SchemaMigrationPlan> ExecuteMigration(IDbConnection connection, ISchemaManager targetManager, SchemaMigrationPlan plan) { foreach (var step in plan.Steps) { await ExecuteMigrationStep(connection, targetManager, step, plan.Target); } return(plan); }
protected void PlanMigrateIndex(SchemaMigrationPlan report, ColumnSchema existingIndex, ColumnSchema targetIndex, MigrationOptions options) { throw new NotImplementedException(); }
protected void PlanMigrateColumn(SchemaMigrationPlan report, ColumnSchema existing, ColumnSchema target, MigrationOptions options) { if (existing == null) { if (target.KeyIndex > 0) { throw new InvalidOperationException($"Cannot migrate column {target.Name} of {report.Target.Name}, keys can't be changed"); } options.AssertNotFrozen($"Create column {target.Name} of {report.Target.Name}"); report.Steps.Add(new MigrationStep() { TargetName = target.Name, Action = MigrationAction.Create, TargetType = MigrationTarget.Column, }); return; } if (target == null) { if (existing.KeyIndex > 0) { throw new InvalidOperationException($"Cannot migrate column {existing.Name} of {report.Target.Name}, keys can't be changed"); } options.AssertColumnDeleteAllowed(report.Target.Name, existing.Name); report.Steps.Add(new MigrationStep() { TargetName = existing.Name, Action = MigrationAction.Drop, TargetType = MigrationTarget.Column, }); return; } bool mismatched = false; if (target.KeyIndex != existing.KeyIndex) { throw new InvalidOperationException($"Cannot migrate column {target.Name} of {report.Target.Name}, keys can't be changed"); } if (target.SqlType != existing.SqlType) { mismatched = true; options.AssertColumnDeleteAllowed(report.Target.Name, target.Name, "type"); } if (target.Nullable != existing.Nullable) { mismatched = true; options.AssertColumnDeleteAllowed(report.Target.Name, target.Name, "nullable"); } if (target.MaxLength != existing.MaxLength) { mismatched = true; options.AssertColumnDeleteAllowed(report.Target.Name, target.Name, "maxlength"); } if (mismatched) { options.AssertColumnDeleteAllowed(report.Target.Name, target.Name); report.Steps.Add(new MigrationStep() { TargetName = target.Name, Action = MigrationAction.Drop, TargetType = MigrationTarget.Column, }); report.Steps.Add(new MigrationStep() { TargetName = target.Name, Action = MigrationAction.Create, TargetType = MigrationTarget.Column, }); return; } }
public async Task <SchemaMigrationPlan> PlanMigration(IDbConnection connection, ISchemaManager targetManager, ObjectSchema targetSchema, MigrationOptions options) { options = options ?? new MigrationOptions(); // Whichever columns are mapped to SqlType, we let the manager decide the best choice foreach (var column in targetSchema.Columns.Values) { if (column.SqlType == null) { column.SqlType = targetManager.MapColumnType(column.DotnetType); } } var report = new SchemaMigrationPlan() { Target = targetSchema, }; report.Existing = await targetManager.GetSchema(connection, targetSchema.Name); if (report.Existing == null) { report.Steps.Add(new MigrationStep() { TargetName = targetSchema.Name, Action = MigrationAction.Create, TargetType = MigrationTarget.Object, }); return(report); } if (options.ForceDropRecreate) { options.AssertTableDeleteAllowed(targetSchema.Name); report.Steps.Add(new MigrationStep() { TargetName = targetSchema.Name, Action = MigrationAction.Drop, TargetType = MigrationTarget.Object, }); report.Steps.Add(new MigrationStep() { TargetName = targetSchema.Name, Action = MigrationAction.Create, TargetType = MigrationTarget.Object, }); return(report); } var allColumnNames = report.Target.Columns.Keys.Union(report.Existing.Columns.Keys); foreach (var column in allColumnNames) { var targetColumn = report.Target.Columns.ContainsKey(column) ? report.Target.Columns[column] : null; var existingColumn = report.Existing.Columns.ContainsKey(column) ? report.Existing.Columns[column] : null; PlanMigrateColumn(report, existingColumn, targetColumn, options); } var allIndexNames = report.Target.Indexes.Keys.Union(report.Existing.Indexes.Keys); foreach (var index in allIndexNames) { var targetIndex = report.Target.Columns.ContainsKey(index) ? report.Target.Columns[index] : null; var existingIndex = report.Existing.Columns.ContainsKey(index) ? report.Existing.Columns[index] : null; PlanMigrateIndex(report, existingIndex, targetIndex, options); } return(report); }