using DD.Persistence.Models;
using DD.Persistence.Models.Common;
using DD.Persistence.Models.Requests;
using DD.Persistence.Models.Requests.ChangeLog;
using DD.Persistence.Repositories;
using Microsoft.Extensions.Caching.Memory;
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.FromSeconds(3);
///
/// ctor
///
///
///
///
public ChangeLogService(
IMemoryCache memoryCache,
IChangeLogCommitRepository commitRepository,
IChangeLogRepository repository)
{
this.memoryCache = memoryCache;
this.commitRepository = commitRepository;
this.repository = repository;
}
///
/// Чтение или создание нового коммита
///
///
///
///
///
private async Task GetOrCreateCommitAsync(Guid idDiscriminator, CreateChangeLogCommitRequest request, CancellationToken token)
{
var key = (idDiscriminator, request.IdAuthor, request.Comment);
var commit = await memoryCache.GetOrCreateAsync(key, async (cacheEntry) =>
{
cacheEntry.AbsoluteExpirationRelativeToNow = AbsoluteExpirationRelativeToNow;
var commit = await commitRepository.Add(request, token);
return commit;
});
return commit!;
}
///
/// Добавление записи в журнал изменений
///
///
///
///
///
///
public async Task AddRange(Guid idDiscriminator, CreateChangeLogCommitRequest request, IEnumerable dtos, CancellationToken token)
{
var commit = await GetOrCreateCommitAsync(idDiscriminator, request, token);
var result = await repository.AddRange(idDiscriminator, commit, dtos, token);
return result;
}
///
/// Пометить запись журнала изменений как удаленную
///
///
///
///
///
///
public async Task MarkAsDeleted(Guid idDiscriminator, IEnumerable ids, CreateChangeLogCommitRequest request, CancellationToken token)
{
var commit = await GetOrCreateCommitAsync(idDiscriminator, request, token);
var result = await repository.MarkAsDeleted(ids, commit, token);
return result;
}
///
/// Очистить старые и добавить новые записи в журнал изменений
///
///
///
///
///
///
public async Task ClearAndAddRange(Guid idDiscriminator, CreateChangeLogCommitRequest request, IEnumerable dtos, CancellationToken token)
{
var commit = await GetOrCreateCommitAsync(idDiscriminator, request, token);
var result = await repository.ClearAndAddRange(idDiscriminator, commit, dtos, token);
return result;
}
///
/// Обновить записи в журнале изменений
///
///
///
///
///
///
public async Task UpdateRange(Guid idDiscriminator, CreateChangeLogCommitRequest commitRequest, IEnumerable dtos, CancellationToken token)
{
var commit = await GetOrCreateCommitAsync(idDiscriminator, commitRequest, token);
var result = await repository.UpdateRange(commit, 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;
}
///
/// Метод получения статистики пользователя по количеству изменений в разрезе дней
///
///
///
///
public async Task> GetUserStatisticsCount(ChangeLogRequest request, CancellationToken token)
{
var result = await commitRepository.GetStatistics(request.DiscriminatorId, request.UserId, token);
return result;
}
///
///
///
///
///
///
///
public async Task> GetHistoryChangeLog(ChangeLogRequest request, CancellationToken token)
{
var commits = await commitRepository.Get(request.DiscriminatorId, request.UserId, token);
if (!commits.Any())
return Enumerable.Empty();
var result = commits.Select(c => new HistoryChangeLogDto()
{
ChangeLogItems = new List(),
Comment = c.Comment ?? string.Empty,
DateTime = c.Creation,
User = new UserDto() {
DisplayName = "",
Id = c.IdAuthor,
}
});
return result;
}
}