Fix tags migration

This commit is contained in:
Stephan
2018-11-15 10:11:22 +01:00
parent 42857ebc2a
commit c2a72ad98f
2 changed files with 37 additions and 37 deletions

View File

@@ -1,47 +1,51 @@
using System;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
{
/// <summary>
/// Set the default storageType for the tags datatype to "CSV" to ensure backwards compatibilty since the default is going to be JSON in new versions
/// </summary>
/// Set the default storageType for the tags datatype to "CSV" to ensure backwards compatibility since the default is going to be JSON in new versions.
/// </summary>
public class SetDefaultTagsStorageType : MigrationBase
{
public SetDefaultTagsStorageType(IMigrationContext context) : base(context)
{
}
public SetDefaultTagsStorageType(IMigrationContext context)
: base(context)
{ }
// dummy editor for deserialization
private class TagConfigurationEditor : ConfigurationEditor<TagConfiguration>
{ }
public override void Migrate()
{
if (Context?.Database == null) return;
// get all Umbraco.Tags datatypes
var dataTypeDtos = Database.Fetch<DataTypeDto>(Context.SqlContext.Sql()
.Select<DataTypeDto>()
.From<DataTypeDto>()
.Where<DataTypeDto>(x => x.EditorAlias == Constants.PropertyEditors.Aliases.Tags));
// We need to get all datatypes with an alias of "umbraco.tags" so we can loop over them and set the missing values if needed
var datatypes = Context.Database.Fetch<DataTypeDto>();
var tagsDataTypes = datatypes.Where(x => string.Equals(x.EditorAlias, Constants.PropertyEditors.Aliases.Tags, StringComparison.InvariantCultureIgnoreCase));
// get a dummy editor for deserialization
var editor = new TagConfigurationEditor();
foreach (var datatype in tagsDataTypes)
foreach (var dataTypeDto in dataTypeDtos)
{
var dataTypePreValues = JsonConvert.DeserializeObject<JObject>(datatype.Configuration);
// need to check storageType on raw dictionary, as TagConfiguration would have a default value
var dictionary = JsonConvert.DeserializeObject<JObject>(dataTypeDto.Configuration);
// We need to check if the node has a "storageType" set
if (!dataTypePreValues.ContainsKey("storageType"))
// if missing, use TagConfiguration to properly update the configuration
// due to ... reasons ... the key can start with a lower or upper 'S'
if (!dictionary.ContainsKey("storageType") && !dictionary.ContainsKey("StorageType"))
{
dataTypePreValues["storageType"] = "Csv";
var configuration = (TagConfiguration)editor.FromDatabase(dataTypeDto.Configuration);
configuration.StorageType = TagsStorageType.Csv;
dataTypeDto.Configuration = ConfigurationEditor.ToDatabase(configuration);
Database.Update(dataTypeDto);
}
Update.Table(Constants.DatabaseSchema.Tables.DataType)
.Set(new { config = JsonConvert.SerializeObject(dataTypePreValues) })
.Where(new { nodeId = datatype.NodeId })
.Do();
}
}
}
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Models;
@@ -31,7 +30,9 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview)
{
// if Json storage type deserialzie and return as string array
if (source == null) return Array.Empty<string>();
// if Json storage type deserialize and return as string array
if (JsonStorageType(propertyType.DataType.Id))
{
var jArray = JsonConvert.DeserializeObject<JArray>(source.ToString());
@@ -39,11 +40,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
}
// Otherwise assume CSV storage type and return as string array
var sourceString = source?.ToString() ?? string.Empty;
var csvTags = sourceString
.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.ToArray();
return csvTags;
return source.ToString().Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
}
public override object ConvertIntermediateToObject(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel cacheLevel, object source, bool preview)
@@ -62,10 +59,9 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
/// </returns>
private bool JsonStorageType(int dataTypeId)
{
// fixme
// GetPreValuesCollectionByDataTypeId is cached at repository level;
// still, the collection is deep-cloned so this is kinda expensive,
// better to cache here + trigger refresh in DataTypeCacheRefresher
// GetDataType(id) is cached at repository level; still, there is some
// deep-cloning involved (expensive) - better cache here + trigger
// refresh in DataTypeCacheRefresher
return Storages.GetOrAdd(dataTypeId, id =>
{