WIP (fixes migrations)

This commit is contained in:
Shannon
2020-09-24 18:37:24 +10:00
parent 8c4650951d
commit 6bd6d97bda
16 changed files with 159 additions and 112 deletions

View File

@@ -7,7 +7,7 @@ using Umbraco.Core.Migrations.Upgrade.V_8_0_0;
using Umbraco.Core.Migrations.Upgrade.V_8_0_1;
using Umbraco.Core.Migrations.Upgrade.V_8_1_0;
using Umbraco.Core.Migrations.Upgrade.V_8_6_0;
using Umbraco.Core.Migrations.Upgrade.V_8_8_0;
using Umbraco.Core.Migrations.Upgrade.V_8_9_0;
namespace Umbraco.Core.Migrations.Upgrade
{
@@ -194,9 +194,9 @@ namespace Umbraco.Core.Migrations.Upgrade
// to 8.7.0...
To<MissingDictionaryIndex>("{a78e3369-8ea3-40ec-ad3f-5f76929d2b20}");
To<AddCmsContentNuByteColumn>("{8DDDCD0B-D7D5-4C97-BD6A-6B38CA65752F}");
// to 8.8.0...
// to 8.9.0...
To<AddCmsContentNuByteColumn>("{8DDDCD0B-D7D5-4C97-BD6A-6B38CA65752F}");
To<UpgradedIncludeIndexes>("{4695D0C9-0729-4976-985B-048D503665D8}");
//FINAL

View File

@@ -1,50 +0,0 @@
using System.Linq;
using Umbraco.Core.Migrations.Expressions.Execute.Expressions;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Dtos;
namespace Umbraco.Core.Migrations.Upgrade.V_8_8_0
{
public class UpgradedIncludeIndexes : MigrationBase
{
public UpgradedIncludeIndexes(IMigrationContext context)
: base(context)
{
}
public override void Migrate()
{
var indexesToReplace = new[] { $"IX_{NodeDto.TableName}_UniqueId", $"IX_{NodeDto.TableName}_ObjectType" };
DeleteIndexes<NodeDto>(indexesToReplace); // delete existing ones
CreateIndexes<NodeDto>(indexesToReplace); // replace
CreateIndexes<NodeDto>($"IX_{NodeDto.TableName}_Level"); // add the new definitions
var contentVersionNodeIdIndex = $"IX_{ContentVersionDto.TableName}_NodeId";
DeleteIndexes<ContentVersionDto>(contentVersionNodeIdIndex); // delete existing ones
CreateIndexes<ContentVersionDto>(contentVersionNodeIdIndex); // replace
CreateIndexes<ContentVersionDto>($"IX_{ContentVersionDto.TableName}_Current"); // add the new definitions
}
private void DeleteIndexes<T>(params string[] toDelete)
{
var tableDef = DefinitionFactory.GetTableDefinition(typeof(T), Context.SqlContext.SqlSyntax);
foreach (var i in toDelete)
Delete.Index(i).OnTable(tableDef.Name).Do();
}
private void CreateIndexes<T>(params string[] toCreate)
{
var tableDef = DefinitionFactory.GetTableDefinition(typeof(T), Context.SqlContext.SqlSyntax);
foreach(var c in toCreate)
{
// get the definition by name
var index = tableDef.Indexes.First(x => x.Name == c);
new ExecuteSqlStatementExpression(Context) { SqlStatement = Context.SqlContext.SqlSyntax.Format(index) }.Execute();
}
}
}
}

View File

@@ -1,7 +1,7 @@
using System.Linq;
using Umbraco.Core.Persistence.Dtos;
namespace Umbraco.Core.Migrations.Upgrade.V_8_6_0
namespace Umbraco.Core.Migrations.Upgrade.V_8_9_0
{
public class AddCmsContentNuByteColumn : MigrationBase
{

View File

@@ -0,0 +1,69 @@
using System.Linq;
using Umbraco.Core.Migrations.Expressions.Execute.Expressions;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Dtos;
namespace Umbraco.Core.Migrations.Upgrade.V_8_9_0
{
public class UpgradedIncludeIndexes : MigrationBase
{
public UpgradedIncludeIndexes(IMigrationContext context)
: base(context)
{
}
public override void Migrate()
{
// Need to drop the FK for the redirect table before modifying the unique id index
Delete.ForeignKey()
.FromTable(Constants.DatabaseSchema.Tables.RedirectUrl)
.ForeignColumn("contentKey")
.ToTable(NodeDto.TableName)
.PrimaryColumn("uniqueID")
.Do();
var nodeDtoIndexes = new[] { $"IX_{NodeDto.TableName}_UniqueId", $"IX_{NodeDto.TableName}_ObjectType", $"IX_{NodeDto.TableName}_Level" };
DeleteIndexes<NodeDto>(nodeDtoIndexes); // delete existing ones
CreateIndexes<NodeDto>(nodeDtoIndexes); // update/add
// Now re-create the FK for the redirect table
Create.ForeignKey()
.FromTable(Constants.DatabaseSchema.Tables.RedirectUrl)
.ForeignColumn("contentKey")
.ToTable(NodeDto.TableName)
.PrimaryColumn("uniqueID")
.Do();
var contentVersionIndexes = new[] { $"IX_{ContentVersionDto.TableName}_NodeId", $"IX_{ContentVersionDto.TableName}_Current" };
DeleteIndexes<ContentVersionDto>(contentVersionIndexes); // delete existing ones
CreateIndexes<ContentVersionDto>(contentVersionIndexes); // update/add
}
private void DeleteIndexes<T>(params string[] toDelete)
{
var tableDef = DefinitionFactory.GetTableDefinition(typeof(T), Context.SqlContext.SqlSyntax);
foreach (var i in toDelete)
{
if (IndexExists(i))
{
Delete.Index(i).OnTable(tableDef.Name).Do();
}
}
}
private void CreateIndexes<T>(params string[] toCreate)
{
var tableDef = DefinitionFactory.GetTableDefinition(typeof(T), Context.SqlContext.SqlSyntax);
foreach (var c in toCreate)
{
// get the definition by name
var index = tableDef.Indexes.First(x => x.Name == c);
new ExecuteSqlStatementExpression(Context) { SqlStatement = Context.SqlContext.SqlSyntax.Format(index) }.Execute();
}
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// When assigned to a DataEditor it indicates that the values it generates can be compressed
/// </summary>
/// <remarks>
/// Used in conjunction with <see cref="CompressedStoragePropertyEditorCompressionOptions"/>
/// </remarks>
[AttributeUsage(AttributeTargets.Class)]
public sealed class CompressedStorageAttribute : Attribute
{
public CompressedStorageAttribute(bool isCompressed = true)
{
IsCompressed = isCompressed;
}
public bool IsCompressed { get; }
}
}

View File

@@ -0,0 +1,44 @@
using System.Collections.Concurrent;
using System.Linq;
using Umbraco.Core.Services;
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// Ensures all property types that have an editor storing a complex value are compressed
/// </summary>
public class CompressedStoragePropertyEditorCompressionOptions : IPropertyCompressionOptions
{
private readonly IContentTypeService _contentTypeService;
private readonly PropertyEditorCollection _propertyEditors;
private readonly ConcurrentDictionary<(int, string), string> _editorValueTypes = new ConcurrentDictionary<(int, string), string>();
public CompressedStoragePropertyEditorCompressionOptions(PropertyEditorCollection propertyEditors)
{
_propertyEditors = propertyEditors;
}
public bool IsCompressed(int contentTypeId, string alias)
{
return false;
//var valueType = _editorValueTypes.GetOrAdd((contentTypeId, alias), x =>
//{
// var ct = _contentTypeService.Get(contentTypeId);
// if (ct == null) return null;
// var propertyType = ct.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == alias);
// if (propertyType == null) return null;
// if (!_propertyEditors.TryGet(propertyType.PropertyEditorAlias, out var propertyEditor)) return null;
// var editor = propertyEditor.GetValueEditor();
// if (editor == null) return null;
// return editor.ValueType;
//});
//return valueType == ValueTypes.Json || valueType == ValueTypes.Xml || valueType == ValueTypes.Text;
}
}
}

View File

@@ -2,6 +2,7 @@
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// Marks a class that represents a data editor.
/// </summary>

View File

@@ -1,4 +1,4 @@
namespace Umbraco.Web.PropertyEditors
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// Determines if a property type's value should be compressed

View File

@@ -132,8 +132,8 @@
<Compile Include="Migrations\Upgrade\V_8_0_0\Models\ContentTypeDto80.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\Models\PropertyDataDto80.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\Models\PropertyTypeDto80.cs" />
<Compile Include="Migrations\Upgrade\V_8_7_0\AddCmsContentNuByteColumn.cs" />
<Compile Include="Migrations\Upgrade\V_8_8_0\UpgradedIncludeIndexes.cs" />
<Compile Include="Migrations\Upgrade\V_8_9_0\AddCmsContentNuByteColumn.cs" />
<Compile Include="Migrations\Upgrade\V_8_9_0\UpgradedIncludeIndexes.cs" />
<Compile Include="Models\Blocks\BlockEditorDataConverter.cs" />
<Compile Include="Models\Blocks\BlockEditorData.cs" />
<Compile Include="Models\Blocks\BlockItemData.cs" />
@@ -152,6 +152,9 @@
<Compile Include="Persistence\Repositories\IInstallationRepository.cs" />
<Compile Include="Persistence\Repositories\Implement\InstallationRepository.cs" />
<Compile Include="Persistence\SqlCeImageMapper.cs" />
<Compile Include="PropertyEditors\CompressedStorageAttribute.cs" />
<Compile Include="PropertyEditors\CompressedStoragePropertyEditorCompressionOptions.cs" />
<Compile Include="PropertyEditors\IPropertyCompressionOptions.cs" />
<Compile Include="Serialization\AutoInterningStringConverter.cs" />
<Compile Include="Serialization\AutoInterningStringKeyCaseInsensitiveDictionaryConverter.cs" />
<Compile Include="PropertyEditors\ComplexPropertyEditorContentEventHandler.cs" />

View File

@@ -1,48 +0,0 @@
using K4os.Compression.LZ4;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;
namespace Umbraco.Web.PropertyEditors
{
/// <summary>
/// Ensures all property types that have an editor storing a complex value are compressed
/// </summary>
public class ComplexEditorPropertyCompressionOptions : IPropertyCompressionOptions
{
private readonly IContentTypeService _contentTypeService;
private readonly PropertyEditorCollection _propertyEditors;
private readonly ConcurrentDictionary<(int, string), string> _editorValueTypes = new ConcurrentDictionary<(int, string), string>();
public ComplexEditorPropertyCompressionOptions(IContentTypeService contentTypeService, PropertyEditorCollection propertyEditors)
{
_contentTypeService = contentTypeService;
_propertyEditors = propertyEditors;
}
public bool IsCompressed(int contentTypeId, string alias)
{
var valueType = _editorValueTypes.GetOrAdd((contentTypeId, alias), x =>
{
var ct = _contentTypeService.Get(contentTypeId);
if (ct == null) return null;
var propertyType = ct.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == alias);
if (propertyType == null) return null;
if (!_propertyEditors.TryGet(propertyType.PropertyEditorAlias, out var propertyEditor)) return null;
var editor = propertyEditor.GetValueEditor();
if (editor == null) return null;
return editor.ValueType;
});
return valueType == ValueTypes.Json || valueType == ValueTypes.Xml || valueType == ValueTypes.Text;
}
}
}

View File

@@ -1,4 +1,6 @@
namespace Umbraco.Web.PropertyEditors
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
/// <summary>
/// Disables all compression for all properties

View File

@@ -129,7 +129,9 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
// We also want to read with a db reader and not load everything into memory, QueryPaged lets us do that.
foreach (var row in scope.Database.QueryPaged<ContentSourceDto>(PageSize, sql, sqlCount))
{
yield return CreateContentNodeKit(row);
}
}
public IEnumerable<ContentNodeKit> GetBranchContentSources(IScope scope, int id)
@@ -145,7 +147,9 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
// We also want to read with a db reader and not load everything into memory, QueryPaged lets us do that.
foreach (var row in scope.Database.QueryPaged<ContentSourceDto>(PageSize, sql))
{
yield return CreateContentNodeKit(row);
}
}
public IEnumerable<ContentNodeKit> GetTypeContentSources(IScope scope, IEnumerable<int> ids)
@@ -161,7 +165,9 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
// We also want to read with a db reader and not load everything into memory, QueryPaged lets us do that.
foreach (var row in scope.Database.QueryPaged<ContentSourceDto>(PageSize, sql))
{
yield return CreateContentNodeKit(row);
}
}
private Sql<ISqlContext> MediaSourcesSelect(IScope scope, Func<Sql<ISqlContext>, Sql<ISqlContext>> joins = null)

View File

@@ -7,6 +7,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Umbraco.Core.PropertyEditors;
using Umbraco.Web.PropertyEditors;
namespace Umbraco.Web.PublishedCache.NuCache.DataSource

View File

@@ -3,6 +3,7 @@ using System.Configuration;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.PropertyEditors;
using Umbraco.Web.PropertyEditors;
using Umbraco.Web.PublishedCache.NuCache.DataSource;
@@ -24,7 +25,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
else
{
composition.RegisterUnique<IContentNestedDataSerializer, MsgPackContentNestedDataSerializer>();
composition.RegisterUnique<IPropertyCompressionOptions, ComplexEditorPropertyCompressionOptions>();
composition.RegisterUnique<IPropertyCompressionOptions, CompressedStoragePropertyEditorCompressionOptions>();
}
composition.RegisterUnique(factory => new ContentDataSerializer(new DictionaryOfPropertyDataSerializer()));

View File

@@ -387,10 +387,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
// contentStore is wlocked (1 thread)
// content (and types) are read-locked
var contentTypes = _serviceContext.ContentTypeService.GetAll()
.Select(x => _publishedContentTypeFactory.CreateContentType(x));
var contentTypes = _serviceContext.ContentTypeService.GetAll().ToList();
_contentStore.SetAllContentTypesLocked(contentTypes);
_contentStore.SetAllContentTypesLocked(contentTypes.Select(x => _publishedContentTypeFactory.CreateContentType(x)));
using (_logger.TraceDuration<PublishedSnapshotService>("Loading content from database"))
{

View File

@@ -262,7 +262,6 @@
<Compile Include="PropertyEditors\BlockListPropertyEditor.cs" />
<Compile Include="Compose\NestedContentPropertyComposer.cs" />
<Compile Include="PropertyEditors\ComplexEditorValidator.cs" />
<Compile Include="PropertyEditors\IPropertyCompressionOptions.cs" />
<Compile Include="PropertyEditors\NoopPropertyCompressionOptions.cs" />
<Compile Include="PropertyEditors\ParameterEditors\MultipleMediaPickerParameterEditor.cs" />
<Compile Include="PropertyEditors\RichTextEditorPastedImages.cs" />
@@ -271,7 +270,6 @@
<Compile Include="PublishedCache\NuCache\DataSource\JsonContentNestedDataSerializer.cs" />
<Compile Include="PublishedCache\NuCache\DataSource\LazyCompressedString.cs" />
<Compile Include="PublishedCache\NuCache\DataSource\MsgPackContentNestedDataSerializer.cs" />
<Compile Include="PropertyEditors\ComplexEditorPropertyCompressionOptions.cs" />
<Compile Include="PropertyEditors\Validation\ComplexEditorElementTypeValidationResult.cs" />
<Compile Include="PropertyEditors\Validation\ComplexEditorPropertyTypeValidationResult.cs" />
<Compile Include="PropertyEditors\Validation\ComplexEditorValidationResult.cs" />