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 @@
-
+
+