Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V8/bugfix/3498 entity service updates #5658

Merged
merged 3 commits into from
Jun 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Umbraco.Core/Models/Entities/DocumentEntitySlim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Umbraco.Core.Models.Entities
{

/// <summary>
/// Implements <see cref="IDocumentEntitySlim"/>.
/// </summary>
Expand Down
46 changes: 0 additions & 46 deletions src/Umbraco.Core/Models/Entities/EntitySlim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,52 +111,6 @@ public class EntitySlim : IEntitySlim
public virtual bool IsContainer { get; set; }


/// <summary>
/// Represents a lightweight property.
/// </summary>
public class PropertySlim
{
/// <summary>
/// Initializes a new instance of the <see cref="PropertySlim"/> class.
/// </summary>
public PropertySlim(string editorAlias, object value)
{
PropertyEditorAlias = editorAlias;
Value = value;
}

/// <summary>
/// Gets the property editor alias.
/// </summary>
public string PropertyEditorAlias { get; }

/// <summary>
/// Gets the property value.
/// </summary>
public object Value { get; }

protected bool Equals(PropertySlim other)
{
return PropertyEditorAlias.Equals(other.PropertyEditorAlias) && Equals(Value, other.Value);
}

public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((PropertySlim) obj);
}

public override int GetHashCode()
{
unchecked
{
return (PropertyEditorAlias.GetHashCode() * 397) ^ (Value != null ? Value.GetHashCode() : 0);
}
}
}

#region IDeepCloneable

/// <inheritdoc />
Expand Down
1 change: 1 addition & 0 deletions src/Umbraco.Core/Models/Entities/IDocumentEntitySlim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Umbraco.Core.Models.Entities
{

/// <summary>
/// Represents a lightweight document entity, managed by the entity service.
/// </summary>
Expand Down
14 changes: 14 additions & 0 deletions src/Umbraco.Core/Models/Entities/IMediaEntitySlim.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Umbraco.Core.Models.Entities
{
/// <summary>
/// Represents a lightweight media entity, managed by the entity service.
/// </summary>
public interface IMediaEntitySlim : IContentEntitySlim
{

/// <summary>
/// The media file's path/url
/// </summary>
string MediaPath { get; }
}
}
10 changes: 10 additions & 0 deletions src/Umbraco.Core/Models/Entities/MediaEntitySlim.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Umbraco.Core.Models.Entities
{
/// <summary>
/// Implements <see cref="IMediaEntitySlim"/>.
/// </summary>
public class MediaEntitySlim : ContentEntitySlim, IMediaEntitySlim
{
public string MediaPath { get; set; }
}
}
159 changes: 50 additions & 109 deletions src/Umbraco.Core/Persistence/Repositories/Implement/EntityRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ public IEnumerable<IEntitySlim> GetPagedResultsByQuery(IQuery<IUmbracoEntity> qu
dtos = page.Items;
totalRecords = page.TotalItems;
}
else if (isMedia)
{
var page = Database.Page<MediaEntityDto>(pageIndexToFetch, pageSize, sql);
dtos = page.Items;
totalRecords = page.TotalItems;
}
else
{
var page = Database.Page<BaseDto>(pageIndexToFetch, pageSize, sql);
Expand All @@ -87,10 +93,6 @@ public IEnumerable<IEntitySlim> GetPagedResultsByQuery(IQuery<IUmbracoEntity> qu
if (isContent)
BuildVariants(entities.Cast<DocumentEntitySlim>());

// TODO: see https://github.com/umbraco/Umbraco-CMS/pull/3460#issuecomment-434903930 we need to not load any property data at all for media
if (isMedia)
BuildProperties(entities, dtos.ToList());

return entities;
}

Expand All @@ -112,14 +114,14 @@ private IEntitySlim GetEntity(Sql<ISqlContext> sql, bool isContent, bool isMedia
return cdtos.Count == 0 ? null : BuildVariants(BuildDocumentEntity(cdtos[0]));
}

var dto = Database.FirstOrDefault<BaseDto>(sql);
var dto = isMedia
? Database.FirstOrDefault<MediaEntityDto>(sql)
: Database.FirstOrDefault<BaseDto>(sql);

if (dto == null) return null;

var entity = BuildEntity(false, isMedia, dto);

if (isMedia)
BuildProperties(entity, dto);

return entity;
}

Expand Down Expand Up @@ -162,7 +164,7 @@ public IEnumerable<IEntitySlim> GetAll(Guid objectType, params Guid[] keys)
: PerformGetAll(objectType);
}

private IEnumerable<IEntitySlim> GetEntities(Sql<ISqlContext> sql, bool isContent, bool isMedia, bool loadMediaProperties)
private IEnumerable<IEntitySlim> GetEntities(Sql<ISqlContext> sql, bool isContent, bool isMedia)
{
//isContent is going to return a 1:M result now with the variants so we need to do different things
if (isContent)
Expand All @@ -174,15 +176,12 @@ private IEnumerable<IEntitySlim> GetEntities(Sql<ISqlContext> sql, bool isConten
: BuildVariants(cdtos.Select(BuildDocumentEntity)).ToList();
}

var dtos = Database.Fetch<BaseDto>(sql);
if (dtos.Count == 0) return Enumerable.Empty<IEntitySlim>();
var dtos = isMedia
? (IEnumerable<BaseDto>)Database.Fetch<MediaEntityDto>(sql)
: Database.Fetch<BaseDto>(sql);

var entities = dtos.Select(x => BuildEntity(false, isMedia, x)).ToArray();

// TODO: See https://github.com/umbraco/Umbraco-CMS/pull/3460#issuecomment-434903930 we need to not load any property data at all for media
if (isMedia && loadMediaProperties)
BuildProperties(entities, dtos);

return entities;
}

Expand All @@ -192,7 +191,7 @@ private IEnumerable<IEntitySlim> PerformGetAll(Guid objectType, Action<Sql<ISqlC
var isMedia = objectType == Constants.ObjectTypes.Media;

var sql = GetFullSqlForEntityType(isContent, isMedia, objectType, filter);
return GetEntities(sql, isContent, isMedia, true);
return GetEntities(sql, isContent, isMedia);
}

public IEnumerable<TreeEntityPath> GetAllPaths(Guid objectType, params int[] ids)
Expand Down Expand Up @@ -238,22 +237,7 @@ public IEnumerable<IEntitySlim> GetByQuery(IQuery<IUmbracoEntity> query, Guid ob
sql = translator.Translate();
sql = AddGroupBy(isContent, isMedia, sql, true);

return GetEntities(sql, isContent, isMedia, true);
}

// TODO: See https://github.com/umbraco/Umbraco-CMS/pull/3460#issuecomment-434903930 we need to not load any property data at all for media
internal IEnumerable<IEntitySlim> GetMediaByQueryWithoutPropertyData(IQuery<IUmbracoEntity> query)
{
var isContent = false;
var isMedia = true;

var sql = GetBaseWhere(isContent, isMedia, false, null, Constants.ObjectTypes.Media);

var translator = new SqlTranslator<IUmbracoEntity>(sql, query);
sql = translator.Translate();
sql = AddGroupBy(isContent, isMedia, sql, true);

return GetEntities(sql, isContent, isMedia, false);
return GetEntities(sql, isContent, isMedia);
}

public UmbracoObjectTypes GetObjectType(int id)
Expand All @@ -280,41 +264,6 @@ public bool Exists(int id)
return Database.ExecuteScalar<int>(sql) > 0;
}

// TODO: see https://github.com/umbraco/Umbraco-CMS/pull/3460#issuecomment-434903930 we need to not load any property data at all for media
private void BuildProperties(EntitySlim entity, BaseDto dto)
{
var pdtos = Database.Fetch<PropertyDataDto>(GetPropertyData(dto.VersionId));
foreach (var pdto in pdtos)
BuildProperty(entity, pdto);
}

// TODO: see https://github.com/umbraco/Umbraco-CMS/pull/3460#issuecomment-434903930 we need to not load any property data at all for media
private void BuildProperties(EntitySlim[] entities, List<BaseDto> dtos)
{
var versionIds = dtos.Select(x => x.VersionId).Distinct().ToList();
var pdtos = Database.FetchByGroups<PropertyDataDto, int>(versionIds, 2000, GetPropertyData);

var xentity = entities.ToDictionary(x => x.Id, x => x); // nodeId -> entity
var xdto = dtos.ToDictionary(x => x.VersionId, x => x.NodeId); // versionId -> nodeId
foreach (var pdto in pdtos)
{
var nodeId = xdto[pdto.VersionId];
var entity = xentity[nodeId];
BuildProperty(entity, pdto);
}
}

// TODO: see https://github.com/umbraco/Umbraco-CMS/pull/3460#issuecomment-434903930 we need to not load any property data at all for media
private void BuildProperty(EntitySlim entity, PropertyDataDto pdto)
{
// explain ?!
var value = string.IsNullOrWhiteSpace(pdto.TextValue)
? pdto.VarcharValue
: pdto.TextValue.ConvertToJsonIfPossible();

entity.AdditionalData[pdto.PropertyTypeDto.Alias] = new EntitySlim.PropertySlim(pdto.PropertyTypeDto.DataTypeDto.EditorAlias, value);
}

private DocumentEntitySlim BuildVariants(DocumentEntitySlim entity)
=> BuildVariants(new[] { entity }).First();

Expand Down Expand Up @@ -400,31 +349,10 @@ protected Sql<ISqlContext> GetFullSqlForEntityType(bool isContent, bool isMedia,
return AddGroupBy(isContent, isMedia, sql, true);
}

private Sql<ISqlContext> GetPropertyData(int versionId)
{
return Sql()
.Select<PropertyDataDto>(r => r.Select(x => x.PropertyTypeDto, r1 => r1.Select(x => x.DataTypeDto)))
.From<PropertyDataDto>()
.InnerJoin<PropertyTypeDto>().On<PropertyDataDto, PropertyTypeDto>((left, right) => left.PropertyTypeId == right.Id)
.InnerJoin<DataTypeDto>().On<PropertyTypeDto, DataTypeDto>((left, right) => left.DataTypeId == right.NodeId)
.Where<PropertyDataDto>(x => x.VersionId == versionId);
}

private Sql<ISqlContext> GetPropertyData(IEnumerable<int> versionIds)
{
return Sql()
.Select<PropertyDataDto>(r => r.Select(x => x.PropertyTypeDto, r1 => r1.Select(x => x.DataTypeDto)))
.From<PropertyDataDto>()
.InnerJoin<PropertyTypeDto>().On<PropertyDataDto, PropertyTypeDto>((left, right) => left.PropertyTypeId == right.Id)
.InnerJoin<DataTypeDto>().On<PropertyTypeDto, DataTypeDto>((left, right) => left.DataTypeId == right.NodeId)
.WhereIn<PropertyDataDto>(x => x.VersionId, versionIds)
.OrderBy<PropertyDataDto>(x => x.VersionId);
}

// gets the base SELECT + FROM [+ filter] sql
// always from the 'current' content version
protected Sql<ISqlContext> GetBase(bool isContent, bool isMedia, Action<Sql<ISqlContext>> filter, bool isCount = false)
{
{
var sql = Sql();

if (isCount)
Expand All @@ -448,6 +376,12 @@ protected Sql<ISqlContext> GetBase(bool isContent, bool isMedia, Action<Sql<ISql
sql
.AndSelect<DocumentDto>(x => x.Published, x => x.Edited);
}

if (isMedia)
{
sql
.AndSelect<MediaVersionDto>(x => Alias(x.Path, "MediaPath"));
}
}

sql
Expand All @@ -467,6 +401,12 @@ protected Sql<ISqlContext> GetBase(bool isContent, bool isMedia, Action<Sql<ISql
.InnerJoin<DocumentDto>().On<NodeDto, DocumentDto>((left, right) => left.NodeId == right.NodeId);
}

if (isMedia)
{
sql
.InnerJoin<MediaVersionDto>().On<ContentVersionDto, MediaVersionDto>((left, right) => left.Id == right.Id);
}

//Any LeftJoin statements need to come last
if (isCount == false)
{
Expand Down Expand Up @@ -536,6 +476,12 @@ protected Sql<ISqlContext> AddGroupBy(bool isContent, bool isMedia, Sql<ISqlCont
.AndBy<DocumentDto>(x => x.Published, x => x.Edited);
}

if (isMedia)
{
sql
.AndBy<MediaVersionDto>(x => Alias(x.Path, "MediaPath"));
}


if (isContent || isMedia)
sql
Expand Down Expand Up @@ -566,23 +512,6 @@ private void ApplyOrdering(ref Sql<ISqlContext> sql, Ordering ordering)

#region Classes

[ExplicitColumns]
internal class UmbracoPropertyDto
{
[Column("propertyEditorAlias")]
public string PropertyEditorAlias { get; set; }

[Column("propertyTypeAlias")]
public string PropertyAlias { get; set; }

[Column("varcharValue")]
public string VarcharValue { get; set; }

[Column("textValue")]
public string TextValue { get; set; }
}


/// <summary>
/// The DTO used to fetch results for a content item with its variation info
/// </summary>
Expand All @@ -594,6 +523,11 @@ private class ContentEntityDto : BaseDto
public bool Edited { get; set; }
}

private class MediaEntityDto : BaseDto
{
public string MediaPath { get; set; }
}

public class VariantInfoDto
{
public int NodeId { get; set; }
Expand Down Expand Up @@ -645,7 +579,7 @@ private EntitySlim BuildEntity(bool isContent, bool isMedia, BaseDto dto)
if (isContent)
return BuildDocumentEntity(dto);
if (isMedia)
return BuildContentEntity(dto);
return BuildMediaEntity(dto);

// EntitySlim does not track changes
var entity = new EntitySlim();
Expand Down Expand Up @@ -678,11 +612,18 @@ private static void BuildContentEntity(ContentEntitySlim entity, BaseDto dto)
entity.ContentTypeThumbnail = dto.Thumbnail;
}

private static EntitySlim BuildContentEntity(BaseDto dto)
private MediaEntitySlim BuildMediaEntity(BaseDto dto)
{
// EntitySlim does not track changes
var entity = new ContentEntitySlim();
var entity = new MediaEntitySlim();
BuildContentEntity(entity, dto);

if (dto is MediaEntityDto contentDto)
{
// fill in the media info
entity.MediaPath = contentDto.MediaPath;
}

return entity;
}

Expand Down
Loading