public void GetMigrationsTo(long timestamp, Predicate <string> moduleSelector, out IEnumerable <ApplicableMigration> applicableMigrations, out IEnumerable <IMigrationMetadata> unidentifiedMigrations) { var moduleMigrations = from m in _importedMigrations where moduleSelector(m.Metadata.ModuleName) select m; var comparer = new MigrationMetadataComparer(); var applicableUpMigrations = new List <ApplicableMigration>( from m in moduleMigrations where m.Metadata.Timestamp <= timestamp && !_executedMigrations.Any(x => comparer.Equals(x, m.Metadata)) orderby m.Metadata.Timestamp ascending select new ApplicableMigration(m.Implementation, new ScheduledMigrationMetadata(m.Metadata.Timestamp, m.Metadata.ModuleName, m.Metadata.Tag, MigrationDirection.Up))); var applicableDownMigrations = new List <ApplicableMigration>( from m in moduleMigrations where m.Metadata.Timestamp > timestamp && _executedMigrations.Any(x => comparer.Equals(x, m.Metadata)) orderby m.Metadata.Timestamp descending select new ApplicableMigration(m.Implementation, new ScheduledMigrationMetadata(m.Metadata.Timestamp, m.Metadata.ModuleName, m.Metadata.Tag, MigrationDirection.Down))); if (applicableDownMigrations.Any(m => !(m.Implementation is IReversibleMigration))) { throw new IrreversibleMigrationException(); } int countUp = applicableUpMigrations.Count(); int countDown = applicableDownMigrations.Count(); Log.Info("Found {0} (up: {1}, down: {2}) applicable migration(s)", countUp + countDown, countUp, countDown); applicableMigrations = applicableDownMigrations.Concat(applicableUpMigrations); // order matters! unidentifiedMigrations = new List <IMigrationMetadata>( from m in _executedMigrations where !_importedMigrations.Any(a => a.Metadata.ModuleName == m.ModuleName && a.Metadata.Timestamp == m.Timestamp) orderby m.Timestamp select m); if (unidentifiedMigrations.Count() > 0) { Log.Warning("Found {0} migration(s) that were executed in the database but are not contained in the application.", unidentifiedMigrations.Count()); } }
private bool IsApplicable(IMigrationMetadata migration) { var comparer = new MigrationMetadataComparer(); return(_applicableMigrations.Select(m => m.Migration.Metadata).Contains(migration, comparer)); }