Adding two missing properties to ContentTypeBase.
Creating mappers for the few types that supports "db queries" through the repository U4-978
This commit is contained in:
@@ -82,6 +82,43 @@ namespace Umbraco.Core
|
||||
});
|
||||
}
|
||||
|
||||
public static MemberInfo FindProperty(LambdaExpression lambdaExpression)
|
||||
{
|
||||
Expression expressionToCheck = lambdaExpression;
|
||||
|
||||
bool done = false;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
switch (expressionToCheck.NodeType)
|
||||
{
|
||||
case ExpressionType.Convert:
|
||||
expressionToCheck = ((UnaryExpression)expressionToCheck).Operand;
|
||||
break;
|
||||
case ExpressionType.Lambda:
|
||||
expressionToCheck = ((LambdaExpression)expressionToCheck).Body;
|
||||
break;
|
||||
case ExpressionType.MemberAccess:
|
||||
var memberExpression = ((MemberExpression)expressionToCheck);
|
||||
|
||||
if (memberExpression.Expression.NodeType != ExpressionType.Parameter &&
|
||||
memberExpression.Expression.NodeType != ExpressionType.Convert)
|
||||
{
|
||||
throw new ArgumentException(string.Format("Expression '{0}' must resolve to top-level member and not any child object's properties. Use a custom resolver on the child type or the AfterMap option instead.", lambdaExpression), "lambdaExpression");
|
||||
}
|
||||
|
||||
MemberInfo member = memberExpression.Member;
|
||||
|
||||
return member;
|
||||
default:
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("Configuration for members is only supported for top-level individual members on a type.");
|
||||
}
|
||||
|
||||
public static IDictionary<string, object> GetMethodParams<T1, T2>(Expression<Func<T1, T2>> fromExpression)
|
||||
{
|
||||
if (fromExpression == null) return null;
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace Umbraco.Core.Models
|
||||
private string _icon;
|
||||
private string _thumbnail;
|
||||
private int _userId;
|
||||
private bool _allowedAsRoot;
|
||||
private bool _isContainer;
|
||||
private bool _trashed;
|
||||
private PropertyGroupCollection _propertyGroups;
|
||||
private IEnumerable<ContentTypeSort> _allowedContentTypes;
|
||||
@@ -43,6 +45,8 @@ namespace Umbraco.Core.Models
|
||||
private static readonly PropertyInfo IconSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, string>(x => x.Icon);
|
||||
private static readonly PropertyInfo ThumbnailSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, string>(x => x.Thumbnail);
|
||||
private static readonly PropertyInfo UserIdSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, int>(x => x.UserId);
|
||||
private static readonly PropertyInfo AllowedAsRootSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, bool>(x => x.AllowedAsRoot);
|
||||
private static readonly PropertyInfo IsContainerSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, bool>(x => x.IsContainer);
|
||||
private static readonly PropertyInfo TrashedSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, bool>(x => x.Trashed);
|
||||
private static readonly PropertyInfo AllowedContentTypesSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, IEnumerable<ContentTypeSort>>(x => x.AllowedContentTypes);
|
||||
private static readonly PropertyInfo PropertyGroupCollectionSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, PropertyGroupCollection>(x => x.PropertyGroups);
|
||||
@@ -193,6 +197,37 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets a boolean indicating whether this ContentType is allowed at the root
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public virtual bool AllowedAsRoot
|
||||
{
|
||||
get { return _allowedAsRoot; }
|
||||
set
|
||||
{
|
||||
_allowedAsRoot = value;
|
||||
OnPropertyChanged(AllowedAsRootSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets a boolean indicating whether this ContentType is a Container
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ContentType Containers doesn't show children in the tree, but rather in grid-type view.
|
||||
/// </remarks>
|
||||
[DataMember]
|
||||
public virtual bool IsContainer
|
||||
{
|
||||
get { return _isContainer; }
|
||||
set
|
||||
{
|
||||
_isContainer = value;
|
||||
OnPropertyChanged(IsContainerSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Boolean indicating whether this ContentType is Trashed or not.
|
||||
/// If ContentType is Trashed it will be located in the Recyclebin.
|
||||
|
||||
@@ -59,6 +59,19 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
int UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets a boolean indicating whether this ContentType is allowed at the root
|
||||
/// </summary>
|
||||
bool AllowedAsRoot { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets a boolean indicating whether this ContentType is a Container
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ContentType Containers doesn't show children in the tree, but rather in grid-type view.
|
||||
/// </remarks>
|
||||
bool IsContainer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets a list of integer Ids of the ContentTypes allowed under the ContentType
|
||||
/// </summary>
|
||||
|
||||
@@ -38,6 +38,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
dto.ContentTypeDto.NodeDto.UserId.HasValue
|
||||
? dto.ContentTypeDto.NodeDto.UserId.Value
|
||||
: 0,
|
||||
AllowedAsRoot = dto.ContentTypeDto.AllowAtRoot,
|
||||
IsContainer = dto.ContentTypeDto.IsContainer,
|
||||
Trashed = dto.ContentTypeDto.NodeDto.Trashed
|
||||
};
|
||||
return contentType;
|
||||
@@ -62,6 +64,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
Icon = entity.Icon,
|
||||
Thumbnail = entity.Thumbnail,
|
||||
NodeId = entity.Id,
|
||||
AllowAtRoot = entity.AllowedAsRoot,
|
||||
IsContainer = entity.IsContainer,
|
||||
NodeDto = BuildNodeDto(entity)
|
||||
};
|
||||
return contentTypeDto;
|
||||
|
||||
@@ -38,6 +38,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
dto.NodeDto.UserId.HasValue
|
||||
? dto.NodeDto.UserId.Value
|
||||
: 0,
|
||||
AllowedAsRoot = dto.AllowAtRoot,
|
||||
IsContainer = dto.IsContainer,
|
||||
Trashed = dto.NodeDto.Trashed
|
||||
};
|
||||
return contentType;
|
||||
@@ -52,6 +54,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
Icon = entity.Icon,
|
||||
Thumbnail = entity.Thumbnail,
|
||||
NodeId = entity.Id,
|
||||
AllowAtRoot = entity.AllowedAsRoot,
|
||||
IsContainer = entity.IsContainer,
|
||||
NodeDto = BuildNodeDto(entity)
|
||||
};
|
||||
return contentTypeDto;
|
||||
|
||||
38
src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs
Normal file
38
src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
internal abstract class BaseMapper
|
||||
{
|
||||
internal abstract void BuildMap();
|
||||
|
||||
internal abstract string Map(string propertyName);
|
||||
|
||||
internal abstract void CacheMap<TSource, TDestination>(Expression<Func<TSource, object>> sourceMember, Expression<Func<TDestination, object>> destinationMember);
|
||||
|
||||
internal DtoMapModel ResolveMapping<TSource, TDestination>(Expression<Func<TSource, object>> sourceMember, Expression<Func<TDestination, object>> destinationMember)
|
||||
{
|
||||
var source = ExpressionHelper.FindProperty(sourceMember);
|
||||
var destination = ExpressionHelper.FindProperty(destinationMember) as PropertyInfo;
|
||||
|
||||
return new DtoMapModel(typeof(TDestination), destination, source.Name);
|
||||
}
|
||||
|
||||
internal virtual string GetColumnName(Type dtoType, PropertyInfo dtoProperty)
|
||||
{
|
||||
var tableNameAttribute = dtoType.FirstAttribute<TableNameAttribute>();
|
||||
string tableName = tableNameAttribute.Value;
|
||||
|
||||
var columnAttribute = dtoProperty.FirstAttribute<ColumnAttribute>();
|
||||
string columnName = columnAttribute.Name;
|
||||
|
||||
string columnMap = string.Format("{0}.{1}",
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName),
|
||||
SyntaxConfig.SqlSyntaxProvider.GetQuotedColumnName(columnName));
|
||||
return columnMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
67
src/Umbraco.Core/Persistence/Mappers/ContentMapper.cs
Normal file
67
src/Umbraco.Core/Persistence/Mappers/ContentMapper.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="Content"/> to DTO mapper used to translate the properties of the public api
|
||||
/// implementation to that of the database's DTO as sql: [tableName].[columnName].
|
||||
/// </summary>
|
||||
internal sealed class ContentMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
internal static ContentMapper Instance = new ContentMapper();
|
||||
|
||||
private ContentMapper()
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
#region Overrides of BaseMapper
|
||||
|
||||
internal override void BuildMap()
|
||||
{
|
||||
if(PropertyInfoCache.IsEmpty)
|
||||
{
|
||||
CacheMap<Content, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<Content, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<Content, NodeDto>(src => src.Level, dto => dto.Level);
|
||||
CacheMap<Content, NodeDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<Content, NodeDto>(src => src.Path, dto => dto.Path);
|
||||
CacheMap<Content, NodeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<Content, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<Content, NodeDto>(src => src.Trashed, dto => dto.Trashed);
|
||||
CacheMap<Content, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<Content, NodeDto>(src => src.UserId, dto => dto.UserId);
|
||||
//CacheMap<Content, DocumentDto>(src => src.Name, dto => dto.Alias);
|
||||
CacheMap<Content, DocumentDto>(src => src.ExpireDate, dto => dto.ExpiresDate);
|
||||
CacheMap<Content, DocumentDto>(src => src.ReleaseDate, dto => dto.ReleaseDate);
|
||||
CacheMap<Content, DocumentDto>(src => src.Published, dto => dto.Published);
|
||||
CacheMap<Content, DocumentDto>(src => src.UpdateDate, dto => dto.UpdateDate);
|
||||
//CacheMap<Content, DocumentDto>(src => src, dto => dto.Newest);
|
||||
//CacheMap<Content, DocumentDto>(src => src.Template, dto => dto.TemplateId);
|
||||
CacheMap<Content, DocumentDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<Content, DocumentDto>(src => src.Version, dto => dto.VersionId);
|
||||
}
|
||||
}
|
||||
|
||||
internal override string Map(string propertyName)
|
||||
{
|
||||
var dtoTypeProperty = PropertyInfoCache[propertyName];
|
||||
|
||||
return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo);
|
||||
}
|
||||
|
||||
internal override void CacheMap<TSource, TDestination>(Expression<Func<TSource, object>> sourceMember, Expression<Func<TDestination, object>> destinationMember)
|
||||
{
|
||||
var property = base.ResolveMapping(sourceMember, destinationMember);
|
||||
PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
64
src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs
Normal file
64
src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="ContentType"/> to DTO mapper used to translate the properties of the public api
|
||||
/// implementation to that of the database's DTO as sql: [tableName].[columnName].
|
||||
/// </summary>
|
||||
internal sealed class ContentTypeMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
internal static ContentTypeMapper Instance = new ContentTypeMapper();
|
||||
|
||||
private ContentTypeMapper()
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
#region Overrides of BaseMapper
|
||||
|
||||
internal override void BuildMap()
|
||||
{
|
||||
if (PropertyInfoCache.IsEmpty)
|
||||
{
|
||||
CacheMap<ContentType, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<ContentType, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Level, dto => dto.Level);
|
||||
CacheMap<ContentType, NodeDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Path, dto => dto.Path);
|
||||
CacheMap<ContentType, NodeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Trashed, dto => dto.Trashed);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<ContentType, NodeDto>(src => src.UserId, dto => dto.UserId);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.Alias, dto => dto.Alias);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.AllowedAsRoot, dto => dto.AllowAtRoot);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.Description, dto => dto.Description);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.Icon, dto => dto.Icon);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.IsContainer, dto => dto.IsContainer);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.Thumbnail, dto => dto.Thumbnail);
|
||||
}
|
||||
}
|
||||
|
||||
internal override string Map(string propertyName)
|
||||
{
|
||||
var dtoTypeProperty = PropertyInfoCache[propertyName];
|
||||
|
||||
return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo);
|
||||
}
|
||||
|
||||
internal override void CacheMap<TSource, TDestination>(Expression<Func<TSource, object>> sourceMember, Expression<Func<TDestination, object>> destinationMember)
|
||||
{
|
||||
var property = base.ResolveMapping(sourceMember, destinationMember);
|
||||
PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="DataTypeDefinition"/> to DTO mapper used to translate the properties of the public api
|
||||
/// implementation to that of the database's DTO as sql: [tableName].[columnName].
|
||||
/// </summary>
|
||||
internal sealed class DataTypeDefinitionMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
internal static DataTypeDefinitionMapper Instance = new DataTypeDefinitionMapper();
|
||||
|
||||
private DataTypeDefinitionMapper()
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
#region Overrides of BaseMapper
|
||||
|
||||
internal override void BuildMap()
|
||||
{
|
||||
CacheMap<DataTypeDefinition, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<DataTypeDefinition, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<DataTypeDefinition, NodeDto>(src => src.Level, dto => dto.Level);
|
||||
CacheMap<DataTypeDefinition, NodeDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<DataTypeDefinition, NodeDto>(src => src.Path, dto => dto.Path);
|
||||
CacheMap<DataTypeDefinition, NodeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<DataTypeDefinition, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<DataTypeDefinition, NodeDto>(src => src.Trashed, dto => dto.Trashed);
|
||||
CacheMap<DataTypeDefinition, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<DataTypeDefinition, NodeDto>(src => src.UserId, dto => dto.UserId);
|
||||
CacheMap<DataTypeDefinition, DataTypeDto>(src => src.ControlId, dto => dto.ControlId);
|
||||
CacheMap<DataTypeDefinition, DataTypeDto>(src => src.DatabaseType, dto => dto.DbType);
|
||||
|
||||
}
|
||||
|
||||
internal override string Map(string propertyName)
|
||||
{
|
||||
var dtoTypeProperty = PropertyInfoCache[propertyName];
|
||||
|
||||
return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo);
|
||||
}
|
||||
|
||||
internal override void CacheMap<TSource, TDestination>(Expression<Func<TSource, object>> sourceMember, Expression<Func<TDestination, object>> destinationMember)
|
||||
{
|
||||
var property = base.ResolveMapping(sourceMember, destinationMember);
|
||||
PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
52
src/Umbraco.Core/Persistence/Mappers/DictionaryMapper.cs
Normal file
52
src/Umbraco.Core/Persistence/Mappers/DictionaryMapper.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="DictionaryItem"/> to DTO mapper used to translate the properties of the public api
|
||||
/// implementation to that of the database's DTO as sql: [tableName].[columnName].
|
||||
/// </summary>
|
||||
internal sealed class DictionaryMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
internal static DictionaryMapper Instance = new DictionaryMapper();
|
||||
|
||||
private DictionaryMapper()
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
#region Overrides of BaseMapper
|
||||
|
||||
internal override void BuildMap()
|
||||
{
|
||||
CacheMap<DictionaryItem, DictionaryDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<DictionaryItem, DictionaryDto>(src => src.ItemKey, dto => dto.Key);
|
||||
CacheMap<DictionaryItem, DictionaryDto>(src => src.ParentId, dto => dto.Parent);
|
||||
|
||||
CacheMap<DictionaryTranslation, LanguageTextDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<DictionaryTranslation, LanguageTextDto>(src => src.Language.Id, dto => dto.LanguageId);
|
||||
CacheMap<DictionaryTranslation, LanguageTextDto>(src => src.Value, dto => dto.Value);
|
||||
}
|
||||
|
||||
internal override string Map(string propertyName)
|
||||
{
|
||||
var dtoTypeProperty = PropertyInfoCache[propertyName];
|
||||
|
||||
return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo);
|
||||
}
|
||||
|
||||
internal override void CacheMap<TSource, TDestination>(Expression<Func<TSource, object>> sourceMember, Expression<Func<TDestination, object>> destinationMember)
|
||||
{
|
||||
var property = base.ResolveMapping(sourceMember, destinationMember);
|
||||
PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
19
src/Umbraco.Core/Persistence/Mappers/DtoMapModel.cs
Normal file
19
src/Umbraco.Core/Persistence/Mappers/DtoMapModel.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
internal class DtoMapModel
|
||||
{
|
||||
public DtoMapModel(Type type, PropertyInfo propertyInfo, string sourcePropertyName)
|
||||
{
|
||||
Type = type;
|
||||
PropertyInfo = propertyInfo;
|
||||
SourcePropertyName = sourcePropertyName;
|
||||
}
|
||||
|
||||
public string SourcePropertyName { get; set; }
|
||||
public Type Type { get; set; }
|
||||
public PropertyInfo PropertyInfo { get; set; }
|
||||
}
|
||||
}
|
||||
48
src/Umbraco.Core/Persistence/Mappers/LanguageMapper.cs
Normal file
48
src/Umbraco.Core/Persistence/Mappers/LanguageMapper.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="Language"/> to DTO mapper used to translate the properties of the public api
|
||||
/// implementation to that of the database's DTO as sql: [tableName].[columnName].
|
||||
/// </summary>
|
||||
internal sealed class LanguageMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
internal static LanguageMapper Instance = new LanguageMapper();
|
||||
|
||||
private LanguageMapper()
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
#region Overrides of BaseMapper
|
||||
|
||||
internal override void BuildMap()
|
||||
{
|
||||
CacheMap<Language, LanguageDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<Language, LanguageDto>(src => src.IsoCode, dto => dto.IsoCode);
|
||||
CacheMap<Language, LanguageDto>(src => src.CultureName, dto => dto.CultureName);
|
||||
}
|
||||
|
||||
internal override string Map(string propertyName)
|
||||
{
|
||||
var dtoTypeProperty = PropertyInfoCache[propertyName];
|
||||
|
||||
return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo);
|
||||
}
|
||||
|
||||
internal override void CacheMap<TSource, TDestination>(Expression<Func<TSource, object>> sourceMember, Expression<Func<TDestination, object>> destinationMember)
|
||||
{
|
||||
var property = base.ResolveMapping(sourceMember, destinationMember);
|
||||
PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
57
src/Umbraco.Core/Persistence/Mappers/MediaMapper.cs
Normal file
57
src/Umbraco.Core/Persistence/Mappers/MediaMapper.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="Models.Media"/> to DTO mapper used to translate the properties of the public api
|
||||
/// implementation to that of the database's DTO as sql: [tableName].[columnName].
|
||||
/// </summary>
|
||||
internal sealed class MediaMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
internal static MediaMapper Instance = new MediaMapper();
|
||||
|
||||
private MediaMapper()
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
#region Overrides of BaseMapper
|
||||
|
||||
internal override void BuildMap()
|
||||
{
|
||||
if (PropertyInfoCache.IsEmpty)
|
||||
{
|
||||
CacheMap<Models.Media, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.Level, dto => dto.Level);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.Path, dto => dto.Path);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.Trashed, dto => dto.Trashed);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.UserId, dto => dto.UserId);
|
||||
}
|
||||
}
|
||||
|
||||
internal override string Map(string propertyName)
|
||||
{
|
||||
var dtoTypeProperty = PropertyInfoCache[propertyName];
|
||||
|
||||
return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo);
|
||||
}
|
||||
|
||||
internal override void CacheMap<TSource, TDestination>(Expression<Func<TSource, object>> sourceMember, Expression<Func<TDestination, object>> destinationMember)
|
||||
{
|
||||
var property = base.ResolveMapping(sourceMember, destinationMember);
|
||||
PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,9 @@ using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
/// <summary>
|
||||
/// Public api models to DTO mapper used by PetaPoco to map Properties to Columns
|
||||
/// </summary>
|
||||
internal class ModelDtoMapper : IMapper
|
||||
{
|
||||
public void GetTableInfo(Type t, TableInfo ti)
|
||||
@@ -13,61 +16,44 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
if (pi.DeclaringType == typeof(Content) || pi.DeclaringType == typeof(IContent))
|
||||
{
|
||||
switch (pi.Name)
|
||||
{
|
||||
case "Trashed":
|
||||
columnName = "[umbracoNode].[trashed]";
|
||||
return true;
|
||||
case "ParentId":
|
||||
columnName = "[umbracoNode].[parentID]";
|
||||
return true;
|
||||
case "UserId":
|
||||
columnName = "[umbracoNode].[nodeUser]";
|
||||
return true;
|
||||
case "Level":
|
||||
columnName = "[umbracoNode].[level]";
|
||||
return true;
|
||||
case "Path":
|
||||
columnName = "[umbracoNode].[path]";
|
||||
return true;
|
||||
case "SortOrder":
|
||||
columnName = "[umbracoNode].[sortOrder]";
|
||||
return true;
|
||||
case "NodeId":
|
||||
columnName = "[umbracoNode].[id]";
|
||||
return true;
|
||||
case "Published":
|
||||
columnName = "[cmsDocument].[published]";
|
||||
return true;
|
||||
case "Key":
|
||||
columnName = "[umbracoNode].[uniqueID]";
|
||||
return true;
|
||||
case "CreateDate":
|
||||
columnName = "[umbracoNode].[createDate]";
|
||||
return true;
|
||||
case "Name":
|
||||
columnName = "[umbracoNode].[text]";
|
||||
return true;
|
||||
}
|
||||
columnName = ContentMapper.Instance.Map(pi.Name);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pi.DeclaringType == typeof(ContentType) || pi.DeclaringType == typeof(IContentType))
|
||||
if (pi.DeclaringType == typeof(Models.Media) || pi.DeclaringType == typeof(IMedia))
|
||||
{
|
||||
switch (pi.Name)
|
||||
{
|
||||
case "Alias":
|
||||
columnName = "[cmsContentType].[alias]";
|
||||
return true;
|
||||
case "Icon":
|
||||
columnName = "[cmsContentType].[icon]";
|
||||
return true;
|
||||
case "Thumbnail":
|
||||
columnName = "[cmsContentType].[thumbnail]";
|
||||
return true;
|
||||
case "Description":
|
||||
columnName = "[cmsContentType].[description]";
|
||||
return true;
|
||||
}
|
||||
columnName = MediaMapper.Instance.Map(pi.Name);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pi.DeclaringType == typeof(ContentType) || pi.DeclaringType == typeof(IContentType) || pi.DeclaringType == typeof(IMediaType))
|
||||
{
|
||||
columnName = ContentTypeMapper.Instance.Map(pi.Name);
|
||||
}
|
||||
|
||||
if (pi.DeclaringType == typeof(DataTypeDefinition))
|
||||
{
|
||||
columnName = DataTypeDefinitionMapper.Instance.Map(pi.Name);
|
||||
}
|
||||
|
||||
if (pi.DeclaringType == typeof(DictionaryItem))
|
||||
{
|
||||
columnName = DictionaryMapper.Instance.Map(pi.Name);
|
||||
}
|
||||
|
||||
if (pi.DeclaringType == typeof(Language))
|
||||
{
|
||||
columnName = LanguageMapper.Instance.Map(pi.Name);
|
||||
}
|
||||
|
||||
if (pi.DeclaringType == typeof(Relation))
|
||||
{
|
||||
columnName = RelationMapper.Instance.Map(pi.Name);
|
||||
}
|
||||
|
||||
if (pi.DeclaringType == typeof(RelationType))
|
||||
{
|
||||
columnName = RelationTypeMapper.Instance.Map(pi.Name);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
51
src/Umbraco.Core/Persistence/Mappers/RelationMapper.cs
Normal file
51
src/Umbraco.Core/Persistence/Mappers/RelationMapper.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="Relation"/> to DTO mapper used to translate the properties of the public api
|
||||
/// implementation to that of the database's DTO as sql: [tableName].[columnName].
|
||||
/// </summary>
|
||||
internal sealed class RelationMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
internal static RelationMapper Instance = new RelationMapper();
|
||||
|
||||
private RelationMapper()
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
#region Overrides of BaseMapper
|
||||
|
||||
internal override void BuildMap()
|
||||
{
|
||||
CacheMap<Relation, RelationDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<Relation, RelationDto>(src => src.ChildId, dto => dto.ChildId);
|
||||
CacheMap<Relation, RelationDto>(src => src.Comment, dto => dto.Comment);
|
||||
CacheMap<Relation, RelationDto>(src => src.CreateDate, dto => dto.Datetime);
|
||||
CacheMap<Relation, RelationDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<Relation, RelationDto>(src => src.RelationType.Id, dto => dto.RelationType);
|
||||
}
|
||||
|
||||
internal override string Map(string propertyName)
|
||||
{
|
||||
var dtoTypeProperty = PropertyInfoCache[propertyName];
|
||||
|
||||
return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo);
|
||||
}
|
||||
|
||||
internal override void CacheMap<TSource, TDestination>(Expression<Func<TSource, object>> sourceMember, Expression<Func<TDestination, object>> destinationMember)
|
||||
{
|
||||
var property = base.ResolveMapping(sourceMember, destinationMember);
|
||||
PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
51
src/Umbraco.Core/Persistence/Mappers/RelationTypeMapper.cs
Normal file
51
src/Umbraco.Core/Persistence/Mappers/RelationTypeMapper.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="RelationType"/> to DTO mapper used to translate the properties of the public api
|
||||
/// implementation to that of the database's DTO as sql: [tableName].[columnName].
|
||||
/// </summary>
|
||||
internal sealed class RelationTypeMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
internal static RelationTypeMapper Instance = new RelationTypeMapper();
|
||||
|
||||
private RelationTypeMapper()
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
#region Overrides of BaseMapper
|
||||
|
||||
internal override void BuildMap()
|
||||
{
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.Alias, dto => dto.Alias);
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.ChildObjectType, dto => dto.ChildObjectType);
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.IsBidirectional, dto => dto.Dual);
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.Name, dto => dto.Name);
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.ParentObjectType, dto => dto.ParentObjectType);
|
||||
}
|
||||
|
||||
internal override string Map(string propertyName)
|
||||
{
|
||||
var dtoTypeProperty = PropertyInfoCache[propertyName];
|
||||
|
||||
return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo);
|
||||
}
|
||||
|
||||
internal override void CacheMap<TSource, TDestination>(Expression<Func<TSource, object>> sourceMember, Expression<Func<TDestination, object>> destinationMember)
|
||||
{
|
||||
var property = base.ResolveMapping(sourceMember, destinationMember);
|
||||
PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var translator = new SqlTranslator<IContent>(sqlClause, query);
|
||||
var sql = translator.Translate();
|
||||
|
||||
//NOTE: This doesn't allow properties to be part of the query
|
||||
var dtos = Database.Fetch<DocumentDto, ContentVersionDto, ContentDto, NodeDto>(sql);
|
||||
|
||||
foreach (var dto in dtos)
|
||||
|
||||
@@ -10,6 +10,9 @@ using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a repository for doing CRUD operations for <see cref="Language"/>
|
||||
/// </summary>
|
||||
internal class LanguageRepository : PetaPocoRepositoryBase<int, Language>, ILanguageRepository
|
||||
{
|
||||
public LanguageRepository(IUnitOfWork work) : base(work)
|
||||
|
||||
@@ -130,7 +130,17 @@
|
||||
<Compile Include="Persistence\Factories\PropertyGroupFactory.cs" />
|
||||
<Compile Include="Persistence\Factories\RelationFactory.cs" />
|
||||
<Compile Include="Persistence\Factories\RelationTypeFactory.cs" />
|
||||
<Compile Include="Persistence\Mappers\BaseMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\ContentMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\ContentTypeMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\DataTypeDefinitionMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\DictionaryMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\DtoMapModel.cs" />
|
||||
<Compile Include="Persistence\Mappers\LanguageMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\MediaMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\ModelDtoMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\RelationMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\RelationTypeMapper.cs" />
|
||||
<Compile Include="Persistence\Migrations\Initial\BaseDataCreation.cs" />
|
||||
<Compile Include="Persistence\Migrations\Initial\DatabaseCreation.cs" />
|
||||
<Compile Include="Persistence\PetaPocoExtensions.cs" />
|
||||
|
||||
Reference in New Issue
Block a user