From 512e59871e2c3c8bc533d0b8295d529d18799286 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 21 Jan 2015 17:43:03 +1100 Subject: [PATCH] Fixed issues relating to domain repository and added more tests, starts creating DomainService --- .../Persistence/Mappers/DomainMapper.cs | 29 ++++ .../Persistence/Mappers/LanguageMapper.cs | 2 - .../Persistence/Mappers/MapperAttribute.cs | 18 --- .../Persistence/Mappers/ModelDtoMapper.cs | 86 ----------- .../Repositories/DomainRepository.cs | 23 ++- .../Interfaces/IDomainRepository.cs | 2 +- src/Umbraco.Core/Services/ContentService.cs | 8 +- src/Umbraco.Core/Services/DomainService.cs | 27 ++++ src/Umbraco.Core/Umbraco.Core.csproj | 2 + .../Repositories/DomainRepositoryTest.cs | 138 ++++++++++++++++++ 10 files changed, 220 insertions(+), 115 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/Mappers/DomainMapper.cs delete mode 100644 src/Umbraco.Core/Persistence/Mappers/MapperAttribute.cs delete mode 100644 src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs create mode 100644 src/Umbraco.Core/Services/DomainService.cs diff --git a/src/Umbraco.Core/Persistence/Mappers/DomainMapper.cs b/src/Umbraco.Core/Persistence/Mappers/DomainMapper.cs new file mode 100644 index 0000000000..15d0852158 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Mappers/DomainMapper.cs @@ -0,0 +1,29 @@ +using System.Collections.Concurrent; +using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence.Repositories; + +namespace Umbraco.Core.Persistence.Mappers +{ + [MapperFor(typeof(DomainRepository.CacheableDomain))] + public sealed class DomainMapper : BaseMapper + { + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); + + public DomainMapper() + { + BuildMap(); + } + + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + + internal override void BuildMap() + { + CacheMap(src => src.Id, dto => dto.Id); + CacheMap(src => src.RootContentId, dto => dto.RootStructureId); + CacheMap(src => src.DefaultLanguageId, dto => dto.DefaultLanguage); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/LanguageMapper.cs b/src/Umbraco.Core/Persistence/Mappers/LanguageMapper.cs index b891bc7ec8..0832aace89 100644 --- a/src/Umbraco.Core/Persistence/Mappers/LanguageMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/LanguageMapper.cs @@ -16,8 +16,6 @@ namespace Umbraco.Core.Persistence.Mappers { private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); - //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it - // otherwise that would fail because there is no public constructor. public LanguageMapper() { BuildMap(); diff --git a/src/Umbraco.Core/Persistence/Mappers/MapperAttribute.cs b/src/Umbraco.Core/Persistence/Mappers/MapperAttribute.cs deleted file mode 100644 index b9e033ac88..0000000000 --- a/src/Umbraco.Core/Persistence/Mappers/MapperAttribute.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -namespace Umbraco.Core.Persistence.Mappers -{ - /// - /// An attribute used to decorate entities in order to associate with a mapper - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] - internal sealed class MapperAttribute : Attribute - { - public Type MapperType { get; private set; } - - public MapperAttribute(Type mapperType) - { - MapperType = mapperType; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs b/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs deleted file mode 100644 index 6f43b8e304..0000000000 --- a/src/Umbraco.Core/Persistence/Mappers/ModelDtoMapper.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Reflection; -using Umbraco.Core.Models; - -namespace Umbraco.Core.Persistence.Mappers -{ - internal class ModelDtoMapper : IMapper - { - public void GetTableInfo(Type t, TableInfo ti) - { } - - public bool MapPropertyToColumn(PropertyInfo pi, ref string columnName, ref bool resultColumn) - { - if (pi.DeclaringType == typeof(Content) || pi.DeclaringType == typeof(IContent)) - { - switch (pi.Name) - { - case "Trashed": - columnName = "[umbracoNode].[trashed]"; - return true; - case "ParentId": - columnName = "[umbracoNode].[parentID]"; - return true; - case "UserId": - columnName = "[umbracoNode].[nodeUser]"; - return true; - case "Level": - columnName = "[umbracoNode].[level]"; - return true; - case "Path": - columnName = "[umbracoNode].[path]"; - return true; - case "SortOrder": - columnName = "[umbracoNode].[sortOrder]"; - return true; - case "NodeId": - columnName = "[umbracoNode].[id]"; - return true; - case "Published": - columnName = "[cmsDocument].[published]"; - return true; - case "Key": - columnName = "[umbracoNode].[uniqueID]"; - return true; - case "CreateDate": - columnName = "[umbracoNode].[createDate]"; - return true; - case "Name": - columnName = "[umbracoNode].[text]"; - return true; - } - } - - if (pi.DeclaringType == typeof(ContentType) || pi.DeclaringType == typeof(IContentType)) - { - switch (pi.Name) - { - case "Alias": - columnName = "[cmsContentType].[alias]"; - return true; - case "Icon": - columnName = "[cmsContentType].[icon]"; - return true; - case "Thumbnail": - columnName = "[cmsContentType].[thumbnail]"; - return true; - case "Description": - columnName = "[cmsContentType].[description]"; - return true; - } - } - - return true; - } - - public Func GetFromDbConverter(PropertyInfo pi, Type sourceType) - { - return null; - } - - public Func GetToDbConverter(Type sourceType) - { - return null; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs index 36fadcf6a6..d447f6dfb7 100644 --- a/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs @@ -72,13 +72,18 @@ namespace Umbraco.Core.Persistence.Repositories return "umbracoDomains.id = @Id"; } + protected override void PersistDeletedItem(IDomain entity) + { + using (var repo = new CachedDomainRepository(this, UnitOfWork, RepositoryCache, Logger, SqlSyntax)) + { + var factory = new DomainModelFactory(); + repo.PersistDeletedItem(factory.BuildEntity(entity)); + } + } + protected override IEnumerable GetDeleteClauses() { - var list = new List - { - "DELETE FROM umbracoDomain WHERE id = @Id" - }; - return list; + throw new NotImplementedException(); } protected override Guid NodeObjectTypeId @@ -119,7 +124,7 @@ namespace Umbraco.Core.Persistence.Repositories } } - public IEnumerable GetDomainsForContent(int contentId, bool includeWildcards) + public IEnumerable GetAssignedDomains(int contentId, bool includeWildcards) { using (var repo = new CachedDomainRepository(this, UnitOfWork, RepositoryCache, Logger, SqlSyntax)) { @@ -216,7 +221,11 @@ namespace Umbraco.Core.Persistence.Repositories protected override IEnumerable GetDeleteClauses() { - return _domainRepo.GetDeleteClauses(); + var list = new List + { + "DELETE FROM umbracoDomains WHERE id = @Id" + }; + return list; } protected override Guid NodeObjectTypeId diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IDomainRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IDomainRepository.cs index d19355632f..f4fcbdfdfc 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IDomainRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IDomainRepository.cs @@ -6,6 +6,6 @@ namespace Umbraco.Core.Persistence.Repositories public interface IDomainRepository : IRepositoryQueryable { IEnumerable GetAll(bool includeWildcards); - IEnumerable GetDomainsForContent(int contentId, bool includeWildcards); + IEnumerable GetAssignedDomains(int contentId, bool includeWildcards); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index e5a99cf038..e2d465b955 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -22,12 +22,18 @@ using Umbraco.Core.Publishing; namespace Umbraco.Core.Services { + public interface IDomainService : IService + { + IEnumerable GetAll(bool includeWildcards); + IEnumerable GetDomainsForContent(int contentId, bool includeWildcards); + } + /// /// Represents the Content Service, which is an easy access to operations involving /// public class ContentService : RepositoryService, IContentService { - + private readonly IPublishingStrategy _publishingStrategy; private readonly EntityXmlSerializer _entitySerializer = new EntityXmlSerializer(); private readonly IDataTypeService _dataTypeService; diff --git a/src/Umbraco.Core/Services/DomainService.cs b/src/Umbraco.Core/Services/DomainService.cs new file mode 100644 index 0000000000..59432de2ba --- /dev/null +++ b/src/Umbraco.Core/Services/DomainService.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.UnitOfWork; + +namespace Umbraco.Core.Services +{ + public class DomainService : RepositoryService, IDomainService + { + public DomainService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger) + : base(provider, repositoryFactory, logger) + { + } + + public IEnumerable GetAll(bool includeWildcards) + { + throw new NotImplementedException(); + } + + public IEnumerable GetDomainsForContent(int contentId, bool includeWildcards) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 87f57ab344..b948e33201 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -324,6 +324,7 @@ + @@ -340,6 +341,7 @@ + diff --git a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs index 351136c5e5..3385cb8ce5 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Moq; using NUnit.Framework; +using umbraco.cms.businesslogic.contentitem; using Umbraco.Core; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; @@ -85,6 +86,41 @@ namespace Umbraco.Tests.Persistence.Repositories } + } + + [Test] + public void Can_Delete() + { + var provider = new PetaPocoUnitOfWorkProvider(Logger); + var unitOfWork = provider.GetUnitOfWork(); + + ContentType ct; + var contentId = CreateTestData("en-AU", out ct); + + ContentRepository contentRepo; + LanguageRepository langRepo; + ContentTypeRepository contentTypeRepo; + + using (var repo = CreateRepository(unitOfWork, out contentTypeRepo, out contentRepo, out langRepo)) + { + var lang = langRepo.GetByIsoCode("en-AU"); + var content = contentRepo.Get(contentId); + + var domain = (IDomain)new UmbracoDomain { RootContent = content, DefaultLanguage = lang, DomainName = "test.com" }; + repo.AddOrUpdate(domain); + unitOfWork.Commit(); + + repo.Delete(domain); + unitOfWork.Commit(); + + //re-get + domain = repo.Get(domain.Id); + + + Assert.IsNull(domain); + } + + } [Test] @@ -237,5 +273,107 @@ namespace Umbraco.Tests.Persistence.Repositories } } + [Test] + public void Get_All_For_Content() + { + var provider = new PetaPocoUnitOfWorkProvider(Logger); + var unitOfWork = provider.GetUnitOfWork(); + + ContentType ct; + var contentId = CreateTestData("en-AU", out ct); + + ContentRepository contentRepo; + LanguageRepository langRepo; + ContentTypeRepository contentTypeRepo; + + using (var repo = CreateRepository(unitOfWork, out contentTypeRepo, out contentRepo, out langRepo)) + { + var contentItems = new List(); + + var lang = langRepo.GetByIsoCode("en-AU"); + contentItems.Add(contentRepo.Get(contentId)); + + //more test data (3 content items total) + for (int i = 0; i < 2; i++) + { + var c = new Content("test" + i, -1, ct) { CreatorId = 0, WriterId = 0 }; + contentRepo.AddOrUpdate(c); + unitOfWork.Commit(); + contentItems.Add(c); + } + + for (int i = 0; i < 10; i++) + { + var domain = (IDomain)new UmbracoDomain + { + RootContent = (i % 2 == 0) ? contentItems[0] : contentItems[1], + DefaultLanguage = lang, + DomainName = (i % 2 == 0) ? "test " + i + ".com" : ("*" + i) + }; + repo.AddOrUpdate(domain); + unitOfWork.Commit(); + } + + var all1 = repo.GetAssignedDomains(contentItems[0].Id, true); + Assert.AreEqual(5, all1.Count()); + + var all2 = repo.GetAssignedDomains(contentItems[1].Id, true); + Assert.AreEqual(5, all2.Count()); + + var all3 = repo.GetAssignedDomains(contentItems[2].Id, true); + Assert.AreEqual(0, all3.Count()); + } + } + + [Test] + public void Get_All_For_Content_Without_Wildcards() + { + var provider = new PetaPocoUnitOfWorkProvider(Logger); + var unitOfWork = provider.GetUnitOfWork(); + + ContentType ct; + var contentId = CreateTestData("en-AU", out ct); + + ContentRepository contentRepo; + LanguageRepository langRepo; + ContentTypeRepository contentTypeRepo; + + using (var repo = CreateRepository(unitOfWork, out contentTypeRepo, out contentRepo, out langRepo)) + { + var contentItems = new List(); + + var lang = langRepo.GetByIsoCode("en-AU"); + contentItems.Add(contentRepo.Get(contentId)); + + //more test data (3 content items total) + for (int i = 0; i < 2; i++) + { + var c = new Content("test" + i, -1, ct) { CreatorId = 0, WriterId = 0 }; + contentRepo.AddOrUpdate(c); + unitOfWork.Commit(); + contentItems.Add(c); + } + + for (int i = 0; i < 10; i++) + { + var domain = (IDomain)new UmbracoDomain + { + RootContent = (i % 2 == 0) ? contentItems[0] : contentItems[1], + DefaultLanguage = lang, + DomainName = (i % 2 == 0) ? "test " + i + ".com" : ("*" + i) + }; + repo.AddOrUpdate(domain); + unitOfWork.Commit(); + } + + var all1 = repo.GetAssignedDomains(contentItems[0].Id, false); + Assert.AreEqual(5, all1.Count()); + + var all2 = repo.GetAssignedDomains(contentItems[1].Id, false); + Assert.AreEqual(0, all2.Count()); + + } + } + } } \ No newline at end of file