From 79bbd6a70c9b3dc8203b29ddac2f35f99a35c99f Mon Sep 17 00:00:00 2001 From: Stephan Date: Sun, 12 Jun 2016 15:27:54 +0200 Subject: [PATCH] U4-8361 - implement repository --- src/Umbraco.Core/Models/RedirectUrl.cs | 45 ++++- .../Interfaces/IRedirectUrlRepository.cs | 9 +- .../Repositories/RedirectUrlRepository.cs | 186 ++++++++++++++++++ .../ServerRegistrationRepository.cs | 4 +- .../Persistence/RepositoryFactory.cs | 9 + .../Services/IRedirectUrlService.cs | 16 +- .../Services/RedirectUrlService.cs | 92 +++------ src/Umbraco.Core/Services/ServiceContext.cs | 18 +- src/Umbraco.Core/Umbraco.Core.csproj | 1 + 9 files changed, 304 insertions(+), 76 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs diff --git a/src/Umbraco.Core/Models/RedirectUrl.cs b/src/Umbraco.Core/Models/RedirectUrl.cs index 28c7d8635a..6622d2d182 100644 --- a/src/Umbraco.Core/Models/RedirectUrl.cs +++ b/src/Umbraco.Core/Models/RedirectUrl.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using System.Runtime.Serialization; using Umbraco.Core.Models.EntityBase; @@ -13,10 +14,48 @@ namespace Umbraco.Core.Models CreateDateUtc = DateTime.UtcNow; } - public int ContentId { get; set; } + private static readonly PropertyInfo ContentIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ContentId); + private static readonly PropertyInfo CreateDateUtcSelector = ExpressionHelper.GetPropertyInfo(x => x.CreateDateUtc); + private static readonly PropertyInfo UrlSelector = ExpressionHelper.GetPropertyInfo(x => x.Url); - public DateTime CreateDateUtc { get; set; } + private int _contentId; + private DateTime _createDateUtc; + private string _url; - public string Url { get; set; } + public int ContentId + { + get { return _contentId; } + set + { + SetPropertyValueAndDetectChanges(o => + { + return _contentId = value; + }, _contentId, ContentIdSelector); + } + } + + public DateTime CreateDateUtc + { + get { return _createDateUtc; } + set + { + SetPropertyValueAndDetectChanges(o => + { + return _createDateUtc = value; + }, _createDateUtc, CreateDateUtcSelector); + } + } + + public string Url + { + get { return _url; } + set + { + SetPropertyValueAndDetectChanges(o => + { + return _url = value; + }, _url, UrlSelector); + } + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRedirectUrlRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRedirectUrlRepository.cs index bebed2b336..9608c55e4c 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRedirectUrlRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRedirectUrlRepository.cs @@ -7,7 +7,14 @@ using Umbraco.Core.Models; namespace Umbraco.Core.Persistence.Repositories { - interface IRedirectUrlRepository : IRepositoryQueryable + public interface IRedirectUrlRepository : IRepositoryQueryable { + void Delete(int id); + void DeleteAll(); + void DeleteContentUrls(int contentId); + IRedirectUrl GetMostRecentRule(string url); + IEnumerable GetContentUrls(int contentId); + IEnumerable GetAllUrls(long pageIndex, int pageSize, out long total); + IEnumerable GetAllUrls(int rootContentId, long pageIndex, int pageSize, out long total); } } diff --git a/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs new file mode 100644 index 0000000000..e33ba82f63 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Repositories/RedirectUrlRepository.cs @@ -0,0 +1,186 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; +using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence.Querying; +using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Core.Persistence.UnitOfWork; + +namespace Umbraco.Core.Persistence.Repositories +{ + class RedirectUrlRepository : PetaPocoRepositoryBase, IRedirectUrlRepository + { + public RedirectUrlRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax) + : base(work, cache, logger, sqlSyntax) + { } + + protected override int PerformCount(IQuery query) + { + throw new NotSupportedException("This repository does not support this method."); + } + + protected override bool PerformExists(int id) + { + return PerformGet(id) != null; + } + + protected override IRedirectUrl PerformGet(int id) + { + var sql = GetBaseQuery(false).Where(x => x.Id == id); + var dto = Database.Fetch(sql).FirstOrDefault(); + return dto == null ? null : Map(dto); + } + + protected override IEnumerable PerformGetAll(params int[] ids) + { + if (ids.Length > 2000) + throw new NotSupportedException("This repository does not support more than 2000 ids."); + var sql = GetBaseQuery(false).WhereIn(x => x.Id, ids); + var dtos = Database.Fetch(sql); + return dtos.WhereNotNull().Select(Map); + } + + protected override IEnumerable PerformGetByQuery(IQuery query) + { + throw new NotSupportedException("This repository does not support this method."); + } + + protected override Sql GetBaseQuery(bool isCount) + { + var sql = new Sql(); + sql.Select(isCount ? "COUNT(*)" : "*").From(SqlSyntax); + return sql; + } + + protected override string GetBaseWhereClause() + { + return "id = @Id"; + } + + protected override IEnumerable GetDeleteClauses() + { + var list = new List + { + "DELETE FROM umbracoRedirectUrl WHERE id = @Id" + }; + return list; + } + + protected override Guid NodeObjectTypeId + { + get { throw new NotImplementedException(); } + } + + protected override void PersistNewItem(IRedirectUrl entity) + { + var dto = Map(entity); + Database.Insert(dto); + entity.Id = dto.Id; + } + + protected override void PersistUpdatedItem(IRedirectUrl entity) + { + var dto = Map(entity); + Database.Update(dto); + } + + private static RedirectUrlDto Map(IRedirectUrl redirectUrl) + { + if (redirectUrl == null) return null; + + return new RedirectUrlDto + { + Id = redirectUrl.Id, + ContentId = redirectUrl.ContentId, + CreateDateUtc = redirectUrl.CreateDateUtc, + Url = redirectUrl.Url + }; + } + + private static IRedirectUrl Map(RedirectUrlDto dto) + { + if (dto == null) return null; + + return new RedirectUrl + { + Id = dto.Id, + ContentId = dto.ContentId, + CreateDateUtc = dto.CreateDateUtc, + Url = dto.Url + }; + } + + public void DeleteAll() + { + Database.Execute("DELETE FROM umbracoContentUrl"); + } + + public void DeleteContentUrls(int contentId) + { + Database.Execute("DELETE FROM umbracoContentUrl WHERE contentId=@contentId", new { contentId }); + } + + public void Delete(int id) + { + Database.Delete(id); + } + + public IRedirectUrl GetMostRecentRule(string url) + { + var dtos = Database.Fetch("SELECT * FROM umbracoContentUrlRule WHERE url=@url ORDER BY createDateUtc DESC;", + new { url }); + var dto = dtos.FirstOrDefault(); + return dto == null ? null : Map(dto); + } + + public IEnumerable GetContentUrls(int contentId) + { + var dtos = Database.Fetch("SELECT * FROM umbracoContentUrlRule WHERE contentId=@id ORDER BY createDateUtc DESC;", + new { id = contentId }); + return dtos.Select(x => new RedirectUrl + { + Id = x.Id, + ContentId = x.ContentId, + CreateDateUtc = x.CreateDateUtc, + Url = x.Url + }); + } + + public IEnumerable GetAllUrls(long pageIndex, int pageSize, out long total) + { + var sql = GetBaseQuery(false).OrderByDescending(x => x.CreateDateUtc, SqlSyntax); + var result = Database.Page(pageIndex + 1, pageSize, sql); + total = Convert.ToInt32(result.TotalItems); + + var rules = result.Items.Select(x => new RedirectUrl + { + Id = x.Id, + ContentId = x.ContentId, + CreateDateUtc = x.CreateDateUtc, + Url = x.Url + }); + return rules; + } + + public IEnumerable GetAllUrls(int rootContentId, long pageIndex, int pageSize, out long total) + { + var sql = GetBaseQuery(false) + .InnerJoin(SqlSyntax).On(SqlSyntax, left => left.NodeId, right => right.ContentId) + .Where("umbracoNode.path LIKE @path", new { path = "%," + rootContentId + ",%" }) + .OrderByDescending(x => x.CreateDateUtc, SqlSyntax); + var result = Database.Page(pageIndex + 1, pageSize, sql); + total = Convert.ToInt32(result.TotalItems); + + var rules = result.Items.Select(x => new RedirectUrl + { + Id = x.Id, + ContentId = x.ContentId, + CreateDateUtc = x.CreateDateUtc, + Url = x.Url + }); + return rules; + } + } +} diff --git a/src/Umbraco.Core/Persistence/Repositories/ServerRegistrationRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ServerRegistrationRepository.cs index 20d3c38042..02794ef1fb 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ServerRegistrationRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ServerRegistrationRepository.cs @@ -25,7 +25,7 @@ namespace Umbraco.Core.Persistence.Repositories protected override int PerformCount(IQuery query) { - throw new NotSupportedException("This repository does not support this method"); + throw new NotSupportedException("This repository does not support this method."); } protected override bool PerformExists(int id) @@ -55,7 +55,7 @@ namespace Umbraco.Core.Persistence.Repositories protected override IEnumerable PerformGetByQuery(IQuery query) { - throw new NotSupportedException("This repository does not support this method"); + throw new NotSupportedException("This repository does not support this method."); } protected override Sql GetBaseQuery(bool isCount) diff --git a/src/Umbraco.Core/Persistence/RepositoryFactory.cs b/src/Umbraco.Core/Persistence/RepositoryFactory.cs index e2b2c2cc22..85eb00ea87 100644 --- a/src/Umbraco.Core/Persistence/RepositoryFactory.cs +++ b/src/Umbraco.Core/Persistence/RepositoryFactory.cs @@ -333,5 +333,14 @@ namespace Umbraco.Core.Persistence _logger, _sqlSyntax, containerObjectType); } + + public IRedirectUrlRepository CreateRedirectUrlRepository(IDatabaseUnitOfWork uow) + { + return new RedirectUrlRepository( + uow, + _cacheHelper, + _logger, + _sqlSyntax); + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/IRedirectUrlService.cs b/src/Umbraco.Core/Services/IRedirectUrlService.cs index 88d010b8e0..6dd36d438c 100644 --- a/src/Umbraco.Core/Services/IRedirectUrlService.cs +++ b/src/Umbraco.Core/Services/IRedirectUrlService.cs @@ -5,20 +5,22 @@ namespace Umbraco.Core.Services { public interface IRedirectUrlService : IService { - void Save(RedirectUrl redirectUrl); + void Save(IRedirectUrl redirectUrl); + + void DeleteContentUrls(int contentId); + + void Delete(IRedirectUrl redirectUrl); void Delete(int id); - void DeleteContentRules(int contentId); - void DeleteAll(); - RedirectUrl GetMostRecentRule(string url); + IRedirectUrl GetMostRecentRule(string url); - IEnumerable GetRules(int contentId); + IEnumerable GetContentUrls(int contentId); - IEnumerable GetAllRules(long pageIndex, int pageSize, out long total); + IEnumerable GetAllUrls(long pageIndex, int pageSize, out long total); - IEnumerable GetAllRules(int rootContentId, long pageIndex, int pageSize, out long total); + IEnumerable GetAllUrls(int rootContentId, long pageIndex, int pageSize, out long total); } } diff --git a/src/Umbraco.Core/Services/RedirectUrlService.cs b/src/Umbraco.Core/Services/RedirectUrlService.cs index f2496a9e89..39c7fd0da5 100644 --- a/src/Umbraco.Core/Services/RedirectUrlService.cs +++ b/src/Umbraco.Core/Services/RedirectUrlService.cs @@ -15,41 +15,46 @@ namespace Umbraco.Core.Services : base(provider, repositoryFactory, logger, eventMessagesFactory) { } - public void Save(RedirectUrl redirectUrl) + public void Save(IRedirectUrl redirectUrl) { // check if the url already exists // the url actually is a primary key? // though we might want to keep the history? using (var uow = UowProvider.GetUnitOfWork()) + using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) { - var dto = new RedirectUrlDto - { - Id = redirectUrl.Id, - ContentId = redirectUrl.ContentId, - CreateDateUtc = redirectUrl.CreateDateUtc, - Url = redirectUrl.Url - }; - uow.Database.InsertOrUpdate(dto); + repo.AddOrUpdate(redirectUrl); + uow.Commit(); + } + } + + public void Delete(IRedirectUrl redirectUrl) + { + using (var uow = UowProvider.GetUnitOfWork()) + using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) + { + repo.Delete(redirectUrl); uow.Commit(); - redirectUrl.Id = dto.Id; } } public void Delete(int id) { using (var uow = UowProvider.GetUnitOfWork()) + using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) { - uow.Database.Execute("DELETE FROM umbracoContentUrlRule WHERE id=@id", new { id = id }); + repo.Delete(id); uow.Commit(); } } - public void DeleteContentRules(int contentId) + public void DeleteContentUrls(int contentId) { using (var uow = UowProvider.GetUnitOfWork()) + using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) { - uow.Database.Execute("DELETE FROM umbracoContentUrlRule WHERE contenId=@id", new { id = contentId }); + repo.DeleteContentUrls(contentId); uow.Commit(); } } @@ -57,85 +62,52 @@ namespace Umbraco.Core.Services public void DeleteAll() { using (var uow = UowProvider.GetUnitOfWork()) + using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) { - uow.Database.Execute("DELETE FROM umbracoContentUrlRule;"); + repo.DeleteAll(); uow.Commit(); } } - public RedirectUrl GetMostRecentRule(string url) + public IRedirectUrl GetMostRecentRule(string url) { using (var uow = UowProvider.GetUnitOfWork()) + using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) { - var ruleDtos = uow.Database.Fetch("SELECT * FROM umbracoContentUrlRule WHERE url=@url ORDER BY createDateUtc DESC;", - new { url }); - var ruleDto = ruleDtos.FirstOrDefault(); - var rule = ruleDto == null ? null : new RedirectUrl - { - Id = ruleDto.Id, - ContentId = ruleDto.ContentId, - CreateDateUtc = ruleDto.CreateDateUtc, - Url = ruleDto.Url - }; + var rule = repo.GetMostRecentRule(url); uow.Commit(); return rule; } } - public IEnumerable GetRules(int contentId) + public IEnumerable GetContentUrls(int contentId) { using (var uow = UowProvider.GetUnitOfWork()) + using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) { - var ruleDtos = uow.Database.Fetch("SELECT * FROM umbracoContentUrlRule WHERE contentId=@id ORDER BY createDateUtc DESC;", - new { id = contentId }); - var rules = ruleDtos.Select(x=> new RedirectUrl - { - Id = x.Id, - ContentId = x.ContentId, - CreateDateUtc = x.CreateDateUtc, - Url = x.Url - }); + var rules = repo.GetContentUrls(contentId); uow.Commit(); return rules; } } - public IEnumerable GetAllRules(long pageIndex, int pageSize, out long total) + public IEnumerable GetAllUrls(long pageIndex, int pageSize, out long total) { using (var uow = UowProvider.GetUnitOfWork()) + using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) { - var ruleDtos = uow.Database.Fetch("SELECT * FROM umbracoContentUrlRule ORDER BY createDateUtc DESC;"); - var rules = ruleDtos.Select(x => new RedirectUrl - { - Id = x.Id, - ContentId = x.ContentId, - CreateDateUtc = x.CreateDateUtc, - Url = x.Url - }).ToArray(); - total = rules.Length; + var rules = repo.GetAllUrls(pageIndex, pageSize, out total); uow.Commit(); return rules; } } - public IEnumerable GetAllRules(int rootContentId, long pageIndex, int pageSize, out long total) + public IEnumerable GetAllUrls(int rootContentId, long pageIndex, int pageSize, out long total) { using (var uow = UowProvider.GetUnitOfWork()) + using (var repo = RepositoryFactory.CreateRedirectUrlRepository(uow)) { - var path = "%," + rootContentId + ",%"; - - var ruleDtos = uow.Database.Fetch(@"SELECT * FROM umbracoContentUrlRule -JOIN umbracoNode ON umbracoNode.id=umbracoContentUrlRule.contentId -WHERE umbracoNode.path LIKE @path -ORDER BY createDateUtc DESC;", new { path }); - var rules = ruleDtos.Select(x => new RedirectUrl - { - Id = x.Id, - ContentId = x.ContentId, - CreateDateUtc = x.CreateDateUtc, - Url = x.Url - }).ToArray(); - total = rules.Length; + var rules = repo.GetAllUrls(rootContentId, pageIndex, pageSize, out total); uow.Commit(); return rules; } diff --git a/src/Umbraco.Core/Services/ServiceContext.cs b/src/Umbraco.Core/Services/ServiceContext.cs index 10601a30fa..a18df0ade1 100644 --- a/src/Umbraco.Core/Services/ServiceContext.cs +++ b/src/Umbraco.Core/Services/ServiceContext.cs @@ -1,5 +1,4 @@ using System; -using log4net; using Umbraco.Core.Logging; using System.IO; using System.Linq; @@ -7,7 +6,6 @@ using Umbraco.Core.IO; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Core.Publishing; -using umbraco.interfaces; using Umbraco.Core.Events; namespace Umbraco.Core.Services @@ -64,6 +62,7 @@ namespace Umbraco.Core.Services private Lazy _memberGroupService; private Lazy _notificationService; private Lazy _externalLoginService; + private Lazy _redirectUrlService; /// /// public ctor - will generally just be used for unit testing all items are optional and if not specified, the defaults will be used @@ -93,6 +92,7 @@ namespace Umbraco.Core.Services /// /// /// + /// public ServiceContext( IContentService contentService = null, IMediaService mediaService = null, @@ -118,7 +118,8 @@ namespace Umbraco.Core.Services IMacroService macroService = null, IPublicAccessService publicAccessService = null, IExternalLoginService externalLoginService = null, - IMigrationEntryService migrationEntryService = null) + IMigrationEntryService migrationEntryService = null, + IRedirectUrlService redirectUrlService = null) { if (migrationEntryService != null) _migrationEntryService = new Lazy(() => migrationEntryService); if (externalLoginService != null) _externalLoginService = new Lazy(() => externalLoginService); @@ -145,6 +146,7 @@ namespace Umbraco.Core.Services if (taskService != null) _taskService = new Lazy(() => taskService); if (macroService != null) _macroService = new Lazy(() => macroService); if (publicAccessService != null) _publicAccessService = new Lazy(() => publicAccessService); + if (redirectUrlService != null) _redirectUrlService = new Lazy(() => redirectUrlService); } /// @@ -310,6 +312,8 @@ namespace Umbraco.Core.Services if (_memberGroupService == null) _memberGroupService = new Lazy(() => new MemberGroupService(provider, repositoryFactory, logger, eventMessagesFactory)); + if (_redirectUrlService == null) + _redirectUrlService = new Lazy(() => new RedirectUrlService(provider, repositoryFactory, logger, eventMessagesFactory)); } /// @@ -516,5 +520,13 @@ namespace Umbraco.Core.Services { get { return _externalLoginService.Value; } } + + /// + /// Gets the RedirectUrlService. + /// + public IRedirectUrlService RedirectUrlService + { + get { return _redirectUrlService.Value; } + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 7af77f359a..1b3b8022f9 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -479,6 +479,7 @@ +