diff --git a/src/Umbraco.Core/Models/ValueStorageType.cs b/src/Umbraco.Core/Models/ValueStorageType.cs index 975369f993..e7e4f8b354 100644 --- a/src/Umbraco.Core/Models/ValueStorageType.cs +++ b/src/Umbraco.Core/Models/ValueStorageType.cs @@ -14,13 +14,13 @@ public enum ValueStorageType // changing the casing of values. /// - /// Store property value as NText. + /// Store property value as NVarchar(max). /// [EnumMember] Ntext, /// - /// Store property value as NVarChar. + /// Store property value as NVarChar(512). /// [EnumMember] Nvarchar, diff --git a/src/Umbraco.Core/PropertyEditors/ValueTypes.cs b/src/Umbraco.Core/PropertyEditors/ValueTypes.cs index ac6e6a9bb8..dc1e636c7f 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueTypes.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueTypes.cs @@ -45,7 +45,7 @@ public static class ValueTypes public const string Json = "JSON"; // NText /// - /// Text value (maps to text database type). + /// Text value (maps to nvarchar(max) database type). /// public const string Text = "TEXT"; // NText @@ -55,7 +55,7 @@ public static class ValueTypes public const string Time = "TIME"; // Date /// - /// Text value (maps to varchar database type). + /// Text value (maps to nvarchar(512) database type). /// public const string String = "STRING"; // NVarchar diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs index e99ce46587..7fed5a6afb 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs @@ -2060,7 +2060,7 @@ internal sealed class DatabaseDataCreator NodeId = -43, EditorAlias = Constants.PropertyEditors.Aliases.CheckBoxList, EditorUiAlias = "Umb.PropertyEditorUi.CheckBoxList", - DbType = "Nvarchar", + DbType = "Ntext", }); } diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs index b02c56fea6..a62ce1d8a1 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs @@ -126,5 +126,6 @@ public class UmbracoPlan : MigrationPlan // To 17.0.0 To("{17D5F6CA-CEB8-462A-AF86-4B9C3BF91CF1}"); + To("{EB1E50B7-CD5E-4B6B-B307-36237DD2C506}"); } } diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_17_0_0/MigrateCheckboxListDataTypesAndPropertyData.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_17_0_0/MigrateCheckboxListDataTypesAndPropertyData.cs new file mode 100644 index 0000000000..35873b9501 --- /dev/null +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_17_0_0/MigrateCheckboxListDataTypesAndPropertyData.cs @@ -0,0 +1,50 @@ +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Services; + +namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_17_0_0; + +/// +/// Migrates data types based on the Umbraco.CheckBoxList property editor to store data in the text column without length restriction. +/// Also migrates the data for properties this property editor from the length restricted field (varcharValue - nvarchar(512)), to the +/// one without a restriction (textValue - nvarchar(max)). +/// +public class MigrateCheckboxListDataTypesAndPropertyData : AsyncMigrationBase +{ + private readonly IDataTypeService _dataTypeService; + + /// + /// Initializes a new instance of the class. + /// + public MigrateCheckboxListDataTypesAndPropertyData(IMigrationContext context, IDataTypeService dataTypeService) + : base(context) => _dataTypeService = dataTypeService; + + /// + protected override async Task MigrateAsync() + { + // Update the definition of the datatypes. + IEnumerable dataTypes = await _dataTypeService.GetByEditorAliasAsync(Constants.PropertyEditors.Aliases.CheckBoxList); + foreach (IDataType dataType in dataTypes) + { + dataType.DatabaseType = ValueStorageType.Ntext; + await _dataTypeService.UpdateAsync(dataType, Constants.Security.SuperUserKey); + } + + // Copy from varcharValue to textValue and set varcharValue to null for all property data stored using data types based on + // the Umbraco.CheckBoxList property editor. + string sql = $@" +UPDATE umbracoPropertyData +SET textValue = varcharValue, varcharValue = NULL +WHERE propertyTypeId IN ( + SELECT id + FROM cmsPropertyType + WHERE dataTypeId IN ( + SELECT nodeId + FROM umbracoDataType + WHERE propertyEditorAlias = '{Constants.PropertyEditors.Aliases.CheckBoxList}' + ) +) +AND varcharValue IS NOT NULL"; + await Database.ExecuteAsync(sql); + } +} diff --git a/src/Umbraco.Infrastructure/PropertyEditors/CheckBoxListPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/CheckBoxListPropertyEditor.cs index cd06118041..9f9606e3f0 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/CheckBoxListPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/CheckBoxListPropertyEditor.cs @@ -12,6 +12,7 @@ namespace Umbraco.Cms.Core.PropertyEditors; /// [DataEditor( Constants.PropertyEditors.Aliases.CheckBoxList, + ValueType = ValueTypes.Text, // We use the Text value type to ensure we don't run out of storage space in the database field with large lists with multiple values selected. ValueEditorIsReusable = true)] public class CheckBoxListPropertyEditor : DataEditor {