2025-02-18 15:43:27 +05:00
|
|
|
|
using DD.Persistence.Models.Common;
|
|
|
|
|
using DD.Persistence.Models;
|
|
|
|
|
using DD.Persistence.Models.Requests;
|
2025-02-17 08:44:48 +05:00
|
|
|
|
using DD.Persistence.Repositories;
|
2025-02-13 17:57:43 +05:00
|
|
|
|
using Microsoft.Extensions.Caching.Memory;
|
2025-02-18 15:43:27 +05:00
|
|
|
|
using DD.Persistence.Database.Entity;
|
2025-02-13 17:57:43 +05:00
|
|
|
|
|
|
|
|
|
namespace DD.Persistence.API.Services;
|
2025-02-18 10:34:42 +05:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Сервис по работе с журналом изменений
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class ChangeLogService
|
2025-02-13 17:57:43 +05:00
|
|
|
|
{
|
|
|
|
|
private readonly IMemoryCache memoryCache;
|
|
|
|
|
private readonly IChangeLogCommitRepository commitRepository;
|
|
|
|
|
private readonly IChangeLogRepository repository;
|
|
|
|
|
private readonly TimeSpan? AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60);
|
|
|
|
|
|
2025-02-18 10:34:42 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// ctor
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="memoryCache"></param>
|
|
|
|
|
/// <param name="commitRepository"></param>
|
|
|
|
|
/// <param name="repository"></param>
|
2025-02-13 17:57:43 +05:00
|
|
|
|
public ChangeLogService(
|
|
|
|
|
IMemoryCache memoryCache,
|
|
|
|
|
IChangeLogCommitRepository commitRepository,
|
|
|
|
|
IChangeLogRepository repository)
|
|
|
|
|
{
|
|
|
|
|
this.memoryCache = memoryCache;
|
|
|
|
|
this.commitRepository = commitRepository;
|
|
|
|
|
this.repository = repository;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-18 10:34:42 +05:00
|
|
|
|
/// <summary>
|
2025-02-20 18:30:56 +05:00
|
|
|
|
/// Чтение ключа коммита из кеша или (если коммита в кеше нет) создание коммита
|
2025-02-18 10:34:42 +05:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="commitDto"></param>
|
|
|
|
|
/// <param name="token"></param>
|
|
|
|
|
/// <returns></returns>
|
2025-02-21 12:25:22 +05:00
|
|
|
|
private async Task<Guid> GetOrCreateCommitAsync(ChangeLogCommitRequest commitDto, CancellationToken token)
|
2025-02-13 17:57:43 +05:00
|
|
|
|
{
|
2025-02-17 08:44:48 +05:00
|
|
|
|
var key = (commitDto.IdAuthor, commitDto.Comment);
|
2025-02-13 17:57:43 +05:00
|
|
|
|
var commitId = await memoryCache.GetOrCreateAsync(key, async (cacheEntry) =>
|
|
|
|
|
{
|
|
|
|
|
cacheEntry.AbsoluteExpirationRelativeToNow = AbsoluteExpirationRelativeToNow;
|
|
|
|
|
|
2025-02-17 08:44:48 +05:00
|
|
|
|
var commitId = await commitRepository.Add(commitDto, token);
|
2025-02-13 17:57:43 +05:00
|
|
|
|
|
|
|
|
|
return commitId;
|
|
|
|
|
});
|
|
|
|
|
return commitId;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-18 10:34:42 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Добавление записи в журнал изменений
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="idDiscriminator"></param>
|
2025-02-21 12:25:22 +05:00
|
|
|
|
/// <param name="commitRequestDto"></param>
|
2025-02-18 15:53:54 +05:00
|
|
|
|
/// <param name="dtos"></param>
|
2025-02-18 10:34:42 +05:00
|
|
|
|
/// <param name="token"></param>
|
|
|
|
|
/// <returns></returns>
|
2025-02-21 12:25:22 +05:00
|
|
|
|
public async Task<int> AddRange(Guid idDiscriminator, ChangeLogCommitRequest commitRequestDto, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token)
|
2025-02-17 08:44:48 +05:00
|
|
|
|
{
|
2025-02-21 12:25:22 +05:00
|
|
|
|
var commitId = await GetOrCreateCommitAsync(commitRequestDto, token);
|
|
|
|
|
var commitDto = new ChangeLogCommitDto(commitId, commitRequestDto);
|
2025-02-17 08:44:48 +05:00
|
|
|
|
|
2025-02-18 15:53:54 +05:00
|
|
|
|
var result = await repository.AddRange(idDiscriminator, commitDto, dtos, token);
|
2025-02-17 08:44:48 +05:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-18 10:34:42 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Пометить запись журнала изменений как удаленную
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="ids"></param>
|
2025-02-21 12:25:22 +05:00
|
|
|
|
/// <param name="commitRequestDto"></param>
|
2025-02-18 10:34:42 +05:00
|
|
|
|
/// <param name="token"></param>
|
|
|
|
|
/// <returns></returns>
|
2025-02-21 12:25:22 +05:00
|
|
|
|
public async Task<int> MarkAsDeleted(IEnumerable<Guid> ids, ChangeLogCommitRequest commitRequestDto, CancellationToken token)
|
2025-02-13 17:57:43 +05:00
|
|
|
|
{
|
2025-02-21 12:25:22 +05:00
|
|
|
|
var commitId = await GetOrCreateCommitAsync(commitRequestDto, token);
|
|
|
|
|
var commitDto = new ChangeLogCommitDto(commitId, commitRequestDto);
|
2025-02-17 08:44:48 +05:00
|
|
|
|
|
|
|
|
|
var result = await repository.MarkAsDeleted(commitId, ids, commitDto.Creation, token);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-18 10:34:42 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Очистить старые и добавить новые записи в журнал изменений
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="idDiscriminator"></param>
|
2025-02-21 12:25:22 +05:00
|
|
|
|
/// <param name="commitRequestDto"></param>
|
2025-02-18 15:53:54 +05:00
|
|
|
|
/// <param name="dtos"></param>
|
2025-02-18 10:34:42 +05:00
|
|
|
|
/// <param name="token"></param>
|
|
|
|
|
/// <returns></returns>
|
2025-02-21 12:25:22 +05:00
|
|
|
|
public async Task<int> ClearAndAddRange(Guid idDiscriminator, ChangeLogCommitRequest commitRequestDto, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token)
|
2025-02-17 08:44:48 +05:00
|
|
|
|
{
|
2025-02-21 12:25:22 +05:00
|
|
|
|
var commitId = await GetOrCreateCommitAsync(commitRequestDto, token);
|
|
|
|
|
var commitDto = new ChangeLogCommitDto(commitId, commitRequestDto);
|
2025-02-17 08:44:48 +05:00
|
|
|
|
|
2025-02-18 15:53:54 +05:00
|
|
|
|
var result = await repository.ClearAndAddRange(idDiscriminator, commitDto, dtos, token);
|
2025-02-17 08:44:48 +05:00
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-18 10:34:42 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Обновить записи в журнале изменений
|
|
|
|
|
/// </summary>
|
2025-02-21 12:25:22 +05:00
|
|
|
|
/// <param name="commitRequestDto"></param>
|
2025-02-18 15:53:54 +05:00
|
|
|
|
/// <param name="dtos"></param>
|
2025-02-18 10:34:42 +05:00
|
|
|
|
/// <param name="token"></param>
|
|
|
|
|
/// <returns></returns>
|
2025-02-21 12:25:22 +05:00
|
|
|
|
public async Task<int> UpdateRange(ChangeLogCommitRequest commitRequestDto, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token)
|
2025-02-17 08:44:48 +05:00
|
|
|
|
{
|
2025-02-21 12:25:22 +05:00
|
|
|
|
var commitId = await GetOrCreateCommitAsync(commitRequestDto, token);
|
|
|
|
|
var commitDto = new ChangeLogCommitDto(commitId, commitRequestDto);
|
2025-02-17 08:44:48 +05:00
|
|
|
|
|
2025-02-21 12:25:22 +05:00
|
|
|
|
var result = await repository.UpdateRange(commitDto, dtos, token);
|
2025-02-17 08:44:48 +05:00
|
|
|
|
|
|
|
|
|
return result;
|
2025-02-13 17:57:43 +05:00
|
|
|
|
}
|
2025-02-18 15:43:27 +05:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Получение актуальных записей на определенный момент времени (с пагинацией)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="idDiscriminator"></param>
|
|
|
|
|
/// <param name="momentUtc"></param>
|
|
|
|
|
/// <param name="paginationRequest"></param>
|
|
|
|
|
/// <param name="token"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<PaginationContainer<ChangeLogValuesDto>> GetByDate(
|
|
|
|
|
Guid idDiscriminator,
|
|
|
|
|
DateTimeOffset momentUtc,
|
|
|
|
|
PaginationRequest paginationRequest,
|
|
|
|
|
CancellationToken token)
|
|
|
|
|
{
|
|
|
|
|
var result = await repository.GetByDate(idDiscriminator, momentUtc, paginationRequest, token);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Получение измененных записей за период времени
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="idDiscriminator"></param>
|
|
|
|
|
/// <param name="dateBegin"></param>
|
|
|
|
|
/// <param name="dateEnd"></param>
|
|
|
|
|
/// <param name="token"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<IEnumerable<ChangeLogDto>> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token)
|
|
|
|
|
{
|
|
|
|
|
var result = await repository.GetChangeLogForInterval(idDiscriminator, dateBegin, dateEnd, token);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Получение списка дат, в которые происходили изменения (день, месяц, год, без времени)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="idDiscriminator"></param>
|
|
|
|
|
/// <param name="token"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<IEnumerable<DateOnly>> GetDatesChange(Guid idDiscriminator, CancellationToken token)
|
|
|
|
|
{
|
|
|
|
|
var result = await repository.GetDatesChange(idDiscriminator, token);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Получить данные, начиная с определенной даты
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="idDiscriminator"></param>
|
|
|
|
|
/// <param name="dateBegin"></param>
|
|
|
|
|
/// <param name="token"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<IEnumerable<ChangeLogValuesDto>> GetGtDate(Guid idDiscriminator, DateTimeOffset dateBegin, CancellationToken token)
|
|
|
|
|
{
|
|
|
|
|
var result = await repository.GetGtDate(idDiscriminator, dateBegin, token);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Получить диапазон дат, для которых есть данные в репозитории
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="idDiscriminator"></param>
|
|
|
|
|
/// <param name="token"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token)
|
|
|
|
|
{
|
|
|
|
|
var result = await repository.GetDatesRange(idDiscriminator, token);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2025-02-13 17:57:43 +05:00
|
|
|
|
}
|