Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/Core/Grand.Infrastructure/Migrations/IMigrationVersionStamp.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Grand.Infrastructure.Migrations;

/// <summary>
/// Marks the migration that records a database version as reached.
/// </summary>
/// <remarks>
/// A version stamp must be the last migration to run for its <see cref="IBaseMigration.Version" />, and it must only
/// run when every other migration of that version succeeded. <see cref="MigrationManager.GetCurrentMigrations" />
/// filters by version, so a version recorded before its own migrations completed makes them unreachable forever —
/// they compare equal to the installed version and are never selected again.
/// </remarks>
public interface IMigrationVersionStamp : IMigration;
5 changes: 4 additions & 1 deletion src/Core/Grand.Infrastructure/Migrations/MigrationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ public IEnumerable<IMigration> GetCurrentMigrations(DbVersion installedVersion)
{
return GetAllMigrations()
.Where(x => x.Version.CompareTo(installedVersion) > 0)
.OrderBy(mg => mg.Version.ToString())
//DbVersion, not its string form - "2.10" sorts before "2.2" as text
.OrderBy(mg => mg.Version)
//the version stamp closes its version, whatever priority it declares
.ThenBy(mg => mg is IMigrationVersionStamp ? 1 : 0)
.ThenBy(mg => mg.Priority)
.ToList();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
using Grand.Data;
using Grand.Domain.Common;
using Grand.Infrastructure;
using Grand.Infrastructure.Migrations;
using Microsoft.Extensions.DependencyInjection;

namespace Grand.Module.Migration.Migrations._1._1;

public class MigrationUpgradeDbVersion_11 : IMigration
public class MigrationUpgradeDbVersion_11 : MigrationUpgradeDbVersionBase
{
public int Priority => 0;
public override DbVersion Version => new(1, 1);

public DbVersion Version => new(1, 1);

public Guid Identity => new("6BDB7093-4C31-4D78-9604-58188DF728D3");

public string Name => "Upgrade version of the database to 1.1";

/// <summary>
/// Upgrade process
/// </summary>
/// <param name="database"></param>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public bool UpgradeProcess(IServiceProvider serviceProvider)
{
var repository = serviceProvider.GetRequiredService<IRepository<GrandNodeVersion>>();

var dbversion = repository.Table.FirstOrDefault();
dbversion!.DataBaseVersion = $"{GrandVersion.SupportedDBVersion}";
repository.Update(dbversion);

return true;
}
}
public override Guid Identity => new("6BDB7093-4C31-4D78-9604-58188DF728D3");
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
using Grand.Data;
using Grand.Domain.Common;
using Grand.Infrastructure;
using Grand.Infrastructure.Migrations;
using Microsoft.Extensions.DependencyInjection;

namespace Grand.Module.Migration.Migrations._2._0;

public class MigrationUpgradeDbVersion_20 : IMigration
public class MigrationUpgradeDbVersion_20 : MigrationUpgradeDbVersionBase
{
public int Priority => 0;
public override DbVersion Version => new(2, 0);

public DbVersion Version => new(2, 0);

public Guid Identity => new("AEC3CF1F-4443-474A-B932-4F91D08C8F61");

public string Name => "Upgrade version of the database to 2.0";

/// <summary>
/// Upgrade process
/// </summary>
/// <param name="database"></param>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public bool UpgradeProcess(IServiceProvider serviceProvider)
{
var repository = serviceProvider.GetRequiredService<IRepository<GrandNodeVersion>>();

var dbversion = repository.Table.FirstOrDefault();
dbversion!.DataBaseVersion = $"{GrandVersion.SupportedDBVersion}";
repository.Update(dbversion);

return true;
}
}
public override Guid Identity => new("AEC3CF1F-4443-474A-B932-4F91D08C8F61");
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
using Grand.Data;
using Grand.Domain.Common;
using Grand.Infrastructure;
using Grand.Infrastructure.Migrations;
using Microsoft.Extensions.DependencyInjection;

namespace Grand.Module.Migration.Migrations._2._1;

public class MigrationUpgradeDbVersion_21 : IMigration
public class MigrationUpgradeDbVersion_21 : MigrationUpgradeDbVersionBase
{
public int Priority => 0;
public override DbVersion Version => new(2, 1);

public DbVersion Version => new(2, 1);

public Guid Identity => new("EA674DAA-66B2-4F21-9C68-008ACE752FBD");

public string Name => "Upgrade version of the database to 2.1";

/// <summary>
/// Upgrade process
/// </summary>
/// <param name="database"></param>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public bool UpgradeProcess(IServiceProvider serviceProvider)
{
var repository = serviceProvider.GetRequiredService<IRepository<GrandNodeVersion>>();

var dbversion = repository.Table.FirstOrDefault();
dbversion!.DataBaseVersion = $"{GrandVersion.SupportedDBVersion}";
repository.Update(dbversion);

return true;
}
}
public override Guid Identity => new("EA674DAA-66B2-4F21-9C68-008ACE752FBD");
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
using Grand.Data;
using Grand.Domain.Common;
using Grand.Infrastructure;
using Grand.Infrastructure.Migrations;
using Microsoft.Extensions.DependencyInjection;

namespace Grand.Module.Migration.Migrations._2._2;

public class MigrationUpgradeDbVersion_22 : IMigration
public class MigrationUpgradeDbVersion_22 : MigrationUpgradeDbVersionBase
{
public int Priority => 0;
public override DbVersion Version => new(2, 2);

public DbVersion Version => new(2, 2);

public Guid Identity => new("9B9FD138-7E67-44AA-913B-273F3D5B5DE9");

public string Name => "Upgrade version of the database to 2.2";

/// <summary>
/// Upgrade process
/// </summary>
/// <param name="database"></param>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public bool UpgradeProcess(IServiceProvider serviceProvider)
{
var repository = serviceProvider.GetRequiredService<IRepository<GrandNodeVersion>>();

var dbversion = repository.Table.FirstOrDefault();
dbversion!.DataBaseVersion = $"{GrandVersion.SupportedDBVersion}";
repository.Update(dbversion);

return true;
}
}
public override Guid Identity => new("9B9FD138-7E67-44AA-913B-273F3D5B5DE9");
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,10 @@
using Grand.Data;
using Grand.Domain.Common;
using Grand.Infrastructure;
using Grand.Infrastructure.Migrations;
using Microsoft.Extensions.DependencyInjection;

namespace Grand.Module.Migration.Migrations._2._3;

public class MigrationUpgradeDbVersion_23 : IMigration
public class MigrationUpgradeDbVersion_23 : MigrationUpgradeDbVersionBase
{
public int Priority => 0;
public override DbVersion Version => new(2, 3);

public DbVersion Version => new(2, 3);

public Guid Identity => new("689E5BFA-7229-41A5-AF48-07CB58C0D608");

public string Name => "Upgrade version of the database to 2.3";

/// <summary>
/// Upgrade process
/// </summary>
/// <param name="database"></param>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public bool UpgradeProcess(IServiceProvider serviceProvider)
{
var repository = serviceProvider.GetRequiredService<IRepository<GrandNodeVersion>>();

var dbversion = repository.Table.FirstOrDefault();
dbversion!.InstalledVersion = $"{GrandVersion.SupportedDBVersion}";
dbversion!.DataBaseVersion = $"{GrandVersion.SupportedDBVersion}";
repository.Update(dbversion);

return true;
}
}
public override Guid Identity => new("689E5BFA-7229-41A5-AF48-07CB58C0D608");
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
using Grand.Data;
using Grand.Domain.Common;
using Grand.Infrastructure;
using Grand.Infrastructure.Migrations;
using Microsoft.Extensions.DependencyInjection;

namespace Grand.Module.Migration.Migrations._2._4;

public class MigrationUpgradeDbVersion_24 : IMigration
public class MigrationUpgradeDbVersion_24 : MigrationUpgradeDbVersionBase
{
public int Priority => 0;
public override DbVersion Version => new(2, 4);

public DbVersion Version => new(2, 4);

public Guid Identity => new("A1B2C3D4-E5F6-7890-ABCD-EF1234567890");

public string Name => "Upgrade version of the database to 2.4";

/// <summary>
/// Upgrade process
/// </summary>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public bool UpgradeProcess(IServiceProvider serviceProvider)
{
var repository = serviceProvider.GetRequiredService<IRepository<GrandNodeVersion>>();

var dbversion = repository.Table.FirstOrDefault();
dbversion!.InstalledVersion = $"{GrandVersion.SupportedDBVersion}";
dbversion!.DataBaseVersion = $"{GrandVersion.SupportedDBVersion}";
repository.Update(dbversion);

return true;
}
public override Guid Identity => new("A1B2C3D4-E5F6-7890-ABCD-EF1234567890");
}
43 changes: 37 additions & 6 deletions src/Modules/Grand.Module.Migration/Migrations/MigrationProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,45 @@ public virtual void RunMigrationProcess()
{
var migrationsDb = GetMigrationDb();
var version = _repositoryVersion.Table.FirstOrDefault();
if(version == null)
if (version == null)
return;
var majorVersion = string.IsNullOrEmpty(version?.InstalledVersion) ? int.Parse(version?.DataBaseVersion.Split('.')[0]!) : int.Parse(version?.InstalledVersion.Split('.')[0]!);
var minorVersion = string.IsNullOrEmpty(version?.InstalledVersion) ? int.Parse(version?.DataBaseVersion.Split('.')[1]!) : int.Parse(version?.InstalledVersion.Split('.')[1]!);

var installedVersion = ParseDbVersion(string.IsNullOrEmpty(version.InstalledVersion)
? version.DataBaseVersion
: version.InstalledVersion);

if (installedVersion == null)
{
_logger.LogError("Cannot read the installed database version - migration process skipped");
return;
}

var migrationManager = new MigrationManager();
foreach (var item in migrationManager.GetCurrentMigrations(new DbVersion(majorVersion, minorVersion)))
if (migrationsDb.FirstOrDefault(x => x.Identity == item.Identity) == null)
RunProcess(item);
foreach (var item in migrationManager.GetCurrentMigrations(installedVersion))
{
if (migrationsDb.Any(x => x.Identity == item.Identity))
continue;

if (RunProcess(item).Success) continue;

//stop before the version stamp of this version runs - recording a version whose
//migrations did not all succeed puts them below the installed version, and
//GetCurrentMigrations never selects them again
_logger.LogError("Migration process stopped at {MigrationName} ({Version}) - it will be retried on the next start",
item.Name, item.Version);
return;
}
Comment thread
KrzysztofPajak marked this conversation as resolved.
Dismissed
}

private static DbVersion? ParseDbVersion(string? version)
{
var parts = version?.Split('.');
if (parts is not { Length: >= 2 })
return null;

return int.TryParse(parts[0], out var major) && int.TryParse(parts[1], out var minor)
? new DbVersion(major, minor)
: null;
}

private MigrationResult RunProcessInternal(IMigration migration)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Grand.Data;
using Grand.Domain.Common;
using Grand.Infrastructure.Migrations;
using Microsoft.Extensions.DependencyInjection;

namespace Grand.Module.Migration.Migrations;

/// <summary>
/// Records <see cref="Version" /> as the version the database has reached.
/// </summary>
/// <remarks>
/// Runs last within its version - see <see cref="IMigrationVersionStamp" />.
/// </remarks>
public abstract class MigrationUpgradeDbVersionBase : IMigrationVersionStamp
{
public int Priority => 0;

public abstract DbVersion Version { get; }

public abstract Guid Identity { get; }

public string Name => $"Upgrade version of the database to {Version}";

/// <summary>
/// Upgrade process
/// </summary>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public bool UpgradeProcess(IServiceProvider serviceProvider)
{
var repository = serviceProvider.GetRequiredService<IRepository<GrandNodeVersion>>();

var dbversion = repository.Table.FirstOrDefault();
if (dbversion == null)
return false;

//stamp the version this migration closes, not the version the build supports - stamping
//the latest supported version here makes every migration in between unreachable
dbversion.InstalledVersion = Version.ToString();
dbversion.DataBaseVersion = Version.ToString();
repository.Update(dbversion);

return true;
}
}
Loading
Loading