WIP - Handle migration of Checkbox list data

This commit is contained in:
Bjarke Berg
2019-02-12 08:58:49 +01:00
parent f5d31a4c5a
commit f4db356511
3 changed files with 30 additions and 191 deletions

View File

@@ -1,150 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
{
public class CheckBoxListPropertyEditorsMigration : MigrationBase
{
public CheckBoxListPropertyEditorsMigration(IMigrationContext context)
: base(context)
{
}
public override void Migrate()
{
//need to convert the old drop down data types to use the new one
var dataTypes = Database.Fetch<DataTypeDto>(Sql()
.Select<DataTypeDto>()
.From<DataTypeDto>()
.Where<DataTypeDto>(x => x.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.CheckBoxList)));
var refreshCache = false;
foreach (var dataType in dataTypes)
{
ValueListConfiguration config;
if (!dataType.Configuration.IsNullOrWhiteSpace())
{
// parse configuration, and update everything accordingly
try
{
config = (ValueListConfiguration) new ValueListConfigurationEditor().FromDatabase(
dataType.Configuration);
}
catch (Exception ex)
{
Logger.Error<DropDownPropertyEditorsMigration>(
ex,
"Invalid drop down configuration detected: \"{Configuration}\", cannot convert editor, values will be cleared",
dataType.Configuration);
continue;
}
// get property data dtos
var propertyDataDtos = Database.Fetch<PropertyDataDto>(Sql()
.Select<PropertyDataDto>()
.From<PropertyDataDto>()
.InnerJoin<PropertyTypeDto>()
.On<PropertyTypeDto, PropertyDataDto>((pt, pd) => pt.Id == pd.PropertyTypeId)
.InnerJoin<DataTypeDto>()
.On<DataTypeDto, PropertyTypeDto>((dt, pt) => dt.NodeId == pt.DataTypeId)
.Where<PropertyTypeDto>(x => x.DataTypeId == dataType.NodeId));
// update dtos
var updatedDtos = propertyDataDtos.Where(x => UpdatePropertyDataDto(x, config));
// persist changes
foreach (var propertyDataDto in updatedDtos) Database.Update(propertyDataDto);
UpdateDataType(dataType);
refreshCache = true;
}
}
if (refreshCache)
{
//FIXME: trigger cache rebuild. Currently the data in the database tables is wrong.
}
}
private void UpdateDataType(DataTypeDto dataType)
{
dataType.DbType = ValueStorageType.Nvarchar.ToString();
Database.Update(dataType);
}
private bool UpdatePropertyDataDto(PropertyDataDto propData, ValueListConfiguration config)
{
//Get the INT ids stored for this property/drop down
int[] ids = null;
if (!propData.VarcharValue.IsNullOrWhiteSpace())
{
ids = ConvertStringValues(propData.VarcharValue);
}
else if (!propData.TextValue.IsNullOrWhiteSpace())
{
ids = ConvertStringValues(propData.TextValue);
}
else if (propData.IntegerValue.HasValue)
{
ids = new[] { propData.IntegerValue.Value };
}
//if there are INT ids, convert them to values based on the configuration
if (ids == null || ids.Length <= 0) return false;
//map the ids to values
var values = new List<string>();
var canConvert = true;
foreach (var id in ids)
{
var val = config.Items.FirstOrDefault(x => x.Id == id);
if (val != null)
values.Add(val.Value);
else
{
Logger.Warn<DropDownPropertyEditorsMigration>(
"Could not find associated data type configuration for stored Id {DataTypeId}", id);
canConvert = false;
}
}
if (!canConvert) return false;
propData.VarcharValue = JsonConvert.SerializeObject(values);
propData.TextValue = null;
propData.IntegerValue = null;
return true;
}
private class ValueListConfigurationEditor : ConfigurationEditor<ValueListConfiguration>
{
}
private int[] ConvertStringValues(string val)
{
var splitVals = JsonConvert.DeserializeObject<string[]>(val);
var intVals = splitVals
.Select(x => int.TryParse(x, out var i) ? i : int.MinValue)
.Where(x => x != int.MinValue)
.ToArray();
//only return if the number of values are the same (i.e. All INTs)
if (splitVals.Length == intVals.Length)
return intVals;
return null;
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
@@ -18,24 +19,22 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
public override void Migrate()
{
MigrateRadioButtons();
MigrateCheckBoxes();
}
private void MigrateCheckBoxes()
{
//fixme: complete this
var dataTypes = GetDataTypes(Constants.PropertyEditors.Aliases.CheckBoxList);
}
private void MigrateRadioButtons()
{
var dataTypes = GetDataTypes(Constants.PropertyEditors.Aliases.RadioButtonList);
var refreshCache = false;
refreshCache |= Migrate(Constants.PropertyEditors.Aliases.RadioButtonList, str => str.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries));
refreshCache |= Migrate(Constants.PropertyEditors.Aliases.CheckBoxList, JsonConvert.DeserializeObject<string[]>);
if (refreshCache)
{
//FIXME: trigger cache rebuild. Currently the data in the database tables is wrong.
}
}
private bool Migrate(string editorAlias, Func<string, string[]> splitValuesFunc)
{
var refreshCache = false;
var dataTypes = GetDataTypes(editorAlias);
foreach (var dataType in dataTypes)
{
ValueListConfiguration config;
@@ -46,7 +45,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
// parse configuration, and update everything accordingly
try
{
config = (ValueListConfiguration)new ValueListConfigurationEditor().FromDatabase(
config = (ValueListConfiguration) new ValueListConfigurationEditor().FromDatabase(
dataType.Configuration);
}
catch (Exception ex)
@@ -70,7 +69,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
.Where<PropertyTypeDto>(x => x.DataTypeId == dataType.NodeId));
// update dtos
var updatedDtos = propertyDataDtos.Where(x => UpdatePropertyDataDto(x, config));
var updatedDtos = propertyDataDtos.Where(x => UpdateRadioPropertyDataDto(x, config, splitValuesFunc));
// persist changes
foreach (var propertyDataDto in updatedDtos) Database.Update(propertyDataDto);
@@ -79,10 +78,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
refreshCache = true;
}
if (refreshCache)
{
//FIXME: trigger cache rebuild. Currently the data in the database tables is wrong.
}
return refreshCache;
}
private List<DataTypeDto> GetDataTypes(string editorAlias)
@@ -101,22 +97,16 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
Database.Update(dataType);
}
private bool UpdatePropertyDataDto(PropertyDataDto propData, ValueListConfiguration config)
private bool UpdateRadioPropertyDataDto(PropertyDataDto propData, ValueListConfiguration config,
Func<string, string[]> splitValuesFunc)
{
//Get the INT ids stored for this property/drop down
int[] ids = null;
if (!propData.VarcharValue.IsNullOrWhiteSpace())
{
ids = ConvertStringValues(propData.VarcharValue);
}
ids = ConvertStringValues(propData.VarcharValue, splitValuesFunc);
else if (!propData.TextValue.IsNullOrWhiteSpace())
{
ids = ConvertStringValues(propData.TextValue);
}
else if (propData.IntegerValue.HasValue)
{
ids = new[] { propData.IntegerValue.Value };
}
ids = ConvertStringValues(propData.TextValue, splitValuesFunc);
else if (propData.IntegerValue.HasValue) ids = new[] {propData.IntegerValue.Value};
//if there are INT ids, convert them to values based on the configuration
if (ids == null || ids.Length <= 0) return false;
@@ -147,13 +137,9 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
return true;
}
private class ValueListConfigurationEditor : ConfigurationEditor<ValueListConfiguration>
private int[] ConvertStringValues(string val, Func<string, string[]> splitValuesFunc)
{
}
private int[] ConvertStringValues(string val)
{
var splitVals = val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var splitVals = splitValuesFunc(val);
var intVals = splitVals
.Select(x => int.TryParse(x, out var i) ? i : int.MinValue)
@@ -166,5 +152,9 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
return null;
}
private class ValueListConfigurationEditor : ConfigurationEditor<ValueListConfiguration>
{
}
}
}

View File

@@ -367,7 +367,6 @@
<Compile Include="Migrations\Upgrade\V_7_9_0\AddUmbracoAuditTable.cs" />
<Compile Include="Migrations\Upgrade\V_7_9_0\AddUmbracoConsentTable.cs" />
<Compile Include="Migrations\Upgrade\V_7_9_0\CreateSensitiveDataUserGroup.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\CheckBoxListPropertyEditorsMigration.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\AddUserLoginDtoDateIndex.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\ConvertRelatedLinksToMultiUrlPicker.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\AddContentTypeIsElementColumn.cs" />