using Mapster; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json.Linq; using DD.Persistence.Database.Entity; using DD.Persistence.Models; using DD.Persistence.Models.Requests; using DD.Persistence.Repositories; using UuidExtensions; namespace DD.Persistence.Repository.Repositories { public class TechMessagesRepository : ITechMessagesRepository { private readonly IDataSourceSystemRepository sourceSystemRepository; private DbContext db; public TechMessagesRepository(DbContext db, IDataSourceSystemRepository sourceSystemRepository) { this.db = db; this.sourceSystemRepository = sourceSystemRepository; } protected virtual IQueryable GetQueryReadOnly() => db.Set() .Include(e => e.System); public async Task> GetPage(PaginationRequest request, CancellationToken token) { var query = GetQueryReadOnly(); var count = await query.CountAsync(token); var sort = request.SortSettings != string.Empty ? request.SortSettings! : nameof(TechMessage.Timestamp); var entities = await query .SortBy(sort) .Skip(request.Skip) .Take(request.Take) .ToArrayAsync(token); var dto = new PaginationContainer() { Skip = request.Skip, Take = request.Take, Count = count, Items = entities.Select(e => e.Adapt()) }; return dto; } public async Task> GetStatistics(IEnumerable systems, IEnumerable categoryIds, CancellationToken token) { var query = GetQueryReadOnly(); var result = await query .Where(e => !systems.Any() || systems.Contains(e.System.SystemId)) .GroupBy(e => e.System.SystemId, (key, group) => new { System = group.FirstOrDefault()!.System.Name, Categories = group .Where(g => !categoryIds.Any() || categoryIds.Contains(g.CategoryId)) }) .ToArrayAsync(token); var entities = new List(); foreach (var e in result) { var categories = e.Categories .GroupBy(g => g.CategoryId) .ToDictionary(c => c.Key, v => v.Count()); var entity = new MessagesStatisticDto() { System = e.System, Categories = categories }; entities.Add(entity); } return entities; } public async Task AddRange(Guid systemId, IEnumerable dtos, Guid userId, CancellationToken token) { await CreateSystemIfNotExist(systemId, token); var entities = new List(); foreach (var dto in dtos) { var entity = dto.Adapt(); await CreateSystemIfNotExist(systemId, token); entity.SystemId = systemId; entities.Add(entity); } await db.Set().AddRangeAsync(entities, token); var result = await db.SaveChangesAsync(token); return result; } public async Task> GetPart(DateTimeOffset dateBegin, int take, CancellationToken token) { var query = GetQueryReadOnly(); var entities = await query .Where(e => e.Timestamp >= dateBegin) .Take(take) .ToArrayAsync(token); var dtos = entities .Select(e => e.Adapt()); return dtos; } public async Task> GetSystems(CancellationToken token) { var systems = await sourceSystemRepository.Get(token); return systems!; } public async Task GetDatesRangeAsync(CancellationToken token) { var query = GetQueryReadOnly() .GroupBy(e => 1) .Select(group => new { Min = group.Min(e => e.Timestamp), Max = group.Max(e => e.Timestamp), }); var values = await query.FirstOrDefaultAsync(token); if (values == null) return null; var result = new DatesRangeDto() { From = values?.Min ?? DateTimeOffset.MinValue, To = values?.Max ?? DateTimeOffset.MaxValue }; return result; } private async Task CreateSystemIfNotExist(Guid systemId, CancellationToken token) { var systems = await sourceSystemRepository.Get(token); var system = systems?.FirstOrDefault(e => e.SystemId == systemId); if (system == null) { system = new DataSourceSystemDto() { SystemId = systemId, Name = string.Empty }; await sourceSystemRepository.Add(system, token); } } } }