mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-14 11:23:42 +02:00
Upgrade FluentMigrator from 1.6.2 to v3
Co-Authored-By: ta264 <ta264@users.noreply.github.com>
This commit is contained in:
parent
e263331880
commit
fd5ac3c713
@ -6,7 +6,6 @@
|
|||||||
<add key="dotnet-bsd-crossbuild" value="https://pkgs.dev.azure.com/Servarr/Servarr/_packaging/dotnet-bsd-crossbuild/nuget/v3/index.json" />
|
<add key="dotnet-bsd-crossbuild" value="https://pkgs.dev.azure.com/Servarr/Servarr/_packaging/dotnet-bsd-crossbuild/nuget/v3/index.json" />
|
||||||
<add key="Mono.Posix.NETStandard" value="https://pkgs.dev.azure.com/Servarr/Servarr/_packaging/Mono.Posix.NETStandard/nuget/v3/index.json" />
|
<add key="Mono.Posix.NETStandard" value="https://pkgs.dev.azure.com/Servarr/Servarr/_packaging/Mono.Posix.NETStandard/nuget/v3/index.json" />
|
||||||
<add key="SQLite" value="https://pkgs.dev.azure.com/Servarr/Servarr/_packaging/SQLite/nuget/v3/index.json" />
|
<add key="SQLite" value="https://pkgs.dev.azure.com/Servarr/Servarr/_packaging/SQLite/nuget/v3/index.json" />
|
||||||
<add key="FluentMigrator" value="https://pkgs.dev.azure.com/fluentmigrator/fluentmigrator/_packaging/fluentmigrator/nuget/v3/index.json" />
|
|
||||||
<add key="coverlet-nightly" value="https://pkgs.dev.azure.com/Servarr/coverlet/_packaging/coverlet-nightly/nuget/v3/index.json" />
|
<add key="coverlet-nightly" value="https://pkgs.dev.azure.com/Servarr/coverlet/_packaging/coverlet-nightly/nuget/v3/index.json" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>
|
</configuration>
|
@ -2,10 +2,10 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using FluentMigrator;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
using NzbDrone.Core.Datastore.Migration;
|
using NzbDrone.Core.Datastore.Migration;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||||
@ -89,9 +89,9 @@ public void should_leave_other_data()
|
|||||||
history.DownloadId.Should().Be("123");
|
history.DownloadId.Should().Be("123");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InsertHistory(MigrationBase migrationBase, Dictionary<string, string> data)
|
private void InsertHistory(NzbDroneMigrationBase migration, Dictionary<string, string> data)
|
||||||
{
|
{
|
||||||
migrationBase.Insert.IntoTable("History").Row(new
|
migration.Insert.IntoTable("History").Row(new
|
||||||
{
|
{
|
||||||
EpisodeId = 1,
|
EpisodeId = 1,
|
||||||
SeriesId = 1,
|
SeriesId = 1,
|
||||||
|
@ -14,7 +14,7 @@ public class SqliteSchemaDumperFixture
|
|||||||
[SetUp]
|
[SetUp]
|
||||||
public void 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")]
|
[TestCase(@"CREATE TABLE TestTable (MyId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT)", "TestTable", "MyId")]
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data.SQLite;
|
using System.Data.SQLite;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentMigrator.Runner;
|
|
||||||
using Marr.Data;
|
using Marr.Data;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
@ -96,9 +96,14 @@ protected virtual ITestDatabase WithTestDb(MigrationContext migrationContext)
|
|||||||
return testDb;
|
return testDb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void SetupLogging()
|
||||||
|
{
|
||||||
|
Mocker.SetConstant<ILoggerProvider>(NullLoggerProvider.Instance);
|
||||||
|
}
|
||||||
protected void SetupContainer()
|
protected void SetupContainer()
|
||||||
{
|
{
|
||||||
WithTempAsAppPath();
|
WithTempAsAppPath();
|
||||||
|
SetupLogging();
|
||||||
|
|
||||||
Mocker.SetConstant<IConnectionStringFactory>(Mocker.Resolve<ConnectionStringFactory>());
|
Mocker.SetConstant<IConnectionStringFactory>(Mocker.Resolve<ConnectionStringFactory>());
|
||||||
Mocker.SetConstant<IMigrationController>(Mocker.Resolve<MigrationController>());
|
Mocker.SetConstant<IMigrationController>(Mocker.Resolve<MigrationController>());
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using FluentMigrator;
|
using FluentMigrator;
|
||||||
using FluentMigrator.Runner;
|
using Microsoft.Extensions.Logging;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
@ -35,10 +35,14 @@ protected virtual IDirectDataMapper WithMigrationTestDb(Action<TMigration> befor
|
|||||||
return db.GetDirectDataMapper();
|
return db.GetDirectDataMapper();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void SetupLogging()
|
||||||
|
{
|
||||||
|
Mocker.SetConstant<ILoggerProvider>(Mocker.Resolve<MigrationLoggerProvider>());
|
||||||
|
}
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public override void SetupDb()
|
public override void SetupDb()
|
||||||
{
|
{
|
||||||
Mocker.SetConstant<IAnnouncer>(Mocker.Resolve<MigrationLogger>());
|
|
||||||
SetupContainer();
|
SetupContainer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,13 @@
|
|||||||
using FluentMigrator;
|
using FluentMigrator;
|
||||||
using FluentMigrator.Infrastructure;
|
|
||||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
using System.Data;
|
|
||||||
using System.Data.SQLite;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore.Migration
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
{
|
{
|
||||||
[Migration(128)]
|
[Migration(128)]
|
||||||
public class rename_quality_profiles_add_upgrade_allowed : NzbDroneMigrationBase
|
public class rename_quality_profiles_add_upgrade_allowed : NzbDroneMigrationBase
|
||||||
{
|
{
|
||||||
private IMigrationContext _capturedContext;
|
|
||||||
|
|
||||||
protected override void MainDbUpgrade()
|
protected override void MainDbUpgrade()
|
||||||
{
|
{
|
||||||
FixupMigration111();
|
|
||||||
|
|
||||||
Rename.Table("Profiles").To("QualityProfiles");
|
Rename.Table("Profiles").To("QualityProfiles");
|
||||||
|
|
||||||
Alter.Table("QualityProfiles").AddColumn("UpgradeAllowed").AsInt32().Nullable();
|
Alter.Table("QualityProfiles").AddColumn("UpgradeAllowed").AsInt32().Nullable();
|
||||||
@ -26,41 +19,5 @@ protected override void MainDbUpgrade()
|
|||||||
|
|
||||||
Rename.Column("ProfileId").OnTable("Series").To("QualityProfileId");
|
Rename.Column("ProfileId").OnTable("Series").To("QualityProfileId");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void GetUpExpressions(IMigrationContext context)
|
|
||||||
{
|
|
||||||
_capturedContext = context;
|
|
||||||
|
|
||||||
base.GetUpExpressions(context);
|
|
||||||
|
|
||||||
_capturedContext = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Early Radarr versions can mess up Sonarr's database if they point to the same config. Fixup the damage.
|
|
||||||
private void FixupMigration111()
|
|
||||||
{
|
|
||||||
var builder = new SQLiteConnectionStringBuilder(ConnectionString);
|
|
||||||
builder.Pooling = false;
|
|
||||||
|
|
||||||
// In order to get the expressions we need to check the database directly
|
|
||||||
using (var connection = new SQLiteConnection(builder.ToString()))
|
|
||||||
using (var command = connection.CreateCommand())
|
|
||||||
{
|
|
||||||
connection.Open();
|
|
||||||
command.CommandText = "SELECT Description FROM VersionInfo WHERE Version = 111";
|
|
||||||
|
|
||||||
var description = command.ExecuteScalar() as string;
|
|
||||||
connection.Close();
|
|
||||||
|
|
||||||
if (description == "remove_bitmetv")
|
|
||||||
{
|
|
||||||
// Get the migration expressions from the 111 migration
|
|
||||||
var migration111 = new create_language_profiles();
|
|
||||||
migration111.GetUpExpressions(_capturedContext);
|
|
||||||
|
|
||||||
Execute.Sql("UPDATE VersionInfo SET Description = 'create_language_profiles fixup' WHERE Version = 111");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
|
|||||||
{
|
{
|
||||||
public class MigrationContext
|
public class MigrationContext
|
||||||
{
|
{
|
||||||
|
public static MigrationContext Current { get; set; }
|
||||||
|
|
||||||
public MigrationType MigrationType { get; private set; }
|
public MigrationType MigrationType { get; private set; }
|
||||||
public long? DesiredVersion { get; set; }
|
public long? DesiredVersion { get; set; }
|
||||||
|
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
using System.Data.SQLite;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using FluentMigrator.Runner;
|
using FluentMigrator.Runner;
|
||||||
using FluentMigrator.Runner.Initialization;
|
using FluentMigrator.Runner.Initialization;
|
||||||
|
using FluentMigrator.Runner.Processors;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore.Migration.Framework
|
namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||||
{
|
{
|
||||||
@ -13,56 +17,59 @@ public interface IMigrationController
|
|||||||
|
|
||||||
public class MigrationController : IMigrationController
|
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)
|
public void Migrate(string connectionString, MigrationContext migrationContext)
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
_announcer.Heading("Checking database for required migrations " + 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<TypeFilterOptions>(opt => opt.Namespace = "NzbDrone.Core.Datastore.Migration")
|
||||||
|
.Configure<ProcessorOptions>(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",
|
var runner = scope.ServiceProvider.GetRequiredService<IMigrationRunner>();
|
||||||
ApplicationContext = migrationContext
|
|
||||||
};
|
|
||||||
|
|
||||||
var options = new MigrationOptions { PreviewOnly = false, Timeout = 60 };
|
MigrationContext.Current = migrationContext;
|
||||||
var factory = new NzbDroneSqliteProcessorFactory();
|
|
||||||
var processor = factory.Create(connectionString, _announcer, options);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var runner = new MigrationRunner(assembly, runnerContext, processor);
|
|
||||||
|
|
||||||
if (migrationContext.DesiredVersion.HasValue)
|
if (migrationContext.DesiredVersion.HasValue)
|
||||||
{
|
{
|
||||||
runner.MigrateUp(migrationContext.DesiredVersion.Value, true);
|
runner.MigrateUp(migrationContext.DesiredVersion.Value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
runner.MigrateUp(true);
|
runner.MigrateUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
processor.Dispose();
|
MigrationContext.Current = null;
|
||||||
}
|
|
||||||
catch (SQLiteException)
|
|
||||||
{
|
|
||||||
processor.Dispose();
|
|
||||||
SQLiteConnection.ClearAllPools();
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
|
|
||||||
_announcer.ElapsedTime(sw.Elapsed);
|
_logger.Debug("Took: {0}", sw.Elapsed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,12 @@
|
|||||||
using System.Data;
|
using FluentMigrator;
|
||||||
using FluentMigrator.Builders.Create;
|
using FluentMigrator.Builders.Create;
|
||||||
using FluentMigrator.Builders.Create.Table;
|
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;
|
||||||
|
using System.Data;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore.Migration.Framework
|
namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||||
{
|
{
|
||||||
@ -20,11 +26,24 @@ public static IDbCommand CreateCommand(this IDbConnection conn, IDbTransaction t
|
|||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddParameter(this IDbCommand command, object value)
|
public static void AddParameter(this System.Data.IDbCommand command, object value)
|
||||||
{
|
{
|
||||||
var parameter = command.CreateParameter();
|
var parameter = command.CreateParameter();
|
||||||
parameter.Value = value;
|
parameter.Value = value;
|
||||||
command.Parameters.Add(parameter);
|
command.Parameters.Add(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IMigrationRunnerBuilder AddNzbDroneSQLite(this IMigrationRunnerBuilder builder)
|
||||||
|
{
|
||||||
|
builder.Services
|
||||||
|
.AddTransient<SQLiteBatchParser>()
|
||||||
|
.AddScoped<SQLiteDbFactory>()
|
||||||
|
.AddScoped<NzbDroneSQLiteProcessor>()
|
||||||
|
.AddScoped<IMigrationProcessor>(sp => sp.GetRequiredService<NzbDroneSQLiteProcessor>())
|
||||||
|
.AddScoped<SQLiteQuoter>()
|
||||||
|
.AddScoped<SQLiteGenerator>()
|
||||||
|
.AddScoped<IMigrationGenerator>(sp => sp.GetRequiredService<SQLiteGenerator>());
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,58 +1,59 @@
|
|||||||
using System;
|
using System;
|
||||||
using FluentMigrator.Runner;
|
using FluentMigrator.Runner;
|
||||||
|
using FluentMigrator.Runner.Logging;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore.Migration.Framework
|
namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||||
{
|
{
|
||||||
public class MigrationLogger : IAnnouncer
|
public class MigrationLogger : FluentMigratorLogger
|
||||||
{
|
{
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public MigrationLogger(Logger logger,
|
||||||
public MigrationLogger(Logger logger)
|
FluentMigratorLoggerOptions options)
|
||||||
|
: base(options)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void WriteHeading(string message)
|
||||||
public void Heading(string message)
|
|
||||||
{
|
{
|
||||||
_logger.Info("*** {0} ***", message);
|
_logger.Info("*** {0} ***", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Say(string message)
|
protected override void WriteSay(string message)
|
||||||
{
|
{
|
||||||
_logger.Debug(message);
|
_logger.Debug(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Emphasize(string message)
|
protected override void WriteEmphasize(string message)
|
||||||
{
|
{
|
||||||
_logger.Warn(message);
|
_logger.Warn(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Sql(string sql)
|
protected override void WriteSql(string sql)
|
||||||
{
|
{
|
||||||
_logger.Debug(sql);
|
_logger.Debug(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ElapsedTime(TimeSpan timeSpan)
|
protected override void WriteEmptySql()
|
||||||
|
{
|
||||||
|
_logger.Debug(@"No SQL statement executed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void WriteElapsedTime(TimeSpan timeSpan)
|
||||||
{
|
{
|
||||||
_logger.Debug("Took: {0}", timeSpan);
|
_logger.Debug("Took: {0}", timeSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Error(string message)
|
protected override void WriteError(string message)
|
||||||
{
|
{
|
||||||
_logger.Error(message);
|
_logger.Error(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Error(Exception exception)
|
protected override void WriteError(Exception exception)
|
||||||
{
|
{
|
||||||
_logger.Error(exception);
|
_logger.Error(exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(string message, bool escaped)
|
|
||||||
{
|
|
||||||
_logger.Info(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
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()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,7 +8,6 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
|
|||||||
public abstract class NzbDroneMigrationBase : FluentMigrator.Migration
|
public abstract class NzbDroneMigrationBase : FluentMigrator.Migration
|
||||||
{
|
{
|
||||||
protected readonly Logger _logger;
|
protected readonly Logger _logger;
|
||||||
private MigrationContext _migrationContext;
|
|
||||||
|
|
||||||
protected NzbDroneMigrationBase()
|
protected NzbDroneMigrationBase()
|
||||||
{
|
{
|
||||||
@ -32,26 +31,14 @@ public int Version
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MigrationContext Context
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_migrationContext == null)
|
|
||||||
{
|
|
||||||
_migrationContext = (MigrationContext)ApplicationContext;
|
|
||||||
}
|
|
||||||
return _migrationContext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Up()
|
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:
|
case MigrationType.Main:
|
||||||
LogMigrationMessage(MigrationType.Main);
|
LogMigrationMessage(MigrationType.Main);
|
||||||
|
@ -1,28 +1,32 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentMigrator;
|
using System.Text.RegularExpressions;
|
||||||
using FluentMigrator.Expressions;
|
using FluentMigrator.Expressions;
|
||||||
using FluentMigrator.Model;
|
using FluentMigrator.Model;
|
||||||
using FluentMigrator.Runner;
|
|
||||||
using FluentMigrator.Runner.Announcers;
|
|
||||||
using FluentMigrator.Runner.Generators.SQLite;
|
using FluentMigrator.Runner.Generators.SQLite;
|
||||||
|
using FluentMigrator.Runner.Initialization;
|
||||||
|
using FluentMigrator.Runner.Processors;
|
||||||
using FluentMigrator.Runner.Processors.SQLite;
|
using FluentMigrator.Runner.Processors.SQLite;
|
||||||
using System.Text.RegularExpressions;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore.Migration.Framework
|
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)
|
public NzbDroneSQLiteProcessor(SQLiteDbFactory factory,
|
||||||
: base(connection, generator, announcer, options, factory)
|
SQLiteGenerator generator,
|
||||||
|
ILogger<NzbDroneSQLiteProcessor> logger,
|
||||||
|
IOptionsSnapshot<ProcessorOptions> options,
|
||||||
|
IConnectionStringAccessor connectionStringAccessor,
|
||||||
|
IServiceProvider serviceProvider,
|
||||||
|
SQLiteQuoter quoter)
|
||||||
|
: base(factory, generator, logger, options, connectionStringAccessor, serviceProvider, quoter)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool SupportsTransactions => true;
|
|
||||||
|
|
||||||
public override void Process(AlterColumnExpression expression)
|
public override void Process(AlterColumnExpression expression)
|
||||||
{
|
{
|
||||||
var tableDefinition = GetTableSchema(expression.TableName);
|
var tableDefinition = GetTableSchema(expression.TableName);
|
||||||
@ -107,7 +111,7 @@ public override void Process(RenameColumnExpression expression)
|
|||||||
|
|
||||||
protected virtual TableDefinition GetTableSchema(string tableName)
|
protected virtual TableDefinition GetTableSchema(string tableName)
|
||||||
{
|
{
|
||||||
var schemaDumper = new SqliteSchemaDumper(this, Announcer);
|
var schemaDumper = new SqliteSchemaDumper(this);
|
||||||
var schema = schemaDumper.ReadDbSchema();
|
var schema = schemaDumper.ReadDbSchema();
|
||||||
|
|
||||||
return schema.Single(v => v.Name == tableName);
|
return schema.Single(v => v.Name == tableName);
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,7 +2,6 @@
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FluentMigrator.Model;
|
using FluentMigrator.Model;
|
||||||
using FluentMigrator.Runner;
|
|
||||||
using FluentMigrator.Runner.Processors.SQLite;
|
using FluentMigrator.Runner.Processors.SQLite;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Datastore.Migration.Framework
|
namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||||
@ -11,13 +10,11 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
|
|||||||
// The original implementation had bad support for escaped identifiers, amongst other things.
|
// The original implementation had bad support for escaped identifiers, amongst other things.
|
||||||
public class SqliteSchemaDumper
|
public class SqliteSchemaDumper
|
||||||
{
|
{
|
||||||
public SqliteSchemaDumper(SQLiteProcessor processor, IAnnouncer announcer)
|
public SqliteSchemaDumper(SQLiteProcessor processor)
|
||||||
{
|
{
|
||||||
Announcer = announcer;
|
|
||||||
Processor = processor;
|
Processor = processor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IAnnouncer Announcer { get; set; }
|
|
||||||
public SQLiteProcessor Processor { get; set; }
|
public SQLiteProcessor Processor { get; set; }
|
||||||
|
|
||||||
protected internal virtual TableDefinition ReadTableSchema(string sqlSchema)
|
protected internal virtual TableDefinition ReadTableSchema(string sqlSchema)
|
||||||
@ -42,7 +39,9 @@ protected virtual TableDefinition ParseCreateTableStatement(SqliteSyntaxReader r
|
|||||||
{
|
{
|
||||||
var table = new TableDefinition();
|
var table = new TableDefinition();
|
||||||
|
|
||||||
while (reader.Read() != SqliteSyntaxReader.TokenType.StringToken || reader.ValueToUpper != "TABLE") ;
|
while (reader.Read() != SqliteSyntaxReader.TokenType.StringToken || reader.ValueToUpper != "TABLE")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
if (reader.Read() == SqliteSyntaxReader.TokenType.StringToken && reader.ValueToUpper == "IF")
|
if (reader.Read() == SqliteSyntaxReader.TokenType.StringToken && reader.ValueToUpper == "IF")
|
||||||
{
|
{
|
||||||
@ -135,7 +134,10 @@ protected virtual IndexDefinition ParseCreateIndexStatement(SqliteSyntaxReader r
|
|||||||
reader.Read();
|
reader.Read();
|
||||||
index.IsUnique = reader.ValueToUpper == "UNIQUE";
|
index.IsUnique = reader.ValueToUpper == "UNIQUE";
|
||||||
|
|
||||||
while (reader.ValueToUpper != "INDEX") reader.Read();
|
while (reader.ValueToUpper != "INDEX")
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
|
||||||
if (reader.Read() == SqliteSyntaxReader.TokenType.StringToken && reader.ValueToUpper == "IF")
|
if (reader.Read() == SqliteSyntaxReader.TokenType.StringToken && reader.ValueToUpper == "IF")
|
||||||
{
|
{
|
||||||
@ -196,8 +198,6 @@ protected virtual string ParseIdentifier(SqliteSyntaxReader reader)
|
|||||||
return reader.Value;
|
return reader.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region ISchemaDumper Members
|
|
||||||
|
|
||||||
public virtual IList<TableDefinition> ReadDbSchema()
|
public virtual IList<TableDefinition> ReadDbSchema()
|
||||||
{
|
{
|
||||||
IList<TableDefinition> tables = ReadTables();
|
IList<TableDefinition> tables = ReadTables();
|
||||||
@ -210,8 +210,6 @@ public virtual IList<TableDefinition> ReadDbSchema()
|
|||||||
return tables;
|
return tables;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
protected virtual DataSet Read(string template, params object[] args)
|
protected virtual DataSet Read(string template, params object[] args)
|
||||||
{
|
{
|
||||||
return Processor.Read(template, args);
|
return Processor.Read(template, args);
|
||||||
|
@ -48,18 +48,25 @@ public void TrimBuffer()
|
|||||||
|
|
||||||
public void SkipWhitespace()
|
public void SkipWhitespace()
|
||||||
{
|
{
|
||||||
while (!IsEndOfFile && char.IsWhiteSpace(Buffer[Index])) Index++;
|
while (!IsEndOfFile && char.IsWhiteSpace(Buffer[Index]))
|
||||||
|
{
|
||||||
|
Index++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SkipTillToken(TokenType tokenType)
|
public void SkipTillToken(TokenType tokenType)
|
||||||
{
|
{
|
||||||
if (IsEndOfFile)
|
if (IsEndOfFile)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (Read() != tokenType)
|
while (Read() != tokenType)
|
||||||
{
|
{
|
||||||
if (Type == TokenType.ListStart)
|
if (Type == TokenType.ListStart)
|
||||||
|
{
|
||||||
SkipTillToken(TokenType.ListEnd);
|
SkipTillToken(TokenType.ListEnd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,9 +155,12 @@ public TokenType Read()
|
|||||||
{
|
{
|
||||||
var start = Index;
|
var start = Index;
|
||||||
var end = start + 1;
|
var end = start + 1;
|
||||||
while (end < Buffer.Length && (char.IsLetter(Buffer[end]) || char.IsNumber(Buffer[end]) || Buffer[end] == '_')) end++;
|
while (end < Buffer.Length && (char.IsLetter(Buffer[end]) || char.IsNumber(Buffer[end]) || Buffer[end] == '_'))
|
||||||
|
{
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
|
||||||
if (end >= Buffer.Length || Buffer[end] == ',' || Buffer[end] == '(' || Buffer[end] == ')' || char.IsWhiteSpace(Buffer[end]))
|
if (end >= Buffer.Length || Buffer[end] == ',' || Buffer[end] == ')' || Buffer[end] == '(' || char.IsWhiteSpace(Buffer[end]))
|
||||||
{
|
{
|
||||||
Index = end;
|
Index = end;
|
||||||
}
|
}
|
||||||
@ -215,7 +225,10 @@ protected string ReadTerminatedString(char terminator)
|
|||||||
var start = Index + 1;
|
var start = Index + 1;
|
||||||
var end = Buffer.IndexOf(terminator, Index);
|
var end = Buffer.IndexOf(terminator, Index);
|
||||||
|
|
||||||
if (end == -1) throw new SyntaxErrorException();
|
if (end == -1)
|
||||||
|
{
|
||||||
|
throw new SyntaxErrorException();
|
||||||
|
}
|
||||||
|
|
||||||
Index = end + 1;
|
Index = end + 1;
|
||||||
return Buffer.Substring(start, end - start);
|
return Buffer.Substring(start, end - start);
|
||||||
@ -230,12 +243,18 @@ protected string ReadEscapedString(char escape)
|
|||||||
var start = Index + 1;
|
var start = Index + 1;
|
||||||
var end = Buffer.IndexOf(escape, start);
|
var end = Buffer.IndexOf(escape, start);
|
||||||
|
|
||||||
if (end == -1) throw new SyntaxErrorException();
|
if (end == -1)
|
||||||
|
{
|
||||||
|
throw new SyntaxErrorException();
|
||||||
|
}
|
||||||
|
|
||||||
Index = end + 1;
|
Index = end + 1;
|
||||||
identifier.Append(Buffer.Substring(start, end - start));
|
identifier.Append(Buffer.Substring(start, end - start));
|
||||||
|
|
||||||
if (Buffer[Index] != escape) break;
|
if (Buffer[Index] != escape)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
identifier.Append(escape);
|
identifier.Append(escape);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright (c) 2007-2009, Sean Chambers <schambers80@gmail.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
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<ColumnDefinition>();
|
||||||
|
ForeignKeys = new List<ForeignKeyDefinition>();
|
||||||
|
Indexes = new List<IndexDefinition>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual string Name { get; set; }
|
||||||
|
public virtual string SchemaName { get; set; }
|
||||||
|
public virtual ICollection<ColumnDefinition> Columns { get; set; }
|
||||||
|
public virtual ICollection<ForeignKeyDefinition> ForeignKeys { get; set; }
|
||||||
|
public virtual ICollection<IndexDefinition> Indexes { get; set; }
|
||||||
|
|
||||||
|
public object Clone()
|
||||||
|
{
|
||||||
|
return new TableDefinition
|
||||||
|
{
|
||||||
|
Name = Name,
|
||||||
|
SchemaName = SchemaName,
|
||||||
|
Columns = Columns.CloneAll().ToList(),
|
||||||
|
Indexes = Indexes.CloneAll().ToList()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,8 @@
|
|||||||
<Platforms>x86</Platforms>
|
<Platforms>x86</Platforms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentMigrator.Runner" Version="1.6.2" />
|
<PackageReference Include="FluentMigrator.Runner" Version="3.3.2" />
|
||||||
|
<PackageReference Include="FluentMigrator.Runner.SQLite" Version="3.3.2" />
|
||||||
<PackageReference Include="FluentValidation" Version="8.4.0" />
|
<PackageReference Include="FluentValidation" Version="8.4.0" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta0007" />
|
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta0007" />
|
||||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||||
|
Loading…
Reference in New Issue
Block a user