diff --git a/src/Umbraco.Core/Cache/NoCacheRepositoryCachePolicy.cs b/src/Umbraco.Core/Cache/NoCacheRepositoryCachePolicy.cs index b1a12ec411..fecab66d84 100644 --- a/src/Umbraco.Core/Cache/NoCacheRepositoryCachePolicy.cs +++ b/src/Umbraco.Core/Cache/NoCacheRepositoryCachePolicy.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Umbraco.Core.Models.Entities; -using Umbraco.Core.Scoping; namespace Umbraco.Core.Cache { @@ -13,11 +12,6 @@ namespace Umbraco.Core.Cache public static NoCacheRepositoryCachePolicy Instance { get; } = new NoCacheRepositoryCachePolicy(); - public IRepositoryCachePolicy Scoped(IAppPolicyCache runtimeCache, IScope scope) - { - throw new NotImplementedException(); - } - public TEntity Get(TId id, Func performGet, Func> performGetAll) { return performGet(id); diff --git a/src/Umbraco.Core/Composing/CompositionExtensions/Repositories.cs b/src/Umbraco.Core/Composing/CompositionExtensions/Repositories.cs index 03f13f96cb..23dc9e67c6 100644 --- a/src/Umbraco.Core/Composing/CompositionExtensions/Repositories.cs +++ b/src/Umbraco.Core/Composing/CompositionExtensions/Repositories.cs @@ -46,6 +46,7 @@ namespace Umbraco.Core.Composing.CompositionExtensions composition.RegisterUnique(); composition.RegisterUnique(); composition.RegisterUnique(); + composition.RegisterUnique(); return composition; } diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseSchemaCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseSchemaCreator.cs index d8283fd112..eab7afe308 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseSchemaCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseSchemaCreator.cs @@ -47,7 +47,7 @@ namespace Umbraco.Core.Migrations.Install typeof (LogDto), typeof (MacroDto), typeof (MacroPropertyDto), - typeof (MemberTypeDto), + typeof (MemberPropertyTypeDto), typeof (MemberDto), typeof (Member2MemberGroupDto), typeof (PropertyTypeGroupDto), diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/AddIsSensitiveMemberTypeColumn.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/AddIsSensitiveMemberTypeColumn.cs index 4e1a7d1470..2b5f481769 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/AddIsSensitiveMemberTypeColumn.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/AddIsSensitiveMemberTypeColumn.cs @@ -13,8 +13,8 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0 { var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray(); - if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.MemberType) && x.ColumnName.InvariantEquals("isSensitive")) == false) - AddColumn("isSensitive"); + if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.MemberPropertyType) && x.ColumnName.InvariantEquals("isSensitive")) == false) + AddColumn("isSensitive"); } } } diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs index ed8a098299..d4e35cccdf 100644 --- a/src/Umbraco.Core/Models/ContentTypeBase.cs +++ b/src/Umbraco.Core/Models/ContentTypeBase.cs @@ -210,9 +210,7 @@ namespace Umbraco.Core.Models return Variations.ValidateVariation(culture, segment, false, true, false); } - /// - /// List of PropertyGroups available on this ContentType - /// + /// /// /// A PropertyGroup corresponds to a Tab in the UI /// Marked DoNotClone because we will manually deal with cloning and the event handlers @@ -230,9 +228,7 @@ namespace Umbraco.Core.Models } } - /// - /// Gets all property types, across all property groups. - /// + /// [IgnoreDataMember] [DoNotClone] public IEnumerable PropertyTypes @@ -243,12 +239,7 @@ namespace Umbraco.Core.Models } } - /// - /// Gets or sets the property types that are not in a group. - /// - /// - /// Marked DoNotClone because we will manually deal with cloning and the event handlers - /// + /// [DoNotClone] public IEnumerable NoGroupPropertyTypes { diff --git a/src/Umbraco.Core/Models/ContentTypeCompositionBase.cs b/src/Umbraco.Core/Models/ContentTypeCompositionBase.cs index 7497c100bc..ff61a15979 100644 --- a/src/Umbraco.Core/Models/ContentTypeCompositionBase.cs +++ b/src/Umbraco.Core/Models/ContentTypeCompositionBase.cs @@ -43,9 +43,7 @@ namespace Umbraco.Core.Models } } - /// - /// Gets the property groups for the entire composition. - /// + /// [IgnoreDataMember] public IEnumerable CompositionPropertyGroups { @@ -76,9 +74,7 @@ namespace Umbraco.Core.Models } } - /// - /// Gets the property types for the entire composition. - /// + /// [IgnoreDataMember] public IEnumerable CompositionPropertyTypes { diff --git a/src/Umbraco.Core/Models/IContentTypeBase.cs b/src/Umbraco.Core/Models/IContentTypeBase.cs index 215c8532c1..5f1fe6ed49 100644 --- a/src/Umbraco.Core/Models/IContentTypeBase.cs +++ b/src/Umbraco.Core/Models/IContentTypeBase.cs @@ -96,17 +96,17 @@ namespace Umbraco.Core.Models IEnumerable AllowedContentTypes { get; set; } /// - /// Gets or Sets a collection of Property Groups + /// Gets or sets the local property groups. /// PropertyGroupCollection PropertyGroups { get; set; } /// - /// Gets all property types, across all property groups. + /// Gets all local property types belonging to a group, across all local property groups. /// IEnumerable PropertyTypes { get; } /// - /// Gets or sets the property types that are not in a group. + /// Gets or sets the local property types that do not belong to a group. /// IEnumerable NoGroupPropertyTypes { get; set; } diff --git a/src/Umbraco.Core/Persistence/Constants-DatabaseSchema.cs b/src/Umbraco.Core/Persistence/Constants-DatabaseSchema.cs index b62a99ce83..742d7cfdc5 100644 --- a/src/Umbraco.Core/Persistence/Constants-DatabaseSchema.cs +++ b/src/Umbraco.Core/Persistence/Constants-DatabaseSchema.cs @@ -57,7 +57,7 @@ namespace Umbraco.Core public const string MacroProperty = /*TableNamePrefix*/ "cms" + "MacroProperty"; public const string Member = /*TableNamePrefix*/ "cms" + "Member"; - public const string MemberType = /*TableNamePrefix*/ "cms" + "MemberType"; + public const string MemberPropertyType = /*TableNamePrefix*/ "cms" + "MemberType"; public const string Member2MemberGroup = /*TableNamePrefix*/ "cms" + "Member2MemberGroup"; public const string Access = TableNamePrefix + "Access"; diff --git a/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs b/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs index 4f3a67aa91..e7a14a26e2 100644 --- a/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs @@ -54,6 +54,7 @@ namespace Umbraco.Core.Persistence.Dtos public byte Variations { get; set; } [ResultColumn] + [Reference(ReferenceType.OneToOne, ColumnName = "NodeId")] public NodeDto NodeDto { get; set; } } } diff --git a/src/Umbraco.Core/Persistence/Dtos/DataTypeDto.cs b/src/Umbraco.Core/Persistence/Dtos/DataTypeDto.cs index d270c7b732..24f0e07295 100644 --- a/src/Umbraco.Core/Persistence/Dtos/DataTypeDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/DataTypeDto.cs @@ -26,7 +26,7 @@ namespace Umbraco.Core.Persistence.Dtos public string Configuration { get; set; } [ResultColumn] - [Reference(ReferenceType.OneToOne, ColumnName = "DataTypeId")] + [Reference(ReferenceType.OneToOne, ColumnName = "NodeId")] public NodeDto NodeDto { get; set; } } } diff --git a/src/Umbraco.Core/Persistence/Dtos/MemberTypeDto.cs b/src/Umbraco.Core/Persistence/Dtos/MemberPropertyTypeDto.cs similarity index 88% rename from src/Umbraco.Core/Persistence/Dtos/MemberTypeDto.cs rename to src/Umbraco.Core/Persistence/Dtos/MemberPropertyTypeDto.cs index 545f92bb82..7186455489 100644 --- a/src/Umbraco.Core/Persistence/Dtos/MemberTypeDto.cs +++ b/src/Umbraco.Core/Persistence/Dtos/MemberPropertyTypeDto.cs @@ -3,10 +3,10 @@ using Umbraco.Core.Persistence.DatabaseAnnotations; namespace Umbraco.Core.Persistence.Dtos { - [TableName(Constants.DatabaseSchema.Tables.MemberType)] + [TableName(Constants.DatabaseSchema.Tables.MemberPropertyType)] [PrimaryKey("pk")] [ExplicitColumns] - internal class MemberTypeDto + internal class MemberPropertyTypeDto { [Column("pk")] [PrimaryKeyColumn] diff --git a/src/Umbraco.Core/Persistence/Dtos/MemberTypeReadOnlyDto.cs b/src/Umbraco.Core/Persistence/Dtos/MemberTypeReadOnlyDto.cs deleted file mode 100644 index c4ea6a10fd..0000000000 --- a/src/Umbraco.Core/Persistence/Dtos/MemberTypeReadOnlyDto.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections.Generic; -using NPoco; - -namespace Umbraco.Core.Persistence.Dtos -{ - [TableName(Constants.DatabaseSchema.Tables.Node)] - [PrimaryKey("id")] - [ExplicitColumns] - internal class MemberTypeReadOnlyDto - { - /* from umbracoNode */ - [Column("id")] - public int NodeId { get; set; } - - [Column("trashed")] - public bool Trashed { get; set; } - - [Column("parentID")] - public int ParentId { get; set; } - - [Column("nodeUser")] - public int? UserId { get; set; } - - [Column("level")] - public short Level { get; set; } - - [Column("path")] - public string Path { get; set; } - - [Column("sortOrder")] - public int SortOrder { get; set; } - - [Column("uniqueID")] - public Guid? UniqueId { get; set; } - - [Column("text")] - public string Text { get; set; } - - [Column("nodeObjectType")] - public Guid? NodeObjectType { get; set; } - - [Column("createDate")] - public DateTime CreateDate { get; set; } - - /* cmsContentType */ - [Column("pk")] - public int PrimaryKey { get; set; } - - [Column("alias")] - public string Alias { get; set; } - - [Column("icon")] - public string Icon { get; set; } - - [Column("thumbnail")] - public string Thumbnail { get; set; } - - [Column("description")] - public string Description { get; set; } - - [Column("isContainer")] - public bool IsContainer { get; set; } - - [Column("allowAtRoot")] - public bool AllowAtRoot { get; set; } - - /* PropertyTypes */ - // TODO: Add PropertyTypeDto (+MemberTypeDto and DataTypeDto as one) ReadOnly list - [ResultColumn] - [Reference(ReferenceType.Many, ReferenceMemberName = "ContentTypeId")] - public List PropertyTypes { get; set; } - - /* PropertyTypeGroups */ - // TODO: Add PropertyTypeGroupDto ReadOnly list - [ResultColumn] - [Reference(ReferenceType.Many, ReferenceMemberName = "ContentTypeNodeId")] - public List PropertyTypeGroups { get; set; } - } -} diff --git a/src/Umbraco.Core/Persistence/Dtos/PropertyTypeCommonDto.cs b/src/Umbraco.Core/Persistence/Dtos/PropertyTypeCommonDto.cs new file mode 100644 index 0000000000..040123353e --- /dev/null +++ b/src/Umbraco.Core/Persistence/Dtos/PropertyTypeCommonDto.cs @@ -0,0 +1,18 @@ +using NPoco; + +namespace Umbraco.Core.Persistence.Dtos +{ + // this is PropertyTypeDto + the special property type fields for members + // it is used for querying everything needed for a property type, at once + internal class PropertyTypeCommonDto : PropertyTypeDto + { + [Column("memberCanEdit")] + public bool CanEdit { get; set; } + + [Column("viewOnProfile")] + public bool ViewOnProfile { get; set; } + + [Column("isSensitive")] + public bool IsSensitive { get; set; } + } +} diff --git a/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs b/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs index 7a04a6d0d9..54cfee0ffa 100644 --- a/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs @@ -67,16 +67,28 @@ namespace Umbraco.Core.Persistence.Factories public static IMemberType BuildMemberTypeEntity(ContentTypeDto dto) { - throw new NotImplementedException(); + var contentType = new MemberType(dto.NodeDto.ParentId); + try + { + contentType.DisableChangeTracking(); + BuildCommonEntity(contentType, dto, false); + contentType.ResetDirtyProperties(false); + } + finally + { + contentType.EnableChangeTracking(); + } + + return contentType; } - public static IEnumerable BuildMemberTypeDtos(IMemberType entity) + public static IEnumerable BuildMemberPropertyTypeDtos(IMemberType entity) { var memberType = entity as MemberType; if (memberType == null || memberType.PropertyTypes.Any() == false) - return Enumerable.Empty(); + return Enumerable.Empty(); - var dtos = memberType.PropertyTypes.Select(x => new MemberTypeDto + var dtos = memberType.PropertyTypes.Select(x => new MemberPropertyTypeDto { NodeId = entity.Id, PropertyTypeId = x.Id, @@ -91,7 +103,7 @@ namespace Umbraco.Core.Persistence.Factories #region Common - private static void BuildCommonEntity(ContentTypeBase entity, ContentTypeDto dto) + private static void BuildCommonEntity(ContentTypeBase entity, ContentTypeDto dto, bool setVariations = true) { entity.Id = dto.NodeDto.NodeId; entity.Key = dto.NodeDto.UniqueId; @@ -102,6 +114,7 @@ namespace Umbraco.Core.Persistence.Factories entity.SortOrder = dto.NodeDto.SortOrder; entity.Description = dto.Description; entity.CreateDate = dto.NodeDto.CreateDate; + entity.UpdateDate = dto.NodeDto.CreateDate; entity.Path = dto.NodeDto.Path; entity.Level = dto.NodeDto.Level; entity.CreatorId = dto.NodeDto.UserId ?? Constants.Security.UnknownUserId; @@ -109,7 +122,9 @@ namespace Umbraco.Core.Persistence.Factories entity.IsContainer = dto.IsContainer; entity.IsElement = dto.IsElement; entity.Trashed = dto.NodeDto.Trashed; - entity.Variations = (ContentVariation) dto.Variations; + + if (setVariations) + entity.Variations = (ContentVariation) dto.Variations; } public static ContentTypeDto BuildContentTypeDto(IContentTypeBase entity) diff --git a/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs b/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs deleted file mode 100644 index c7ce98a89c..0000000000 --- a/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs +++ /dev/null @@ -1,194 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Umbraco.Core.Models; -using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.Persistence.Repositories.Implement; - -namespace Umbraco.Core.Persistence.Factories -{ - internal static class MemberTypeReadOnlyFactory - { - public static IMemberType BuildEntity(MemberTypeReadOnlyDto dto, out bool needsSaving) - { - var standardPropertyTypes = Constants.Conventions.Member.GetStandardPropertyTypeStubs(); - needsSaving = false; - - var memberType = new MemberType(dto.ParentId); - - try - { - memberType.DisableChangeTracking(); - - memberType.Alias = dto.Alias; - memberType.AllowedAsRoot = dto.AllowAtRoot; - memberType.CreateDate = dto.CreateDate; - memberType.CreatorId = dto.UserId.HasValue ? dto.UserId.Value : 0; - memberType.Description = dto.Description; - memberType.Icon = dto.Icon; - memberType.Id = dto.NodeId; - memberType.IsContainer = dto.IsContainer; - memberType.Key = dto.UniqueId.Value; - memberType.Level = dto.Level; - memberType.Name = dto.Text; - memberType.Path = dto.Path; - memberType.SortOrder = dto.SortOrder; - memberType.Thumbnail = dto.Thumbnail; - memberType.Trashed = dto.Trashed; - memberType.UpdateDate = dto.CreateDate; - memberType.AllowedContentTypes = Enumerable.Empty(); - - var propertyTypeGroupCollection = GetPropertyTypeGroupCollection(dto, memberType, standardPropertyTypes); - memberType.PropertyGroups = propertyTypeGroupCollection; - - var propertyTypes = GetPropertyTypes(dto, memberType, standardPropertyTypes); - - //By Convention we add 9 standard PropertyTypes - This is only here to support loading of types that didn't have these conventions before. - foreach (var standardPropertyType in standardPropertyTypes) - { - if (dto.PropertyTypes.Any(x => x.Alias.Equals(standardPropertyType.Key))) continue; - - // beware! - // means that we can return a memberType "from database" that has some property types - // that do *not* come from the database and therefore are incomplete eg have no key, - // no id, no dataTypeDefinitionId - ouch! - better notify caller of the situation - needsSaving = true; - - //Add the standard PropertyType to the current list - propertyTypes.Add(standardPropertyType.Value); - - //Internal dictionary for adding "MemberCanEdit", "VisibleOnProfile", "IsSensitive" properties to each PropertyType - memberType.MemberTypePropertyTypes.Add(standardPropertyType.Key, - new MemberTypePropertyProfileAccess(false, false, false)); - } - memberType.NoGroupPropertyTypes = propertyTypes; - - return memberType; - } - finally - { - memberType.EnableChangeTracking(); - } - } - - private static PropertyGroupCollection GetPropertyTypeGroupCollection(MemberTypeReadOnlyDto dto, MemberType memberType, Dictionary standardProps) - { - // see PropertyGroupFactory, repeating code here... - - var propertyGroups = new PropertyGroupCollection(); - foreach (var groupDto in dto.PropertyTypeGroups.Where(x => x.Id.HasValue)) - { - var group = new PropertyGroup(MemberType.SupportsPublishingConst); - - // if the group is defined on the current member type, - // assign its identifier, else it will be zero - if (groupDto.ContentTypeNodeId == memberType.Id) - { - // note: no idea why Id is nullable here, but better check - if (groupDto.Id.HasValue == false) - throw new Exception("GroupDto.Id has no value."); - group.Id = groupDto.Id.Value; - } - - group.Key = groupDto.UniqueId; - group.Name = groupDto.Text; - group.SortOrder = groupDto.SortOrder; - group.PropertyTypes = new PropertyTypeCollection(MemberType.SupportsPublishingConst); - - //Because we are likely to have a group with no PropertyTypes we need to ensure that these are excluded - var localGroupDto = groupDto; - var typeDtos = dto.PropertyTypes.Where(x => x.Id.HasValue && x.Id > 0 && x.PropertyTypeGroupId.HasValue && x.PropertyTypeGroupId.Value == localGroupDto.Id.Value); - foreach (var typeDto in typeDtos) - { - //Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType - memberType.MemberTypePropertyTypes.Add(typeDto.Alias, - new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit, typeDto.IsSensitive)); - - var tempGroupDto = groupDto; - - //ensures that any built-in membership properties have their correct dbtype assigned no matter - //what the underlying data type is - var propDbType = MemberTypeRepository.GetDbTypeForBuiltInProperty( - typeDto.Alias, - typeDto.DbType.EnumParse(true), - standardProps); - - var propertyType = new PropertyType( - typeDto.PropertyEditorAlias, - propDbType.Result, - //This flag tells the property type that it has an explicit dbtype and that it cannot be changed - // which is what we want for the built-in properties. - propDbType.Success, - typeDto.Alias) - { - DataTypeId = typeDto.DataTypeId, - Description = typeDto.Description, - Id = typeDto.Id.Value, - Name = typeDto.Name, - Mandatory = typeDto.Mandatory, - SortOrder = typeDto.SortOrder, - ValidationRegExp = typeDto.ValidationRegExp, - PropertyGroupId = new Lazy(() => tempGroupDto.Id.Value), - CreateDate = memberType.CreateDate, - UpdateDate = memberType.UpdateDate, - Key = typeDto.UniqueId - }; - - // reset dirty initial properties (U4-1946) - propertyType.ResetDirtyProperties(false); - group.PropertyTypes.Add(propertyType); - } - - // reset dirty initial properties (U4-1946) - group.ResetDirtyProperties(false); - propertyGroups.Add(group); - } - - return propertyGroups; - } - - private static List GetPropertyTypes(MemberTypeReadOnlyDto dto, MemberType memberType, Dictionary standardProps) - { - //Find PropertyTypes that does not belong to a PropertyTypeGroup - var propertyTypes = new List(); - foreach (var typeDto in dto.PropertyTypes.Where(x => (x.PropertyTypeGroupId.HasValue == false || x.PropertyTypeGroupId.Value == 0) && x.Id.HasValue)) - { - //Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType - memberType.MemberTypePropertyTypes.Add(typeDto.Alias, - new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit, typeDto.IsSensitive)); - - //ensures that any built-in membership properties have their correct dbtype assigned no matter - //what the underlying data type is - var propDbType = MemberTypeRepository.GetDbTypeForBuiltInProperty( - typeDto.Alias, - typeDto.DbType.EnumParse(true), - standardProps); - - var propertyType = new PropertyType( - typeDto.PropertyEditorAlias, - propDbType.Result, - //This flag tells the property type that it has an explicit dbtype and that it cannot be changed - // which is what we want for the built-in properties. - propDbType.Success, - typeDto.Alias) - { - DataTypeId = typeDto.DataTypeId, - Description = typeDto.Description, - Id = typeDto.Id.Value, - Mandatory = typeDto.Mandatory, - Name = typeDto.Name, - SortOrder = typeDto.SortOrder, - ValidationRegExp = typeDto.ValidationRegExp, - PropertyGroupId = null, - CreateDate = dto.CreateDate, - UpdateDate = dto.CreateDate, - Key = typeDto.UniqueId - }; - - propertyTypes.Add(propertyType); - } - return propertyTypes; - } - - } -} diff --git a/src/Umbraco.Core/Persistence/Repositories/IContentTypeCommonRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IContentTypeCommonRepository.cs new file mode 100644 index 0000000000..e7657ac941 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Repositories/IContentTypeCommonRepository.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using Umbraco.Core.Models; + +namespace Umbraco.Core.Persistence.Repositories +{ + // TODO + // this should be IContentTypeRepository, and what is IContentTypeRepository at the moment should + // become IDocumentTypeRepository - but since these interfaces are public, that would be breaking + + /// + /// Represents the content types common repository, dealing with document, media and member types. + /// + public interface IContentTypeCommonRepository + { + /// + /// Gets and cache all types. + /// + IEnumerable GetAllTypes(); + + /// + /// Clears the cache. + /// + void ClearCache(); + } +} diff --git a/src/Umbraco.Core/Persistence/Repositories/IMediaTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IMediaTypeRepository.cs index 09059089e7..fbaff4f510 100644 --- a/src/Umbraco.Core/Persistence/Repositories/IMediaTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/IMediaTypeRepository.cs @@ -1,16 +1,8 @@ using System.Collections.Generic; using Umbraco.Core.Models; -using Umbraco.Core.Persistence.Querying; namespace Umbraco.Core.Persistence.Repositories { public interface IMediaTypeRepository : IContentTypeRepositoryBase - { - /// - /// Gets all entities of the specified query - /// - /// - /// An enumerable list of objects - IEnumerable GetByQuery(IQuery query); - } + { } } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeCommonRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeCommonRepository.cs new file mode 100644 index 0000000000..56bc5dedc4 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeCommonRepository.cs @@ -0,0 +1,291 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NPoco; +using Umbraco.Core.Models; +using Umbraco.Core.Persistence.Dtos; +using Umbraco.Core.Persistence.Factories; +using Umbraco.Core.Persistence.Querying; +using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Core.Scoping; + +namespace Umbraco.Core.Persistence.Repositories.Implement +{ + /// + /// Implements . + /// + internal class ContentTypeCommonRepository : IContentTypeCommonRepository + { + private readonly IScopeAccessor _scopeAccessor; + private readonly ITemplateRepository _templateRepository; + + /// + /// Initializes a new instance of the class. + /// + public ContentTypeCommonRepository(IScopeAccessor scopeAccessor, ITemplateRepository templateRepository) + { + _scopeAccessor = scopeAccessor; + _templateRepository = templateRepository; + } + + private IScope AmbientScope => _scopeAccessor.AmbientScope; + private IUmbracoDatabase Database => AmbientScope.Database; + private ISqlContext SqlContext => AmbientScope.SqlContext; + private Sql Sql() => SqlContext.Sql(); + private Sql Sql(string sql, params object[] args) => SqlContext.Sql(sql, args); + private ISqlSyntaxProvider SqlSyntax => SqlContext.SqlSyntax; + private IQuery Query() => SqlContext.Query(); + + // a full dataset repository cache policy is equivalent to statically caching everything + private IEnumerable _allTypes; + private readonly object _allTypesLock = new object(); + + /// + public IEnumerable GetAllTypes() + { + lock (_allTypesLock) + { + return _allTypes ?? (_allTypes = GetAllTypesInternal()); + } + } + + /// + public void ClearCache() + { + lock (_allTypesLock) + { + _allTypes = null; + } + } + + private IEnumerable GetAllTypesInternal() + { + var contentTypes = new Dictionary(); + + // get content types + var sql1 = Sql() + .Select(r => r.Select(x => x.NodeDto)) + .From() + .InnerJoin().On((ct, n) => ct.NodeId == n.NodeId) + .OrderBy(x => x.NodeId); + + var contentTypeDtos = Database.Fetch(sql1); + + // get allowed content types + var sql2 = Sql() + .Select() + .From() + .OrderBy(x => x.Id); + + var allowedDtos = Database.Fetch(sql2); + + // prepare + // note: same alias could be used for media, content... but always different ids = ok + var aliases = contentTypeDtos.ToDictionary(x => x.NodeId, x => x.Alias); + + // create + var allowedDtoIx = 0; + foreach (var contentTypeDto in contentTypeDtos) + { + // create content type + IContentTypeComposition contentType; + if (contentTypeDto.NodeDto.NodeObjectType == Constants.ObjectTypes.MediaType) + contentType = ContentTypeFactory.BuildMediaTypeEntity(contentTypeDto); + else if (contentTypeDto.NodeDto.NodeObjectType == Constants.ObjectTypes.DocumentType) + contentType = ContentTypeFactory.BuildContentTypeEntity(contentTypeDto); + else if (contentTypeDto.NodeDto.NodeObjectType == Constants.ObjectTypes.MemberType) + contentType = ContentTypeFactory.BuildMemberTypeEntity(contentTypeDto); + else throw new Exception("panic"); + contentTypes.Add(contentType.Id, contentType); + + // map allowed content types + var allowedContentTypes = new List(); + while (allowedDtoIx < allowedDtos.Count && allowedDtos[allowedDtoIx].Id == contentTypeDto.NodeId) + { + var allowedDto = allowedDtos[allowedDtoIx]; + if (!aliases.TryGetValue(allowedDto.AllowedId, out var alias)) continue; + allowedContentTypes.Add(new ContentTypeSort(new Lazy(() => allowedDto.AllowedId), allowedDto.SortOrder, alias)); + allowedDtoIx++; + } + contentType.AllowedContentTypes = allowedContentTypes; + } + + MapTemplates(contentTypes); + MapComposition(contentTypes); + MapGroupsAndProperties(contentTypes); + + // finalize + foreach (var contentType in contentTypes.Values) + { + contentType.ResetDirtyProperties(false); + } + + return contentTypes.Values; + } + + private void MapTemplates(Dictionary contentTypes) + { + // get templates + var sql1 = Sql() + .Select() + .From() + .OrderBy(x => x.ContentTypeNodeId); + + var templateDtos = Database.Fetch(sql1); + //var templates = templateRepository.GetMany(templateDtos.Select(x => x.TemplateNodeId).ToArray()).ToDictionary(x => x.Id, x => x); + var templates = _templateRepository.GetMany().ToDictionary(x => x.Id, x => x); + var templateDtoIx = 0; + + foreach (var c in contentTypes.Values) + { + if (!(c is ContentType contentType)) continue; + + // map allowed templates + var allowedTemplates = new List(); + var defaultTemplateId = 0; + while (templateDtoIx < templateDtos.Count && templateDtos[templateDtoIx].ContentTypeNodeId == contentType.Id) + { + var allowedDto = templateDtos[templateDtoIx]; + if (!templates.TryGetValue(allowedDto.TemplateNodeId, out var template)) continue; + allowedTemplates.Add(template); + templateDtoIx++; + + if (allowedDto.IsDefault) + defaultTemplateId = template.Id; + } + contentType.AllowedTemplates = allowedTemplates; + contentType.DefaultTemplateId = defaultTemplateId; + } + } + + private void MapComposition(IDictionary contentTypes) + { + // get parent/child + var sql1 = Sql() + .Select() + .From() + .OrderBy(x => x.ChildId); + + var compositionDtos = Database.Fetch(sql1); + + // map + var compositionIx = 0; + foreach (var contentType in contentTypes.Values) + { + while (compositionIx < compositionDtos.Count && compositionDtos[compositionIx].ChildId == contentType.Id) + { + var parentDto = compositionDtos[compositionIx]; + if (!contentTypes.TryGetValue(parentDto.ParentId, out var parentContentType)) continue; + contentType.AddContentType(parentContentType); + compositionIx++; + } + } + } + + private void MapGroupsAndProperties(IDictionary contentTypes) + { + var sql1 = Sql() + .Select() + .From() + .InnerJoin().On((ptg, ct) => ptg.ContentTypeNodeId == ct.NodeId) + .OrderBy(x => x.NodeId) + .AndBy(x => x.SortOrder, x => x.Id); + + var groupDtos = Database.Fetch(sql1); + + var sql2 = Sql() + .Select(r => r.Select(x => x.DataTypeDto)) + .AndSelect() + .From() + .InnerJoin().On((pt, dt) => pt.DataTypeId == dt.NodeId) + .InnerJoin().On((pt, ct) => pt.ContentTypeId == ct.NodeId) + .LeftJoin().On((pt, ptg) => pt.PropertyTypeGroupId == ptg.Id) + .LeftJoin().On((pt, mpt) => pt.Id == mpt.PropertyTypeId) + .OrderBy(x => x.NodeId) + .AndBy(x => x.SortOrder, x => x.Id) // NULLs will come first or last, never mind, we deal with it below + .AndBy(x => x.SortOrder, x => x.Id); + + var propertyDtos = Database.Fetch(sql2); + var builtinProperties = Constants.Conventions.Member.GetStandardPropertyTypeStubs(); + + var groupIx = 0; + var propertyIx = 0; + foreach (var contentType in contentTypes.Values) + { + // only IContentType is publishing + var isPublishing = contentType is IContentType; + + // get group-less properties (in case NULL is ordered first) + var noGroupPropertyTypes = new PropertyTypeCollection(isPublishing); + while (propertyIx < propertyDtos.Count && propertyDtos[propertyIx].ContentTypeId == contentType.Id && propertyDtos[propertyIx].PropertyTypeGroupId == null) + { + noGroupPropertyTypes.Add(MapPropertyType(contentType, propertyDtos[propertyIx], builtinProperties)); + propertyIx++; + } + + // get groups and their properties + var groupCollection = new PropertyGroupCollection(); + while (groupIx < groupDtos.Count && groupDtos[groupIx].ContentTypeNodeId == contentType.Id) + { + var group = MapPropertyGroup(groupDtos[groupIx], isPublishing); + groupCollection.Add(group); + groupIx++; + + while (propertyIx < propertyDtos.Count && propertyDtos[propertyIx].ContentTypeId == contentType.Id && propertyDtos[propertyIx].PropertyTypeGroupId == group.Id) + { + group.PropertyTypes.Add(MapPropertyType(contentType, propertyDtos[propertyIx], builtinProperties)); + propertyIx++; + } + } + contentType.PropertyGroups = groupCollection; + + // get group-less properties (in case NULL is ordered last) + while (propertyIx < propertyDtos.Count && propertyDtos[propertyIx].ContentTypeId == contentType.Id && propertyDtos[propertyIx].PropertyTypeGroupId == null) + { + noGroupPropertyTypes.Add(MapPropertyType(contentType, propertyDtos[propertyIx], builtinProperties)); + propertyIx++; + } + contentType.NoGroupPropertyTypes = noGroupPropertyTypes; + } + } + + private PropertyGroup MapPropertyGroup(PropertyTypeGroupDto dto, bool isPublishing) + { + return new PropertyGroup(new PropertyTypeCollection(isPublishing)) + { + Id = dto.Id, + Name = dto.Text, + SortOrder = dto.SortOrder, + Key = dto.UniqueId + }; + } + + private PropertyType MapPropertyType(IContentTypeComposition contentType, PropertyTypeCommonDto dto, IDictionary builtinProperties) + { + var groupId = dto.PropertyTypeGroupId; + + var readonlyStorageType = builtinProperties.TryGetValue(dto.Alias, out var propertyType); + var storageType = readonlyStorageType ? propertyType.ValueStorageType : Enum.Parse(dto.DataTypeDto.DbType); + + if (contentType is MemberType memberType) + { + var access = new MemberTypePropertyProfileAccess(dto.ViewOnProfile, dto.CanEdit, dto.IsSensitive); + memberType.MemberTypePropertyTypes.Add(dto.Alias, access); + } + + return new PropertyType(dto.DataTypeDto.EditorAlias, storageType, readonlyStorageType, dto.Alias) + { + Description = dto.Description, + DataTypeId = dto.DataTypeId, + Id = dto.Id, + Key = dto.UniqueId, + Mandatory = dto.Mandatory, + Name = dto.Name, + PropertyGroupId = groupId.HasValue ? new Lazy(() => groupId.Value) : null, + SortOrder = dto.SortOrder, + ValidationRegExp = dto.ValidationRegExp, + Variations = (ContentVariation)dto.Variations + }; + } + } +} diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepository.cs index 095c77eb42..98ddcdcb17 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepository.cs @@ -17,13 +17,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement /// internal class ContentTypeRepository : ContentTypeRepositoryBase, IContentTypeRepository { - private readonly ITemplateRepository _templateRepository; - - public ContentTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, ITemplateRepository templateRepository) - : base(scopeAccessor, cache, logger) - { - _templateRepository = templateRepository; - } + public ContentTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository) + : base(scopeAccessor, cache, logger, commonRepository) + { } protected override bool SupportsPublishing => ContentType.SupportsPublishingConst; @@ -32,75 +28,81 @@ namespace Umbraco.Core.Persistence.Repositories.Implement return new FullDataSetRepositoryCachePolicy(GlobalIsolatedCache, ScopeAccessor, GetEntityId, /*expires:*/ true); } + // every GetExists method goes cachePolicy.GetSomething which in turns goes PerformGetAll, + // since this is a FullDataSet policy - and everything is cached + // so here, + // every PerformGet/Exists just GetMany() and then filters + // except PerformGetAll which is the one really doing the job + + // TODO: the filtering is highly inefficient as we deep-clone everything + // there should be a way to GetMany(predicate) right from the cache policy! + // and ah, well, this all caching should be refactored + the cache refreshers + // should to repository.Clear() not deal with magic caches by themselves + protected override IContentType PerformGet(int id) - { - //use the underlying GetAll which will force cache all content types - return GetMany().FirstOrDefault(x => x.Id == id); - } + => GetMany().FirstOrDefault(x => x.Id == id); protected override IContentType PerformGet(Guid id) - { - //use the underlying GetAll which will force cache all content types - return GetMany().FirstOrDefault(x => x.Key == id); - } + => GetMany().FirstOrDefault(x => x.Key == id); protected override IContentType PerformGet(string alias) - { - //use the underlying GetAll which will force cache all content types - return GetMany().FirstOrDefault(x => x.Alias.InvariantEquals(alias)); - } + => GetMany().FirstOrDefault(x => x.Alias.InvariantEquals(alias)); protected override bool PerformExists(Guid id) - { - return GetMany().FirstOrDefault(x => x.Key == id) != null; - } + => GetMany().FirstOrDefault(x => x.Key == id) != null; protected override IEnumerable PerformGetAll(params int[] ids) { - if (ids.Any()) - { - //NOTE: This logic should never be executed according to our cache policy - return ContentTypeQueryMapper.GetContentTypes(Database, SqlSyntax, SupportsPublishing, this, _templateRepository) - .Where(x => ids.Contains(x.Id)); - } - - return ContentTypeQueryMapper.GetContentTypes(Database, SqlSyntax, SupportsPublishing, this, _templateRepository); + // the cache policy will always want everything + // even GetMany(ids) gets everything and filters afterwards + if (ids.Any()) throw new Exception("panic"); + return CommonRepository.GetAllTypes().OfType(); } protected override IEnumerable PerformGetAll(params Guid[] ids) { - // use the underlying GetAll which will force cache all content types - return ids.Any() ? GetMany().Where(x => ids.Contains(x.Key)) : GetMany(); + var all = GetMany(); + return ids.Any() ? all.Where(x => ids.Contains(x.Key)) : all; } protected override IEnumerable PerformGetByQuery(IQuery query) { - var sqlClause = GetBaseQuery(false); - var translator = new SqlTranslator(sqlClause, query); + var baseQuery = GetBaseQuery(false); + var translator = new SqlTranslator(baseQuery, query); var sql = translator.Translate(); + var ids = Database.Fetch(sql).Distinct().ToArray(); - var dtos = Database.Fetch(sql); - - return - //This returns a lookup from the GetAll cached lookup - (dtos.Any() - ? GetMany(dtos.DistinctBy(x => x.ContentTypeDto.NodeId).Select(x => x.ContentTypeDto.NodeId).ToArray()) - : Enumerable.Empty()) - //order the result by name - .OrderBy(x => x.Name); + return ids.Length > 0 ? GetMany(ids).OrderBy(x => x.Name) : Enumerable.Empty(); } - /// - /// Gets all entities of the specified query - /// - /// - /// An enumerable list of objects + /// public IEnumerable GetByQuery(IQuery query) { var ints = PerformGetByQuery(query).ToArray(); - return ints.Any() - ? GetMany(ints) - : Enumerable.Empty(); + return ints.Length > 0 ? GetMany(ints) : Enumerable.Empty(); + } + + protected IEnumerable PerformGetByQuery(IQuery query) + { + // used by DataTypeService to remove properties + // from content types if they have a deleted data type - see + // notes in DataTypeService.Delete as it's a bit weird + + var sqlClause = Sql() + .SelectAll() + .From() + .RightJoin() + .On(left => left.Id, right => right.PropertyTypeGroupId) + .InnerJoin() + .On(left => left.DataTypeId, right => right.NodeId); + + var translator = new SqlTranslator(sqlClause, query); + var sql = translator.Translate() + .OrderBy(x => x.PropertyTypeGroupId); + + return Database + .FetchOneToMany(x => x.PropertyTypeDtos, sql) + .Select(x => x.ContentTypeNodeId).Distinct(); } /// @@ -141,7 +143,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement if (aliases.Length == 0) return Enumerable.Empty(); var sql = Sql() - .Select("cmsContentType.nodeId") + .Select(x => x.NodeId) .From() .InnerJoin() .On(dto => dto.NodeId, dto => dto.NodeId) @@ -156,14 +158,12 @@ namespace Umbraco.Core.Persistence.Repositories.Implement sql = isCount ? sql.SelectCount() - : sql.Select(r => r.Select(x => x.ContentTypeDto, r1 => r1.Select(x => x.NodeDto))); + : sql.Select(x => x.NodeId); sql .From() - .InnerJoin() - .On(left => left.NodeId, right => right.NodeId) - .LeftJoin() - .On(left => left.ContentTypeNodeId, right => right.NodeId) + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .LeftJoin().On(left => left.ContentTypeNodeId, right => right.NodeId) .Where(x => x.NodeObjectType == NodeObjectTypeId); return sql; diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs index e9b952f11d..1b184da559 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs @@ -10,11 +10,9 @@ using Umbraco.Core.Events; using Umbraco.Core.Exceptions; using Umbraco.Core.Logging; using Umbraco.Core.Models; -using Umbraco.Core.Models.Entities; using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.Persistence.Factories; using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Scoping; using Umbraco.Core.Services; @@ -28,9 +26,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement internal abstract class ContentTypeRepositoryBase : NPocoRepositoryBase, IReadRepository where TEntity : class, IContentTypeComposition { - protected ContentTypeRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger) + protected ContentTypeRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository) : base(scopeAccessor, cache, logger) - { } + { + CommonRepository = commonRepository; + } + + protected IContentTypeCommonRepository CommonRepository { get; } protected abstract bool SupportsPublishing { get; } @@ -82,38 +84,16 @@ namespace Umbraco.Core.Persistence.Repositories.Implement return moveInfo; } - /// - /// Returns the content type ids that match the query - /// - /// - /// - protected IEnumerable PerformGetByQuery(IQuery query) + + protected virtual PropertyType CreatePropertyType(string propertyEditorAlias, ValueStorageType storageType, string propertyTypeAlias) { - // used by DataTypeDefinitionRepository to remove properties - // from content types if they have a deleted data type - see - // notes in DataTypeDefinitionRepository.Delete as it's a bit - // weird - - var sqlClause = Sql() - .SelectAll() - .From() - .RightJoin() - .On(left => left.Id, right => right.PropertyTypeGroupId) - .InnerJoin() - .On(left => left.DataTypeId, right => right.NodeId); - - var translator = new SqlTranslator(sqlClause, query); - var sql = translator.Translate() - .OrderBy(x => x.PropertyTypeGroupId); - - return Database - .FetchOneToMany(x => x.PropertyTypeDtos, sql) - .Select(x => x.ContentTypeNodeId).Distinct(); + return new PropertyType(propertyEditorAlias, storageType, propertyTypeAlias); } - protected virtual PropertyType CreatePropertyType(string propertyEditorAlias, ValueStorageType dbType, string propertyTypeAlias) + protected override void PersistDeletedItem(TEntity entity) { - return new PropertyType(propertyEditorAlias, dbType, propertyTypeAlias); + base.PersistDeletedItem(entity); + CommonRepository.ClearCache(); // always } protected void PersistNewBaseContentType(IContentTypeComposition entity) @@ -228,6 +208,8 @@ AND umbracoNode.nodeObjectType = @objectType", propertyType.PropertyEditorAlias = dataTypeDto.EditorAlias; propertyType.ValueStorageType = dataTypeDto.DbType.EnumParse(true); } + + CommonRepository.ClearCache(); // always } protected void PersistUpdatedBaseContentType(IContentTypeComposition entity) @@ -532,6 +514,8 @@ AND umbracoNode.id <> @id", if (orphanPropertyTypeIds != null) foreach (var id in orphanPropertyTypeIds) DeletePropertyType(entity.Id, id); + + CommonRepository.ClearCache(); // always } private IEnumerable GetImpactedContentTypes(IContentTypeComposition contentType, IEnumerable all) @@ -992,74 +976,6 @@ AND umbracoNode.id <> @id", new { Id = contentTypeId, PropertyTypeId = propertyTypeId }); } - protected IEnumerable GetAllowedContentTypeIds(int id) - { - var sql = Sql() - .SelectAll() - .From() - .LeftJoin() - .On(left => left.AllowedId, right => right.NodeId) - .Where(x => x.Id == id); - - var allowedContentTypeDtos = Database.Fetch(sql); - return allowedContentTypeDtos.Select(x => new ContentTypeSort(new Lazy(() => x.AllowedId), x.SortOrder, x.ContentTypeDto.Alias)).ToList(); - } - - protected PropertyGroupCollection GetPropertyGroupCollection(int id, DateTime createDate, DateTime updateDate) - { - var sql = Sql() - .SelectAll() - .From() - .LeftJoin() - .On(left => left.Id, right => right.PropertyTypeGroupId) - .LeftJoin() - .On(left => left.DataTypeId, right => right.NodeId) - .Where(x => x.ContentTypeNodeId == id) - .OrderBy(x => x.Id); - - - var dtos = Database - .Fetch(sql); - - var propertyGroups = PropertyGroupFactory.BuildEntity(dtos, SupportsPublishing, id, createDate, updateDate,CreatePropertyType); - - return new PropertyGroupCollection(propertyGroups); - } - - protected PropertyTypeCollection GetPropertyTypeCollection(int id, DateTime createDate, DateTime updateDate) - { - var sql = Sql() - .SelectAll() - .From() - .InnerJoin() - .On(left => left.DataTypeId, right => right.NodeId) - .Where(x => x.ContentTypeId == id); - - var dtos = Database.Fetch(sql); - - // TODO: Move this to a PropertyTypeFactory - var list = new List(); - foreach (var dto in dtos.Where(x => x.PropertyTypeGroupId <= 0)) - { - var propType = CreatePropertyType(dto.DataTypeDto.EditorAlias, dto.DataTypeDto.DbType.EnumParse(true), dto.Alias); - propType.DataTypeId = dto.DataTypeId; - propType.Description = dto.Description; - propType.Id = dto.Id; - propType.Key = dto.UniqueId; - propType.Name = dto.Name; - propType.Mandatory = dto.Mandatory; - propType.SortOrder = dto.SortOrder; - propType.ValidationRegExp = dto.ValidationRegExp; - propType.CreateDate = createDate; - propType.UpdateDate = updateDate; - list.Add(propType); - } - //Reset dirty properties - Parallel.ForEach(list, currentFile => currentFile.ResetDirtyProperties(false)); - - return new PropertyTypeCollection(SupportsPublishing, list); - } - protected void ValidateAlias(PropertyType pt) { if (string.IsNullOrWhiteSpace(pt.Alias)) @@ -1114,589 +1030,6 @@ AND umbracoNode.id <> @id", } } - internal static class ContentTypeQueryMapper - { - public class AssociatedTemplate - { - public AssociatedTemplate(int templateId, string alias, string templateName) - { - TemplateId = templateId; - Alias = alias; - TemplateName = templateName; - } - - public int TemplateId { get; set; } - public string Alias { get; set; } - public string TemplateName { get; set; } - - protected bool Equals(AssociatedTemplate other) - { - return TemplateId == other.TemplateId; - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((AssociatedTemplate)obj); - } - - public override int GetHashCode() - { - return TemplateId; - } - } - - public static IEnumerable GetMediaTypes( - IDatabase db, ISqlSyntaxProvider sqlSyntax, bool isPublishing, - TRepo contentTypeRepository) - where TRepo : IReadRepository - { - IDictionary> allParentMediaTypeIds; - var mediaTypes = MapMediaTypes(db, sqlSyntax, out allParentMediaTypeIds) - .ToArray(); - - MapContentTypeChildren(mediaTypes, db, sqlSyntax, isPublishing, contentTypeRepository, allParentMediaTypeIds); - - return mediaTypes; - } - - public static IEnumerable GetContentTypes( - IDatabase db, ISqlSyntaxProvider sqlSyntax, bool isPublishing, - TRepo contentTypeRepository, - ITemplateRepository templateRepository) - where TRepo : IReadRepository - { - IDictionary> allAssociatedTemplates; - IDictionary> allParentContentTypeIds; - var contentTypes = MapContentTypes(db, sqlSyntax, out allAssociatedTemplates, out allParentContentTypeIds) - .ToArray(); - - if (contentTypes.Any()) - { - MapContentTypeTemplates( - contentTypes, db, contentTypeRepository, templateRepository, allAssociatedTemplates); - - MapContentTypeChildren(contentTypes, db, sqlSyntax, isPublishing, contentTypeRepository, allParentContentTypeIds); - } - - return contentTypes; - } - - internal static void MapContentTypeChildren(IContentTypeComposition[] contentTypes, - IDatabase db, ISqlSyntaxProvider sqlSyntax, bool isPublishing, - TRepo contentTypeRepository, - IDictionary> allParentContentTypeIds) - where TRepo : IReadRepository - { - //NOTE: SQL call #2 - - var ids = contentTypes.Select(x => x.Id).ToArray(); - IDictionary allPropGroups; - IDictionary allPropTypes; - MapGroupsAndProperties(ids, db, sqlSyntax, isPublishing, out allPropTypes, out allPropGroups); - - foreach (var contentType in contentTypes) - { - contentType.PropertyGroups = allPropGroups[contentType.Id]; - contentType.NoGroupPropertyTypes = allPropTypes[contentType.Id]; - } - - //NOTE: SQL call #3++ - - if (allParentContentTypeIds != null) - { - var allParentIdsAsArray = allParentContentTypeIds.SelectMany(x => x.Value).Distinct().ToArray(); - if (allParentIdsAsArray.Any()) - { - var allParentContentTypes = contentTypes.Where(x => allParentIdsAsArray.Contains(x.Id)).ToArray(); - - foreach (var contentType in contentTypes) - { - var entityId = contentType.Id; - - var parentContentTypes = allParentContentTypes.Where(x => - { - var parentEntityId = x.Id; - - return allParentContentTypeIds[entityId].Contains(parentEntityId); - }); - foreach (var parentContentType in parentContentTypes) - { - var result = contentType.AddContentType(parentContentType); - //Do something if adding fails? (Should hopefully not be possible unless someone created a circular reference) - } - - // reset dirty initial properties (U4-1946) - ((EntityBase)contentType).ResetDirtyProperties(false); - } - } - } - - - } - - internal static void MapContentTypeTemplates(IContentType[] contentTypes, - IDatabase db, - TRepo contentTypeRepository, - ITemplateRepository templateRepository, - IDictionary> associatedTemplates) - where TRepo : IReadRepository - { - if (associatedTemplates == null || associatedTemplates.Any() == false) return; - - //NOTE: SQL call #3++ - //SEE: http://issues.umbraco.org/issue/U4-5174 to fix this - - var templateIds = associatedTemplates.SelectMany(x => x.Value).Select(x => x.TemplateId) - .Distinct() - .ToArray(); - - var templates = (templateIds.Any() - ? templateRepository.GetMany(templateIds) - : Enumerable.Empty()).ToArray(); - - foreach (var contentType in contentTypes) - { - var entityId = contentType.Id; - - var associatedTemplateIds = associatedTemplates[entityId].Select(x => x.TemplateId) - .Distinct() - .ToArray(); - - contentType.AllowedTemplates = (associatedTemplateIds.Any() - ? templates.Where(x => associatedTemplateIds.Contains(x.Id)) - : Enumerable.Empty()).ToArray(); - } - - - } - - internal static IEnumerable MapMediaTypes(IDatabase db, ISqlSyntaxProvider sqlSyntax, - out IDictionary> parentMediaTypeIds) - { - if (db == null) throw new ArgumentNullException(nameof(db)); - - var sql = @"SELECT cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc, cmsContentType.variations as ctVariations, - cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.IsElement as ctIsElement, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb, - AllowedTypes.AllowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias, - ParentTypes.parentContentTypeId as chtParentId, ParentTypes.parentContentTypeKey as chtParentKey, - umbracoNode.createDate as nCreateDate, umbracoNode." + sqlSyntax.GetQuotedColumnName("level") + @" as nLevel, umbracoNode.nodeObjectType as nObjectType, umbracoNode.nodeUser as nUser, - umbracoNode.parentID as nParentId, umbracoNode." + sqlSyntax.GetQuotedColumnName("path") + @" as nPath, umbracoNode.sortOrder as nSortOrder, umbracoNode." + sqlSyntax.GetQuotedColumnName("text") + @" as nName, umbracoNode.trashed as nTrashed, - umbracoNode.uniqueID as nUniqueId - FROM cmsContentType - INNER JOIN umbracoNode - ON cmsContentType.nodeId = umbracoNode.id - LEFT JOIN ( - SELECT cmsContentTypeAllowedContentType.Id, cmsContentTypeAllowedContentType.AllowedId, cmsContentType.alias, cmsContentTypeAllowedContentType.SortOrder - FROM cmsContentTypeAllowedContentType - INNER JOIN cmsContentType - ON cmsContentTypeAllowedContentType.AllowedId = cmsContentType.nodeId - ) AllowedTypes - ON AllowedTypes.Id = cmsContentType.nodeId - LEFT JOIN ( - SELECT cmsContentType2ContentType.parentContentTypeId, umbracoNode.uniqueID AS parentContentTypeKey, cmsContentType2ContentType.childContentTypeId - FROM cmsContentType2ContentType - INNER JOIN umbracoNode - ON cmsContentType2ContentType.parentContentTypeId = umbracoNode." + sqlSyntax.GetQuotedColumnName("id") + @" - ) ParentTypes - ON ParentTypes.childContentTypeId = cmsContentType.nodeId - WHERE (umbracoNode.nodeObjectType = @nodeObjectType) - ORDER BY ctId"; - - var result = db.Fetch(sql, new { nodeObjectType = Constants.ObjectTypes.MediaType }); - - if (result.Any() == false) - { - parentMediaTypeIds = null; - return Enumerable.Empty(); - } - - parentMediaTypeIds = new Dictionary>(); - var mappedMediaTypes = new List(); - - //loop through each result and fill in our required values, each row will contain different required data than the rest. - // it is much quicker to iterate each result and populate instead of looking up the values over and over in the result like - // we used to do. - var queue = new Queue(result); - var currAllowedContentTypes = new List(); - - while (queue.Count > 0) - { - var ct = queue.Dequeue(); - - //check for allowed content types - int? allowedCtId = ct.ctaAllowedId; - int? allowedCtSort = ct.ctaSortOrder; - string allowedCtAlias = ct.ctaAlias; - if (allowedCtId.HasValue && allowedCtSort.HasValue && allowedCtAlias != null) - { - var ctSort = new ContentTypeSort(new Lazy(() => allowedCtId.Value), allowedCtSort.Value, allowedCtAlias); - if (currAllowedContentTypes.Contains(ctSort) == false) - { - currAllowedContentTypes.Add(ctSort); - } - } - - //always ensure there's a list for this content type - if (parentMediaTypeIds.ContainsKey(ct.ctId) == false) - parentMediaTypeIds[ct.ctId] = new List(); - - //check for parent ids and assign to the outgoing collection - int? parentId = ct.chtParentId; - if (parentId.HasValue) - { - var associatedParentIds = parentMediaTypeIds[ct.ctId]; - if (associatedParentIds.Contains(parentId.Value) == false) - associatedParentIds.Add(parentId.Value); - } - - if (queue.Count == 0 || queue.Peek().ctId != ct.ctId) - { - //it's the last in the queue or the content type is changing (moving to the next one) - var mediaType = CreateForMapping(ct, currAllowedContentTypes); - mappedMediaTypes.Add(mediaType); - - //Here we need to reset the current variables, we're now collecting data for a different content type - currAllowedContentTypes = new List(); - } - } - - return mappedMediaTypes; - } - - private static IMediaType CreateForMapping(dynamic currCt, List currAllowedContentTypes) - { - // * create the DTO object - // * create the content type object - // * map the allowed content types - // * add to the outgoing list - - var contentTypeDto = new ContentTypeDto - { - Alias = currCt.ctAlias, - AllowAtRoot = currCt.ctAllowAtRoot, - Description = currCt.ctDesc, - Icon = currCt.ctIcon, - IsContainer = currCt.ctIsContainer, - IsElement = currCt.ctIsElement, - NodeId = currCt.ctId, - PrimaryKey = currCt.ctPk, - Thumbnail = currCt.ctThumb, - Variations = (byte) currCt.ctVariations, - //map the underlying node dto - NodeDto = new NodeDto - { - CreateDate = currCt.nCreateDate, - Level = (short)currCt.nLevel, - NodeId = currCt.ctId, - NodeObjectType = currCt.nObjectType, - ParentId = currCt.nParentId, - Path = currCt.nPath, - SortOrder = currCt.nSortOrder, - Text = currCt.nName, - Trashed = currCt.nTrashed, - UniqueId = currCt.nUniqueId, - UserId = currCt.nUser - } - }; - - //now create the content type object; - var mediaType = ContentTypeFactory.BuildMediaTypeEntity(contentTypeDto); - - //map the allowed content types - mediaType.AllowedContentTypes = currAllowedContentTypes; - - return mediaType; - } - - internal static IEnumerable MapContentTypes(IDatabase db, ISqlSyntaxProvider sqlSyntax, - out IDictionary> associatedTemplates, - out IDictionary> parentContentTypeIds) - { - if (db == null) throw new ArgumentNullException(nameof(db)); - - var sql = @"SELECT cmsDocumentType.IsDefault as dtIsDefault, cmsDocumentType.templateNodeId as dtTemplateId, - cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc, cmsContentType.variations as ctVariations, - cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.IsElement as ctIsElement, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb, - AllowedTypes.AllowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias, - ParentTypes.parentContentTypeId as chtParentId,ParentTypes.parentContentTypeKey as chtParentKey, - umbracoNode.createDate as nCreateDate, umbracoNode." + sqlSyntax.GetQuotedColumnName("level") + @" as nLevel, umbracoNode.nodeObjectType as nObjectType, umbracoNode.nodeUser as nUser, - umbracoNode.parentID as nParentId, umbracoNode." + sqlSyntax.GetQuotedColumnName("path") + @" as nPath, umbracoNode.sortOrder as nSortOrder, umbracoNode." + sqlSyntax.GetQuotedColumnName("text") + @" as nName, umbracoNode.trashed as nTrashed, - umbracoNode.uniqueID as nUniqueId, - Template.alias as tAlias, Template.nodeId as tId,Template.text as tText - FROM cmsContentType - INNER JOIN umbracoNode - ON cmsContentType.nodeId = umbracoNode.id - LEFT JOIN cmsDocumentType - ON cmsDocumentType.contentTypeNodeId = cmsContentType.nodeId - LEFT JOIN ( - SELECT cmsContentTypeAllowedContentType.Id, cmsContentTypeAllowedContentType.AllowedId, cmsContentType.alias, cmsContentTypeAllowedContentType.SortOrder - FROM cmsContentTypeAllowedContentType - INNER JOIN cmsContentType - ON cmsContentTypeAllowedContentType.AllowedId = cmsContentType.nodeId - ) AllowedTypes - ON AllowedTypes.Id = cmsContentType.nodeId - LEFT JOIN ( - SELECT * FROM cmsTemplate - INNER JOIN umbracoNode - ON cmsTemplate.nodeId = umbracoNode.id - ) as Template - ON Template.nodeId = cmsDocumentType.templateNodeId - LEFT JOIN ( - SELECT cmsContentType2ContentType.parentContentTypeId, umbracoNode.uniqueID AS parentContentTypeKey, cmsContentType2ContentType.childContentTypeId - FROM cmsContentType2ContentType - INNER JOIN umbracoNode - ON cmsContentType2ContentType.parentContentTypeId = umbracoNode." + sqlSyntax.GetQuotedColumnName("id") + @" - ) ParentTypes - ON ParentTypes.childContentTypeId = cmsContentType.nodeId - WHERE (umbracoNode.nodeObjectType = @nodeObjectType) - ORDER BY ctId"; - - var result = db.Fetch(sql, new { nodeObjectType = Constants.ObjectTypes.DocumentType }); - - if (result.Any() == false) - { - parentContentTypeIds = null; - associatedTemplates = null; - return Enumerable.Empty(); - } - - parentContentTypeIds = new Dictionary>(); - associatedTemplates = new Dictionary>(); - var mappedContentTypes = new List(); - - var queue = new Queue(result); - var currDefaultTemplate = -1; - var currAllowedContentTypes = new List(); - while (queue.Count > 0) - { - var ct = queue.Dequeue(); - - //check for default templates - bool? isDefaultTemplate = Convert.ToBoolean(ct.dtIsDefault); - int? templateId = ct.dtTemplateId; - if (currDefaultTemplate == -1 && isDefaultTemplate.HasValue && isDefaultTemplate.Value && templateId.HasValue) - { - currDefaultTemplate = templateId.Value; - } - - //always ensure there's a list for this content type - if (associatedTemplates.ContainsKey(ct.ctId) == false) - associatedTemplates[ct.ctId] = new List(); - - //check for associated templates and assign to the outgoing collection - if (ct.tId != null) - { - var associatedTemplate = new AssociatedTemplate(ct.tId, ct.tAlias, ct.tText); - var associatedList = associatedTemplates[ct.ctId]; - - if (associatedList.Contains(associatedTemplate) == false) - associatedList.Add(associatedTemplate); - } - - //check for allowed content types - int? allowedCtId = ct.ctaAllowedId; - int? allowedCtSort = ct.ctaSortOrder; - string allowedCtAlias = ct.ctaAlias; - if (allowedCtId.HasValue && allowedCtSort.HasValue && allowedCtAlias != null) - { - var ctSort = new ContentTypeSort(new Lazy(() => allowedCtId.Value), allowedCtSort.Value, allowedCtAlias); - if (currAllowedContentTypes.Contains(ctSort) == false) - { - currAllowedContentTypes.Add(ctSort); - } - } - - //always ensure there's a list for this content type - if (parentContentTypeIds.ContainsKey(ct.ctId) == false) - parentContentTypeIds[ct.ctId] = new List(); - - //check for parent ids and assign to the outgoing collection - int? parentId = ct.chtParentId; - if (parentId.HasValue) - { - var associatedParentIds = parentContentTypeIds[ct.ctId]; - - if (associatedParentIds.Contains(parentId.Value) == false) - associatedParentIds.Add(parentId.Value); - } - - if (queue.Count == 0 || queue.Peek().ctId != ct.ctId) - { - //it's the last in the queue or the content type is changing (moving to the next one) - var contentType = CreateForMapping(ct, currAllowedContentTypes, currDefaultTemplate); - mappedContentTypes.Add(contentType); - - //Here we need to reset the current variables, we're now collecting data for a different content type - currDefaultTemplate = -1; - currAllowedContentTypes = new List(); - } - } - - return mappedContentTypes; - } - - private static IContentType CreateForMapping(dynamic currCt, List currAllowedContentTypes, int currDefaultTemplate) - { - // * set the default template to the first one if a default isn't found - // * create the DTO object - // * create the content type object - // * map the allowed content types - // * add to the outgoing list - - var dtDto = new ContentTypeTemplateDto - { - //create the content type dto - ContentTypeDto = new ContentTypeDto - { - Alias = currCt.ctAlias, - AllowAtRoot = currCt.ctAllowAtRoot, - Description = currCt.ctDesc, - Icon = currCt.ctIcon, - IsContainer = currCt.ctIsContainer, - IsElement = currCt.ctIsElement, - NodeId = currCt.ctId, - PrimaryKey = currCt.ctPk, - Thumbnail = currCt.ctThumb, - Variations = (byte) currCt.ctVariations, - //map the underlying node dto - NodeDto = new NodeDto - { - CreateDate = currCt.nCreateDate, - Level = (short)currCt.nLevel, - NodeId = currCt.ctId, - NodeObjectType = currCt.nObjectType, - ParentId = currCt.nParentId, - Path = currCt.nPath, - SortOrder = currCt.nSortOrder, - Text = currCt.nName, - Trashed = currCt.nTrashed, - UniqueId = currCt.nUniqueId, - UserId = currCt.nUser - } - }, - ContentTypeNodeId = currCt.ctId, - IsDefault = currDefaultTemplate != -1, - TemplateNodeId = currDefaultTemplate != -1 ? currDefaultTemplate : 0, - }; - - //now create the content type object - var contentType = ContentTypeFactory.BuildContentTypeEntity(dtDto.ContentTypeDto); - - // NOTE - // that was done by the factory but makes little sense, moved here, so - // now we have to reset dirty props again (as the factory does it) and yet, - // we are not managing allowed templates... the whole thing is weird. - ((ContentType)contentType).DefaultTemplateId = dtDto.TemplateNodeId; - contentType.ResetDirtyProperties(false); - - //map the allowed content types - contentType.AllowedContentTypes = currAllowedContentTypes; - - return contentType; - } - - internal static void MapGroupsAndProperties(int[] contentTypeIds, IDatabase db, ISqlSyntaxProvider sqlSyntax, bool isPublishing, - out IDictionary allPropertyTypeCollection, - out IDictionary allPropertyGroupCollection) - { - allPropertyGroupCollection = new Dictionary(); - allPropertyTypeCollection = new Dictionary(); - - // query below is not safe + pointless if array is empty - if (contentTypeIds.Length == 0) return; - - var sqlGroups = @"SELECT - pg.contenttypeNodeId AS contentTypeId, - pg.id AS id, pg.uniqueID AS " + sqlSyntax.GetQuotedColumnName("key") + @", - pg.sortOrder AS sortOrder, pg." + sqlSyntax.GetQuotedColumnName("text") + @" AS text -FROM cmsPropertyTypeGroup pg -WHERE pg.contenttypeNodeId IN (@ids) -ORDER BY contentTypeId, id"; - - var sqlProps = @"SELECT - pt.contentTypeId AS contentTypeId, - pt.id AS id, pt.uniqueID AS " + sqlSyntax.GetQuotedColumnName("key") + @", - pt.propertyTypeGroupId AS groupId, - pt.Alias AS alias, pt." + sqlSyntax.GetQuotedColumnName("Description") + @" AS " + sqlSyntax.GetQuotedColumnName("desc") + $@", pt.mandatory AS mandatory, - pt.Name AS name, pt.sortOrder AS sortOrder, pt.validationRegExp AS regexp, pt.variations as variations, - dt.nodeId as dataTypeId, dt.dbType as dbType, dt.propertyEditorAlias as editorAlias -FROM cmsPropertyType pt -INNER JOIN {Constants.DatabaseSchema.Tables.DataType} as dt ON pt.dataTypeId = dt.nodeId -WHERE pt.contentTypeId IN (@ids) -ORDER BY contentTypeId, groupId, id"; - - if (contentTypeIds.Length > 2000) - throw new InvalidOperationException("Cannot perform this lookup, too many sql parameters"); - - var groups = db.Fetch(sqlGroups, new { ids = contentTypeIds }); - var groupsEnumerator = groups.GetEnumerator(); - var group = groupsEnumerator.MoveNext() ? groupsEnumerator.Current : null; - - var props = db.Fetch(sqlProps, new { ids = contentTypeIds }); - var propsEnumerator = props.GetEnumerator(); - var prop = propsEnumerator.MoveNext() ? propsEnumerator.Current : null; - - // groups are ordered by content type, group id - // props are ordered by content type, group id, prop id - - foreach (var contentTypeId in contentTypeIds) - { - var propertyTypeCollection = allPropertyTypeCollection[contentTypeId] = new PropertyTypeCollection(isPublishing); - var propertyGroupCollection = allPropertyGroupCollection[contentTypeId] = new PropertyGroupCollection(); - - while (prop != null && prop.contentTypeId == contentTypeId && prop.groupId == null) - { - AddPropertyType(propertyTypeCollection, prop); - prop = propsEnumerator.MoveNext() ? propsEnumerator.Current : null; - } - - while (group != null && group.contentTypeId == contentTypeId) - { - var propertyGroup = new PropertyGroup(new PropertyTypeCollection(isPublishing)) - { - Id = group.id, - Name = group.text, - SortOrder = group.sortOrder, - Key = group.key - }; - propertyGroupCollection.Add(propertyGroup); - - while (prop != null && prop.groupId == group.id) - { - AddPropertyType(propertyGroup.PropertyTypes, prop, propertyGroup); - prop = propsEnumerator.MoveNext() ? propsEnumerator.Current : null; - } - - group = groupsEnumerator.MoveNext() ? groupsEnumerator.Current : null; - } - } - - propsEnumerator.Dispose(); - groupsEnumerator.Dispose(); - } - - private static void AddPropertyType(PropertyTypeCollection propertyTypes, dynamic prop, PropertyGroup propertyGroup = null) - { - var propertyType = new PropertyType(prop.editorAlias, Enum.Parse(prop.dbType), prop.alias) - { - Description = prop.desc, - DataTypeId = prop.dataTypeId, - Id = prop.id, - Key = prop.key, - Mandatory = Convert.ToBoolean(prop.mandatory), - Name = prop.name, - PropertyGroupId = propertyGroup == null ? null : new Lazy(() => propertyGroup.Id), - SortOrder = prop.sortOrder, - ValidationRegExp = prop.regexp, - Variations = (ContentVariation) prop.variations - }; - propertyTypes.Add(propertyType); - } - } - protected abstract TEntity PerformGet(Guid id); protected abstract TEntity PerformGet(string alias); protected abstract IEnumerable PerformGetAll(params Guid[] ids); diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/MediaTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/MediaTypeRepository.cs index a6f39bdb71..281255e755 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/MediaTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/MediaTypeRepository.cs @@ -16,8 +16,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement /// internal class MediaTypeRepository : ContentTypeRepositoryBase, IMediaTypeRepository { - public MediaTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger) - : base(scopeAccessor, cache, logger) + public MediaTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository) + : base(scopeAccessor, cache, logger, commonRepository) { } protected override bool SupportsPublishing => MediaType.SupportsPublishingConst; @@ -27,83 +27,46 @@ namespace Umbraco.Core.Persistence.Repositories.Implement return new FullDataSetRepositoryCachePolicy(GlobalIsolatedCache, ScopeAccessor, GetEntityId, /*expires:*/ true); } + // every GetExists method goes cachePolicy.GetSomething which in turns goes PerformGetAll, + // since this is a FullDataSet policy - and everything is cached + // so here, + // every PerformGet/Exists just GetMany() and then filters + // except PerformGetAll which is the one really doing the job + protected override IMediaType PerformGet(int id) - { - //use the underlying GetAll which will force cache all content types - return GetMany().FirstOrDefault(x => x.Id == id); - } + => GetMany().FirstOrDefault(x => x.Id == id); protected override IMediaType PerformGet(Guid id) - { - //use the underlying GetAll which will force cache all content types - return GetMany().FirstOrDefault(x => x.Key == id); - } + => GetMany().FirstOrDefault(x => x.Key == id); protected override bool PerformExists(Guid id) - { - return GetMany().FirstOrDefault(x => x.Key == id) != null; - } + => GetMany().FirstOrDefault(x => x.Key == id) != null; protected override IMediaType PerformGet(string alias) - { - //use the underlying GetAll which will force cache all content types - return GetMany().FirstOrDefault(x => x.Alias.InvariantEquals(alias)); - } + => GetMany().FirstOrDefault(x => x.Alias.InvariantEquals(alias)); protected override IEnumerable PerformGetAll(params int[] ids) { - if (ids.Any()) - { - //NOTE: This logic should never be executed according to our cache policy - return ContentTypeQueryMapper.GetMediaTypes(Database, SqlSyntax, SupportsPublishing, this) - .Where(x => ids.Contains(x.Id)); - } - - return ContentTypeQueryMapper.GetMediaTypes(Database, SqlSyntax, SupportsPublishing, this); + // the cache policy will always want everything + // even GetMany(ids) gets everything and filters afterwards + if (ids.Any()) throw new Exception("panic"); + return CommonRepository.GetAllTypes().OfType(); } protected override IEnumerable PerformGetAll(params Guid[] ids) { - //use the underlying GetAll which will force cache all content types - - if (ids.Any()) - { - return GetMany().Where(x => ids.Contains(x.Key)); - } - else - { - return GetMany(); - } + var all = GetMany(); + return ids.Any() ? all.Where(x => ids.Contains(x.Key)) : all; } protected override IEnumerable PerformGetByQuery(IQuery query) { - var sqlClause = GetBaseQuery(false); - var translator = new SqlTranslator(sqlClause, query); + var baseQuery = GetBaseQuery(false); + var translator = new SqlTranslator(baseQuery, query); var sql = translator.Translate(); + var ids = Database.Fetch(sql).Distinct().ToArray(); - var dtos = Database.Fetch(sql); - - return - //This returns a lookup from the GetAll cached lookup - (dtos.Any() - ? GetMany(dtos.DistinctBy(x => x.NodeId).Select(x => x.NodeId).ToArray()) - : Enumerable.Empty()) - //order the result by name - .OrderBy(x => x.Name); - } - - /// - /// Gets all entities of the specified query - /// - /// - /// An enumerable list of objects - public IEnumerable GetByQuery(IQuery query) - { - var ints = PerformGetByQuery(query).ToArray(); - return ints.Any() - ? GetMany(ints) - : Enumerable.Empty(); + return ids.Length > 0 ? GetMany(ids).OrderBy(x => x.Name) : Enumerable.Empty(); } protected override Sql GetBaseQuery(bool isCount) @@ -112,12 +75,11 @@ namespace Umbraco.Core.Persistence.Repositories.Implement sql = isCount ? sql.SelectCount() - : sql.Select(r => r.Select(x => x.NodeDto)); + : sql.Select(x => x.NodeId); sql .From() - .InnerJoin() - .On( left => left.NodeId, right => right.NodeId) + .InnerJoin().On( left => left.NodeId, right => right.NodeId) .Where(x => x.NodeObjectType == NodeObjectTypeId); return sql; diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs index afb6ac8b43..a32ec1b422 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs @@ -17,8 +17,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement /// internal class MemberTypeRepository : ContentTypeRepositoryBase, IMemberTypeRepository { - public MemberTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger) - : base(scopeAccessor, cache, logger) + public MemberTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository) + : base(scopeAccessor, cache, logger, commonRepository) { } protected override bool SupportsPublishing => MemberType.SupportsPublishingConst; @@ -28,108 +28,49 @@ namespace Umbraco.Core.Persistence.Repositories.Implement return new FullDataSetRepositoryCachePolicy(GlobalIsolatedCache, ScopeAccessor, GetEntityId, /*expires:*/ true); } + // every GetExists method goes cachePolicy.GetSomething which in turns goes PerformGetAll, + // since this is a FullDataSet policy - and everything is cached + // so here, + // every PerformGet/Exists just GetMany() and then filters + // except PerformGetAll which is the one really doing the job + protected override IMemberType PerformGet(int id) - { - //use the underlying GetAll which will force cache all content types - return GetMany().FirstOrDefault(x => x.Id == id); - } + => GetMany().FirstOrDefault(x => x.Id == id); protected override IMemberType PerformGet(Guid id) - { - //use the underlying GetAll which will force cache all content types - return GetMany().FirstOrDefault(x => x.Key == id); - } + => GetMany().FirstOrDefault(x => x.Key == id); protected override IEnumerable PerformGetAll(params Guid[] ids) { - //use the underlying GetAll which will force cache all content types - - if (ids.Any()) - { - return GetMany().Where(x => ids.Contains(x.Key)); - } - else - { - return GetMany(); - } + var all = GetMany(); + return ids.Any() ? all.Where(x => ids.Contains(x.Key)) : all; } protected override bool PerformExists(Guid id) - { - return GetMany().FirstOrDefault(x => x.Key == id) != null; - } + => GetMany().FirstOrDefault(x => x.Key == id) != null; protected override IMemberType PerformGet(string alias) - { - //use the underlying GetAll which will force cache all content types - return GetMany().FirstOrDefault(x => x.Alias.InvariantEquals(alias)); - } + => GetMany().FirstOrDefault(x => x.Alias.InvariantEquals(alias)); protected override IEnumerable PerformGetAll(params int[] ids) { - var sql = GetBaseQuery(false); - if (ids.Any()) - { - //NOTE: This logic should never be executed according to our cache policy - var statement = string.Join(" OR ", ids.Select(x => string.Format("umbracoNode.id='{0}'", x))); - sql.Where(statement); - } - sql.OrderByDescending(x => x.NodeId); - - var dtos = Database - .Fetch(sql) // cannot use FetchOneToMany because we have 2 collections! - .Transform(MapOneToManies) - .ToList(); - - return BuildFromDtos(dtos); + // the cache policy will always want everything + // even GetMany(ids) gets everything and filters afterwards + if (ids.Any()) throw new Exception("panic"); + return CommonRepository.GetAllTypes().OfType(); } protected override IEnumerable PerformGetByQuery(IQuery query) { - var sqlSubquery = GetSubquery(); - var translator = new SqlTranslator(sqlSubquery, query); - var subquery = translator.Translate(); + var subQuery = GetSubquery(); + var translator = new SqlTranslator(subQuery, query); + var subSql = translator.Translate(); var sql = GetBaseQuery(false) - .Append("WHERE umbracoNode.id IN (" + subquery.SQL + ")", subquery.Arguments) + .WhereIn(x => x.NodeId, subSql) .OrderBy(x => x.SortOrder); + var ids = Database.Fetch(sql).Distinct().ToArray(); - var dtos = Database - .Fetch(sql) // cannot use FetchOneToMany because we have 2 collections! - .Transform(MapOneToManies) - .ToList(); - - return BuildFromDtos(dtos); - } - - private IEnumerable MapOneToManies(IEnumerable dtos) - { - MemberTypeReadOnlyDto acc = null; - foreach (var dto in dtos) - { - if (acc == null) - { - acc = dto; - } - else if (acc.UniqueId == dto.UniqueId) - { - var prop = dto.PropertyTypes.SingleOrDefault(); - var group = dto.PropertyTypeGroups.SingleOrDefault(); - - if (prop != null && prop.Id.HasValue && acc.PropertyTypes.Any(x => x.Id == prop.Id.Value) == false) - acc.PropertyTypes.Add(prop); - - if (group != null && group.Id.HasValue && acc.PropertyTypeGroups.Any(x => x.Id == group.Id.Value) == false) - acc.PropertyTypeGroups.Add(group); - } - else - { - yield return acc; - acc = dto; - } - } - - if (acc != null) - yield return acc; + return ids.Length > 0 ? GetMany(ids).OrderBy(x => x.Name) : Enumerable.Empty(); } protected override Sql GetBaseQuery(bool isCount) @@ -144,18 +85,11 @@ namespace Umbraco.Core.Persistence.Repositories.Implement } var sql = Sql() - .Select("umbracoNode.*", "cmsContentType.*", "cmsPropertyType.id AS PropertyTypeId", "cmsPropertyType.Alias", - "cmsPropertyType.Name", "cmsPropertyType.Description", "cmsPropertyType.mandatory", "cmsPropertyType.UniqueID", - "cmsPropertyType.validationRegExp", "cmsPropertyType.dataTypeId", "cmsPropertyType.sortOrder AS PropertyTypeSortOrder", - "cmsPropertyType.propertyTypeGroupId AS PropertyTypesGroupId", - "cmsMemberType.memberCanEdit", "cmsMemberType.viewOnProfile", "cmsMemberType.isSensitive", - $"{Constants.DatabaseSchema.Tables.DataType}.propertyEditorAlias", $"{Constants.DatabaseSchema.Tables.DataType}.dbType", "cmsPropertyTypeGroup.id AS PropertyTypeGroupId", - "cmsPropertyTypeGroup.text AS PropertyGroupName", "cmsPropertyTypeGroup.uniqueID AS PropertyGroupUniqueID", - "cmsPropertyTypeGroup.sortorder AS PropertyGroupSortOrder", "cmsPropertyTypeGroup.contenttypeNodeId") + .Select(x => x.NodeId) .From() .InnerJoin().On(left => left.NodeId, right => right.NodeId) .LeftJoin().On(left => left.ContentTypeId, right => right.NodeId) - .LeftJoin().On(left => left.PropertyTypeId, right => right.Id) + .LeftJoin().On(left => left.PropertyTypeId, right => right.Id) .LeftJoin().On(left => left.NodeId, right => right.DataTypeId) .LeftJoin().On(left => left.ContentTypeNodeId, right => right.NodeId) .Where(x => x.NodeObjectType == NodeObjectTypeId); @@ -170,7 +104,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement .From() .InnerJoin().On(left => left.NodeId, right => right.NodeId) .LeftJoin().On(left => left.ContentTypeId, right => right.NodeId) - .LeftJoin().On(left => left.PropertyTypeId, right => right.Id) + .LeftJoin().On(left => left.PropertyTypeId, right => right.Id) .LeftJoin().On(left => left.NodeId, right => right.DataTypeId) .LeftJoin().On(left => left.ContentTypeNodeId, right => right.NodeId) .Where(x => x.NodeObjectType == NodeObjectTypeId); @@ -212,12 +146,12 @@ namespace Umbraco.Core.Persistence.Repositories.Implement { entity.AddPropertyType(standardPropertyType.Value, Constants.Conventions.Member.StandardPropertiesGroupName); } - + EnsureExplicitDataTypeForBuiltInProperties(entity); PersistNewBaseContentType(entity); //Handles the MemberTypeDto (cmsMemberType table) - var memberTypeDtos = ContentTypeFactory.BuildMemberTypeDtos(entity); + var memberTypeDtos = ContentTypeFactory.BuildMemberPropertyTypeDtos(entity); foreach (var memberTypeDto in memberTypeDtos) { Database.Insert(memberTypeDto); @@ -245,13 +179,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement new { ParentId = entity.ParentId, NodeObjectType = NodeObjectTypeId }); entity.SortOrder = maxSortOrder + 1; } - + EnsureExplicitDataTypeForBuiltInProperties(entity); PersistUpdatedBaseContentType(entity); // remove and insert - handle cmsMemberType table - Database.Delete("WHERE NodeId = @Id", new { Id = entity.Id }); - var memberTypeDtos = ContentTypeFactory.BuildMemberTypeDtos(entity); + Database.Delete("WHERE NodeId = @Id", new { Id = entity.Id }); + var memberTypeDtos = ContentTypeFactory.BuildMemberPropertyTypeDtos(entity); foreach (var memberTypeDto in memberTypeDtos) { Database.Insert(memberTypeDto); @@ -264,19 +198,16 @@ namespace Umbraco.Core.Persistence.Repositories.Implement /// Override so we can specify explicit db type's on any property types that are built-in. /// /// - /// + /// /// /// - protected override PropertyType CreatePropertyType(string propertyEditorAlias, ValueStorageType dbType, string propertyTypeAlias) + protected override PropertyType CreatePropertyType(string propertyEditorAlias, ValueStorageType storageType, string propertyTypeAlias) { //custom property type constructor logic to set explicit dbtype's for built in properties - var stdProps = Constants.Conventions.Member.GetStandardPropertyTypeStubs(); - var propDbType = GetDbTypeForBuiltInProperty(propertyTypeAlias, dbType, stdProps); - return new PropertyType(propertyEditorAlias, propDbType.Result, - //This flag tells the property type that it has an explicit dbtype and that it cannot be changed - // which is what we want for the built-in properties. - propDbType.Success, - propertyTypeAlias); + var builtinProperties = Constants.Conventions.Member.GetStandardPropertyTypeStubs(); + var readonlyStorageType = builtinProperties.TryGetValue(propertyTypeAlias, out var propertyType); + storageType = readonlyStorageType ? propertyType.ValueStorageType : storageType; + return new PropertyType(propertyEditorAlias, storageType, readonlyStorageType, propertyTypeAlias); } /// @@ -286,62 +217,15 @@ namespace Umbraco.Core.Persistence.Repositories.Implement /// private static void EnsureExplicitDataTypeForBuiltInProperties(IContentTypeBase memberType) { - var stdProps = Constants.Conventions.Member.GetStandardPropertyTypeStubs(); + var builtinProperties = Constants.Conventions.Member.GetStandardPropertyTypeStubs(); foreach (var propertyType in memberType.PropertyTypes) { - var dbTypeAttempt = GetDbTypeForBuiltInProperty(propertyType.Alias, propertyType.ValueStorageType, stdProps); - if (dbTypeAttempt) + if (builtinProperties.ContainsKey(propertyType.Alias)) { - //this reset's it's current data type reference which will be re-assigned based on the property editor assigned on the next line + //this reset's its current data type reference which will be re-assigned based on the property editor assigned on the next line propertyType.DataTypeId = 0; } } } - - /// - /// Builds a collection of entities from a collection of Dtos - /// - /// - /// - private IEnumerable BuildFromDtos(List dtos) - { - if (dtos == null || dtos.Any() == false) - return Enumerable.Empty(); - - return dtos.Select(x => - { - bool needsSaving; - var memberType = MemberTypeReadOnlyFactory.BuildEntity(x, out needsSaving); - if (needsSaving) PersistUpdatedItem(memberType); - return memberType; - }).ToList(); - } - - /// - /// If this is one of our internal properties - we will manually assign the data type since they must - /// always correspond to the correct db type no matter what the backing data type is assigned. - /// - /// - /// - /// - /// - /// Successful attempt if it was a built in property - /// - internal static Attempt GetDbTypeForBuiltInProperty( - string propAlias, - ValueStorageType dbType, - Dictionary standardProps) - { - var aliases = standardProps.Select(x => x.Key).ToArray(); - - //check if it is built in - if (aliases.Contains(propAlias)) - { - //return the pre-determined db type for this property - return Attempt.Succeed(standardProps.Single(x => x.Key == propAlias).Value.ValueStorageType); - } - - return Attempt.Fail(dbType); - } } } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/RepositoryBaseOfTIdTEntity.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/RepositoryBaseOfTIdTEntity.cs index a7e366a94f..69e4db5940 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/RepositoryBaseOfTIdTEntity.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/RepositoryBaseOfTIdTEntity.cs @@ -78,51 +78,24 @@ namespace Umbraco.Core.Persistence.Repositories.Implement } } - // TODO: but now that we have 1 unique repository? - // this is a *bad* idea because PerformCount captures the current repository and its UOW - // - //private static RepositoryCachePolicyOptions _defaultOptions; - //protected virtual RepositoryCachePolicyOptions DefaultOptions - //{ - // get - // { - // return _defaultOptions ?? (_defaultOptions - // = new RepositoryCachePolicyOptions(() => - // { - // // get count of all entities of current type (TEntity) to ensure cached result is correct - // // create query once if it is needed (no need for locking here) - query is static! - // var query = _hasIdQuery ?? (_hasIdQuery = Query.Builder.Where(x => x.Id != 0)); - // return PerformCount(query); - // })); - // } - //} - + // ReSharper disable once StaticMemberInGenericType + private static RepositoryCachePolicyOptions _defaultOptions; + // ReSharper disable once InconsistentNaming protected virtual RepositoryCachePolicyOptions DefaultOptions { get { - return new RepositoryCachePolicyOptions(() => - { - // get count of all entities of current type (TEntity) to ensure cached result is correct - // create query once if it is needed (no need for locking here) - query is static! - var query = _hasIdQuery ?? (_hasIdQuery = AmbientScope.SqlContext.Query().Where(x => x.Id != 0)); - return PerformCount(query); - }); + return _defaultOptions ?? (_defaultOptions + = new RepositoryCachePolicyOptions(() => + { + // get count of all entities of current type (TEntity) to ensure cached result is correct + // create query once if it is needed (no need for locking here) - query is static! + var query = _hasIdQuery ?? (_hasIdQuery = AmbientScope.SqlContext.Query().Where(x => x.Id != 0)); + return PerformCount(query); + })); } } - // this would be better for perfs BUT it breaks the tests - l8tr - // - //private static IRepositoryCachePolicy _defaultCachePolicy; - //protected virtual IRepositoryCachePolicy DefaultCachePolicy - //{ - // get - // { - // return _defaultCachePolicy ?? (_defaultCachePolicy - // = new DefaultRepositoryCachePolicy(IsolatedCache, DefaultOptions)); - // } - //} - protected IRepositoryCachePolicy CachePolicy { get diff --git a/src/Umbraco.Core/Services/Implement/DataTypeService.cs b/src/Umbraco.Core/Services/Implement/DataTypeService.cs index 445daddff4..3552b2d8fc 100644 --- a/src/Umbraco.Core/Services/Implement/DataTypeService.cs +++ b/src/Umbraco.Core/Services/Implement/DataTypeService.cs @@ -424,7 +424,6 @@ namespace Umbraco.Core.Services.Implement return; } - // find ContentTypes using this IDataTypeDefinition on a PropertyType, and delete // TODO: media and members?! // TODO: non-group properties?! diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index fa046acd63..12ffa9ae4c 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -210,6 +210,9 @@ + + + @@ -852,8 +855,7 @@ - - + @@ -948,7 +950,6 @@ - diff --git a/src/Umbraco.Tests/Persistence/Querying/ContentTypeSqlMappingTests.cs b/src/Umbraco.Tests/Persistence/Querying/ContentTypeSqlMappingTests.cs index ce6447f4b5..fcf64641c8 100644 --- a/src/Umbraco.Tests/Persistence/Querying/ContentTypeSqlMappingTests.cs +++ b/src/Umbraco.Tests/Persistence/Querying/ContentTypeSqlMappingTests.cs @@ -1,200 +1,199 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NPoco; -using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.Persistence.Repositories; -using Umbraco.Core.Persistence.Repositories.Implement; -using Umbraco.Tests.TestHelpers; -using Umbraco.Tests.Testing; +// fixme - does it make any sense to keep these tests here? +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using NPoco; +//using NUnit.Framework; +//using Umbraco.Core; +//using Umbraco.Core.Models; +//using Umbraco.Core.Persistence.Dtos; +//using Umbraco.Core.Persistence.Repositories; +//using Umbraco.Core.Persistence.Repositories.Implement; +//using Umbraco.Tests.TestHelpers; +//using Umbraco.Tests.Testing; -namespace Umbraco.Tests.Persistence.Querying -{ - [TestFixture] - [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - public class ContentTypeSqlMappingTests : TestWithDatabaseBase - { - [Test] - public void Can_Map_Content_Type_Templates_And_Allowed_Types() - { - IDictionary> allAssociatedTemplates; - IDictionary> allParentContentTypeIds; - IContentType[] contentTypes; +//namespace Umbraco.Tests.Persistence.Querying +//{ +// [TestFixture] +// [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] +// public class ContentTypeSqlMappingTests : TestWithDatabaseBase +// { +// [Test] +// public void Can_Map_Content_Type_Templates_And_Allowed_Types() +// { +// IDictionary.AssociatedTemplate>> allAssociatedTemplates; +// IDictionary> allParentContentTypeIds; +// IContentType[] contentTypes; - using (var scope = ScopeProvider.CreateScope()) - { - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("umbracoNode")))); - scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 55554, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,55554", SortOrder = 1, UniqueId = new Guid("87D1EAB6-AB27-4852-B3DF-DE8DBA4A1AA0"), Text = "Template 1", NodeObjectType = Constants.ObjectTypes.Template, CreateDate = DateTime.Now }); - scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 55555, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,55555", SortOrder = 1, UniqueId = new Guid("3390BDF4-C974-4211-AA95-3812A8CE7C46"), Text = "Template 2", NodeObjectType = Constants.ObjectTypes.Template, CreateDate = DateTime.Now }); - scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99997, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99997", SortOrder = 0, UniqueId = new Guid("BB3241D5-6842-4EFA-A82A-5F56885CF528"), Text = "Test Content Type 1", NodeObjectType = Constants.ObjectTypes.DocumentType, CreateDate = DateTime.Now }); - scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99998, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99998", SortOrder = 0, UniqueId = new Guid("EEA66B06-302E-49BA-A8B2-EDF07248BC59"), Text = "Test Content Type 2", NodeObjectType = Constants.ObjectTypes.DocumentType, CreateDate = DateTime.Now }); - scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99999, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99999", SortOrder = 0, UniqueId = new Guid("C45CC083-BB27-4C1C-B448-6F703CC9B799"), Text = "Test Content Type 2", NodeObjectType = Constants.ObjectTypes.DocumentType, CreateDate = DateTime.Now }); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("umbracoNode")))); +// using (var scope = ScopeProvider.CreateScope()) +// { +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("umbracoNode")))); +// scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 55554, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,55554", SortOrder = 1, UniqueId = new Guid("87D1EAB6-AB27-4852-B3DF-DE8DBA4A1AA0"), Text = "Template 1", NodeObjectType = Constants.ObjectTypes.Template, CreateDate = DateTime.Now }); +// scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 55555, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,55555", SortOrder = 1, UniqueId = new Guid("3390BDF4-C974-4211-AA95-3812A8CE7C46"), Text = "Template 2", NodeObjectType = Constants.ObjectTypes.Template, CreateDate = DateTime.Now }); +// scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99997, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99997", SortOrder = 0, UniqueId = new Guid("BB3241D5-6842-4EFA-A82A-5F56885CF528"), Text = "Test Content Type 1", NodeObjectType = Constants.ObjectTypes.DocumentType, CreateDate = DateTime.Now }); +// scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99998, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99998", SortOrder = 0, UniqueId = new Guid("EEA66B06-302E-49BA-A8B2-EDF07248BC59"), Text = "Test Content Type 2", NodeObjectType = Constants.ObjectTypes.DocumentType, CreateDate = DateTime.Now }); +// scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99999, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99999", SortOrder = 0, UniqueId = new Guid("C45CC083-BB27-4C1C-B448-6F703CC9B799"), Text = "Test Content Type 2", NodeObjectType = Constants.ObjectTypes.DocumentType, CreateDate = DateTime.Now }); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("umbracoNode")))); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("cmsTemplate")))); - scope.Database.Insert("cmsTemplate", "pk", false, new TemplateDto { NodeId = 55554, Alias = "testTemplate1", PrimaryKey = 22221}); - scope.Database.Insert("cmsTemplate", "pk", false, new TemplateDto { NodeId = 55555, Alias = "testTemplate2", PrimaryKey = 22222 }); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("cmsTemplate")))); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("cmsTemplate")))); +// scope.Database.Insert("cmsTemplate", "pk", false, new TemplateDto { NodeId = 55554, Alias = "testTemplate1", PrimaryKey = 22221}); +// scope.Database.Insert("cmsTemplate", "pk", false, new TemplateDto { NodeId = 55555, Alias = "testTemplate2", PrimaryKey = 22222 }); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("cmsTemplate")))); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("cmsContentType")))); - scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88887, NodeId = 99997, Alias = "TestContentType1", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); - scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88888, NodeId = 99998, Alias = "TestContentType2", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); - scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88889, NodeId = 99999, Alias = "TestContentType3", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("cmsContentType")))); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("cmsContentType")))); +// scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88887, NodeId = 99997, Alias = "TestContentType1", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); +// scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88888, NodeId = 99998, Alias = "TestContentType2", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); +// scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88889, NodeId = 99999, Alias = "TestContentType3", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("cmsContentType")))); - scope.Database.Insert(new ContentTypeTemplateDto { ContentTypeNodeId = 99997, IsDefault = true, TemplateNodeId = 55555 }); - scope.Database.Insert(new ContentTypeTemplateDto { ContentTypeNodeId = 99997, IsDefault = false, TemplateNodeId = 55554 }); +// scope.Database.Insert(new ContentTypeTemplateDto { ContentTypeNodeId = 99997, IsDefault = true, TemplateNodeId = 55555 }); +// scope.Database.Insert(new ContentTypeTemplateDto { ContentTypeNodeId = 99997, IsDefault = false, TemplateNodeId = 55554 }); - scope.Database.Insert(new ContentTypeAllowedContentTypeDto { AllowedId = 99998, Id = 99997, SortOrder = 1 }); - scope.Database.Insert(new ContentTypeAllowedContentTypeDto { AllowedId = 99999, Id = 99997, SortOrder = 2}); +// scope.Database.Insert(new ContentTypeAllowedContentTypeDto { AllowedId = 99998, Id = 99997, SortOrder = 1 }); +// scope.Database.Insert(new ContentTypeAllowedContentTypeDto { AllowedId = 99999, Id = 99997, SortOrder = 2}); - scope.Database.Insert(new ContentType2ContentTypeDto { ChildId = 99999, ParentId = 99997}); - scope.Database.Insert(new ContentType2ContentTypeDto { ChildId = 99998, ParentId = 99997 }); +// scope.Database.Insert(new ContentType2ContentTypeDto { ChildId = 99999, ParentId = 99997}); +// scope.Database.Insert(new ContentType2ContentTypeDto { ChildId = 99998, ParentId = 99997 }); - contentTypes = ContentTypeRepository.ContentTypeQueryMapper.MapContentTypes( - scope.Database, SqlSyntax, out allAssociatedTemplates, out allParentContentTypeIds) - .Where(x => new[] { 99997, 99998 }.Contains(x.Id)) - .ToArray(); +// contentTypes = ContentTypeQueryMapper.GetContentTypes( +// scope.Database, out allAssociatedTemplates, out allParentContentTypeIds) +// .Where(x => new[] { 99997, 99998 }.Contains(x.Id)) +// .ToArray(); - scope.Complete(); - } +// scope.Complete(); +// } - var contentType1 = contentTypes.SingleOrDefault(x => x.Id == 99997); - Assert.IsNotNull(contentType1); +// var contentType1 = contentTypes.SingleOrDefault(x => x.Id == 99997); +// Assert.IsNotNull(contentType1); - var associatedTemplates1 = allAssociatedTemplates[contentType1.Id]; - var parentContentTypes1 = allParentContentTypeIds[contentType1.Id]; +// var associatedTemplates1 = allAssociatedTemplates[contentType1.Id]; +// var parentContentTypes1 = allParentContentTypeIds[contentType1.Id]; - Assert.AreEqual(2, contentType1.AllowedContentTypes.Count()); - Assert.AreEqual(2, associatedTemplates1.Count()); - Assert.AreEqual(0, parentContentTypes1.Count()); +// Assert.AreEqual(2, contentType1.AllowedContentTypes.Count()); +// Assert.AreEqual(2, associatedTemplates1.Count()); +// Assert.AreEqual(0, parentContentTypes1.Count()); - var contentType2 = contentTypes.SingleOrDefault(x => x.Id == 99998); - Assert.IsNotNull(contentType2); +// var contentType2 = contentTypes.SingleOrDefault(x => x.Id == 99998); +// Assert.IsNotNull(contentType2); - var associatedTemplates2 = allAssociatedTemplates[contentType2.Id]; - var parentContentTypes2 = allParentContentTypeIds[contentType2.Id]; +// var associatedTemplates2 = allAssociatedTemplates[contentType2.Id]; +// var parentContentTypes2 = allParentContentTypeIds[contentType2.Id]; - Assert.AreEqual(0, contentType2.AllowedContentTypes.Count()); - Assert.AreEqual(0, associatedTemplates2.Count()); - Assert.AreEqual(1, parentContentTypes2.Count()); - } +// Assert.AreEqual(0, contentType2.AllowedContentTypes.Count()); +// Assert.AreEqual(0, associatedTemplates2.Count()); +// Assert.AreEqual(1, parentContentTypes2.Count()); +// } - [Test] - public void Can_Map_Media_Type_And_Allowed_Types() - { - IDictionary> allParentContentTypeIds; - IMediaType[] contentTypes; +// [Test] +// public void Can_Map_Media_Type_And_Allowed_Types() +// { +// IDictionary> allParentContentTypeIds; +// IMediaType[] contentTypes; - using (var scope = ScopeProvider.CreateScope()) - { - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("umbracoNode")))); - scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99997, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99997", SortOrder = 0, UniqueId = new Guid("BB3241D5-6842-4EFA-A82A-5F56885CF528"), Text = "Test Media Type 1", NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); - scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99998, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99998", SortOrder = 0, UniqueId = new Guid("EEA66B06-302E-49BA-A8B2-EDF07248BC59"), Text = "Test Media Type 2", NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); - scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99999, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99999", SortOrder = 0, UniqueId = new Guid("C45CC083-BB27-4C1C-B448-6F703CC9B799"), Text = "Test Media Type 2", NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("umbracoNode")))); +// using (var scope = ScopeProvider.CreateScope()) +// { +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("umbracoNode")))); +// scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99997, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99997", SortOrder = 0, UniqueId = new Guid("BB3241D5-6842-4EFA-A82A-5F56885CF528"), Text = "Test Media Type 1", NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); +// scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99998, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99998", SortOrder = 0, UniqueId = new Guid("EEA66B06-302E-49BA-A8B2-EDF07248BC59"), Text = "Test Media Type 2", NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); +// scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99999, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99999", SortOrder = 0, UniqueId = new Guid("C45CC083-BB27-4C1C-B448-6F703CC9B799"), Text = "Test Media Type 2", NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now }); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("umbracoNode")))); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("cmsContentType")))); - scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88887, NodeId = 99997, Alias = "TestContentType1", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); - scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88888, NodeId = 99998, Alias = "TestContentType2", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); - scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88889, NodeId = 99999, Alias = "TestContentType3", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("cmsContentType")))); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("cmsContentType")))); +// scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88887, NodeId = 99997, Alias = "TestContentType1", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); +// scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88888, NodeId = 99998, Alias = "TestContentType2", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); +// scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88889, NodeId = 99999, Alias = "TestContentType3", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("cmsContentType")))); - scope.Database.Insert(new ContentTypeAllowedContentTypeDto { AllowedId = 99998, Id = 99997, SortOrder = 1 }); - scope.Database.Insert(new ContentTypeAllowedContentTypeDto { AllowedId = 99999, Id = 99997, SortOrder = 2 }); +// scope.Database.Insert(new ContentTypeAllowedContentTypeDto { AllowedId = 99998, Id = 99997, SortOrder = 1 }); +// scope.Database.Insert(new ContentTypeAllowedContentTypeDto { AllowedId = 99999, Id = 99997, SortOrder = 2 }); - scope.Database.Insert(new ContentType2ContentTypeDto { ChildId = 99999, ParentId = 99997 }); - scope.Database.Insert(new ContentType2ContentTypeDto { ChildId = 99998, ParentId = 99997 }); +// scope.Database.Insert(new ContentType2ContentTypeDto { ChildId = 99999, ParentId = 99997 }); +// scope.Database.Insert(new ContentType2ContentTypeDto { ChildId = 99998, ParentId = 99997 }); - contentTypes = ContentTypeRepository.ContentTypeQueryMapper.MapMediaTypes( - scope.Database, SqlSyntax, out allParentContentTypeIds) - .Where(x => (new[] { 99997, 99998 }).Contains(x.Id)) - .ToArray(); +// contentTypes = ContentTypeQueryMapper.MapMediaTypes( +// scope.Database, SqlSyntax, out allParentContentTypeIds) +// .Where(x => (new[] { 99997, 99998 }).Contains(x.Id)) +// .ToArray(); - scope.Complete(); - } +// scope.Complete(); +// } - var contentType1 = contentTypes.SingleOrDefault(x => x.Id == 99997); - Assert.IsNotNull(contentType1); +// var contentType1 = contentTypes.SingleOrDefault(x => x.Id == 99997); +// Assert.IsNotNull(contentType1); - var parentContentTypes1 = allParentContentTypeIds[contentType1.Id]; +// var parentContentTypes1 = allParentContentTypeIds[contentType1.Id]; - Assert.AreEqual(2, contentType1.AllowedContentTypes.Count()); - Assert.AreEqual(0, parentContentTypes1.Count()); +// Assert.AreEqual(2, contentType1.AllowedContentTypes.Count()); +// Assert.AreEqual(0, parentContentTypes1.Count()); - var contentType2 = contentTypes.SingleOrDefault(x => x.Id == 99998); - Assert.IsNotNull(contentType2); +// var contentType2 = contentTypes.SingleOrDefault(x => x.Id == 99998); +// Assert.IsNotNull(contentType2); - var parentContentTypes2 = allParentContentTypeIds[contentType2.Id]; +// var parentContentTypes2 = allParentContentTypeIds[contentType2.Id]; - Assert.AreEqual(0, contentType2.AllowedContentTypes.Count()); - Assert.AreEqual(1, parentContentTypes2.Count()); +// Assert.AreEqual(0, contentType2.AllowedContentTypes.Count()); +// Assert.AreEqual(1, parentContentTypes2.Count()); - } +// } - [Test] - public void Can_Map_All_Property_Groups_And_Types() - { - IDictionary allPropTypeCollection; - IDictionary allPropGroupCollection; +// [Test] +// public void Can_Map_All_Property_Groups_And_Types() +// { +// IDictionary allPropTypeCollection; +// IDictionary allPropGroupCollection; - using (var scope = ScopeProvider.CreateScope()) - { - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("umbracoNode")))); - scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 55555, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,55555", SortOrder = 1, UniqueId = new Guid("3390BDF4-C974-4211-AA95-3812A8CE7C46"), Text = "Test Data Type", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99999, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99999", SortOrder = 0, UniqueId = new Guid("129241F0-D24E-4FC3-92D1-BC2D48B7C431"), Text = "Test Content Type", NodeObjectType = Constants.ObjectTypes.DocumentType, CreateDate = DateTime.Now }); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("umbracoNode")))); +// using (var scope = ScopeProvider.CreateScope()) +// { +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("umbracoNode")))); +// scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 55555, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,55555", SortOrder = 1, UniqueId = new Guid("3390BDF4-C974-4211-AA95-3812A8CE7C46"), Text = "Test Data Type", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); +// scope.Database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 99999, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,99999", SortOrder = 0, UniqueId = new Guid("129241F0-D24E-4FC3-92D1-BC2D48B7C431"), Text = "Test Content Type", NodeObjectType = Constants.ObjectTypes.DocumentType, CreateDate = DateTime.Now }); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("umbracoNode")))); - scope.Database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 55555, EditorAlias = Constants.PropertyEditors.Aliases.TextBox, DbType = "Nvarchar" }); +// scope.Database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 55555, EditorAlias = Constants.PropertyEditors.Aliases.TextBox, DbType = "Nvarchar" }); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("cmsContentType")))); - scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88888, NodeId = 99999, Alias = "TestContentType", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("cmsContentType")))); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("cmsContentType")))); +// scope.Database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 88888, NodeId = 99999, Alias = "TestContentType", Icon = "icon-folder", Thumbnail = "folder.png", IsContainer = false, AllowAtRoot = true }); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("cmsContentType")))); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("cmsPropertyTypeGroup")))); - scope.Database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 77776, UniqueId = 77776.ToGuid(), ContentTypeNodeId = 99999, Text = "Group1", SortOrder = 1 }); - scope.Database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 77777, UniqueId = 77777.ToGuid(), ContentTypeNodeId = 99999, Text = "Group2", SortOrder = 2 }); - scope.Database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 77778, UniqueId = 77778.ToGuid(), ContentTypeNodeId = 99999, Text = "Group3", SortOrder = 3 }); - scope.Database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 77779, UniqueId = 77779.ToGuid(), ContentTypeNodeId = 99999, Text = "Group4", SortOrder = 4 }); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("cmsPropertyTypeGroup")))); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("cmsPropertyTypeGroup")))); +// scope.Database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 77776, UniqueId = 77776.ToGuid(), ContentTypeNodeId = 99999, Text = "Group1", SortOrder = 1 }); +// scope.Database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 77777, UniqueId = 77777.ToGuid(), ContentTypeNodeId = 99999, Text = "Group2", SortOrder = 2 }); +// scope.Database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 77778, UniqueId = 77778.ToGuid(), ContentTypeNodeId = 99999, Text = "Group3", SortOrder = 3 }); +// scope.Database.Insert("cmsPropertyTypeGroup", "id", false, new PropertyTypeGroupDto { Id = 77779, UniqueId = 77779.ToGuid(), ContentTypeNodeId = 99999, Text = "Group4", SortOrder = 4 }); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("cmsPropertyTypeGroup")))); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("cmsPropertyType")))); - scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66662, UniqueId = 66662.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = 77776, Alias = "property1", Name = "Property 1", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null }); - scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66663, UniqueId = 66663.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = 77776, Alias = "property2", Name = "Property 2", SortOrder = 1, Mandatory = false, ValidationRegExp = null, Description = null }); - scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66664, UniqueId = 66664.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = 77777, Alias = "property3", Name = "Property 3", SortOrder = 2, Mandatory = false, ValidationRegExp = null, Description = null }); - scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66665, UniqueId = 66665.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = 77777, Alias = "property4", Name = "Property 4", SortOrder = 3, Mandatory = false, ValidationRegExp = null, Description = null }); - scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66666, UniqueId = 66666.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = null, Alias = "property5", Name = "Property 5", SortOrder = 4, Mandatory = false, ValidationRegExp = null, Description = null }); - scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66667, UniqueId = 66667.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = 77778, Alias = "property6", Name = "Property 6", SortOrder = 5, Mandatory = false, ValidationRegExp = null, Description = null }); - scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66668, UniqueId = 66668.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = 77778, Alias = "property7", Name = "Property 7", SortOrder = 6, Mandatory = false, ValidationRegExp = null, Description = null }); - scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("cmsPropertyType")))); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SqlSyntax.GetQuotedTableName("cmsPropertyType")))); +// scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66662, UniqueId = 66662.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = 77776, Alias = "property1", Name = "Property 1", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null }); +// scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66663, UniqueId = 66663.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = 77776, Alias = "property2", Name = "Property 2", SortOrder = 1, Mandatory = false, ValidationRegExp = null, Description = null }); +// scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66664, UniqueId = 66664.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = 77777, Alias = "property3", Name = "Property 3", SortOrder = 2, Mandatory = false, ValidationRegExp = null, Description = null }); +// scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66665, UniqueId = 66665.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = 77777, Alias = "property4", Name = "Property 4", SortOrder = 3, Mandatory = false, ValidationRegExp = null, Description = null }); +// scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66666, UniqueId = 66666.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = null, Alias = "property5", Name = "Property 5", SortOrder = 4, Mandatory = false, ValidationRegExp = null, Description = null }); +// scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66667, UniqueId = 66667.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = 77778, Alias = "property6", Name = "Property 6", SortOrder = 5, Mandatory = false, ValidationRegExp = null, Description = null }); +// scope.Database.Insert("cmsPropertyType", "id", false, new PropertyTypeDto { Id = 66668, UniqueId = 66668.ToGuid(), DataTypeId = 55555, ContentTypeId = 99999, PropertyTypeGroupId = 77778, Alias = "property7", Name = "Property 7", SortOrder = 6, Mandatory = false, ValidationRegExp = null, Description = null }); +// scope.Database.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF ", SqlSyntax.GetQuotedTableName("cmsPropertyType")))); - ContentTypeRepository.ContentTypeQueryMapper.MapGroupsAndProperties(new[] { 99999 }, scope.Database, SqlSyntax, true, out allPropTypeCollection, out allPropGroupCollection); +// ContentTypeQueryMapper.MapGroupsAndProperties_(new[] { 99999 }, scope.Database, SqlSyntax, true, out allPropTypeCollection, out allPropGroupCollection); - scope.Complete(); - } +// scope.Complete(); +// } - var propGroupCollection = allPropGroupCollection[99999]; - var propTypeCollection = allPropTypeCollection[99999]; +// var propGroupCollection = allPropGroupCollection[99999]; +// var propTypeCollection = allPropTypeCollection[99999]; - Assert.AreEqual(4, propGroupCollection.Count); - Assert.AreEqual(2, propGroupCollection["Group1"].PropertyTypes.Count); - Assert.IsTrue(propGroupCollection["Group1"].PropertyTypes.Contains("property1")); - Assert.IsTrue(propGroupCollection["Group1"].PropertyTypes.Contains("property2")); - Assert.AreEqual(2, propGroupCollection["Group2"].PropertyTypes.Count); - Assert.IsTrue(propGroupCollection["Group2"].PropertyTypes.Contains("property3")); - Assert.IsTrue(propGroupCollection["Group2"].PropertyTypes.Contains("property4")); - Assert.AreEqual(2, propGroupCollection["Group3"].PropertyTypes.Count); - Assert.IsTrue(propGroupCollection["Group3"].PropertyTypes.Contains("property6")); - Assert.IsTrue(propGroupCollection["Group3"].PropertyTypes.Contains("property7")); - Assert.AreEqual(0, propGroupCollection["Group4"].PropertyTypes.Count); +// Assert.AreEqual(4, propGroupCollection.Count); +// Assert.AreEqual(2, propGroupCollection["Group1"].PropertyTypes.Count); +// Assert.IsTrue(propGroupCollection["Group1"].PropertyTypes.Contains("property1")); +// Assert.IsTrue(propGroupCollection["Group1"].PropertyTypes.Contains("property2")); +// Assert.AreEqual(2, propGroupCollection["Group2"].PropertyTypes.Count); +// Assert.IsTrue(propGroupCollection["Group2"].PropertyTypes.Contains("property3")); +// Assert.IsTrue(propGroupCollection["Group2"].PropertyTypes.Contains("property4")); +// Assert.AreEqual(2, propGroupCollection["Group3"].PropertyTypes.Count); +// Assert.IsTrue(propGroupCollection["Group3"].PropertyTypes.Contains("property6")); +// Assert.IsTrue(propGroupCollection["Group3"].PropertyTypes.Contains("property7")); +// Assert.AreEqual(0, propGroupCollection["Group4"].PropertyTypes.Count); - Assert.AreEqual(1, propTypeCollection.Count); - Assert.IsTrue(propTypeCollection.Contains("property5")); - - } - - } -} +// Assert.AreEqual(1, propTypeCollection.Count); +// Assert.IsTrue(propTypeCollection.Contains("property5")); +// } +// } +//} diff --git a/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs index 03aae74920..54ef156b38 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs @@ -35,7 +35,8 @@ namespace Umbraco.Tests.Persistence.Repositories var cacheHelper = AppCaches.Disabled; var templateRepository = new TemplateRepository(scopeAccessor, cacheHelper, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(scopeAccessor, cacheHelper, Logger); - contentTypeRepository = new ContentTypeRepository(scopeAccessor, cacheHelper, Logger, templateRepository); + var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository); + contentTypeRepository = new ContentTypeRepository(scopeAccessor, cacheHelper, Logger, commonRepository); var languageRepository = new LanguageRepository(scopeAccessor, cacheHelper, Logger); var repository = new DocumentRepository(scopeAccessor, cacheHelper, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository); return repository; @@ -44,13 +45,16 @@ namespace Umbraco.Tests.Persistence.Repositories private ContentTypeRepository CreateRepository(IScopeAccessor scopeAccessor) { var templateRepository = new TemplateRepository(scopeAccessor, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock()); - var contentTypeRepository = new ContentTypeRepository(scopeAccessor, AppCaches.Disabled, Logger, templateRepository); + var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository); + var contentTypeRepository = new ContentTypeRepository(scopeAccessor, AppCaches.Disabled, Logger, commonRepository); return contentTypeRepository; } private MediaTypeRepository CreateMediaTypeRepository(IScopeAccessor scopeAccessor) { - var contentTypeRepository = new MediaTypeRepository(scopeAccessor, AppCaches.Disabled, Logger); + var templateRepository = new TemplateRepository(scopeAccessor, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock()); + var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository); + var contentTypeRepository = new MediaTypeRepository(scopeAccessor, AppCaches.Disabled, Logger, commonRepository); return contentTypeRepository; } @@ -60,7 +64,7 @@ namespace Umbraco.Tests.Persistence.Repositories } // TODO: Add test to verify SetDefaultTemplates updates both AllowedTemplates and DefaultTemplate(id). - + [Test] public void Maps_Templates_Correctly() { @@ -80,13 +84,13 @@ namespace Umbraco.Tests.Persistence.Repositories { templateRepo.Save(template); } - + var contentType = MockedContentTypes.CreateSimpleContentType(); contentType.AllowedTemplates = new[] { templates[0], templates[1] }; contentType.SetDefaultTemplate(templates[0]); repository.Save(contentType); - + //re-get var result = repository.Get(contentType.Id); @@ -107,16 +111,16 @@ namespace Umbraco.Tests.Persistence.Repositories var repository = CreateRepository((IScopeAccessor) provider); var container1 = new EntityContainer(Constants.ObjectTypes.DocumentType) { Name = "blah1" }; containerRepository.Save(container1); - + var container2 = new EntityContainer(Constants.ObjectTypes.DocumentType) { Name = "blah2", ParentId = container1.Id }; containerRepository.Save(container2); - + var contentType = (IContentType)MockedContentTypes.CreateBasicContentType("asdfasdf"); contentType.ParentId = container2.Id; repository.Save(contentType); - + //create a var contentType2 = (IContentType)new ContentType(contentType, "hello") @@ -125,10 +129,10 @@ namespace Umbraco.Tests.Persistence.Repositories }; contentType.ParentId = contentType.Id; repository.Save(contentType2); - + var result = repository.Move(contentType, container1).ToArray(); - + Assert.AreEqual(2, result.Count()); @@ -152,7 +156,7 @@ namespace Umbraco.Tests.Persistence.Repositories var containerRepository = CreateContainerRepository((IScopeAccessor) provider, Constants.ObjectTypes.DocumentTypeContainer); var container = new EntityContainer(Constants.ObjectTypes.DocumentType) { Name = "blah" }; containerRepository.Save(container); - + Assert.That(container.Id, Is.GreaterThan(0)); var found = containerRepository.Get(container.Id); @@ -176,7 +180,7 @@ namespace Umbraco.Tests.Persistence.Repositories containerRepository.Save(container2); container3 = new EntityContainer(Constants.ObjectTypes.DocumentType) { Name = "container3" }; containerRepository.Save(container3); - + Assert.That(container1.Id, Is.GreaterThan(0)); Assert.That(container2.Id, Is.GreaterThan(0)); Assert.That(container3.Id, Is.GreaterThan(0)); @@ -201,11 +205,11 @@ namespace Umbraco.Tests.Persistence.Repositories var containerRepository = CreateContainerRepository((IScopeAccessor) provider, Constants.ObjectTypes.DocumentTypeContainer); var container = new EntityContainer(Constants.ObjectTypes.DocumentType) { Name = "blah" }; containerRepository.Save(container); - + // Act containerRepository.Delete(container); - + var found = containerRepository.Get(container.Id); Assert.IsNull(found); @@ -222,12 +226,12 @@ namespace Umbraco.Tests.Persistence.Repositories var repository = CreateRepository((IScopeAccessor) provider); var container = new EntityContainer(Constants.ObjectTypes.MediaType) { Name = "blah" }; containerRepository.Save(container); - + var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test", propertyGroupName: "testGroup"); contentType.ParentId = container.Id; repository.Save(contentType); - + Assert.AreEqual(container.Id, contentType.ParentId); } @@ -243,16 +247,16 @@ namespace Umbraco.Tests.Persistence.Repositories var repository = CreateMediaTypeRepository((IScopeAccessor) provider); var container = new EntityContainer(Constants.ObjectTypes.MediaType) { Name = "blah" }; containerRepository.Save(container); - + IMediaType contentType = MockedContentTypes.CreateSimpleMediaType("test", "Test", propertyGroupName: "testGroup"); contentType.ParentId = container.Id; repository.Save(contentType); - + // Act containerRepository.Delete(container); - + var found = containerRepository.Get(container.Id); Assert.IsNull(found); @@ -274,7 +278,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Act var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test", propertyGroupName: "testGroup"); repository.Save(contentType); - + var fetched = repository.Get(contentType.Id); @@ -294,7 +298,7 @@ namespace Umbraco.Tests.Persistence.Repositories Assert.AreNotEqual(propertyType.Key, Guid.Empty); } - TestHelper.AssertPropertyValuesAreEqual(contentType, fetched, "yyyy-MM-dd HH:mm:ss", ignoreProperties: new [] { "DefaultTemplate", "AllowedTemplates", "UpdateDate" }); + TestHelper.AssertPropertyValuesAreEqual(fetched, contentType, "yyyy-MM-dd HH:mm:ss", ignoreProperties: new [] { "DefaultTemplate", "AllowedTemplates", "UpdateDate" }); } } @@ -323,7 +327,7 @@ namespace Umbraco.Tests.Persistence.Repositories Assert.AreEqual(4, mapped.PropertyTypes.Count()); repository.Save(mapped); - + Assert.AreEqual(4, mapped.PropertyTypes.Count()); @@ -371,7 +375,7 @@ namespace Umbraco.Tests.Persistence.Repositories DataTypeId = -88 }); repository.Save(contentType); - + var dirty = contentType.IsDirty(); @@ -469,7 +473,7 @@ namespace Umbraco.Tests.Persistence.Repositories Assert.IsTrue(mapped.PropertyTypes.Any(x => x.Alias == "subtitle")); repository.Save(mapped); - + var dirty = mapped.IsDirty(); @@ -500,11 +504,11 @@ namespace Umbraco.Tests.Persistence.Repositories // Act var contentType = MockedContentTypes.CreateSimpleContentType(); repository.Save(contentType); - + var contentType2 = repository.Get(contentType.Id); repository.Delete(contentType2); - + var exists = repository.Exists(contentType.Id); @@ -528,13 +532,13 @@ namespace Umbraco.Tests.Persistence.Repositories repository.Save(ctMain); repository.Save(ctChild1); repository.Save(ctChild2); - + // Act var resolvedParent = repository.Get(ctMain.Id); repository.Delete(resolvedParent); - + // Assert Assert.That(repository.Exists(ctMain.Id), Is.False); @@ -546,19 +550,27 @@ namespace Umbraco.Tests.Persistence.Repositories [Test] public void Can_Perform_Query_On_ContentTypeRepository_Sort_By_Name() { + IContentType contentType; + // Arrange var provider = TestObjects.GetScopeProvider(Logger); using (var scope = provider.CreateScope()) { var repository = CreateRepository((IScopeAccessor) provider); - var contentType = repository.Get(NodeDto.NodeIdSeed + 1); + contentType = repository.Get(NodeDto.NodeIdSeed + 1); var child1 = MockedContentTypes.CreateSimpleContentType("abc", "abc", contentType, randomizeAliases: true); repository.Save(child1); var child3 = MockedContentTypes.CreateSimpleContentType("zyx", "zyx", contentType, randomizeAliases: true); repository.Save(child3); var child2 = MockedContentTypes.CreateSimpleContentType("a123", "a123", contentType, randomizeAliases: true); repository.Save(child2); - + + scope.Complete(); + } + + using (var scope = provider.CreateScope()) + { + var repository = CreateRepository((IScopeAccessor)provider); // Act var contentTypes = repository.Get(scope.SqlContext.Query().Where(x => x.ParentId == contentType.Id)); @@ -601,7 +613,7 @@ namespace Umbraco.Tests.Persistence.Repositories var contentType = repository.Get(NodeDto.NodeIdSeed + 1); var childContentType = MockedContentTypes.CreateSimpleContentType("blah", "Blah", contentType, randomizeAliases:true); repository.Save(childContentType); - + // Act var result = repository.Get(childContentType.Key); @@ -703,7 +715,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Act contentType.PropertyGroups["Meta"].PropertyTypes.Remove("description"); repository.Save(contentType); - + var result = repository.Get(NodeDto.NodeIdSeed + 1); @@ -779,7 +791,7 @@ namespace Umbraco.Tests.Persistence.Repositories Assert.That(contentType.PropertyTypes.Count(), Is.EqualTo(5)); repository.Save(contentType); - + // Assert var updated = repository.Get(NodeDto.NodeIdSeed + 1); @@ -804,7 +816,7 @@ namespace Umbraco.Tests.Persistence.Repositories var simpleSubpageContentType = MockedContentTypes.CreateSimpleContentType("umbSimpleSubpage", "Simple Subpage"); repository.Save(subpageContentType); repository.Save(simpleSubpageContentType); - + // Act var contentType = repository.Get(NodeDto.NodeIdSeed); @@ -814,7 +826,7 @@ namespace Umbraco.Tests.Persistence.Repositories new ContentTypeSort(new Lazy(() => simpleSubpageContentType.Id), 1, simpleSubpageContentType.Alias) }; repository.Save(contentType); - + //Assert var updated = repository.Get(NodeDto.NodeIdSeed); @@ -838,12 +850,12 @@ namespace Umbraco.Tests.Persistence.Repositories var subpage = MockedContent.CreateTextpageContent(contentType, "Text Page 1", contentType.Id); contentRepository.Save(subpage); - + // Act contentType.RemovePropertyType("keywords"); repository.Save(contentType); - + // Assert Assert.That(contentType.PropertyTypes.Count(), Is.EqualTo(3)); @@ -865,13 +877,13 @@ namespace Umbraco.Tests.Persistence.Repositories var subpage = MockedContent.CreateTextpageContent(contentType, "Text Page 1", contentType.Id); contentRepository.Save(subpage); - + // Act var propertyGroup = contentType.PropertyGroups.First(x => x.Name == "Meta"); propertyGroup.PropertyTypes.Add(new PropertyType("test", ValueStorageType.Ntext, "metaAuthor") { Name = "Meta Author", Description = "", Mandatory = false, SortOrder = 1, DataTypeId = -88 }); repository.Save(contentType); - + // Assert Assert.That(contentType.PropertyTypes.Count(), Is.EqualTo(5)); @@ -893,18 +905,18 @@ namespace Umbraco.Tests.Persistence.Repositories var subpage = MockedContent.CreateTextpageContent(contentType, "Text Page 1", contentType.Id); contentRepository.Save(subpage); - + var propertyGroup = contentType.PropertyGroups.First(x => x.Name == "Meta"); propertyGroup.PropertyTypes.Add(new PropertyType("test", ValueStorageType.Ntext, "metaAuthor") { Name = "Meta Author", Description = "", Mandatory = false, SortOrder = 1, DataTypeId = -88 }); repository.Save(contentType); - + // Act var content = contentRepository.Get(subpage.Id); content.SetValue("metaAuthor", "John Doe"); contentRepository.Save(content); - + //Assert var updated = contentRepository.Get(subpage.Id); @@ -927,7 +939,7 @@ namespace Umbraco.Tests.Persistence.Repositories var subpage = MockedContent.CreateTextpageContent(contentType, "Text Page 1", contentType.Id); contentRepository.Save(subpage); - + //Remove PropertyType contentType.RemovePropertyType("keywords"); @@ -935,13 +947,13 @@ namespace Umbraco.Tests.Persistence.Repositories var propertyGroup = contentType.PropertyGroups.First(x => x.Name == "Meta"); propertyGroup.PropertyTypes.Add(new PropertyType("test", ValueStorageType.Ntext, "metaAuthor") { Name = "Meta Author", Description = "", Mandatory = false, SortOrder = 1, DataTypeId = -88 }); repository.Save(contentType); - + // Act var content = contentRepository.Get(subpage.Id); content.SetValue("metaAuthor", "John Doe"); contentRepository.Save(content); - + //Assert var updated = contentRepository.Get(subpage.Id); diff --git a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs index 2c4f3f1908..a2133976e8 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs @@ -66,7 +66,8 @@ namespace Umbraco.Tests.Persistence.Repositories templateRepository = new TemplateRepository(scopeAccessor, appCaches, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(scopeAccessor, appCaches, Logger); - contentTypeRepository = new ContentTypeRepository(scopeAccessor, appCaches, Logger, templateRepository); + var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository); + contentTypeRepository = new ContentTypeRepository(scopeAccessor, appCaches, Logger, commonRepository); var languageRepository = new LanguageRepository(scopeAccessor, appCaches, Logger); var repository = new DocumentRepository(scopeAccessor, appCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository); return repository; diff --git a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs index d0da875332..f3accf429e 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs @@ -22,7 +22,8 @@ namespace Umbraco.Tests.Persistence.Repositories var accessor = (IScopeAccessor) provider; var templateRepository = new TemplateRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(accessor, Core.Cache.AppCaches.Disabled, Logger); - contentTypeRepository = new ContentTypeRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, templateRepository); + var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository); + contentTypeRepository = new ContentTypeRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, commonRepository); languageRepository = new LanguageRepository(accessor, Core.Cache.AppCaches.Disabled, Logger); documentRepository = new DocumentRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository); var domainRepository = new DomainRepository(accessor, Core.Cache.AppCaches.Disabled, Logger); diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs index 1c1b5e60f4..b58079aa29 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs @@ -4,6 +4,7 @@ using Moq; using NUnit.Framework; using Umbraco.Core.Cache; using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.Persistence; @@ -35,7 +36,9 @@ namespace Umbraco.Tests.Persistence.Repositories appCaches = appCaches ?? AppCaches; var scopeAccessor = (IScopeAccessor) provider; - mediaTypeRepository = new MediaTypeRepository(scopeAccessor, appCaches, Logger); + var templateRepository = new TemplateRepository(scopeAccessor, appCaches, Logger, TestObjects.GetFileSystemsMock()); + var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository); + mediaTypeRepository = new MediaTypeRepository(scopeAccessor, appCaches, Logger, commonRepository); var tagRepository = new TagRepository(scopeAccessor, appCaches, Logger); var repository = new MediaRepository(scopeAccessor, appCaches, Logger, mediaTypeRepository, tagRepository, Mock.Of()); return repository; diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs index 49bb93f2a7..d854ec9859 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs @@ -6,7 +6,6 @@ using Umbraco.Core.Cache; using Umbraco.Core.Models; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.Scoping; using Umbraco.Tests.TestHelpers; @@ -21,7 +20,10 @@ namespace Umbraco.Tests.Persistence.Repositories { private MediaTypeRepository CreateRepository(IScopeProvider provider) { - return new MediaTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger); + var cacheHelper = AppCaches.Disabled; + var templateRepository = new TemplateRepository((IScopeAccessor)provider, cacheHelper, Logger, TestObjects.GetFileSystemsMock()); + var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, templateRepository); + return new MediaTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository); } private EntityContainerRepository CreateContainerRepository(IScopeProvider provider) diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs index c46a090685..92c3da5f68 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs @@ -29,7 +29,9 @@ namespace Umbraco.Tests.Persistence.Repositories private MemberRepository CreateRepository(IScopeProvider provider, out MemberTypeRepository memberTypeRepository, out MemberGroupRepository memberGroupRepository) { var accessor = (IScopeAccessor) provider; - memberTypeRepository = new MemberTypeRepository(accessor, AppCaches.Disabled, Logger); + var templateRepository = Mock.Of(); + var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository); + memberTypeRepository = new MemberTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository); memberGroupRepository = new MemberGroupRepository(accessor, AppCaches.Disabled, Logger); var tagRepo = new TagRepository(accessor, AppCaches.Disabled, Logger); var repository = new MemberRepository(accessor, AppCaches.Disabled, Logger, memberTypeRepository, memberGroupRepository, tagRepo, Mock.Of()); @@ -196,17 +198,17 @@ namespace Umbraco.Tests.Persistence.Repositories var memberType = MockedContentTypes.CreateSimpleMemberType(); memberTypeRepository.Save(memberType); - + var member = MockedMember.CreateSimpleMember(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty"); repository.Save(member); - + sut = repository.Get(member.Id); //when the password is null it will not overwrite what is already there. sut.RawPasswordValue = null; repository.Save(sut); - + sut = repository.Get(member.Id); Assert.That(sut.RawPasswordValue, Is.EqualTo("123")); @@ -226,17 +228,17 @@ namespace Umbraco.Tests.Persistence.Repositories var memberType = MockedContentTypes.CreateSimpleMemberType(); memberTypeRepository.Save(memberType); - + var member = MockedMember.CreateSimpleMember(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty"); repository.Save(member); - + sut = repository.Get(member.Id); sut.Username = "This is new"; sut.Email = "thisisnew@hello.com"; repository.Save(sut); - + sut = repository.Get(member.Id); Assert.That(sut.Email, Is.EqualTo("thisisnew@hello.com")); @@ -278,7 +280,7 @@ namespace Umbraco.Tests.Persistence.Repositories { memberType = MockedContentTypes.CreateSimpleMemberType(); memberTypeRepository.Save(memberType); - + } var member = MockedMember.CreateSimpleMember(memberType, name ?? "Johnny Hefty", email ?? "johnny@example.com", password ?? "123", username ?? "hefty", key); diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs index 0c2314fd47..67f022d8ad 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs @@ -22,7 +22,9 @@ namespace Umbraco.Tests.Persistence.Repositories { private MemberTypeRepository CreateRepository(IScopeProvider provider) { - return new MemberTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Mock.Of()); + var templateRepository = Mock.Of(); + var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, templateRepository); + return new MemberTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Mock.Of(), commonRepository); } [Test] @@ -35,7 +37,6 @@ namespace Umbraco.Tests.Persistence.Repositories var memberType = (IMemberType) MockedContentTypes.CreateSimpleMemberType(); repository.Save(memberType); - var sut = repository.Get(memberType.Id); @@ -88,7 +89,7 @@ namespace Umbraco.Tests.Persistence.Repositories var memberType = MockedContentTypes.CreateSimpleMemberType(); memberType.Alias = null; - + Assert.Throws(() => repository.Save(memberType)); } @@ -104,13 +105,13 @@ namespace Umbraco.Tests.Persistence.Repositories var memberType1 = MockedContentTypes.CreateSimpleMemberType(); repository.Save(memberType1); - + var memberType2 = MockedContentTypes.CreateSimpleMemberType(); memberType2.Name = "AnotherType"; memberType2.Alias = "anotherType"; repository.Save(memberType2); - + var result = repository.GetMany(); @@ -129,13 +130,13 @@ namespace Umbraco.Tests.Persistence.Repositories var memberType1 = MockedContentTypes.CreateSimpleMemberType(); repository.Save(memberType1); - + var memberType2 = MockedContentTypes.CreateSimpleMemberType(); memberType2.Name = "AnotherType"; memberType2.Alias = "anotherType"; repository.Save(memberType2); - + var result = ((IReadRepository)repository).GetMany(memberType1.Key, memberType2.Key); @@ -154,13 +155,13 @@ namespace Umbraco.Tests.Persistence.Repositories var memberType1 = MockedContentTypes.CreateSimpleMemberType(); repository.Save(memberType1); - + var memberType2 = MockedContentTypes.CreateSimpleMemberType(); memberType2.Name = "AnotherType"; memberType2.Alias = "anotherType"; repository.Save(memberType2); - + var result = repository.Get(memberType1.Key); @@ -183,14 +184,14 @@ namespace Umbraco.Tests.Persistence.Repositories var memberType1 = MockedContentTypes.CreateSimpleMemberType(); memberType1.PropertyTypeCollection.Clear(); repository.Save(memberType1); - + var memberType2 = MockedContentTypes.CreateSimpleMemberType(); memberType2.PropertyTypeCollection.Clear(); memberType2.Name = "AnotherType"; memberType2.Alias = "anotherType"; repository.Save(memberType2); - + var result = repository.GetMany(); @@ -210,7 +211,7 @@ namespace Umbraco.Tests.Persistence.Repositories IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); repository.Save(memberType); - + memberType = repository.Get(memberType.Id); Assert.That(memberType, Is.Not.Null); } @@ -226,7 +227,7 @@ namespace Umbraco.Tests.Persistence.Repositories IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); repository.Save(memberType); - + memberType = repository.Get(memberType.Key); Assert.That(memberType, Is.Not.Null); } @@ -242,7 +243,7 @@ namespace Umbraco.Tests.Persistence.Repositories IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); repository.Save(memberType); - + memberType = repository.Get(memberType.Id); @@ -265,7 +266,7 @@ namespace Umbraco.Tests.Persistence.Repositories IMemberType memberType2 = MockedContentTypes.CreateSimpleMemberType("test2"); repository.Save(memberType1); repository.Save(memberType2); - + var m1Ids = memberType1.PropertyTypes.Select(x => x.Id).ToArray(); var m2Ids = memberType2.PropertyTypes.Select(x => x.Id).ToArray(); @@ -286,11 +287,11 @@ namespace Umbraco.Tests.Persistence.Repositories // Act IMemberType memberType = MockedContentTypes.CreateSimpleMemberType(); repository.Save(memberType); - + var contentType2 = repository.Get(memberType.Id); repository.Delete(contentType2); - + var exists = repository.Exists(memberType.Id); diff --git a/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs index 684c8f9a22..bab06922c7 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs @@ -307,7 +307,8 @@ namespace Umbraco.Tests.Persistence.Repositories var accessor = (IScopeAccessor) provider; var templateRepository = new TemplateRepository(accessor, AppCaches, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(accessor, AppCaches, Logger); - contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, Logger, templateRepository); + var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository); + contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, Logger, commonRepository); var languageRepository = new LanguageRepository(accessor, AppCaches, Logger); var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository); return repository; diff --git a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs index ddbf3bfc9d..d074c4b689 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs @@ -955,7 +955,8 @@ namespace Umbraco.Tests.Persistence.Repositories var accessor = (IScopeAccessor) provider; var templateRepository = new TemplateRepository(accessor, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(accessor, AppCaches.Disabled, Logger); - contentTypeRepository = new ContentTypeRepository(accessor, AppCaches.Disabled, Logger, templateRepository); + var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository); + contentTypeRepository = new ContentTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository); var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, Logger); var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository); return repository; @@ -964,8 +965,10 @@ namespace Umbraco.Tests.Persistence.Repositories private MediaRepository CreateMediaRepository(IScopeProvider provider, out MediaTypeRepository mediaTypeRepository) { var accessor = (IScopeAccessor) provider; + var templateRepository = new TemplateRepository(accessor, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(accessor, AppCaches.Disabled, Logger); - mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches.Disabled, Logger); + var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository); + mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository); var repository = new MediaRepository(accessor, AppCaches.Disabled, Logger, mediaTypeRepository, tagRepository, Mock.Of()); return repository; } diff --git a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs index 8f0150277d..3933995a28 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs @@ -238,7 +238,8 @@ namespace Umbraco.Tests.Persistence.Repositories var templateRepository = CreateRepository(ScopeProvider); var tagRepository = new TagRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger); - var contentTypeRepository = new ContentTypeRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger, templateRepository); + var commonRepository = new ContentTypeCommonRepository(ScopeProvider, templateRepository); + var contentTypeRepository = new ContentTypeRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger, commonRepository); var languageRepository = new LanguageRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger); var contentRepo = new DocumentRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository); diff --git a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs index 1d50fcac9e..f6e9e68b4e 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs @@ -3,8 +3,6 @@ using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; -using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence.Mappers; @@ -26,7 +24,9 @@ namespace Umbraco.Tests.Persistence.Repositories private MediaRepository CreateMediaRepository(IScopeProvider provider, out IMediaTypeRepository mediaTypeRepository) { var accessor = (IScopeAccessor) provider; - mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches, Mock.Of()); + var templateRepository = new TemplateRepository(accessor, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock()); + var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository); + mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches, Mock.Of(), commonRepository); var tagRepository = new TagRepository(accessor, AppCaches, Mock.Of()); var repository = new MediaRepository(accessor, AppCaches, Mock.Of(), mediaTypeRepository, tagRepository, Mock.Of()); return repository; @@ -43,7 +43,8 @@ namespace Umbraco.Tests.Persistence.Repositories var accessor = (IScopeAccessor) provider; templateRepository = new TemplateRepository(accessor, AppCaches, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(accessor, AppCaches, Logger); - contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, Logger, templateRepository); + var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository); + contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, Logger, commonRepository); var languageRepository = new LanguageRepository(accessor, AppCaches, Logger); var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository); return repository; diff --git a/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs b/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs index dcbf5919eb..2afbdaca8f 100644 --- a/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs +++ b/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs @@ -316,7 +316,7 @@ namespace Umbraco.Tests.Persistence helper.CreateTable(); helper.CreateTable(); - helper.CreateTable(); + helper.CreateTable(); scope.Complete(); } diff --git a/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs b/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs index cb7a984ff3..08c3243fe2 100644 --- a/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs +++ b/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs @@ -165,7 +165,8 @@ namespace Umbraco.Tests.Services { var tRepository = new TemplateRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepo = new TagRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger); - var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, tRepository); + var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, tRepository); + var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository); var languageRepository = new LanguageRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger); var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository); @@ -198,7 +199,8 @@ namespace Umbraco.Tests.Services { var tRepository = new TemplateRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepo = new TagRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger); - var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, tRepository); + var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, tRepository); + var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository); var languageRepository = new LanguageRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger); var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository); @@ -229,7 +231,8 @@ namespace Umbraco.Tests.Services { var tRepository = new TemplateRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepo = new TagRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger); - var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, tRepository); + var commonRepository = new ContentTypeCommonRepository((IScopeAccessor) provider, tRepository); + var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository); var languageRepository = new LanguageRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger); var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository); @@ -263,7 +266,8 @@ namespace Umbraco.Tests.Services { var tRepository = new TemplateRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepo = new TagRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger); - var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, tRepository); + var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, tRepository); + var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository); var languageRepository = new LanguageRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger); var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository); diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 04cdc2aab7..8d7c61d93e 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -757,7 +757,7 @@ namespace Umbraco.Tests.Services content = ServiceContext.ContentService.GetById(content.Id); Assert.IsFalse(content.IsCulturePublished(langFr.IsoCode)); Assert.IsTrue(content.IsCulturePublished(langUk.IsoCode)); - + } @@ -784,7 +784,7 @@ namespace Umbraco.Tests.Services IContent content = new Content("content", Constants.System.Root, contentType); content.SetCultureName("content-en", langGB.IsoCode); content.SetCultureName("content-fr", langFr.IsoCode); - + Assert.IsTrue(ServiceContext.ContentService.SaveAndPublish(content, new []{ langGB.IsoCode , langFr.IsoCode }).Success); //re-get @@ -1579,7 +1579,7 @@ namespace Umbraco.Tests.Services var contentType = MockedContentTypes.CreateAllTypesContentType("test", "test"); ServiceContext.ContentTypeService.Save(contentType, Constants.Security.SuperUserId); - + object obj = new { @@ -2989,7 +2989,8 @@ namespace Umbraco.Tests.Services var accessor = (IScopeAccessor) provider; var templateRepository = new TemplateRepository(accessor, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(accessor, AppCaches.Disabled, Logger); - contentTypeRepository = new ContentTypeRepository(accessor, AppCaches.Disabled, Logger, templateRepository); + var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository); + contentTypeRepository = new ContentTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository); var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, Logger); var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository); return repository; diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs index 341371ca02..a0b5f01a1f 100644 --- a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs @@ -1654,17 +1654,31 @@ namespace Umbraco.Tests.Services // create 'page' content type with a 'Content_' group var page = MockedContentTypes.CreateSimpleContentType("page", "Page", null, false, "Content_"); - Assert.IsTrue(page.PropertyGroups.Contains("Content_")); + Assert.AreEqual(1, page.PropertyGroups.Count); + Assert.AreEqual("Content_", page.PropertyGroups.First().Name); Assert.AreEqual(3, page.PropertyTypes.Count()); + Assert.AreEqual("Title", page.PropertyTypes.First().Name); + Assert.AreEqual("Body Text", page.PropertyTypes.Skip(1).First().Name); + Assert.AreEqual("Author", page.PropertyTypes.Skip(2).First().Name); service.Save(page); // create 'contentPage' content type as a child of 'page' var contentPage = MockedContentTypes.CreateSimpleContentType("contentPage", "Content Page", page, true); + Assert.AreEqual(1, page.PropertyGroups.Count); + Assert.AreEqual("Content_", page.PropertyGroups.First().Name); Assert.AreEqual(3, contentPage.PropertyTypes.Count()); + Assert.AreEqual("Title", contentPage.PropertyTypes.First().Name); + Assert.AreEqual("Body Text", contentPage.PropertyTypes.Skip(1).First().Name); + Assert.AreEqual("Author", contentPage.PropertyTypes.Skip(2).First().Name); service.Save(contentPage); // add 'Content' group to 'meta' content type var meta = MockedContentTypes.CreateMetaContentType(); + Assert.AreEqual(1, meta.PropertyGroups.Count); + Assert.AreEqual("Meta", meta.PropertyGroups.First().Name); + Assert.AreEqual(2, meta.PropertyTypes.Count()); + Assert.AreEqual("Meta Keywords", meta.PropertyTypes.First().Name); + Assert.AreEqual("Meta Description", meta.PropertyTypes.Skip(1).First().Name); meta.AddPropertyGroup("Content"); Assert.AreEqual(2, meta.PropertyTypes.Count()); service.Save(meta); diff --git a/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs index 493381a5a3..86ff709541 100644 --- a/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs @@ -4,6 +4,8 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Persistence.Repositories; +using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.Services; using Umbraco.Core.Services.Changes; using Umbraco.Web.PublishedCache; @@ -14,14 +16,16 @@ namespace Umbraco.Web.Cache { private readonly IPublishedSnapshotService _publishedSnapshotService; private readonly IPublishedModelFactory _publishedModelFactory; + private readonly IContentTypeCommonRepository _contentTypeCommonRepository; private readonly IdkMap _idkMap; - public ContentTypeCacheRefresher(AppCaches appCaches, IPublishedSnapshotService publishedSnapshotService, IPublishedModelFactory publishedModelFactory, IdkMap idkMap) + public ContentTypeCacheRefresher(AppCaches appCaches, IPublishedSnapshotService publishedSnapshotService, IPublishedModelFactory publishedModelFactory, IdkMap idkMap, IContentTypeCommonRepository contentTypeCommonRepository) : base(appCaches) { _publishedSnapshotService = publishedSnapshotService; _publishedModelFactory = publishedModelFactory; _idkMap = idkMap; + _contentTypeCommonRepository = contentTypeCommonRepository; } #region Define @@ -44,6 +48,8 @@ namespace Umbraco.Web.Cache // we should NOT directly clear caches here, but instead ask whatever class // is managing the cache to please clear that cache properly + _contentTypeCommonRepository.ClearCache(); // always + if (payloads.Any(x => x.ItemType == typeof(IContentType).Name)) { ClearAllIsolatedCacheByEntityType();