using System;
using System.Collections.Generic;
using System.Reflection;
using Migrator.Framework;
namespace Migrator
{
///
/// Handles inspecting code to find all of the Migrations in assemblies and reading
/// other metadata such as the last revision, etc.
///
public class MigrationLoader
{
private readonly ITransformationProvider _provider;
private readonly List _migrationsTypes = new List();
public MigrationLoader(ITransformationProvider provider, Assembly migrationAssembly, bool trace)
{
_provider = provider;
AddMigrations(migrationAssembly);
if (trace)
{
provider.Logger.Trace("Loaded migrations:");
foreach (Type t in _migrationsTypes)
{
provider.Logger.Trace("{0} {1}", GetMigrationVersion(t).ToString().PadLeft(5), StringUtils.ToHumanName(t.Name));
}
}
}
public void AddMigrations(Assembly migrationAssembly)
{
if (migrationAssembly != null)
_migrationsTypes.AddRange(GetMigrationTypes(migrationAssembly));
}
///
/// Returns registered migration types.
///
public List MigrationsTypes
{
get { return _migrationsTypes; }
}
///
/// Returns the last version of the migrations.
///
public long LastVersion
{
get
{
if (_migrationsTypes.Count == 0)
return 0;
return GetMigrationVersion(_migrationsTypes[_migrationsTypes.Count - 1]);
}
}
///
/// Check for duplicated version in migrations.
///
/// CheckForDuplicatedVersion
public void CheckForDuplicatedVersion()
{
List versions = new List();
foreach (Type t in _migrationsTypes)
{
long version = GetMigrationVersion(t);
if (versions.Contains(version))
throw new DuplicatedVersionException(version);
versions.Add(version);
}
}
///
/// Collect migrations in one Assembly.
///
/// The Assembly to browse.
/// The migrations collection
public static List GetMigrationTypes(Assembly asm)
{
List migrations = new List();
foreach (Type t in asm.GetExportedTypes())
{
MigrationAttribute attrib =
(MigrationAttribute) Attribute.GetCustomAttribute(t, typeof (MigrationAttribute));
if (attrib != null && typeof(IMigration).IsAssignableFrom(t) && !attrib.Ignore)
{
migrations.Add(t);
}
}
migrations.Sort(new MigrationTypeComparer(true));
return migrations;
}
///
/// Returns the version of the migration
/// MigrationAttribute.
///
/// Migration type.
/// Version number sepcified in the attribute
public static long GetMigrationVersion(Type t)
{
MigrationAttribute attrib = (MigrationAttribute)
Attribute.GetCustomAttribute(t, typeof(MigrationAttribute));
return attrib.Version;
}
public List GetAvailableMigrations()
{
//List availableMigrations = new List();
_migrationsTypes.Sort(new MigrationTypeComparer(true));
return _migrationsTypes.ConvertAll(new Converter(GetMigrationVersion));
}
public IMigration GetMigration(long version)
{
foreach (Type t in _migrationsTypes)
{
if (GetMigrationVersion(t) == version)
{
IMigration migration = (IMigration)Activator.CreateInstance(t);
migration.Database = _provider;
return migration;
}
}
return null;
}
}
}