Radarr/Migrator.net/Migrator/Migrator.cs

178 lines
5.6 KiB
C#

#region License
//The contents of this file are subject to the Mozilla Public License
//Version 1.1 (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.mozilla.org/MPL/
//Software distributed under the License is distributed on an "AS IS"
//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
//License for the specific language governing rights and limitations
//under the License.
#endregion
using System;
using System.Collections.Generic;
using System.Reflection;
using Migrator.Framework;
using Migrator.Framework.Loggers;
namespace Migrator
{
/// <summary>
/// Migrations mediator.
/// </summary>
public class Migrator
{
private readonly ITransformationProvider _provider;
private readonly MigrationLoader _migrationLoader;
private ILogger _logger = new Logger(false);
protected bool _dryrun;
private string[] _args;
public string[] args
{
get { return _args; }
set { _args = value; }
}
public Migrator(string provider, string connectionString, Assembly migrationAssembly)
: this(provider, connectionString, migrationAssembly, false)
{
}
public Migrator(string provider, string connectionString, Assembly migrationAssembly, bool trace)
: this(ProviderFactory.Create(provider, connectionString), migrationAssembly, trace)
{
}
public Migrator(string provider, string connectionString, Assembly migrationAssembly, bool trace, ILogger logger)
: this(ProviderFactory.Create(provider, connectionString), migrationAssembly, trace, logger)
{
}
public Migrator(ITransformationProvider provider, Assembly migrationAssembly, bool trace)
: this(provider, migrationAssembly, trace, new Logger(trace, new ConsoleWriter()))
{
}
public Migrator(ITransformationProvider provider, Assembly migrationAssembly, bool trace, ILogger logger)
{
_provider = provider;
Logger = logger;
_migrationLoader = new MigrationLoader(provider, migrationAssembly, trace);
_migrationLoader.CheckForDuplicatedVersion();
}
/// <summary>
/// Returns registered migration <see cref="System.Type">types</see>.
/// </summary>
public List<Type> MigrationsTypes
{
get { return _migrationLoader.MigrationsTypes; }
}
/// <summary>
/// Run all migrations up to the latest. Make no changes to database if
/// dryrun is true.
/// </summary>
public void MigrateToLastVersion()
{
MigrateTo(_migrationLoader.LastVersion);
}
/// <summary>
/// Returns the current migrations applied to the database.
/// </summary>
public List<long> AppliedMigrations
{
get { return _provider.AppliedMigrations; }
}
/// <summary>
/// Get or set the event logger.
/// </summary>
public ILogger Logger
{
get { return _logger; }
set
{
_logger = value;
_provider.Logger = value;
}
}
public virtual bool DryRun
{
get { return _dryrun; }
set { _dryrun = value; }
}
/// <summary>
/// Migrate the database to a specific version.
/// Runs all migration between the actual version and the
/// specified version.
/// If <c>version</c> is greater then the current version,
/// the <c>Up()</c> method will be invoked.
/// If <c>version</c> lower then the current version,
/// the <c>Down()</c> method of previous migration will be invoked.
/// If <c>dryrun</c> is set, don't write any changes to the database.
/// </summary>
/// <param name="version">The version that must became the current one</param>
public void MigrateTo(long version)
{
if (_migrationLoader.MigrationsTypes.Count == 0)
{
_logger.Warn("No public classes with the Migration attribute were found.");
return;
}
bool firstRun = true;
BaseMigrate migrate = BaseMigrate.GetInstance(_migrationLoader.GetAvailableMigrations(), _provider, _logger);
migrate.DryRun = DryRun;
Logger.Started(migrate.AppliedVersions, version);
while (migrate.Continue(version))
{
IMigration migration = _migrationLoader.GetMigration(migrate.Current);
if (null == migration)
{
_logger.Skipping(migrate.Current);
migrate.Iterate();
continue;
}
try
{
if (firstRun)
{
migration.InitializeOnce(_args);
firstRun = false;
}
migrate.Migrate(migration);
}
catch (Exception ex)
{
Logger.Exception(migrate.Current, migration.Name, ex);
// Oho! error! We rollback changes.
Logger.RollingBack(migrate.Previous);
_provider.Rollback();
throw;
}
migrate.Iterate();
}
Logger.Finished(migrate.AppliedVersions, version);
}
}
}