Fix tags migration
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 =>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user