using System; using System.Diagnostics; using System.Reflection; using FluentMigrator.Runner; using FluentMigrator.Runner.Generators; using FluentMigrator.Runner.Initialization; using FluentMigrator.Runner.Processors; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using NLog; using NLog.Extensions.Logging; namespace NzbDrone.Core.Datastore.Migration.Framework { public interface IMigrationController { void Migrate(string connectionString, MigrationContext migrationContext, DatabaseType databaseType); } public class MigrationController : IMigrationController { private readonly Logger _logger; private readonly ILoggerProvider _migrationLoggerProvider; public MigrationController(Logger logger, ILoggerProvider migrationLoggerProvider) { _logger = logger; _migrationLoggerProvider = migrationLoggerProvider; } public void Migrate(string connectionString, MigrationContext migrationContext, DatabaseType databaseType) { var sw = Stopwatch.StartNew(); _logger.Info("*** Migrating {0} ***", connectionString); ServiceProvider serviceProvider; var db = databaseType == DatabaseType.SQLite ? "sqlite" : "postgres"; serviceProvider = new ServiceCollection() .AddLogging(b => b.AddNLog()) .AddFluentMigratorCore() .Configure(cfg => cfg.IncludeUntaggedMaintenances = true) .ConfigureRunner( builder => builder .AddPostgres() .AddNzbDroneSQLite() .WithGlobalConnectionString(connectionString) .ScanIn(Assembly.GetExecutingAssembly()).For.All()) .Configure(opt => opt.Namespace = "NzbDrone.Core.Datastore.Migration") .Configure(opt => { opt.PreviewOnly = false; opt.Timeout = TimeSpan.FromMinutes(5); }) .Configure(cfg => { cfg.ProcessorId = db; }) .Configure(cfg => { cfg.GeneratorId = db; }) .BuildServiceProvider(); using (var scope = serviceProvider.CreateScope()) { var runner = scope.ServiceProvider.GetRequiredService(); MigrationContext.Current = migrationContext; if (migrationContext.DesiredVersion.HasValue) { runner.MigrateUp(migrationContext.DesiredVersion.Value); } else { runner.MigrateUp(); } MigrationContext.Current = null; } sw.Stop(); _logger.Debug("Took: {0}", sw.Elapsed); } } }