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); } 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) { var sw = Stopwatch.StartNew(); _logger.Info("*** Migrating {0} ***", connectionString); ServiceProvider serviceProvider; var db = connectionString.Contains(".db") ? "sqlite" : "postgres"; serviceProvider = new ServiceCollection() .AddLogging(b => b.AddNLog()) .AddFluentMigratorCore() .ConfigureRunner( builder => builder .AddPostgres() .AddNzbDroneSQLite() .WithGlobalConnectionString(connectionString) .WithMigrationsIn(Assembly.GetExecutingAssembly())) .Configure(opt => opt.Namespace = "NzbDrone.Core.Datastore.Migration") .Configure(opt => { opt.PreviewOnly = false; opt.Timeout = TimeSpan.FromSeconds(60); }) .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); } } }