From a436b839f6dc4342ded8a9541c55256f380c03de Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Mon, 24 Feb 2025 12:11:48 +0500 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BF?= =?UTF-8?q?=D0=BE=20=D1=80=D0=B5=D0=B7=D1=83=D0=BB=D1=8C=D1=82=D0=B0=D1=82?= =?UTF-8?q?=D0=B0=D0=BC=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ChangeLogController.cs | 4 +- .../Services/ChangeLogService.cs | 60 +++++++++---------- DD.Persistence.Database/Entity/ChangeLog.cs | 13 +++- .../Repositories/ChangeLogCommitRepository.cs | 14 +++-- .../Repositories/ChangeLogRepository.cs | 14 ++--- .../Controllers/ChangeLogControllerTest.cs | 21 +++++++ DD.Persistence.Models/ChangeLogCommitDto.cs | 23 ++++--- .../Requests/CreateChangeLogCommitRequest.cs | 14 ++++- DD.Persistence.Test/ChangeLogTest.cs | 41 ++++++------- .../IChangeLogCommitRepository.cs | 7 +-- .../Repositories/IChangeLogRepository.cs | 11 ++-- 11 files changed, 127 insertions(+), 95 deletions(-) diff --git a/DD.Persistence.API/Controllers/ChangeLogController.cs b/DD.Persistence.API/Controllers/ChangeLogController.cs index 138572d..223c744 100644 --- a/DD.Persistence.API/Controllers/ChangeLogController.cs +++ b/DD.Persistence.API/Controllers/ChangeLogController.cs @@ -16,7 +16,7 @@ using UuidExtensions; [Route("api/[controller]")] public class ChangeLogController : ControllerBase, IChangeLogApi { - private ChangeLogService service { get; } + private readonly ChangeLogService service; /// /// ctor @@ -40,7 +40,7 @@ public class ChangeLogController : ControllerBase, IChangeLogApi public async Task AddRange( [FromRoute] Guid idDiscriminator, [FromBody] IEnumerable dtos, - string comment, + string? comment, CancellationToken token) { var userId = User.GetUserId(); diff --git a/DD.Persistence.API/Services/ChangeLogService.cs b/DD.Persistence.API/Services/ChangeLogService.cs index f4831d2..d6c0b69 100644 --- a/DD.Persistence.API/Services/ChangeLogService.cs +++ b/DD.Persistence.API/Services/ChangeLogService.cs @@ -1,9 +1,8 @@ -using DD.Persistence.Models.Common; -using DD.Persistence.Models; +using DD.Persistence.Models; +using DD.Persistence.Models.Common; using DD.Persistence.Models.Requests; using DD.Persistence.Repositories; using Microsoft.Extensions.Caching.Memory; -using DD.Persistence.Database.Entity; namespace DD.Persistence.API.Services; @@ -34,39 +33,38 @@ public class ChangeLogService } /// - /// Чтение ключа коммита из кеша или (если коммита в кеше нет) создание коммита + /// Чтение или создание нового коммита /// - /// + /// /// /// - private async Task GetOrCreateCommitAsync(CreateChangeLogCommitRequest commitDto, CancellationToken token) + private async Task GetOrCreateCommitAsync(CreateChangeLogCommitRequest request, CancellationToken token) { - var key = (commitDto.IdAuthor, commitDto.Comment); - var commitId = await memoryCache.GetOrCreateAsync(key, async (cacheEntry) => + var key = (request.IdAuthor, request.Comment); + var commit = await memoryCache.GetOrCreateAsync(key, async (cacheEntry) => { cacheEntry.AbsoluteExpirationRelativeToNow = AbsoluteExpirationRelativeToNow; - var commitId = await commitRepository.Add(commitDto, token); + var commit = await commitRepository.Add(request, token); - return commitId; + return commit; }); - return commitId; + return commit!; } /// /// Добавление записи в журнал изменений /// /// - /// + /// /// /// /// - public async Task AddRange(Guid idDiscriminator, CreateChangeLogCommitRequest commitRequestDto, IEnumerable dtos, CancellationToken token) + public async Task AddRange(Guid idDiscriminator, CreateChangeLogCommitRequest request, IEnumerable dtos, CancellationToken token) { - var commitId = await GetOrCreateCommitAsync(commitRequestDto, token); - var commitDto = new ChangeLogCommitDto(commitId, commitRequestDto); + var commit = await GetOrCreateCommitAsync(request, token); - var result = await repository.AddRange(idDiscriminator, commitDto, dtos, token); + var result = await repository.AddRange(idDiscriminator, commit, dtos, token); return result; } @@ -74,15 +72,14 @@ public class ChangeLogService /// Пометить запись журнала изменений как удаленную /// /// - /// + /// /// /// - public async Task MarkAsDeleted(IEnumerable ids, CreateChangeLogCommitRequest commitRequestDto, CancellationToken token) + public async Task MarkAsDeleted(IEnumerable ids, CreateChangeLogCommitRequest request, CancellationToken token) { - var commitId = await GetOrCreateCommitAsync(commitRequestDto, token); - var commitDto = new ChangeLogCommitDto(commitId, commitRequestDto); + var commit = await GetOrCreateCommitAsync(request, token); - var result = await repository.MarkAsDeleted(commitId, ids, commitDto.Creation, token); + var result = await repository.MarkAsDeleted(ids, commit, token); return result; } @@ -91,16 +88,15 @@ public class ChangeLogService /// Очистить старые и добавить новые записи в журнал изменений /// /// - /// + /// /// /// /// - public async Task ClearAndAddRange(Guid idDiscriminator, CreateChangeLogCommitRequest commitRequestDto, IEnumerable dtos, CancellationToken token) + public async Task ClearAndAddRange(Guid idDiscriminator, CreateChangeLogCommitRequest request, IEnumerable dtos, CancellationToken token) { - var commitId = await GetOrCreateCommitAsync(commitRequestDto, token); - var commitDto = new ChangeLogCommitDto(commitId, commitRequestDto); + var commit = await GetOrCreateCommitAsync(request, token); - var result = await repository.ClearAndAddRange(idDiscriminator, commitDto, dtos, token); + var result = await repository.ClearAndAddRange(idDiscriminator, commit, dtos, token); return result; } @@ -108,16 +104,14 @@ public class ChangeLogService /// /// Обновить записи в журнале изменений /// - /// + /// /// /// /// - public async Task UpdateRange(CreateChangeLogCommitRequest commitRequestDto, IEnumerable dtos, CancellationToken token) + public async Task UpdateRange(CreateChangeLogCommitRequest commitRequest, IEnumerable dtos, CancellationToken token) { - var commitId = await GetOrCreateCommitAsync(commitRequestDto, token); - var commitDto = new ChangeLogCommitDto(commitId, commitRequestDto); - - var result = await repository.UpdateRange(commitDto, dtos, token); + var commit = await GetOrCreateCommitAsync(commitRequest, token); + var result = await repository.UpdateRange(commit, dtos, token); return result; } @@ -180,7 +174,7 @@ public class ChangeLogService { var result = await repository.GetGtDate(idDiscriminator, dateBegin, token); - return result; + return result; } /// diff --git a/DD.Persistence.Database/Entity/ChangeLog.cs b/DD.Persistence.Database/Entity/ChangeLog.cs index 3621795..6dbc571 100644 --- a/DD.Persistence.Database/Entity/ChangeLog.cs +++ b/DD.Persistence.Database/Entity/ChangeLog.cs @@ -1,6 +1,5 @@ using DD.Persistence.Database.EntityAbstractions; -using DD.Persistence.ModelsAbstractions; using Microsoft.EntityFrameworkCore; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -19,9 +18,15 @@ public class ChangeLog : IDiscriminatorItem, IChangeLog [Comment("Дискриминатор таблицы")] public Guid DiscriminatorId { get; set; } + /// + /// то же самое поле присутствует в связанной таблице change_log_commit (поле creation) + /// [Comment("Дата создания записи")] public DateTimeOffset Creation { get; set; } + /// + /// то же самое поле присутствует в связанной таблице change_log_commit (поле creation) + /// [Comment("Дата устаревания (например при удалении)")] public DateTimeOffset? Obsolete { get; set; } @@ -37,9 +42,15 @@ public class ChangeLog : IDiscriminatorItem, IChangeLog [Comment("Id коммита на устаревание записи")] public Guid? IdObsoletedCommit { get; set; } + /// + /// коммит для актуальной записи + /// [Required, ForeignKey(nameof(IdCreatedCommit)), Comment("Коммит пользователя на создание записи")] public virtual ChangeLogCommit CreatedCommit { get; set; } = null!; + /// + /// коммит для устаревшей записи + /// [ForeignKey(nameof(IdObsoletedCommit)), Comment("Коммит пользователя на устаревание записи")] public virtual ChangeLogCommit? ObsoletedCommit { get; set; } } diff --git a/DD.Persistence.Database/Repositories/ChangeLogCommitRepository.cs b/DD.Persistence.Database/Repositories/ChangeLogCommitRepository.cs index 634136c..c4fbb70 100644 --- a/DD.Persistence.Database/Repositories/ChangeLogCommitRepository.cs +++ b/DD.Persistence.Database/Repositories/ChangeLogCommitRepository.cs @@ -1,6 +1,7 @@ using DD.Persistence.Database.Entity; using DD.Persistence.Models.Requests; using DD.Persistence.Repositories; +using Mapster; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Caching.Memory; using System; @@ -20,20 +21,21 @@ public class ChangeLogCommitRepository : IChangeLogCommitRepository this.db = db; } - public async Task Add(CreateChangeLogCommitRequest commitRequestDto, CancellationToken token) + public async Task Add(CreateChangeLogCommitRequest commitRequest, CancellationToken token) { var commit = new ChangeLogCommit() { Id = Uuid7.Guid(), - IdAuthor = commitRequestDto.IdAuthor, - Comment = commitRequestDto.Comment, - Creation = commitRequestDto.Creation, + IdAuthor = commitRequest.IdAuthor, + Comment = commitRequest.Comment ?? string.Empty, + Creation = commitRequest.Creation, }; db.Add(commit); - await db.SaveChangesAsync(); - return commit.Id; + + var commitDto = commit.Adapt(); + return commitDto; } } diff --git a/DD.Persistence.Database/Repositories/ChangeLogRepository.cs b/DD.Persistence.Database/Repositories/ChangeLogRepository.cs index 18aa5fb..6cea8ba 100644 --- a/DD.Persistence.Database/Repositories/ChangeLogRepository.cs +++ b/DD.Persistence.Database/Repositories/ChangeLogRepository.cs @@ -42,7 +42,7 @@ public class ChangeLogRepository : IChangeLogRepository return result; } - public async Task MarkAsDeleted(Guid idCommit, IEnumerable ids, DateTimeOffset updateTime, CancellationToken token) + public async Task MarkAsDeleted(IEnumerable ids, ChangeLogCommitDto commit, CancellationToken token) { var query = db.Set() .Where(s => ids.Contains(s.Id)) @@ -57,14 +57,14 @@ public class ChangeLogRepository : IChangeLogRepository foreach (var entity in entities) { - entity.Obsolete = updateTime; - entity.IdObsoletedCommit = idCommit; + entity.Obsolete = commit.Creation; + entity.IdObsoletedCommit = commit.Id; } return await db.SaveChangesAsync(token); } - public async Task MarkAsDeleted(Guid idDiscriminator, Guid idCommit, DateTimeOffset updateTime, CancellationToken token) + public async Task MarkAsDeleted(Guid idDiscriminator, ChangeLogCommitDto commit, CancellationToken token) { var query = db.Set() .Where(s => s.DiscriminatorId == idDiscriminator) @@ -74,8 +74,8 @@ public class ChangeLogRepository : IChangeLogRepository foreach (var entity in entities) { - entity.Obsolete = updateTime; - entity.DiscriminatorId = idCommit; + entity.Obsolete = commit.Creation; + entity.DiscriminatorId = commit.Id; } return await db.SaveChangesAsync(token); @@ -91,7 +91,7 @@ public class ChangeLogRepository : IChangeLogRepository using var transaction = await db.Database.BeginTransactionAsync(token); - result += await MarkAsDeleted(commitDto.Id, changeLogIds, commitDto.Creation, token); + result += await MarkAsDeleted(idDiscriminator, commitDto, token); result += await AddRange(idDiscriminator, commitDto, dtos, token); await transaction.CommitAsync(token); diff --git a/DD.Persistence.IntegrationTests/Controllers/ChangeLogControllerTest.cs b/DD.Persistence.IntegrationTests/Controllers/ChangeLogControllerTest.cs index b17641d..c312a24 100644 --- a/DD.Persistence.IntegrationTests/Controllers/ChangeLogControllerTest.cs +++ b/DD.Persistence.IntegrationTests/Controllers/ChangeLogControllerTest.cs @@ -44,11 +44,20 @@ public class ChangeLogControllerTest : BaseIntegrationTest var idDiscriminator = newEntitiesData.Item1; var dtos = newEntitiesData.Item2; + var newEntitiesData2 = await CreateAndReturnNewDtos(insertedCount, (-15, -1)); + var idDiscriminator2 = newEntitiesData2.Item1; + var dtos2 = newEntitiesData2.Item2; + //act var result = await client.ClearAndAddRange(idDiscriminator, dtos, "Добавление новых элементов и очистка старых", CancellationToken.None); + var changeLogActualWithIdDiscriminator = await client.GetByDate(idDiscriminator2, DateTimeOffset.UtcNow, paginationRequest, CancellationToken.None); + var changeLogActualWithIdDiscriminator2 = await client.GetByDate(idDiscriminator, DateTimeOffset.UtcNow, paginationRequest, CancellationToken.None); // assert Assert.Equal(insertedCount * 2, result); + Assert.Equal(insertedCount, changeLogActualWithIdDiscriminator.Count); + Assert.Equal(insertedCount, changeLogActualWithIdDiscriminator2.Count); + } [Fact] @@ -143,12 +152,24 @@ public class ChangeLogControllerTest : BaseIntegrationTest var idDiscriminator = newEntitiesData.Item1; var dtos = newEntitiesData.Item2; + var newEntitiesData2 = await CreateAndReturnNewDtos(insertedCount, (-15, -1)); + var idDiscriminator2 = newEntitiesData2.Item1; + var dtos2 = newEntitiesData2.Item2; + // act var ids = dtos.Select(e => e.Id); var result = await client.DeleteRange(ids, "Удаление нескольких записей", CancellationToken.None); // assert Assert.Equal(insertedCount, result); + + // act + var actualWithIdDescriminator = await client.GetByDate(idDiscriminator, DateTimeOffset.UtcNow, paginationRequest, CancellationToken.None); + var actualWithIdDescriminator2 = await client.GetByDate(idDiscriminator2, DateTimeOffset.UtcNow, paginationRequest, CancellationToken.None); + + // assert + Assert.Equal(0, actualWithIdDescriminator.Count); + Assert.Equal(insertedCount, actualWithIdDescriminator2.Count); } [Fact] diff --git a/DD.Persistence.Models/ChangeLogCommitDto.cs b/DD.Persistence.Models/ChangeLogCommitDto.cs index 0df8baf..a1aea48 100644 --- a/DD.Persistence.Models/ChangeLogCommitDto.cs +++ b/DD.Persistence.Models/ChangeLogCommitDto.cs @@ -5,17 +5,26 @@ /// public class ChangeLogCommitDto : CreateChangeLogCommitRequest { + /// + /// + /// + public ChangeLogCommitDto() + { + + } + /// + /// ctor + /// + /// + /// + public ChangeLogCommitDto(Guid idAuthor, string? comment) : base(idAuthor, comment) + { + } + /// /// Id /// public Guid Id { get; set; } - /// - /// - /// - public ChangeLogCommitDto(Guid id, CreateChangeLogCommitRequest request) : base(request.IdAuthor, request.Comment) - { - Id = id; - } } diff --git a/DD.Persistence.Models/Requests/CreateChangeLogCommitRequest.cs b/DD.Persistence.Models/Requests/CreateChangeLogCommitRequest.cs index e0bcffa..7393264 100644 --- a/DD.Persistence.Models/Requests/CreateChangeLogCommitRequest.cs +++ b/DD.Persistence.Models/Requests/CreateChangeLogCommitRequest.cs @@ -18,15 +18,23 @@ public class CreateChangeLogCommitRequest /// /// Комментарий /// - public string Comment { get; set; } = string.Empty; + public string? Comment { get; set; } /// /// /// - public CreateChangeLogCommitRequest(Guid idAuthor, string comment) + public CreateChangeLogCommitRequest() + { + + } + + /// + /// + /// + public CreateChangeLogCommitRequest(Guid idAuthor, string? comment) { IdAuthor = idAuthor; - Comment = comment; + Comment = comment ?? string.Empty; Creation = DateTimeOffset.UtcNow; } diff --git a/DD.Persistence.Test/ChangeLogTest.cs b/DD.Persistence.Test/ChangeLogTest.cs index 106dca5..c9d8ff8 100644 --- a/DD.Persistence.Test/ChangeLogTest.cs +++ b/DD.Persistence.Test/ChangeLogTest.cs @@ -24,13 +24,12 @@ public class ChangeLogTest { //arrange var discriminatorId = Uuid7.Guid(); - var expectedCommitId = Uuid7.Guid(); - var comment = "Добавление нескольких значений"; - var commitRequest = new CreateChangeLogCommitRequest(Uuid7.Guid(), comment); - var commit = new ChangeLogCommitDto(expectedCommitId, commitRequest); + var commitRequest = new CreateChangeLogCommitRequest(Uuid7.Guid(), "Добавление нескольких значений"); + var commit = new ChangeLogCommitDto(commitRequest.IdAuthor, commitRequest.Comment); + commit.Id = Uuid7.Guid(); var dtos = GenerateChangeLogValuesDto(2); - changeLogCommitRepository.Add(Arg.Any(), Arg.Any()).Returns(Uuid7.Guid()); + changeLogCommitRepository.Add(Arg.Any(), Arg.Any()).Returns(commit); changeLogRepository .AddRange( Arg.Any(), @@ -55,14 +54,13 @@ public class ChangeLogTest { //arrange var discriminatorId = Uuid7.Guid(); - var expectedCommitId = Uuid7.Guid(); - var comment = "Изменение нескольких значений"; - var commitRequest = new CreateChangeLogCommitRequest(Uuid7.Guid(), comment); - var commit = new ChangeLogCommitDto(expectedCommitId, commitRequest); + var commitRequest = new CreateChangeLogCommitRequest(Uuid7.Guid(), "Изменение нескольких значений"); + var commit = new ChangeLogCommitDto(commitRequest.IdAuthor, commitRequest.Comment); + commit.Id = Uuid7.Guid(); var dtos = GenerateChangeLogValuesDto(2); - changeLogCommitRepository.Add(Arg.Any(), Arg.Any()).Returns(commit.Id); + changeLogCommitRepository.Add(Arg.Any(), Arg.Any()).Returns(commit); changeLogRepository .UpdateRange( @@ -91,19 +89,17 @@ public class ChangeLogTest { //arrange var discriminatorId = Uuid7.Guid(); - var expectedCommitId = Uuid7.Guid(); - var comment = "Удаление нескольких значений"; - var commitRequest = new CreateChangeLogCommitRequest(Uuid7.Guid(), comment); - var commit = new ChangeLogCommitDto(expectedCommitId, commitRequest); + var commitRequest = new CreateChangeLogCommitRequest(Uuid7.Guid(), "Удаление нескольких значений"); + var commit = new ChangeLogCommitDto(commitRequest.IdAuthor, commitRequest.Comment); + commit.Id = Uuid7.Guid(); var dtos = GenerateChangeLogValuesDto(2); var dtoIds = dtos.Select(d => d.Id); - changeLogCommitRepository.Add(Arg.Any(), Arg.Any()).Returns(expectedCommitId); + changeLogCommitRepository.Add(Arg.Any(), Arg.Any()).Returns(commit); changeLogRepository .MarkAsDeleted( - Arg.Any(), Arg.Any>(), - Arg.Any(), + Arg.Any(), Arg.Any()) .Returns(2); @@ -115,7 +111,7 @@ public class ChangeLogTest //assert await changeLogCommitRepository.Received(1).Add(commitRequest, CancellationToken.None); - await changeLogRepository.Received(2).MarkAsDeleted(commit.Id, dtoIds, Arg.Any(), CancellationToken.None); + await changeLogRepository.Received(2).MarkAsDeleted(dtoIds, commit, CancellationToken.None); } [Fact] @@ -123,14 +119,13 @@ public class ChangeLogTest { //arrange var discriminatorId = Uuid7.Guid(); - var expectedCommitId = Uuid7.Guid(); - var comment = "Удаление и добавление нескольких значений"; - var commitRequest = new CreateChangeLogCommitRequest(expectedCommitId, comment); - var commit = new ChangeLogCommitDto(expectedCommitId, commitRequest); + var commitRequest = new CreateChangeLogCommitRequest(Uuid7.Guid(), "Удаление и добавление нескольких значений"); + var commit = new ChangeLogCommitDto(commitRequest.IdAuthor, commitRequest.Comment); + commit.Id = Uuid7.Guid(); var dtos = GenerateChangeLogValuesDto(2); var dtoIds = dtos.Select(d => d.Id); - changeLogCommitRepository.Add(Arg.Any(), Arg.Any()).Returns(Uuid7.Guid()); + changeLogCommitRepository.Add(Arg.Any(), Arg.Any()).Returns(commit); changeLogRepository .ClearAndAddRange( Arg.Any(), diff --git a/DD.Persistence/Repositories/IChangeLogCommitRepository.cs b/DD.Persistence/Repositories/IChangeLogCommitRepository.cs index 6cb1d0d..fecd2c5 100644 --- a/DD.Persistence/Repositories/IChangeLogCommitRepository.cs +++ b/DD.Persistence/Repositories/IChangeLogCommitRepository.cs @@ -1,9 +1,4 @@ using DD.Persistence.Models.Requests; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace DD.Persistence.Repositories; @@ -18,5 +13,5 @@ public interface IChangeLogCommitRepository /// /// /// - Task Add(CreateChangeLogCommitRequest commitDto, CancellationToken token); + Task Add(CreateChangeLogCommitRequest commitDto, CancellationToken token); } diff --git a/DD.Persistence/Repositories/IChangeLogRepository.cs b/DD.Persistence/Repositories/IChangeLogRepository.cs index 5fd3ba6..2703d72 100644 --- a/DD.Persistence/Repositories/IChangeLogRepository.cs +++ b/DD.Persistence/Repositories/IChangeLogRepository.cs @@ -1,7 +1,6 @@ using DD.Persistence.Models; using DD.Persistence.Models.Common; using DD.Persistence.Models.Requests; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; namespace DD.Persistence.Repositories; @@ -23,22 +22,20 @@ public interface IChangeLogRepository : ISyncWithDiscriminatorRepository /// Пометить записи как удаленные /// - /// /// ключи записей - /// + /// /// /// - Task MarkAsDeleted(Guid idCommit, IEnumerable ids, DateTimeOffset updateTime, CancellationToken token); + Task MarkAsDeleted(IEnumerable ids, ChangeLogCommitDto commit, CancellationToken token); /// /// Пометить записи как удаленные /// /// дискриминатор таблицы - /// - /// + /// /// /// - Task MarkAsDeleted(Guid idDiscriminator, Guid idCommit, DateTimeOffset updateTime, CancellationToken token); + Task MarkAsDeleted(Guid idDiscriminator, ChangeLogCommitDto commit, CancellationToken token); /// /// Очистить и добавить новые