Skip to content

Commit

Permalink
V12/data types renames deletes (#530)
Browse files Browse the repository at this point in the history
* WIP #511 - Experiments with moving datatype actions + improving tracking

* bigger comment - so we remember. #511

* Optimise the PostImport to only do the hidden "delete" actions #511
  • Loading branch information
KevinJump committed Aug 8, 2023
1 parent ff8f40f commit e584b4e
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 17 deletions.
2 changes: 1 addition & 1 deletion uSync.BackOffice/Extensions/uSyncActionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static bool ContainsErrors(this IEnumerable<uSyncAction> actions)
/// count how many actions in this list are for changes
/// </summary>
public static int CountChanges(this IEnumerable<uSyncAction> actions)
=> actions.Count(x => x.Change > Core.ChangeType.NoChange);
=> actions.Count(x => x.Change > Core.ChangeType.NoChange && x.Change < Core.ChangeType.Hidden);

/// <summary>
/// checks to see if the reuqested action is valid for the configured list of actions.
Expand Down
36 changes: 25 additions & 11 deletions uSync.BackOffice/SyncHandlers/Handlers/DataTypeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace uSync.BackOffice.SyncHandlers.Handlers
/// Handler to manage DataTypes via uSync
/// </summary>
[SyncHandler(uSyncConstants.Handlers.DataTypeHandler, "Datatypes", "DataTypes", uSyncConstants.Priorites.DataTypes,
Icon = "icon-autofill", EntityType = UdiEntityType.DataType)]
Icon = "icon-autofill", IsTwoPass = true, EntityType = UdiEntityType.DataType)]
public class DataTypeHandler : SyncHandlerContainerBase<IDataType, IDataTypeService>, ISyncHandler, ISyncPostImportHandler,
INotificationHandler<SavedNotification<IDataType>>,
INotificationHandler<MovedNotification<IDataType>>,
Expand Down Expand Up @@ -61,25 +61,39 @@ public DataTypeHandler(
/// Datatypes have to exist early on so DocumentTypes can reference them, but
/// some doctypes reference content or document types, so we re-process them
/// at the end of the import process to ensure those settings can be made too.
///
/// HOWEVER: The above isn't a problem Umbraco 10+ - the references can be set
/// before the actual doctypes exist, so we can do that in one pass.
///
/// HOWEVER: If we move deletes to the end , we still need to process them.
/// but deletes are always 'change' = 'Hidden', so we only process hidden changes
/// </remarks>
public override IEnumerable<uSyncAction> ProcessPostImport(string folder, IEnumerable<uSyncAction> actions, HandlerSettings config)
{
if (actions == null || !actions.Any())
return null;

foreach (var action in actions)
var results = new List<uSyncAction>();


// we only do deletes here.
foreach (var action in actions.Where(x => x.Change == ChangeType.Hidden))
{
var result = Import(action.FileName, config, SerializerFlags.None);
foreach (var attempt in result)
{
if (attempt.Success && attempt.Item is IDataType dataType)
{
ImportSecondPass(action.FileName, dataType, config, null);
}
}
var result = Import(action.FileName, config, SerializerFlags.LastPass);
results.AddRange(result);

//foreach (var attempt in result)
//{
// if (attempt.Success && attempt.Item is IDataType dataType)
// {
// ImportSecondPass(action.FileName, dataType, config, null);
// }
//}
}

return CleanFolders(folder, -1);
results.AddRange(CleanFolders(folder, -1));

return results;
}

/// <summary>
Expand Down
22 changes: 22 additions & 0 deletions uSync.BackOffice/SyncHandlers/SyncHandlerContainerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;

using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Models;
Expand Down Expand Up @@ -173,5 +174,26 @@ private void ProcessContainerChanges(IEnumerable<EntityContainer> containers)
}
}
}

/// <summary>
/// Does this item match the one in a given xml file?
/// </summary>
/// <remarks>
/// container based tree's aren't really trees - as in things can't have the same
/// name inside a folder as something else that might be outside the folder.
///
/// this means when we are comparing files for clean up, we also want to check the
/// alias. so we check the key (in the base) and if doesn't match we check the alias.
///
/// under default setup none of this matters because the name of the item is the file
/// name so we find/overwrite it anyway,
///
/// but for guid / folder structured setups we need to do this compare.
/// </remarks>
protected override bool DoItemsMatch(XElement node, TObject item)
{
if (base.DoItemsMatch(node, item)) return true;
return node.GetAlias().InvariantEquals(GetItemAlias(item));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
/////////

function showChange(change) {
return vm.showAll || (change !== 'NoChange' && change !== 'Removed');
return vm.showAll || (change !== 'NoChange' && change !== 'Removed' && change !== 'Hidden');
}

function hasFailedDetail(details) {
Expand Down Expand Up @@ -111,7 +111,7 @@
function countChanges(changes) {
var count = 0;
angular.forEach(changes, function (val, key) {
if (val.change !== 'NoChange') {
if (val.change !== 'NoChange' && val.change !== 'Hidden') {
count++;
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@
function countChanges(changes) {
var count = 0;
angular.forEach(changes, function (val, key) {
if (val.change !== 'NoChange') {
if (val.change !== 'NoChange' && val.change !== 'Hidden') {
count++;
}
});
Expand Down
10 changes: 9 additions & 1 deletion uSync.Core/ChangeType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,15 @@ public enum ChangeType : int
Mismatch,

[EnumMember(Value = "ParentMissing")]
ParentMissing
ParentMissing,

/// <summary>
/// Hidden changes, don't show up in the UI
/// but they are processed like changes, so
/// get passed to second and last pass attempts
/// </summary>
[EnumMember(Value = "Hidden")]
Hidden = 101
}

}
6 changes: 5 additions & 1 deletion uSync.Core/Serialization/SerializerFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ public enum SerializerFlags
OnePass = 2, // do this in one pass
DoNotSave = 4, // don't save
FailMissingParent = 8, // fail if the parent item is missing
CreateOnly = 16 // only create, if the item is already there we don't overwrite.
CreateOnly = 16, // only create, if the item is already there we don't overwrite.
FirstPast = 32, // this is the first pass, sometime we might not do stuff on first pass.
SecondPass = 64, // this is the second pass
LastPass = 128, // this is the last pass.

}
}
38 changes: 38 additions & 0 deletions uSync.Core/Serialization/Serializers/DataTypeSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,44 @@ public DataTypeSerializer(IEntityService entityService, ILogger<DataTypeSerializ
};
}

/// <summary>
/// Process deletes
/// </summary>
/// <remarks>
/// datatypes are deleted late (in the last pass)
/// this means they are actually deleted at the very
/// end of the process.
///
/// In theory this should be fine,
///
/// any content types that may or may not use
/// datatypes we are about to delete will have
/// already been updated.
///
/// by moving the datatypes to the end we capture the
/// case where the datatype might have been replaced
/// in the content type, by not deleting first we
/// stop the triggering of any of Umbraco's delete
/// processes.
///
/// this only works because we are keeping the track of
/// all the deletes and renames when they happen
/// and we can only reliably do that for items
/// that have ContainerTree's because they are not
/// real trees - but flat (each alias is unique)
/// </remarks>
protected override SyncAttempt<IDataType> ProcessDelete(Guid key, string alias, SerializerFlags flags)
{
if (flags.HasFlag(SerializerFlags.LastPass))
{
logger.LogDebug("Processing deletes as part of the last pass)");
return base.ProcessDelete(key, alias, flags);
}

logger.LogDebug("Delete not processing as this is not the final pass");
return SyncAttempt<IDataType>.Succeed(alias, ChangeType.Hidden);
}

protected override SyncAttempt<IDataType> DeserializeCore(XElement node, SyncSerializerOptions options)
{
var info = node.Element(uSyncConstants.Xml.Info);
Expand Down

0 comments on commit e584b4e

Please sign in to comment.