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; } } }