Cleanup the Umbraco migration plan
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Type = System.Type;
|
||||
|
||||
namespace Umbraco.Core.Migrations
|
||||
{
|
||||
@@ -31,6 +32,11 @@ namespace Umbraco.Core.Migrations
|
||||
DefinePlan();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the transitions.
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<string, Transition> Transitions => _transitions;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the plan.
|
||||
/// </summary>
|
||||
@@ -238,8 +244,8 @@ namespace Umbraco.Core.Migrations
|
||||
{
|
||||
Validate();
|
||||
|
||||
if (migrationBuilder == null || logger == null)
|
||||
throw new InvalidOperationException("Cannot execute a non-executable plan.");
|
||||
if (migrationBuilder == null) throw new ArgumentNullException(nameof(migrationBuilder));
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
logger.Info<MigrationPlan>("Starting '{MigrationName}'...", Name);
|
||||
|
||||
@@ -275,10 +281,47 @@ namespace Umbraco.Core.Migrations
|
||||
return origState;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Follows a path (for tests and debugging).
|
||||
/// </summary>
|
||||
/// <remarks>Does the same thing Execute does, but does not actually execute migrations.</remarks>
|
||||
internal string FollowPath(string fromState, string toState = null)
|
||||
{
|
||||
toState = toState.NullOrWhiteSpaceAsNull();
|
||||
|
||||
Validate();
|
||||
|
||||
var origState = fromState ?? string.Empty;
|
||||
|
||||
if (!_transitions.TryGetValue(origState, out var transition))
|
||||
throw new Exception($"Unknown state \"{origState}\".");
|
||||
|
||||
while (transition != null)
|
||||
{
|
||||
var nextState = transition.TargetState;
|
||||
origState = nextState;
|
||||
|
||||
if (nextState == toState)
|
||||
{
|
||||
transition = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_transitions.TryGetValue(origState, out transition))
|
||||
throw new Exception($"Unknown state \"{origState}\".");
|
||||
}
|
||||
|
||||
// safety check
|
||||
if (origState != (toState ?? _finalState))
|
||||
throw new Exception($"Internal error, reached state {origState} which is not state {toState ?? _finalState}");
|
||||
|
||||
return origState;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a plan transition.
|
||||
/// </summary>
|
||||
private class Transition
|
||||
public class Transition
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Transition"/> class.
|
||||
|
||||
@@ -41,6 +41,11 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
/// <param name="logger">A logger.</param>
|
||||
public void Execute(IScopeProvider scopeProvider, IMigrationBuilder migrationBuilder, IKeyValueService keyValueService, ILogger logger)
|
||||
{
|
||||
if (scopeProvider == null) throw new ArgumentNullException(nameof(scopeProvider));
|
||||
if (migrationBuilder == null) throw new ArgumentNullException(nameof(migrationBuilder));
|
||||
if (keyValueService == null) throw new ArgumentNullException(nameof(keyValueService));
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
var plan = Plan;
|
||||
|
||||
using (var scope = scopeProvider.CreateScope())
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using NPoco;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Migrations;
|
||||
using Umbraco.Core.Migrations.Upgrade;
|
||||
@@ -141,6 +143,40 @@ namespace Umbraco.Tests.Migrations
|
||||
Assert.IsFalse(string.IsNullOrWhiteSpace(plan.FinalState));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanCopyChain()
|
||||
{
|
||||
var plan = new MigrationPlan("default");
|
||||
plan
|
||||
.From(string.Empty)
|
||||
.To("aaa")
|
||||
.To("bbb")
|
||||
.To("ccc")
|
||||
.To("ddd")
|
||||
.To("eee");
|
||||
|
||||
plan
|
||||
.From("xxx")
|
||||
.To("yyy", "bbb", "ddd")
|
||||
.To("eee");
|
||||
|
||||
WritePlanToConsole(plan);
|
||||
|
||||
plan.Validate();
|
||||
Assert.AreEqual("eee", plan.FollowPath("xxx"));
|
||||
Assert.AreEqual("yyy", plan.FollowPath("xxx", "yyy"));
|
||||
}
|
||||
|
||||
private void WritePlanToConsole(MigrationPlan plan)
|
||||
{
|
||||
var final = plan.Transitions.First(x => x.Value == null).Key;
|
||||
|
||||
Console.WriteLine("plan \"{0}\" to final state \"{1}\":", plan.Name, final);
|
||||
foreach (var (_, transition) in plan.Transitions)
|
||||
if (transition != null)
|
||||
Console.WriteLine(transition);
|
||||
}
|
||||
|
||||
public class DeleteRedirectUrlTable : MigrationBase
|
||||
{
|
||||
public DeleteRedirectUrlTable(IMigrationContext context)
|
||||
|
||||
Reference in New Issue
Block a user