diff --git a/src/Umbraco.Core/Events/MigrationEventArgs.cs b/src/Umbraco.Core/Events/MigrationEventArgs.cs index c447ebcd1a..c6da480999 100644 --- a/src/Umbraco.Core/Events/MigrationEventArgs.cs +++ b/src/Umbraco.Core/Events/MigrationEventArgs.cs @@ -4,7 +4,7 @@ using Umbraco.Core.Persistence.Migrations; namespace Umbraco.Core.Events { - public class MigrationEventArgs : CancellableObjectEventArgs> + public class MigrationEventArgs : CancellableObjectEventArgs> { /// /// Constructor accepting multiple migrations that are used in the migration runner @@ -13,7 +13,7 @@ namespace Umbraco.Core.Events /// /// /// - public MigrationEventArgs(IEnumerable eventObject, Version configuredVersion, Version targetVersion, bool canCancel) + public MigrationEventArgs(IList eventObject, Version configuredVersion, Version targetVersion, bool canCancel) : base(eventObject, canCancel) { ConfiguredVersion = configuredVersion; @@ -28,7 +28,7 @@ namespace Umbraco.Core.Events /// /// /// - internal MigrationEventArgs(IEnumerable eventObject, MigrationContext migrationContext, Version configuredVersion, Version targetVersion, bool canCancel) + internal MigrationEventArgs(IList eventObject, MigrationContext migrationContext, Version configuredVersion, Version targetVersion, bool canCancel) : base(eventObject, canCancel) { MigrationContext = migrationContext; @@ -42,7 +42,7 @@ namespace Umbraco.Core.Events /// /// /// - public MigrationEventArgs(IEnumerable eventObject, Version configuredVersion, Version targetVersion) + public MigrationEventArgs(IList eventObject, Version configuredVersion, Version targetVersion) : base(eventObject) { ConfiguredVersion = configuredVersion; @@ -52,7 +52,7 @@ namespace Umbraco.Core.Events /// /// Returns all migrations that were used in the migration runner /// - public IEnumerable Migrations + public IList Migrations { get { return EventObject; } } diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs index f9bf78ae2a..6c077dd987 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs @@ -30,7 +30,7 @@ namespace Umbraco.Core.Persistence.Migrations /// The PetaPoco Database, which the migrations will be run against /// Boolean indicating whether this is an upgrade or downgrade /// True if migrations were applied, otherwise False - public bool Execute(Database database, bool isUpgrade = true) + public virtual bool Execute(Database database, bool isUpgrade = true) { return Execute(database, database.GetDatabaseProvider(), isUpgrade); } @@ -42,11 +42,11 @@ namespace Umbraco.Core.Persistence.Migrations /// /// Boolean indicating whether this is an upgrade or downgrade /// True if migrations were applied, otherwise False - public bool Execute(Database database, DatabaseProviders databaseProvider, bool isUpgrade = true) + public virtual bool Execute(Database database, DatabaseProviders databaseProvider, bool isUpgrade = true) { LogHelper.Info("Initializing database migrations"); - var foundMigrations = MigrationResolver.Current.Migrations.ToArray(); + var foundMigrations = FindMigrations(); //filter all non-schema migrations var migrations = isUpgrade @@ -54,6 +54,7 @@ namespace Umbraco.Core.Persistence.Migrations : OrderedDowngradeMigrations(foundMigrations).ToList(); //SD: Why do we want this? + //MCH: Because extensibility ... Mostly relevant to package developers who needs to utilize this type of event to add or remove migrations from the list if (Migrating.IsRaisedEventCancelled(new MigrationEventArgs(migrations, _currentVersion, _targetVersion, true), this)) return false; @@ -69,7 +70,6 @@ namespace Umbraco.Core.Persistence.Migrations //if this fails then the transaction will be rolled back, BUT if we are using MySql this is not the case, //since it does not support schema changes in a transaction, see: http://dev.mysql.com/doc/refman/5.0/en/implicit-commit.html //so in that case we have to downgrade - if (databaseProvider == DatabaseProviders.MySql) { throw new DataLossException( @@ -86,28 +86,57 @@ namespace Umbraco.Core.Persistence.Migrations return true; } - private void ExecuteMigrations(IMigrationContext context, Database database) + /// + /// Filters and orders migrations based on the migrations listed and the currently configured version and the target installation version + /// + /// + /// + public IEnumerable OrderedUpgradeMigrations(IEnumerable foundMigrations) { - //Transactional execution of the sql that was generated from the found migrations - using (var transaction = database.GetTransaction()) - { - int i = 1; - foreach (var expression in context.Expressions) - { - var sql = expression.Process(database); - if (string.IsNullOrEmpty(sql)) - { - i++; - continue; - } + var migrations = (from migration in foundMigrations + let migrationAttributes = migration.GetType().GetCustomAttributes(false) + from migrationAttribute in migrationAttributes + where migrationAttribute != null + where migrationAttribute.TargetVersion > _currentVersion && + migrationAttribute.TargetVersion <= _targetVersion && + migrationAttribute.ProductName == _productName && + //filter if the migration specifies a minimum current version for which to execute + (migrationAttribute.MinimumCurrentVersion == null || _currentVersion >= migrationAttribute.MinimumCurrentVersion) + orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder ascending + select migration).Distinct(); + return migrations; + } - LogHelper.Info("Executing sql statement " + i + ": " + sql); - database.Execute(sql); - i++; - } + /// + /// Filters and orders migrations based on the migrations listed and the currently configured version and the target installation version + /// + /// + /// + public IEnumerable OrderedDowngradeMigrations(IEnumerable foundMigrations) + { + var migrations = (from migration in foundMigrations + let migrationAttributes = migration.GetType().GetCustomAttributes(false) + from migrationAttribute in migrationAttributes + where migrationAttribute != null + where + migrationAttribute.TargetVersion > _currentVersion && + migrationAttribute.TargetVersion <= _targetVersion && + migrationAttribute.ProductName == _productName && + //filter if the migration specifies a minimum current version for which to execute + (migrationAttribute.MinimumCurrentVersion == null || _currentVersion >= migrationAttribute.MinimumCurrentVersion) + orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder descending + select migration).Distinct(); + return migrations; + } - transaction.Complete(); - } + /// + /// Find all migrations that are available through the + /// + /// An array of + protected virtual IMigration[] FindMigrations() + { + //MCH NOTE: Consider adding the ProductName filter to the Resolver so we don't get a bunch of irrelevant migrations + return MigrationResolver.Current.Migrations.ToArray(); } internal MigrationContext InitializeMigrations(List migrations, Database database, DatabaseProviders databaseProvider, bool isUpgrade = true) @@ -150,48 +179,28 @@ namespace Umbraco.Core.Persistence.Migrations return context; } - /// - /// Filters and orders migrations based on the migrations listed and the currently configured version and the target installation version - /// - /// - /// - internal IEnumerable OrderedUpgradeMigrations(IEnumerable foundMigrations) + private void ExecuteMigrations(IMigrationContext context, Database database) { - var migrations = (from migration in foundMigrations - let migrationAttributes = migration.GetType().GetCustomAttributes(false) - from migrationAttribute in migrationAttributes - where migrationAttribute != null - where - migrationAttribute.TargetVersion > _currentVersion && - migrationAttribute.TargetVersion <= _targetVersion && - migrationAttribute.ProductName == _productName && - //filter if the migration specifies a minimum current version for which to execute - (migrationAttribute.MinimumCurrentVersion == null || _currentVersion >= migrationAttribute.MinimumCurrentVersion) - orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder ascending - select migration).Distinct(); - return migrations; - } + //Transactional execution of the sql that was generated from the found migrations + using (var transaction = database.GetTransaction()) + { + int i = 1; + foreach (var expression in context.Expressions) + { + var sql = expression.Process(database); + if (string.IsNullOrEmpty(sql)) + { + i++; + continue; + } - /// - /// Filters and orders migrations based on the migrations listed and the currently configured version and the target installation version - /// - /// - /// - public IEnumerable OrderedDowngradeMigrations(IEnumerable foundMigrations) - { - var migrations = (from migration in foundMigrations - let migrationAttributes = migration.GetType().GetCustomAttributes(false) - from migrationAttribute in migrationAttributes - where migrationAttribute != null - where - migrationAttribute.TargetVersion > _currentVersion && - migrationAttribute.TargetVersion <= _targetVersion && - migrationAttribute.ProductName == _productName && - //filter if the migration specifies a minimum current version for which to execute - (migrationAttribute.MinimumCurrentVersion == null || _currentVersion >= migrationAttribute.MinimumCurrentVersion) - orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder descending - select migration).Distinct(); - return migrations; + LogHelper.Info("Executing sql statement " + i + ": " + sql); + database.Execute(sql); + i++; + } + + transaction.Complete(); + } } ///