using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudInfrastructure.Services.Cache; using Mapster; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services { public class DataService : IDataService { private readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; private readonly ITelemetryAnalyticsService analyticsService; private readonly CacheTable cacheTelemetry; private readonly CacheTable cacheTelemetryUsers; private readonly CacheTable cacheWells; public DataService(IAsbCloudDbContext db, ITelemetryService telemetryService, ITelemetryAnalyticsService analyticsService, CacheDb cacheDb) { this.db = db; this.telemetryService = telemetryService; this.analyticsService = analyticsService; cacheTelemetry = cacheDb.GetCachedTable((AsbCloudDbContext)db); cacheTelemetryUsers = cacheDb.GetCachedTable((AsbCloudDbContext)db); cacheWells = cacheDb.GetCachedTable((AsbCloudDbContext)db); } public async Task> GetAsync(int idWell, DateTime dateBegin = default, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default) { var well = cacheWells.FirstOrDefault(w => w.Id == idWell); if (well is null) return default; var telemetry = cacheTelemetry.FirstOrDefault(t => t.Id == well.IdTelemetry); if (telemetry is null) return default; if (dateBegin == default) dateBegin = DateTime.Now.AddSeconds(-intervalSec); var datEnd = dateBegin.AddSeconds(intervalSec); var query = from data in db.DataSaubBases where data.IdTelemetry == telemetry.Id && data.Date >= dateBegin && data.Date < datEnd select data; var fullDataCount = await query.CountAsync(token) .ConfigureAwait(false); if (fullDataCount == 0) return default; if (fullDataCount > 1.75 * approxPointsCount) { var m = (int)Math.Round(1d * fullDataCount / approxPointsCount); if (m > 1) query = query.Where(d => d.Id % m == 0); } var entities = await query.AsNoTracking() .ToListAsync(token).ConfigureAwait(false); var dtos = entities.Adapt(); return dtos; } public async Task UpdateDataAsync(string uid, IEnumerable dtos, CancellationToken token = default) { if (dtos == default || !dtos.Any()) return 0; var telemetryId = telemetryService.GetOrCreateTemetryIdByUid(uid); var dtoMinDate = dtos.Min(d => d.Date); var dtoMaxDate = dtos.Max(d => d.Date); var oldDataSaubBase = await (from d in db.DataSaubBases where d.IdTelemetry == telemetryId && d.Date > dtoMinDate && d.Date < dtoMaxDate select d).AsNoTracking() .ToListAsync(token) .ConfigureAwait(false); if (oldDataSaubBase.Any()) db.DataSaubBases.RemoveRange(oldDataSaubBase); foreach (var dto in dtos) { var dataSaub = dto.Adapt(); var telemetryUser = await cacheTelemetryUsers .FirstOrDefaultAsync(u => u.IdTelemetry == telemetryId && (u.Name == dto.User || u.Surname == dto.User), token) .ConfigureAwait(false); dataSaub.IdUser = telemetryUser?.IdUser; dataSaub.IdTelemetry = telemetryId; db.DataSaubBases.Add(dataSaub); dto.IdTelemetry = telemetryId; analyticsService.SaveAnalytics(dto); } return await db.SaveChangesAsync(token); } public async Task GetDataDatesRangeAsync(int idWell, CancellationToken token = default) { var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell); if (telemetryId is null) return null; var (From, To) = await db.GetDatesRangeAsync((int)telemetryId, token) .ConfigureAwait(false); return new DatesRangeDto { From = From, To = To }; } } }