using DD.Persistence.Models.Common; using DD.Persistence.Models; using DD.Persistence.Models.Requests; using DD.Persistence.Repositories; using Microsoft.Extensions.Caching.Memory; using DD.Persistence.Database.Entity; namespace DD.Persistence.API.Services; /// /// Сервис по работе с журналом изменений /// public class ChangeLogService { private readonly IMemoryCache memoryCache; private readonly IChangeLogCommitRepository commitRepository; private readonly IChangeLogRepository repository; private readonly TimeSpan? AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60); /// /// ctor /// /// /// /// public ChangeLogService( IMemoryCache memoryCache, IChangeLogCommitRepository commitRepository, IChangeLogRepository repository) { this.memoryCache = memoryCache; this.commitRepository = commitRepository; this.repository = repository; } /// /// Чтение ключа коммита из кеша или (если коммита в кеше нет) создание коммита /// /// /// /// private async Task GetOrCreateCommitAsync(CreateChangeLogCommitRequest commitDto, CancellationToken token) { var key = (commitDto.IdAuthor, commitDto.Comment); var commitId = await memoryCache.GetOrCreateAsync(key, async (cacheEntry) => { cacheEntry.AbsoluteExpirationRelativeToNow = AbsoluteExpirationRelativeToNow; var commitId = await commitRepository.Add(commitDto, token); return commitId; }); return commitId; } /// /// Добавление записи в журнал изменений /// /// /// /// /// /// public async Task AddRange(Guid idDiscriminator, CreateChangeLogCommitRequest commitRequestDto, IEnumerable dtos, CancellationToken token) { var commitId = await GetOrCreateCommitAsync(commitRequestDto, token); var commitDto = new ChangeLogCommitDto(commitId, commitRequestDto); var result = await repository.AddRange(idDiscriminator, commitDto, dtos, token); return result; } /// /// Пометить запись журнала изменений как удаленную /// /// /// /// /// public async Task MarkAsDeleted(IEnumerable ids, CreateChangeLogCommitRequest commitRequestDto, CancellationToken token) { var commitId = await GetOrCreateCommitAsync(commitRequestDto, token); var commitDto = new ChangeLogCommitDto(commitId, commitRequestDto); var result = await repository.MarkAsDeleted(commitId, ids, commitDto.Creation, token); return result; } /// /// Очистить старые и добавить новые записи в журнал изменений /// /// /// /// /// /// public async Task ClearAndAddRange(Guid idDiscriminator, CreateChangeLogCommitRequest commitRequestDto, IEnumerable dtos, CancellationToken token) { var commitId = await GetOrCreateCommitAsync(commitRequestDto, token); var commitDto = new ChangeLogCommitDto(commitId, commitRequestDto); var result = await repository.ClearAndAddRange(idDiscriminator, commitDto, dtos, token); return result; } /// /// Обновить записи в журнале изменений /// /// /// /// /// public async Task UpdateRange(CreateChangeLogCommitRequest commitRequestDto, IEnumerable dtos, CancellationToken token) { var commitId = await GetOrCreateCommitAsync(commitRequestDto, token); var commitDto = new ChangeLogCommitDto(commitId, commitRequestDto); var result = await repository.UpdateRange(commitDto, dtos, token); return result; } /// /// Получение актуальных записей на определенный момент времени (с пагинацией) /// /// /// /// /// /// public async Task> GetByDate( Guid idDiscriminator, DateTimeOffset momentUtc, PaginationRequest paginationRequest, CancellationToken token) { var result = await repository.GetByDate(idDiscriminator, momentUtc, paginationRequest, token); return result; } /// /// Получение измененных записей за период времени /// /// /// /// /// /// public async Task> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token) { var result = await repository.GetChangeLogForInterval(idDiscriminator, dateBegin, dateEnd, token); return result; } /// /// Получение списка дат, в которые происходили изменения (день, месяц, год, без времени) /// /// /// /// public async Task> GetDatesChange(Guid idDiscriminator, CancellationToken token) { var result = await repository.GetDatesChange(idDiscriminator, token); return result; } /// /// Получить данные, начиная с определенной даты /// /// /// /// /// public async Task> GetGtDate(Guid idDiscriminator, DateTimeOffset dateBegin, CancellationToken token) { var result = await repository.GetGtDate(idDiscriminator, dateBegin, token); return result; } /// /// Получить диапазон дат, для которых есть данные в репозитории /// /// /// /// public async Task GetDatesRange(Guid idDiscriminator, CancellationToken token) { var result = await repository.GetDatesRange(idDiscriminator, token); return result; } }