From ebf4859167bef28926c8c5e7f5f914c894459dae Mon Sep 17 00:00:00 2001 From: ta264 Date: Mon, 28 Oct 2019 21:12:26 +0000 Subject: [PATCH] Update FluentMigrator to v4 --- src/NuGet.config | 9 +-- .../SqliteSchemaDumperFixture.cs | 2 +- src/NzbDrone.Core.Test/Framework/DbTest.cs | 10 ++- .../Framework/MigrationTest.cs | 10 ++- .../Migration/Framework/MigrationContext.cs | 5 +- .../Framework/MigrationController.cs | 62 ++++++++++--------- .../Migration/Framework/MigrationDbFactory.cs | 14 ----- .../Migration/Framework/MigrationExtension.cs | 23 ++++++- .../Migration/Framework/MigrationLogger.cs | 33 +++++----- .../Framework/MigrationLoggerProvider.cs | 34 ++++++++++ .../Migration/Framework/MigrationOptions.cs | 11 ---- .../Framework/NzbDroneMigrationBase.cs | 19 +----- ...rocessor.cs => NzbDroneSQLiteProcessor.cs} | 26 ++++---- .../NzbDroneSqliteProcessorFactory.cs | 18 ------ .../Migration/Framework/SqliteSchemaDumper.cs | 7 +-- .../Migration/Framework/TableDefinition.cs | 54 ++++++++++++++++ src/NzbDrone.Core/Lidarr.Core.csproj | 3 +- 17 files changed, 206 insertions(+), 134 deletions(-) delete mode 100644 src/NzbDrone.Core/Datastore/Migration/Framework/MigrationDbFactory.cs create mode 100644 src/NzbDrone.Core/Datastore/Migration/Framework/MigrationLoggerProvider.cs delete mode 100644 src/NzbDrone.Core/Datastore/Migration/Framework/MigrationOptions.cs rename src/NzbDrone.Core/Datastore/Migration/Framework/{NzbDroneSqliteProcessor.cs => NzbDroneSQLiteProcessor.cs} (86%) delete mode 100644 src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneSqliteProcessorFactory.cs create mode 100644 src/NzbDrone.Core/Datastore/Migration/Framework/TableDefinition.cs diff --git a/src/NuGet.config b/src/NuGet.config index 67a3801b5..d21b55fa6 100644 --- a/src/NuGet.config +++ b/src/NuGet.config @@ -1,6 +1,7 @@ - - - - \ No newline at end of file + + + + + diff --git a/src/NzbDrone.Core.Test/Datastore/SqliteSchemaDumperTests/SqliteSchemaDumperFixture.cs b/src/NzbDrone.Core.Test/Datastore/SqliteSchemaDumperTests/SqliteSchemaDumperFixture.cs index 4a5fc0fda..218b5e93f 100644 --- a/src/NzbDrone.Core.Test/Datastore/SqliteSchemaDumperTests/SqliteSchemaDumperFixture.cs +++ b/src/NzbDrone.Core.Test/Datastore/SqliteSchemaDumperTests/SqliteSchemaDumperFixture.cs @@ -14,7 +14,7 @@ namespace NzbDrone.Core.Test.Datastore.SqliteSchemaDumperTests [SetUp] public void Setup() { - Subject = new SqliteSchemaDumper(null, null); + Subject = new SqliteSchemaDumper(null); } [TestCase(@"CREATE TABLE TestTable (MyId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT)", "TestTable", "MyId")] diff --git a/src/NzbDrone.Core.Test/Framework/DbTest.cs b/src/NzbDrone.Core.Test/Framework/DbTest.cs index 1eb68a55f..d24d288ed 100644 --- a/src/NzbDrone.Core.Test/Framework/DbTest.cs +++ b/src/NzbDrone.Core.Test/Framework/DbTest.cs @@ -5,6 +5,8 @@ using System.IO; using System.Linq; using FluentMigrator.Runner; using Marr.Data; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using NUnit.Framework; using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore.Migration.Framework; @@ -96,9 +98,15 @@ namespace NzbDrone.Core.Test.Framework return testDb; } + protected virtual void SetupLogging() + { + Mocker.SetConstant(NullLoggerProvider.Instance); + } + protected void SetupContainer() { WithTempAsAppPath(); + SetupLogging(); Mocker.SetConstant(Mocker.Resolve()); Mocker.SetConstant(Mocker.Resolve()); @@ -127,4 +135,4 @@ namespace NzbDrone.Core.Test.Framework } } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core.Test/Framework/MigrationTest.cs b/src/NzbDrone.Core.Test/Framework/MigrationTest.cs index 4e538546e..492d068e6 100644 --- a/src/NzbDrone.Core.Test/Framework/MigrationTest.cs +++ b/src/NzbDrone.Core.Test/Framework/MigrationTest.cs @@ -1,6 +1,6 @@ using System; using FluentMigrator; -using FluentMigrator.Runner; +using Microsoft.Extensions.Logging; using NUnit.Framework; using NzbDrone.Core.Datastore.Migration.Framework; @@ -36,11 +36,15 @@ namespace NzbDrone.Core.Test.Framework return db.GetDirectDataMapper(); } + protected override void SetupLogging() + { + Mocker.SetConstant(Mocker.Resolve()); + } + [SetUp] public override void SetupDb() { - Mocker.SetConstant(Mocker.Resolve()); SetupContainer(); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationContext.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationContext.cs index c8882aab0..2ded733a1 100644 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationContext.cs +++ b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationContext.cs @@ -4,9 +4,10 @@ namespace NzbDrone.Core.Datastore.Migration.Framework { public class MigrationContext { + public static MigrationContext Current { get; set; } + public MigrationType MigrationType { get; private set; } public long? DesiredVersion { get; set; } - public Action BeforeMigration { get; set; } public MigrationContext(MigrationType migrationType, long? desiredVersion = null) @@ -15,4 +16,4 @@ namespace NzbDrone.Core.Datastore.Migration.Framework DesiredVersion = desiredVersion; } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationController.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationController.cs index 2e1a2d2ab..b90d3de7c 100644 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationController.cs +++ b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationController.cs @@ -1,8 +1,12 @@ -using System.Data.SQLite; +using System; using System.Diagnostics; using System.Reflection; using FluentMigrator.Runner; using FluentMigrator.Runner.Initialization; +using FluentMigrator.Runner.Processors; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using NLog; namespace NzbDrone.Core.Datastore.Migration.Framework { @@ -13,56 +17,58 @@ namespace NzbDrone.Core.Datastore.Migration.Framework public class MigrationController : IMigrationController { - private readonly IAnnouncer _announcer; + private readonly Logger _logger; + private readonly ILoggerProvider _migrationLoggerProvider; - public MigrationController(IAnnouncer announcer) + public MigrationController(Logger logger, + ILoggerProvider migrationLoggerProvider) { - _announcer = announcer; + _logger = logger; + _migrationLoggerProvider = migrationLoggerProvider; } public void Migrate(string connectionString, MigrationContext migrationContext) { var sw = Stopwatch.StartNew(); - _announcer.Heading("Migrating " + connectionString); + _logger.Info("*** Migrating {0} ***", connectionString); - var assembly = Assembly.GetExecutingAssembly(); + var serviceProvider = new ServiceCollection() + .AddLogging(lb => lb.AddProvider(_migrationLoggerProvider)) + .AddFluentMigratorCore() + .ConfigureRunner( + builder => builder + .AddNzbDroneSQLite() + .WithGlobalConnectionString(connectionString) + .WithMigrationsIn(Assembly.GetExecutingAssembly())) + .Configure(opt => opt.Namespace = "NzbDrone.Core.Datastore.Migration") + .Configure(opt => { + opt.PreviewOnly = false; + opt.Timeout = TimeSpan.FromSeconds(60); + }) + .BuildServiceProvider(); - var runnerContext = new RunnerContext(_announcer) + using (var scope = serviceProvider.CreateScope()) { - Namespace = "NzbDrone.Core.Datastore.Migration", - ApplicationContext = migrationContext - }; + var runner = scope.ServiceProvider.GetRequiredService(); - var options = new MigrationOptions { PreviewOnly = false, Timeout = 60 }; - var factory = new NzbDroneSqliteProcessorFactory(); - var processor = factory.Create(connectionString, _announcer, options); - - try - { - var runner = new MigrationRunner(assembly, runnerContext, processor); + MigrationContext.Current = migrationContext; if (migrationContext.DesiredVersion.HasValue) { - runner.MigrateUp(migrationContext.DesiredVersion.Value, true); + runner.MigrateUp(migrationContext.DesiredVersion.Value); } else { - runner.MigrateUp(true); + runner.MigrateUp(); } - } - catch (SQLiteException) - { - processor.Dispose(); - SQLiteConnection.ClearAllPools(); - throw; - } - processor.Dispose(); + MigrationContext.Current = null; + } sw.Stop(); - _announcer.ElapsedTime(sw.Elapsed); + _logger.Debug("Took: {0}", sw.Elapsed); } } } diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationDbFactory.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationDbFactory.cs deleted file mode 100644 index b28923d1c..000000000 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationDbFactory.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Data.Common; -using System.Data.SQLite; -using FluentMigrator.Runner.Processors; - -namespace NzbDrone.Core.Datastore.Migration.Framework -{ - public class MigrationDbFactory : DbFactoryBase - { - protected override DbProviderFactory CreateFactory() - { - return SQLiteFactory.Instance; - } - } -} \ No newline at end of file diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationExtension.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationExtension.cs index 807e73e2a..8d936463e 100644 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationExtension.cs +++ b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationExtension.cs @@ -1,5 +1,11 @@ -using FluentMigrator.Builders.Create; +using FluentMigrator; +using FluentMigrator.Builders.Create; using FluentMigrator.Builders.Create.Table; +using FluentMigrator.Runner; +using FluentMigrator.Runner.BatchParser; +using FluentMigrator.Runner.Generators.SQLite; +using FluentMigrator.Runner.Processors.SQLite; +using Microsoft.Extensions.DependencyInjection; namespace NzbDrone.Core.Datastore.Migration.Framework { @@ -16,5 +22,18 @@ namespace NzbDrone.Core.Datastore.Migration.Framework parameter.Value = value; command.Parameters.Add(parameter); } + + public static IMigrationRunnerBuilder AddNzbDroneSQLite(this IMigrationRunnerBuilder builder) + { + builder.Services + .AddTransient() + .AddScoped() + .AddScoped() + .AddScoped(sp => sp.GetRequiredService()) + .AddScoped() + .AddScoped() + .AddScoped(sp => sp.GetRequiredService()); + return builder; + } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationLogger.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationLogger.cs index 3418dd921..47ff934e1 100644 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationLogger.cs +++ b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationLogger.cs @@ -1,58 +1,59 @@ using System; using FluentMigrator.Runner; +using FluentMigrator.Runner.Logging; using NLog; namespace NzbDrone.Core.Datastore.Migration.Framework { - public class MigrationLogger : IAnnouncer + public class MigrationLogger : FluentMigratorLogger { private readonly Logger _logger; - - public MigrationLogger(Logger logger) + public MigrationLogger(Logger logger, + FluentMigratorLoggerOptions options) + : base(options) { _logger = logger; } - - public void Heading(string message) + protected override void WriteHeading(string message) { _logger.Info("*** {0} ***", message); } - public void Say(string message) + protected override void WriteSay(string message) { _logger.Debug(message); } - public void Emphasize(string message) + protected override void WriteEmphasize(string message) { _logger.Warn(message); } - public void Sql(string sql) + protected override void WriteSql(string sql) { _logger.Debug(sql); } - public void ElapsedTime(TimeSpan timeSpan) + protected override void WriteEmptySql() { - _logger.Debug("Took: {0}", timeSpan); + _logger.Debug(@"No SQL statement executed."); } - public void Error(string message) + protected override void WriteElapsedTime(TimeSpan timeSpan) { - _logger.Error(message); + _logger.Debug("Took: {0}", timeSpan); } - public void Error(Exception exception) + protected override void WriteError(string message) { - _logger.Error(exception); + _logger.Error(message); } - public void Write(string message, bool escaped) + protected override void WriteError(Exception exception) { - _logger.Info(message); + _logger.Error(exception); } } } diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationLoggerProvider.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationLoggerProvider.cs new file mode 100644 index 000000000..66d368de4 --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationLoggerProvider.cs @@ -0,0 +1,34 @@ +using System; +using FluentMigrator.Runner; +using Microsoft.Extensions.Logging; +using NLog; +using ILogger = Microsoft.Extensions.Logging.ILogger; + +namespace NzbDrone.Core.Datastore.Migration.Framework +{ + public class MigrationLoggerProvider : ILoggerProvider + { + private readonly Logger _logger; + + public MigrationLoggerProvider(Logger logger) + { + _logger = logger; + } + + public ILogger CreateLogger(string categoryName) + { + return new MigrationLogger(_logger, new FluentMigratorLoggerOptions() { ShowElapsedTime = true, ShowSql = true }); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + // Nothing to clean up + } + } +} diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationOptions.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationOptions.cs deleted file mode 100644 index 6a12df8dc..000000000 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/MigrationOptions.cs +++ /dev/null @@ -1,11 +0,0 @@ -using FluentMigrator; - -namespace NzbDrone.Core.Datastore.Migration.Framework -{ - public class MigrationOptions : IMigrationProcessorOptions - { - public bool PreviewOnly { get; set; } - public int Timeout { get; set; } - public string ProviderSwitches { get; private set; } - } -} \ No newline at end of file diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneMigrationBase.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneMigrationBase.cs index 0d4bf0a13..c437e2349 100644 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneMigrationBase.cs +++ b/src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneMigrationBase.cs @@ -8,7 +8,6 @@ namespace NzbDrone.Core.Datastore.Migration.Framework public abstract class NzbDroneMigrationBase : FluentMigrator.Migration { protected readonly Logger _logger; - private MigrationContext _migrationContext; protected NzbDroneMigrationBase() { @@ -32,26 +31,14 @@ namespace NzbDrone.Core.Datastore.Migration.Framework } } - public MigrationContext Context - { - get - { - if (_migrationContext == null) - { - _migrationContext = (MigrationContext)ApplicationContext; - } - return _migrationContext; - } - } - public override void Up() { - if (Context.BeforeMigration != null) + if (MigrationContext.Current.BeforeMigration != null) { - Context.BeforeMigration(this); + MigrationContext.Current.BeforeMigration(this); } - switch (Context.MigrationType) + switch (MigrationContext.Current.MigrationType) { case MigrationType.Main: _logger.Info("Starting migration to " + Version); diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneSqliteProcessor.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneSQLiteProcessor.cs similarity index 86% rename from src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneSqliteProcessor.cs rename to src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneSQLiteProcessor.cs index 929a89e9d..290916aa3 100644 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneSqliteProcessor.cs +++ b/src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneSQLiteProcessor.cs @@ -1,28 +1,30 @@ using System; using System.Collections.Generic; -using System.Data; using System.Linq; -using FluentMigrator; +using System.Text.RegularExpressions; using FluentMigrator.Expressions; using FluentMigrator.Model; -using FluentMigrator.Runner; -using FluentMigrator.Runner.Announcers; using FluentMigrator.Runner.Generators.SQLite; +using FluentMigrator.Runner.Initialization; +using FluentMigrator.Runner.Processors; using FluentMigrator.Runner.Processors.SQLite; -using System.Text.RegularExpressions; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace NzbDrone.Core.Datastore.Migration.Framework { - public class NzbDroneSqliteProcessor : SQLiteProcessor + public class NzbDroneSQLiteProcessor : SQLiteProcessor { - public NzbDroneSqliteProcessor(IDbConnection connection, IMigrationGenerator generator, IAnnouncer announcer, IMigrationProcessorOptions options, FluentMigrator.Runner.Processors.IDbFactory factory) - : base(connection, generator, announcer, options, factory) + public NzbDroneSQLiteProcessor(SQLiteDbFactory factory, + SQLiteGenerator generator, + ILogger logger, + IOptionsSnapshot options, + IConnectionStringAccessor connectionStringAccessor, + IServiceProvider serviceProvider) + : base(factory, generator, logger, options, connectionStringAccessor, serviceProvider) { - } - public override bool SupportsTransactions => true; - public override void Process(AlterColumnExpression expression) { var tableDefinition = GetTableSchema(expression.TableName); @@ -107,7 +109,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework protected virtual TableDefinition GetTableSchema(string tableName) { - var schemaDumper = new SqliteSchemaDumper(this, Announcer); + var schemaDumper = new SqliteSchemaDumper(this); var schema = schemaDumper.ReadDbSchema(); return schema.Single(v => v.Name == tableName); diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneSqliteProcessorFactory.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneSqliteProcessorFactory.cs deleted file mode 100644 index 52ea473e9..000000000 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/NzbDroneSqliteProcessorFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -using FluentMigrator; -using FluentMigrator.Runner; -using FluentMigrator.Runner.Generators.SQLite; -using FluentMigrator.Runner.Processors.SQLite; - -namespace NzbDrone.Core.Datastore.Migration.Framework -{ - public class NzbDroneSqliteProcessorFactory : SQLiteProcessorFactory - { - public override IMigrationProcessor Create(string connectionString, IAnnouncer announcer, IMigrationProcessorOptions options) - { - var factory = new MigrationDbFactory(); - var connection = factory.CreateConnection(connectionString); - var generator = new SQLiteGenerator { compatabilityMode = CompatabilityMode.STRICT }; - return new NzbDroneSqliteProcessor(connection, generator, announcer, options, factory); - } - } -} diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/SqliteSchemaDumper.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/SqliteSchemaDumper.cs index c1f786f79..6b8dc19ca 100644 --- a/src/NzbDrone.Core/Datastore/Migration/Framework/SqliteSchemaDumper.cs +++ b/src/NzbDrone.Core/Datastore/Migration/Framework/SqliteSchemaDumper.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Data; using FluentMigrator.Model; -using FluentMigrator.Runner; using FluentMigrator.Runner.Processors.SQLite; namespace NzbDrone.Core.Datastore.Migration.Framework @@ -10,13 +9,11 @@ namespace NzbDrone.Core.Datastore.Migration.Framework // The original implementation had bad support for escaped identifiers, amongst other things. public class SqliteSchemaDumper { - public SqliteSchemaDumper(SQLiteProcessor processor, IAnnouncer announcer) + public SqliteSchemaDumper(SQLiteProcessor processor) { - Announcer = announcer; Processor = processor; } - public virtual IAnnouncer Announcer { get; set; } public SQLiteProcessor Processor { get; set; } protected internal virtual TableDefinition ReadTableSchema(string sqlSchema) @@ -258,4 +255,4 @@ namespace NzbDrone.Core.Datastore.Migration.Framework return indexes; } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/Datastore/Migration/Framework/TableDefinition.cs b/src/NzbDrone.Core/Datastore/Migration/Framework/TableDefinition.cs new file mode 100644 index 000000000..1a680f0d8 --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/Framework/TableDefinition.cs @@ -0,0 +1,54 @@ +#region License +// +// Copyright (c) 2007-2009, Sean Chambers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#endregion + + +using System; +using System.Collections.Generic; +using System.Linq; +using FluentMigrator.Infrastructure.Extensions; +using FluentMigrator.Model; + +namespace NzbDrone.Core.Datastore.Migration.Framework +{ + public class TableDefinition : ICloneable + { + public TableDefinition() + { + Columns = new List(); + ForeignKeys = new List(); + Indexes = new List(); + } + + public virtual string Name { get; set; } + public virtual string SchemaName { get; set; } + public virtual ICollection Columns { get; set; } + public virtual ICollection ForeignKeys { get; set; } + public virtual ICollection Indexes { get; set; } + + public object Clone() + { + return new TableDefinition + { + Name = Name, + SchemaName = SchemaName, + Columns = Columns.CloneAll().ToList(), + Indexes = Indexes.CloneAll().ToList() + }; + } + } +} diff --git a/src/NzbDrone.Core/Lidarr.Core.csproj b/src/NzbDrone.Core/Lidarr.Core.csproj index 7ae52a2c0..8b2709f18 100644 --- a/src/NzbDrone.Core/Lidarr.Core.csproj +++ b/src/NzbDrone.Core/Lidarr.Core.csproj @@ -4,7 +4,8 @@ - + +