diff --git a/src/Umbraco.Core/Persistence/Mappers/AuditItemMapper.cs b/src/Umbraco.Core/Persistence/Mappers/AuditItemMapper.cs index 853cd9f99e..48e7afdc7e 100644 --- a/src/Umbraco.Core/Persistence/Mappers/AuditItemMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/AuditItemMapper.cs @@ -18,7 +18,8 @@ namespace Umbraco.Core.Persistence.Mappers DefineMap(nameof(AuditItem.Id), nameof(LogDto.NodeId)); DefineMap(nameof(AuditItem.CreateDate), nameof(LogDto.Datestamp)); DefineMap(nameof(AuditItem.UserId), nameof(LogDto.UserId)); - DefineMap(nameof(AuditItem.AuditType), nameof(LogDto.Header)); + // we cannot map that one - because AuditType is an enum but Header is a string + //DefineMap(nameof(AuditItem.AuditType), nameof(LogDto.Header)); DefineMap(nameof(AuditItem.Comment), nameof(LogDto.Comment)); } } diff --git a/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionVisitor.cs b/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionVisitor.cs index 03d82a345f..c87937e41e 100644 --- a/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionVisitor.cs +++ b/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionVisitor.cs @@ -85,6 +85,17 @@ namespace Umbraco.Core.Persistence.Querying // I'm just unsure right now due to time constraints how to make it correct. It won't matter right now and has been working already with this bug but I've // only just discovered what it is actually doing. + // TODO + // in most cases we want to convert the value to a plain object, + // but for in some rare cases, we may want to do it differently, + // for instance a Models.AuditType (an enum) may in some cases + // need to be converted to its string value. + // but - we cannot have specific code here, really - and how would + // we configure this? is it even possible? + /* + var toString = typeof(object).GetMethod("ToString"); + var member = Expression.Call(m, toString); + */ var member = Expression.Convert(m, typeof(object)); var lambda = Expression.Lambda>(member); var getter = lambda.Compile(); diff --git a/src/Umbraco.Core/Persistence/Repositories/IAuditRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IAuditRepository.cs index 7c8a82bb85..b2dd6a3297 100644 --- a/src/Umbraco.Core/Persistence/Repositories/IAuditRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/IAuditRepository.cs @@ -33,5 +33,7 @@ namespace Umbraco.Core.Persistence.Repositories Direction orderDirection, AuditType[] auditTypeFilter, IQuery customFilter); + + IEnumerable Get(AuditType type, IQuery query); } } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/AuditRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/AuditRepository.cs index cda89fd89a..c25328b10c 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/AuditRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/AuditRepository.cs @@ -74,6 +74,18 @@ namespace Umbraco.Core.Persistence.Repositories.Implement return dtos.Select(x => new AuditItem(x.NodeId, Enum.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId, x.EntityType, x.Comment, x.Parameters)).ToList(); } + public IEnumerable Get(AuditType type, IQuery query) + { + var sqlClause = GetBaseQuery(false) + .Where(x => x.Header == type.ToString()); + var translator = new SqlTranslator(sqlClause, query); + var sql = translator.Translate(); + + var dtos = Database.Fetch(sql); + + return dtos.Select(x => new AuditItem(x.NodeId, Enum.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId, x.EntityType, x.Comment, x.Parameters)).ToList(); + } + protected override Sql GetBaseQuery(bool isCount) { var sql = SqlContext.Sql(); diff --git a/src/Umbraco.Core/Services/Implement/AuditService.cs b/src/Umbraco.Core/Services/Implement/AuditService.cs index 46c851a789..5eb08f2dea 100644 --- a/src/Umbraco.Core/Services/Implement/AuditService.cs +++ b/src/Umbraco.Core/Services/Implement/AuditService.cs @@ -51,8 +51,8 @@ namespace Umbraco.Core.Services.Implement using (var scope = ScopeProvider.CreateScope()) { var result = sinceDate.HasValue == false - ? _auditRepository.Get(Query().Where(x => x.UserId == userId && x.AuditType == type)) - : _auditRepository.Get(Query().Where(x => x.UserId == userId && x.AuditType == type && x.CreateDate >= sinceDate.Value)); + ? _auditRepository.Get(type, Query().Where(x => x.UserId == userId)) + : _auditRepository.Get(type, Query().Where(x => x.UserId == userId && x.CreateDate >= sinceDate.Value)); scope.Complete(); return result; } @@ -63,8 +63,8 @@ namespace Umbraco.Core.Services.Implement using (var scope = ScopeProvider.CreateScope()) { var result = sinceDate.HasValue == false - ? _auditRepository.Get(Query().Where(x => x.AuditType == type)) - : _auditRepository.Get(Query().Where(x => x.AuditType == type && x.CreateDate >= sinceDate.Value)); + ? _auditRepository.Get(type, Query()) + : _auditRepository.Get(type, Query().Where(x => x.CreateDate >= sinceDate.Value)); scope.Complete(); return result; } diff --git a/src/Umbraco.Tests/Services/AuditServiceTests.cs b/src/Umbraco.Tests/Services/AuditServiceTests.cs index 6064fe4acc..bfec246e61 100644 --- a/src/Umbraco.Tests/Services/AuditServiceTests.cs +++ b/src/Umbraco.Tests/Services/AuditServiceTests.cs @@ -4,6 +4,7 @@ using NUnit.Framework; using Umbraco.Core.Services.Implement; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; +using Umbraco.Core.Models; namespace Umbraco.Tests.Services { @@ -48,5 +49,19 @@ namespace Umbraco.Tests.Services Assert.AreEqual(123 + 5, entries[0].PerformingUserId); Assert.AreEqual(123 + 4, entries[1].PerformingUserId); } + + [Test] + public void CanReadEntries() + { + var yesterday = DateTime.UtcNow.AddDays(-1); + + for (var i = 0; i < 10; i++) + { + yesterday = yesterday.AddMinutes(1); + ServiceContext.AuditService.Add(AuditType.Unpublish, -1, 33, "", "blah"); + } + + var logs = ServiceContext.AuditService.GetUserLogs(-1, AuditType.Unpublish); + } } }