2021-04-07 18:01:56 +05:00
|
|
|
|
using AsbCloudApp.Data;
|
|
|
|
|
using AsbCloudApp.Services;
|
|
|
|
|
using AsbCloudDb.Model;
|
|
|
|
|
using AsbCloudInfrastructure.Services.Cache;
|
2021-07-28 09:46:58 +05:00
|
|
|
|
using Mapster;
|
2021-09-29 10:12:54 +05:00
|
|
|
|
using System.Collections.Generic;
|
2021-09-27 16:47:16 +05:00
|
|
|
|
using System.Linq;
|
2021-10-15 12:24:04 +05:00
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
2021-09-29 10:12:54 +05:00
|
|
|
|
using System;
|
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
2021-04-07 18:01:56 +05:00
|
|
|
|
|
|
|
|
|
namespace AsbCloudInfrastructure.Services
|
|
|
|
|
{
|
|
|
|
|
public class TelemetryService : ITelemetryService
|
|
|
|
|
{
|
2021-05-20 14:14:51 +05:00
|
|
|
|
private readonly CacheTable<Telemetry> cacheTelemetry;
|
|
|
|
|
private readonly CacheTable<Well> cacheWells;
|
2021-09-27 16:47:16 +05:00
|
|
|
|
private readonly IAsbCloudDbContext db;
|
2021-10-15 12:24:04 +05:00
|
|
|
|
private readonly ITelemetryTracker telemetryTracker;
|
2021-04-07 18:01:56 +05:00
|
|
|
|
|
2021-10-15 12:24:04 +05:00
|
|
|
|
public TelemetryService(IAsbCloudDbContext db, ITelemetryTracker telemetryTracker,
|
|
|
|
|
CacheDb cacheDb)
|
2021-04-07 18:01:56 +05:00
|
|
|
|
{
|
|
|
|
|
cacheTelemetry = cacheDb.GetCachedTable<Telemetry>((AsbCloudDbContext)db);
|
2021-05-17 12:53:30 +05:00
|
|
|
|
cacheWells = cacheDb.GetCachedTable<Well>((AsbCloudDbContext)db);
|
2021-09-27 16:47:16 +05:00
|
|
|
|
this.db = db;
|
2021-10-15 12:24:04 +05:00
|
|
|
|
this.telemetryTracker = telemetryTracker;
|
2021-04-07 18:01:56 +05:00
|
|
|
|
}
|
2021-10-15 12:24:04 +05:00
|
|
|
|
|
|
|
|
|
public async Task<IEnumerable<WellDto>> GetTransmittingWellsAsync(int idCompany, CancellationToken token)
|
|
|
|
|
{
|
|
|
|
|
var wells = new List<Well>();
|
|
|
|
|
IEnumerable<string> activeTelemetriesUids = telemetryTracker.GetTransmittingTelemetryUids();
|
|
|
|
|
if (activeTelemetriesUids.Any())
|
|
|
|
|
{
|
|
|
|
|
wells = await db.GetWellsForCompany(idCompany)
|
|
|
|
|
.Where(w => activeTelemetriesUids.Contains(w.Telemetry.RemoteUid))
|
|
|
|
|
.AsNoTracking()
|
|
|
|
|
.ToListAsync(token)
|
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
|
}
|
|
|
|
|
return wells.Select(w => new WellDto
|
|
|
|
|
{
|
|
|
|
|
Id = w.Id,
|
|
|
|
|
Caption = w.Caption,
|
|
|
|
|
Cluster = w.Cluster.Caption,
|
|
|
|
|
Deposit = w.Cluster.Deposit.Caption,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SaveRequestDate(string uid) =>
|
|
|
|
|
telemetryTracker.SaveRequestDate(uid);
|
2021-04-07 18:01:56 +05:00
|
|
|
|
|
2021-04-23 10:21:25 +05:00
|
|
|
|
public int GetOrCreateTemetryIdByUid(string uid)
|
2021-10-15 12:24:04 +05:00
|
|
|
|
=> GetOrCreateTelemetryByUid(uid).Id;
|
2021-04-07 18:01:56 +05:00
|
|
|
|
|
2021-07-27 14:43:30 +05:00
|
|
|
|
public int? GetidWellByTelemetryUid(string uid)
|
2021-04-23 10:21:25 +05:00
|
|
|
|
=> GetWellByTelemetryUid(uid)?.Id;
|
2021-04-30 17:35:35 +05:00
|
|
|
|
|
2021-06-25 15:10:05 +05:00
|
|
|
|
public double GetTimezoneOffsetByTelemetryId(int idTelemetry) =>
|
2021-10-04 15:54:58 +05:00
|
|
|
|
cacheTelemetry.FirstOrDefault(t => t.Id == idTelemetry).Info?.TimeZoneOffsetTotalHours ?? 0d;
|
2021-06-25 15:10:05 +05:00
|
|
|
|
|
2021-04-23 10:21:25 +05:00
|
|
|
|
public void UpdateInfo(string uid, TelemetryInfoDto info)
|
2021-04-09 17:59:07 +05:00
|
|
|
|
{
|
2021-04-23 10:21:25 +05:00
|
|
|
|
var telemetry = GetOrCreateTelemetryByUid(uid);
|
2021-07-28 09:46:58 +05:00
|
|
|
|
telemetry.Info = info.Adapt<TelemetryInfo>();
|
2021-04-23 10:21:25 +05:00
|
|
|
|
cacheTelemetry.Upsert(telemetry);
|
2021-04-07 18:01:56 +05:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-09 14:01:57 +05:00
|
|
|
|
public int? GetIdTelemetryByIdWell(int idWell)
|
2021-05-17 12:53:30 +05:00
|
|
|
|
{
|
2021-07-27 14:43:30 +05:00
|
|
|
|
var well = cacheWells.FirstOrDefault(w => w.Id == idWell);
|
2021-05-17 12:53:30 +05:00
|
|
|
|
if (well is null)
|
|
|
|
|
return null;
|
|
|
|
|
|
2021-08-09 14:01:57 +05:00
|
|
|
|
return well.IdTelemetry;
|
2021-05-17 12:53:30 +05:00
|
|
|
|
}
|
|
|
|
|
|
2021-04-23 10:21:25 +05:00
|
|
|
|
private Well GetWellByTelemetryUid(string uid)
|
2021-04-07 18:01:56 +05:00
|
|
|
|
{
|
2021-10-04 15:54:58 +05:00
|
|
|
|
var tele = cacheTelemetry.FirstOrDefault(t => t.RemoteUid == uid);
|
2021-04-23 10:21:25 +05:00
|
|
|
|
if (tele is null)
|
|
|
|
|
return null;
|
2021-08-24 10:59:10 +05:00
|
|
|
|
|
2021-05-17 12:53:30 +05:00
|
|
|
|
return cacheWells.FirstOrDefault(w => w?.IdTelemetry == tele.Id);
|
2021-04-07 18:01:56 +05:00
|
|
|
|
}
|
2021-04-23 10:21:25 +05:00
|
|
|
|
|
|
|
|
|
private Telemetry GetOrCreateTelemetryByUid(string uid)
|
2021-10-04 15:54:58 +05:00
|
|
|
|
=> cacheTelemetry.GetOrCreate(t => t.RemoteUid == uid, () => new Telemetry { RemoteUid = uid });
|
2021-09-29 10:12:54 +05:00
|
|
|
|
|
|
|
|
|
public IEnumerable<(string Key, int[] Ids)> GetRedundentRemoteUids()
|
|
|
|
|
{
|
|
|
|
|
return db.Telemetries
|
|
|
|
|
.ToList()
|
|
|
|
|
.GroupBy(t => t.RemoteUid)
|
|
|
|
|
.Where(g => g.Count() > 1)
|
|
|
|
|
.Select(g => (g.Key, g.Select(t=>t.Id).ToArray()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Merge(IEnumerable<int> telemetryIds)
|
|
|
|
|
{
|
|
|
|
|
if (telemetryIds.Count() < 2)
|
|
|
|
|
throw new ArgumentException($"telemetryIds {telemetryIds} < 2. nothing to merge.", nameof(telemetryIds));
|
|
|
|
|
|
|
|
|
|
// найти телеметрию с наиболее полными справочниками и принять её за основную
|
|
|
|
|
// отделить основную от остальных
|
|
|
|
|
// связонные сущности:
|
|
|
|
|
// Telemetry
|
|
|
|
|
// TelemetryInfo
|
|
|
|
|
// TelemetryEvent
|
|
|
|
|
// TelemetryUser
|
|
|
|
|
|
|
|
|
|
// TelemetryMessage
|
|
|
|
|
// TelemetryDataSpin
|
|
|
|
|
// TelemetryDataSaub
|
|
|
|
|
// TelemetryAnalysis
|
|
|
|
|
// Well
|
|
|
|
|
|
|
|
|
|
// Оценка трудоебкости
|
|
|
|
|
var telemetriesGrade = db.Telemetries
|
|
|
|
|
.Include(t => t.Messages)
|
|
|
|
|
.Include(t => t.DataSaub)
|
|
|
|
|
.Include(t => t.DataSpin)
|
|
|
|
|
.Include(t => t.Well)
|
|
|
|
|
.Where(t => telemetryIds.Contains(t.Id))
|
|
|
|
|
.Select(t => new {
|
|
|
|
|
t.Id,
|
|
|
|
|
t.RemoteUid,
|
|
|
|
|
t.Info,
|
|
|
|
|
IdWell = t.Well != null ? t.Well.Id : int.MinValue,
|
|
|
|
|
Records = t.Messages.Count + t.DataSaub.Count + t.DataSpin.Count,
|
|
|
|
|
EventsAny = t.Events.Any(),
|
|
|
|
|
UsersAny = t.Users.Any(),
|
|
|
|
|
})
|
|
|
|
|
.OrderByDescending(t=>t.Records)
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
var telemetryDestId = telemetriesGrade.FirstOrDefault().Id;
|
|
|
|
|
if (telemetryDestId == default)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
var telemetriesSrcIds = telemetryIds.Where(t => t != telemetryDestId).ToList();
|
|
|
|
|
if(!telemetriesSrcIds.Any())
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
var telemetriesSrcIdsSql = $"({string.Join(',', telemetriesSrcIds)})";
|
|
|
|
|
|
|
|
|
|
var telemetryInfoAndUid = telemetriesGrade
|
|
|
|
|
.Where(t => t.Info != null)
|
|
|
|
|
.OrderByDescending(t => t.Id)
|
|
|
|
|
.Select(t => (t.RemoteUid, t.Info))
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
var wellId = telemetriesGrade
|
|
|
|
|
.Where(t => t.IdWell > 0)
|
|
|
|
|
.OrderByDescending(t => t.Id)
|
|
|
|
|
.Select(t => t.IdWell)
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
// начало изменений
|
|
|
|
|
Console.WriteLine($"Start merge telemetries ids: [{string.Join(',', telemetriesSrcIds)}] to {telemetryDestId}");
|
|
|
|
|
var sw = new System.Diagnostics.Stopwatch();
|
|
|
|
|
sw.Start();
|
|
|
|
|
var transaction = db.Database.BeginTransaction();
|
|
|
|
|
int rows = 0;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var telemetryDst = db.Telemetries.FirstOrDefault(t => t.Id == telemetryDestId);
|
|
|
|
|
telemetryDst.RemoteUid = telemetryInfoAndUid.RemoteUid;
|
|
|
|
|
telemetryDst.Info = telemetryInfoAndUid.Info;
|
|
|
|
|
|
|
|
|
|
if (wellId != default)
|
|
|
|
|
{
|
|
|
|
|
var well = db.Wells.FirstOrDefault(w => w.Id == wellId);
|
|
|
|
|
well.IdTelemetry = telemetryDestId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// events merge
|
|
|
|
|
var telemetryDstEventsIds = db.TelemetryEvents.Where(t => t.IdTelemetry == telemetryDestId).Select(t => t.IdEvent).ToList();
|
|
|
|
|
var telemetrySrcEvents = db.TelemetryEvents
|
|
|
|
|
.Where(t => telemetriesSrcIds.Contains(t.IdTelemetry) && !telemetryDstEventsIds.Contains(t.IdEvent))
|
|
|
|
|
.Select(t => new TelemetryEvent
|
|
|
|
|
{
|
|
|
|
|
IdTelemetry = telemetryDestId,
|
|
|
|
|
IdEvent = t.IdEvent,
|
|
|
|
|
IdCategory = t.IdCategory,
|
|
|
|
|
MessageTemplate = t.MessageTemplate,
|
|
|
|
|
})
|
|
|
|
|
.ToList();
|
|
|
|
|
var telemetryEventNewUniq = new Dictionary<int, TelemetryEvent>();
|
|
|
|
|
foreach (var telemetryEvent in telemetrySrcEvents)
|
|
|
|
|
telemetryEventNewUniq[telemetryEvent.IdEvent] = telemetryEvent;
|
|
|
|
|
if (telemetrySrcEvents.Any())
|
|
|
|
|
db.TelemetryEvents.AddRange(telemetryEventNewUniq.Values);
|
|
|
|
|
|
|
|
|
|
// users merge
|
|
|
|
|
var telemetryDstUsersIds = db.TelemetryUsers.Where(t => t.IdTelemetry == telemetryDestId).Select(t => t.IdUser).ToList();
|
|
|
|
|
var telemetrySrcUsers = db.TelemetryUsers
|
|
|
|
|
.Where(t => telemetriesSrcIds.Contains(t.IdTelemetry) && !telemetryDstUsersIds.Contains(t.IdUser))
|
|
|
|
|
.Select(t => new TelemetryUser
|
|
|
|
|
{
|
|
|
|
|
IdTelemetry = telemetryDestId,
|
|
|
|
|
IdUser = t.IdUser,
|
|
|
|
|
Level = t.Level,
|
|
|
|
|
Name = t.Name,
|
|
|
|
|
Patronymic = t.Patronymic,
|
|
|
|
|
Surname = t.Surname,
|
|
|
|
|
}).ToList();
|
|
|
|
|
var telemetryUserNewUniq = new Dictionary<int, TelemetryUser>();
|
|
|
|
|
foreach (var telemetryUser in telemetrySrcUsers)
|
|
|
|
|
telemetryUserNewUniq[telemetryUser.IdUser] = telemetryUser;
|
|
|
|
|
if (telemetrySrcUsers.Any())
|
|
|
|
|
db.TelemetryUsers.AddRange(telemetryUserNewUniq.Values);
|
|
|
|
|
|
|
|
|
|
db.SaveChanges();
|
|
|
|
|
|
|
|
|
|
db.Database.SetCommandTimeout(3_000); // 5 мин
|
|
|
|
|
|
|
|
|
|
db.Database.ExecuteSqlRaw($"ALTER TABLE t_telemetry_data_saub DISABLE TRIGGER ALL;");
|
|
|
|
|
rows += db.Database.ExecuteSqlRaw($"UPDATE t_telemetry_data_saub SET id_telemetry = {telemetryDestId} WHERE id_telemetry IN {telemetriesSrcIdsSql};");
|
|
|
|
|
db.Database.ExecuteSqlRaw($"ALTER TABLE t_telemetry_data_saub ENABLE TRIGGER ALL;");
|
|
|
|
|
|
|
|
|
|
db.Database.ExecuteSqlRaw($"ALTER TABLE t_telemetry_data_spin DISABLE TRIGGER ALL;");
|
|
|
|
|
rows += db.Database.ExecuteSqlRaw($"UPDATE t_telemetry_data_spin SET id_telemetry = {telemetryDestId} WHERE id_telemetry IN {telemetriesSrcIdsSql};");
|
|
|
|
|
db.Database.ExecuteSqlRaw($"ALTER TABLE t_telemetry_data_spin ENABLE TRIGGER ALL;");
|
|
|
|
|
|
|
|
|
|
db.Database.ExecuteSqlRaw($"ALTER TABLE t_telemetry_analysis DISABLE TRIGGER ALL;");
|
|
|
|
|
rows += db.Database.ExecuteSqlRaw($"UPDATE t_telemetry_analysis SET id_telemetry = {telemetryDestId} WHERE id_telemetry IN {telemetriesSrcIdsSql};");
|
|
|
|
|
db.Database.ExecuteSqlRaw($"ALTER TABLE t_telemetry_analysis ENABLE TRIGGER ALL;");
|
|
|
|
|
|
|
|
|
|
db.Database.ExecuteSqlRaw($"ALTER TABLE t_telemetry_message DISABLE TRIGGER ALL;");
|
|
|
|
|
rows += db.Database.ExecuteSqlRaw($"UPDATE t_telemetry_message SET id_telemetry = {telemetryDestId} WHERE id_telemetry IN {telemetriesSrcIdsSql};");
|
|
|
|
|
db.Database.ExecuteSqlRaw($"ALTER TABLE t_telemetry_message ENABLE TRIGGER ALL;");
|
|
|
|
|
|
|
|
|
|
rows += db.Database.ExecuteSqlRaw($"DELETE FROM t_telemetry_event WHERE id_telemetry IN {telemetriesSrcIdsSql};");
|
|
|
|
|
rows += db.Database.ExecuteSqlRaw($"DELETE FROM t_telemetry_user WHERE id_telemetry IN {telemetriesSrcIdsSql};");
|
|
|
|
|
rows += db.Database.ExecuteSqlRaw($"DELETE FROM t_telemetry WHERE id IN {telemetriesSrcIdsSql};");
|
|
|
|
|
|
|
|
|
|
transaction.Commit();
|
|
|
|
|
sw.Stop();
|
2021-10-01 17:37:44 +05:00
|
|
|
|
Console.WriteLine($"Successfully commited in {1d*sw.ElapsedMilliseconds/1000d: #0.00} sec. Affected {rows} rows.");
|
2021-09-29 10:12:54 +05:00
|
|
|
|
}
|
|
|
|
|
catch(Exception ex)
|
|
|
|
|
{
|
2021-10-01 17:37:44 +05:00
|
|
|
|
Console.WriteLine($"Fail. Rollback. Reason is:{ex.Message}");
|
2021-09-29 10:12:54 +05:00
|
|
|
|
transaction.Rollback();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rows;
|
|
|
|
|
}
|
2021-04-07 18:01:56 +05:00
|
|
|
|
}
|
|
|
|
|
}
|