Skip to content

Commit

Permalink
#5580 Fixed problem with executing of skipped and ignored migrations
Browse files Browse the repository at this point in the history
  • Loading branch information
skoshelev committed Sep 17, 2021
1 parent f712bf4 commit 2ab4fc5
Show file tree
Hide file tree
Showing 31 changed files with 129 additions and 136 deletions.
13 changes: 5 additions & 8 deletions src/Libraries/Nop.Data/Migrations/IMigrationManager.cs
@@ -1,7 +1,4 @@
using System;
using System.Reflection;
using FluentMigrator.Builders.Create;
using FluentMigrator.Expressions;
using System.Reflection;

namespace Nop.Data.Migrations
{
Expand All @@ -11,11 +8,11 @@ namespace Nop.Data.Migrations
public interface IMigrationManager
{
/// <summary>
/// Executes all found (and unapplied) migrations
/// Executes an Up for all found unapplied migrations
/// </summary>
/// <param name="assembly">Assembly to find the migration</param>
/// <param name="isUpdateProcess">Indicates whether the upgrade or installation process is ongoing. True - if an upgrade process</param>
void ApplyUpMigrations(Assembly assembly, bool isUpdateProcess = false);
/// <param name="assembly">Assembly to find migrations</param>
/// <param name="migrationProcessType">Type of migration process</param>
void ApplyUpMigrations(Assembly assembly, MigrationProcessType migrationProcessType = MigrationProcessType.Installation);

/// <summary>
/// Executes an Down migration
Expand Down
72 changes: 39 additions & 33 deletions src/Libraries/Nop.Data/Migrations/MigrationManager.cs
@@ -1,21 +1,13 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using FluentMigrator;
using FluentMigrator.Builders.Create;
using FluentMigrator.Builders.Create.Table;
using FluentMigrator.Builders.IfDatabase;
using FluentMigrator.Expressions;
using FluentMigrator.Infrastructure;
using FluentMigrator.Model;
using FluentMigrator.Runner;
using FluentMigrator.Runner.Initialization;
using Nop.Core;
using Nop.Core.Infrastructure;
using Nop.Data.Mapping;
using Nop.Data.Mapping.Builders;

namespace Nop.Data.Migrations
{
Expand Down Expand Up @@ -50,48 +42,65 @@ public partial class MigrationManager : IMigrationManager
#endregion

#region Utils

/// <summary>
/// Returns the instances for found types implementing FluentMigrator.IMigration
/// </summary>
/// <param name="assembly"></param>
/// <param name="assembly">Assembly to find migrations</param>
/// <param name="migrationProcessType">Type of migration process; pass null to load all migrations</param>
/// <returns>The instances for found types implementing FluentMigrator.IMigration</returns>
private IEnumerable<IMigrationInfo> GetMigrations(Assembly assembly)
protected virtual IEnumerable<IMigrationInfo> GetMigrations(Assembly assembly, MigrationProcessType migrationProcessType = MigrationProcessType.NoMatter)
{
var migrations = _filteringMigrationSource.GetMigrations(t => assembly == null || t.Assembly == assembly) ?? Enumerable.Empty<IMigration>();

return migrations.Select(m => _migrationRunnerConventions.GetMigrationInfoForMigration(m)).OrderBy(migration => migration.Version);
var migrations = _filteringMigrationSource
.GetMigrations(t =>
{
var migrationAttribute = t.GetCustomAttribute<NopMigrationAttribute>();
if (migrationAttribute is null || _versionLoader.Value.VersionInfo.HasAppliedMigration(migrationAttribute.Version))
return false;
if (migrationAttribute.TargetMigrationProcess != MigrationProcessType.NoMatter &&
migrationProcessType != MigrationProcessType.NoMatter &&
migrationProcessType != migrationAttribute.TargetMigrationProcess)
return false;
return assembly == null || t.Assembly == assembly;
}) ?? Enumerable.Empty<IMigration>();

return migrations
.Select(m => _migrationRunnerConventions.GetMigrationInfoForMigration(m))
//.OrderBy(m => m.Migration.GetType().GetCustomAttribute<NopMigrationAttribute>().MigrationTarget)
//.ThenBy(migration => migration.Version);
.OrderBy(migration => migration.Version);
}

#endregion

#region Methods

/// <summary>
/// Executes all found (and unapplied) migrations
/// Executes an Up for all found unapplied migrations
/// </summary>
/// <param name="assembly">Assembly to find the migration</param>
/// <param name="isUpdateProcess">Indicates whether the upgrade or installation process is ongoing. True - if an upgrade process</param>
public void ApplyUpMigrations(Assembly assembly, bool isUpdateProcess = false)
/// <param name="assembly">Assembly to find migrations</param>
/// <param name="migrationProcessType">Type of migration process</param>
public virtual void ApplyUpMigrations(Assembly assembly, MigrationProcessType migrationProcessType = MigrationProcessType.Installation)
{
if(assembly is null)
if (assembly is null)
throw new ArgumentNullException(nameof(assembly));

var migrations = GetMigrations(assembly);

bool needToExecute(IMigrationInfo migrationInfo1)
foreach (var migrationInfo in GetMigrations(assembly, migrationProcessType))
{
var skip = migrationInfo1.Migration.GetType().GetCustomAttributes(typeof(SkipMigrationAttribute)).Any() || isUpdateProcess && migrationInfo1.Migration.GetType()
.GetCustomAttributes(typeof(SkipMigrationOnUpdateAttribute)).Any() || !isUpdateProcess && migrationInfo1.Migration.GetType()
.GetCustomAttributes(typeof(SkipMigrationOnInstallAttribute)).Any();
_migrationRunner.Up(migrationInfo.Migration);

return !skip;
#if DEBUG
if (!string.IsNullOrEmpty(migrationInfo.Description) &&
migrationInfo.Description.StartsWith(string.Format(NopMigrationDefaults.UpdateMigrationDescriptionPrefix, NopVersion.FULL_VERSION)))
continue;
#endif
_versionLoader.Value
.UpdateVersionInfo(migrationInfo.Version, migrationInfo.Description ?? migrationInfo.Migration.GetType().Name);
}

foreach (var migrationInfo in migrations.Where(needToExecute))
_migrationRunner.MigrateUp(migrationInfo.Version);
}

/// <summary>
/// Executes all found (and unapplied) migrations
/// </summary>
Expand All @@ -105,9 +114,6 @@ public void ApplyDownMigrations(Assembly assembly)

foreach (var migrationInfo in migrations)
{
if (migrationInfo.Migration.GetType().GetCustomAttributes(typeof(SkipMigrationAttribute)).Any())
continue;

_migrationRunner.Down(migrationInfo.Migration);
_versionLoader.Value.DeleteVersion(migrationInfo.Version);
}
Expand Down
23 changes: 23 additions & 0 deletions src/Libraries/Nop.Data/Migrations/MigrationProcessType.cs
@@ -0,0 +1,23 @@
namespace Nop.Data.Migrations
{
/// <summary>
/// Represents the type of migration process
/// </summary>
public enum MigrationProcessType
{
/// <summary>
/// The type of migration process does not matter
/// </summary>
NoMatter,

/// <summary>
/// Installation
/// </summary>
Installation,

/// <summary>
/// Update
/// </summary>
Update
}
}
37 changes: 30 additions & 7 deletions src/Libraries/Nop.Data/Migrations/NopMigrationAttribute.cs
Expand Up @@ -9,38 +9,48 @@ namespace Nop.Data.Migrations
/// </summary>
public partial class NopMigrationAttribute : MigrationAttribute
{
private static long GetVersion(string dateTime)
#region Utils

protected static long GetVersion(string dateTime)
{
return DateTime.ParseExact(dateTime, NopMigrationDefaults.DateFormats, CultureInfo.InvariantCulture).Ticks;
}

private static long GetVersion(string dateTime, UpdateMigrationType migrationType)
protected static long GetVersion(string dateTime, UpdateMigrationType migrationType)
{
return GetVersion(dateTime) + (int)migrationType;
}
private static string GetDescription(string nopVersion, UpdateMigrationType migrationType)

protected static string GetDescription(string nopVersion, UpdateMigrationType migrationType)
{
return string.Format(NopMigrationDefaults.UpdateMigrationDescription, nopVersion, migrationType.ToString());
}

#endregion

#region Ctor

/// <summary>
/// Initializes a new instance of the NopMigrationAttribute class
/// </summary>
/// <param name="dateTime">The migration date time string to convert on version</param>
public NopMigrationAttribute(string dateTime) :
/// <param name="targetMigrationProcess">The target migration process</param>
public NopMigrationAttribute(string dateTime, MigrationProcessType targetMigrationProcess = MigrationProcessType.NoMatter) :
base(GetVersion(dateTime), null)
{
TargetMigrationProcess = targetMigrationProcess;
}

/// <summary>
/// Initializes a new instance of the NopMigrationAttribute class
/// </summary>
/// <param name="dateTime">The migration date time string to convert on version</param>
/// <param name="description">The migration description</param>
public NopMigrationAttribute(string dateTime, string description) :
/// <param name="targetMigrationProcess">The target migration process</param>
public NopMigrationAttribute(string dateTime, string description, MigrationProcessType targetMigrationProcess = MigrationProcessType.NoMatter) :
base(GetVersion(dateTime), description)
{
TargetMigrationProcess = targetMigrationProcess;
}

/// <summary>
Expand All @@ -49,9 +59,22 @@ private static string GetDescription(string nopVersion, UpdateMigrationType migr
/// <param name="dateTime">The migration date time string to convert on version</param>
/// <param name="nopVersion">nopCommerce full version</param>
/// <param name="migrationType">The migration type</param>
public NopMigrationAttribute(string dateTime, string nopVersion, UpdateMigrationType migrationType) :
/// <param name="targetMigrationProcess">The target migration process</param>
public NopMigrationAttribute(string dateTime, string nopVersion, UpdateMigrationType migrationType, MigrationProcessType targetMigrationProcess = MigrationProcessType.NoMatter) :
base(GetVersion(dateTime, migrationType), GetDescription(nopVersion, migrationType))
{
TargetMigrationProcess = targetMigrationProcess;
}

#endregion

#region Properties

/// <summary>
/// Target migration process
/// </summary>
public MigrationProcessType TargetMigrationProcess { get; set; }

#endregion
}
}
3 changes: 1 addition & 2 deletions src/Libraries/Nop.Data/Migrations/SchemaMigration.cs
Expand Up @@ -28,8 +28,7 @@

namespace Nop.Data.Migrations
{
[SkipMigrationOnUpdate]
[NopMigration("2020/01/31 11:24:16:2551771", "Nop.Data base schema")]
[NopMigration("2020/01/31 11:24:16:2551771", "Nop.Data base schema", MigrationProcessType.Installation)]
public class SchemaMigration : AutoReversingMigration
{
/// <summary>
Expand Down
12 changes: 0 additions & 12 deletions src/Libraries/Nop.Data/Migrations/SkipMigrationAttribute.cs

This file was deleted.

This file was deleted.

12 changes: 0 additions & 12 deletions src/Libraries/Nop.Data/Migrations/SkipMigrationOnUpdate.cs

This file was deleted.

Expand Up @@ -9,8 +9,7 @@

namespace Nop.Data.Migrations.UpgradeTo440
{
[NopMigration("2020-06-10 00:00:00", "4.40.0", UpdateMigrationType.Data)]
[SkipMigrationOnInstall]
[NopMigration("2020-06-10 00:00:00", "4.40.0", UpdateMigrationType.Data, MigrationProcessType.Update)]
public class DataMigration : Migration
{
private readonly INopDataProvider _dataProvider;
Expand Down
Expand Up @@ -5,8 +5,7 @@

namespace Nop.Data.Migrations.UpgradeTo440
{
[NopMigration("2020/03/08 11:26:08:9037680", "Specification attribute grouping")]
[SkipMigrationOnInstall]
[NopMigration("2020/03/08 11:26:08:9037680", "Specification attribute grouping", MigrationProcessType.Update)]
public class SpecificationAttributeGroupingMigration : MigrationBase
{

Expand Down
Expand Up @@ -2,8 +2,7 @@

namespace Nop.Data.Migrations.UpgradeTo450
{
[NopMigration("2021-04-23 00:00:00", "4.50.0", UpdateMigrationType.Data)]
[SkipMigrationOnInstall]
[NopMigration("2021-04-23 00:00:00", "4.50.0", UpdateMigrationType.Data, MigrationProcessType.Update)]
public class DataMigration : Migration
{
private readonly INopDataProvider _dataProvider;
Expand Down
8 changes: 4 additions & 4 deletions src/Libraries/Nop.Services/Plugins/PluginService.cs
Expand Up @@ -199,10 +199,10 @@ protected virtual void DeletePluginData(Type pluginType)
_migrationManager.ApplyDownMigrations(assembly);
}

protected virtual void InsertPluginData(Type pluginType, bool isUpdateProcess = false)
protected virtual void InsertPluginData(Type pluginType, MigrationProcessType migrationProcessType = MigrationProcessType.NoMatter)
{
var assembly = Assembly.GetAssembly(pluginType);
_migrationManager.ApplyUpMigrations(assembly, isUpdateProcess);
_migrationManager.ApplyUpMigrations(assembly, migrationProcessType);
}

#endregion
Expand Down Expand Up @@ -496,7 +496,7 @@ public virtual async Task InstallPluginsAsync()
{
try
{
InsertPluginData(descriptor.PluginType);
InsertPluginData(descriptor.PluginType, MigrationProcessType.Installation);

//try to install an instance
await descriptor.Instance<IPlugin>().InstallAsync();
Expand Down Expand Up @@ -661,7 +661,7 @@ public virtual async Task UpdatePluginsAsync()
continue;

//run new migrations from the plugin if there are exists
InsertPluginData(newVersion.PluginType, true);
InsertPluginData(newVersion.PluginType, MigrationProcessType.Update);

//run the plugin update logic
await newVersion.Instance<IPlugin>().UpdateAsync(installedPlugin.Version, newVersion.Version);
Expand Down
Expand Up @@ -5,8 +5,7 @@

namespace Nop.Plugin.MultiFactorAuth.GoogleAuthenticator.Migrations
{
[SkipMigrationOnUpdate]
[NopMigration("2020/07/30 12:00:00", "Nop.Plugin.MultiFactorAuth.GoogleAuthenticator schema")]
[NopMigration("2020/07/30 12:00:00", "Nop.Plugin.MultiFactorAuth.GoogleAuthenticator schema", MigrationProcessType.Installation)]
public class GoogleAuthenticatorSchemaMigration : AutoReversingMigration
{
/// <summary>
Expand Down
Expand Up @@ -2,7 +2,7 @@
"Group": "Multi-factor authentication",
"FriendlyName": "Google Authenticator",
"SystemName": "MultiFactorAuth.GoogleAuthenticator",
"Version": "1.05",
"Version": "1.06",
"SupportedVersions": [ "4.50" ],
"Author": "nopCommerce team",
"DisplayOrder": 1,
Expand Down
Expand Up @@ -5,8 +5,7 @@

namespace Nop.Plugin.Pickup.PickupInStore.Data
{
[SkipMigrationOnUpdate]
[NopMigration("2020/02/03 09:30:17:6455422", "Pickup.PickupInStore base schema")]
[NopMigration("2020/02/03 09:30:17:6455422", "Pickup.PickupInStore base schema", MigrationProcessType.Installation)]
public class SchemaMigration : AutoReversingMigration
{
public override void Up()
Expand Down
2 changes: 1 addition & 1 deletion src/Plugins/Nop.Plugin.Pickup.PickupInStore/plugin.json
Expand Up @@ -2,7 +2,7 @@
"Group": "Pickup points",
"FriendlyName": "Pickup in store",
"SystemName": "Pickup.PickupInStore",
"Version": "1.40",
"Version": "1.41",
"SupportedVersions": [ "4.50" ],
"Author": "nopCommerce team",
"DisplayOrder": 1,
Expand Down

0 comments on commit 2ab4fc5

Please sign in to comment.