This commit is contained in:
parent
aa0540d2af
commit
750788d550
@ -4,6 +4,7 @@ using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using DD.Persistence.Repositories;
|
||||
using System.Net;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
|
@ -13,7 +13,7 @@ namespace DD.Persistence.API.Controllers;
|
||||
[Route("api/[controller]")]
|
||||
public class DataSaubController : TimeSeriesController<DataSaubDto>
|
||||
{
|
||||
public DataSaubController(ITimeSeriesDataRepository<DataSaubDto> timeSeriesDataRepository) : base(timeSeriesDataRepository)
|
||||
public DataSaubController(ITimestampedValuesRepository<DataSaubDto> timeSeriesDataRepository) : base(timeSeriesDataRepository)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Repositories;
|
||||
using System.Net;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Repositories;
|
||||
using DD.Persistence.ModelsAbstractions;
|
||||
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
@ -9,11 +9,11 @@ namespace DD.Persistence.API.Controllers;
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
public class TimeSeriesController<TDto> : ControllerBase, ITimeSeriesDataApi<TDto>
|
||||
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||
where TDto : class, ITimestampAbstractDto, new()
|
||||
{
|
||||
private readonly ITimeSeriesDataRepository<TDto> timeSeriesDataRepository;
|
||||
private readonly ITimestampedValuesRepository<TDto> timeSeriesDataRepository;
|
||||
|
||||
public TimeSeriesController(ITimeSeriesDataRepository<TDto> timeSeriesDataRepository)
|
||||
public TimeSeriesController(ITimestampedValuesRepository<TDto> timeSeriesDataRepository)
|
||||
{
|
||||
this.timeSeriesDataRepository = timeSeriesDataRepository;
|
||||
}
|
@ -4,6 +4,7 @@ using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using DD.Persistence.Repositories;
|
||||
using System.Net;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
|
@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Repositories;
|
||||
using System.Net;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
|
@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Services.Interfaces;
|
||||
using System.Net;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
|
@ -4,6 +4,7 @@ using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
public class ChangeLogClient : BaseClient, IChangeLogClient
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using DD.Persistence.Models.Requests;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using DD.Persistence.Models.Requests;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using DD.Persistence.ModelsAbstractions;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
|
||||
@ -6,7 +7,7 @@ namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
/// Клиент для работы с временными данными
|
||||
/// </summary>
|
||||
/// <typeparam name="TDto"></typeparam>
|
||||
public interface ITimeSeriesClient<TDto> : IDisposable where TDto : class, ITimeSeriesAbstractDto
|
||||
public interface ITimeSeriesClient<TDto> : IDisposable where TDto : class, ITimestampAbstractDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Добавление записей
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using Refit;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
|
@ -2,6 +2,7 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using Refit;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces.Refit
|
||||
{
|
||||
|
@ -1,9 +1,10 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using DD.Persistence.ModelsAbstractions;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
public interface IRefitTimeSeriesClient<TDto> : IRefitClient, IDisposable
|
||||
where TDto : class, ITimeSeriesAbstractDto
|
||||
where TDto : class, ITimestampAbstractDto
|
||||
{
|
||||
private const string BaseRoute = "/api/dataSaub";
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using Refit;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
|
@ -1,6 +1,7 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using Refit;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
public interface IRefitWitsDataClient : IRefitClient, IDisposable
|
||||
|
@ -3,6 +3,7 @@ using DD.Persistence.Client.Clients.Base;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
|
||||
|
@ -4,6 +4,7 @@ using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
|
||||
|
@ -2,10 +2,11 @@
|
||||
using DD.Persistence.Client.Clients.Base;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using DD.Persistence.ModelsAbstractions;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
public class TimeSeriesClient<TDto> : BaseClient, ITimeSeriesClient<TDto> where TDto : class, ITimeSeriesAbstractDto
|
||||
public class TimeSeriesClient<TDto> : BaseClient, ITimeSeriesClient<TDto> where TDto : class, ITimestampAbstractDto
|
||||
{
|
||||
private readonly IRefitTimeSeriesClient<TDto> timeSeriesClient;
|
||||
|
||||
|
@ -3,6 +3,7 @@ using DD.Persistence.Client.Clients.Base;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
public class TimestampedSetClient : BaseClient, ITimestampedSetClient
|
||||
|
@ -3,6 +3,7 @@ using DD.Persistence.Client.Clients.Base;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
public class WitsDataClient : BaseClient, IWitsDataClient
|
||||
|
@ -1,8 +1,9 @@
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using DD.Persistence.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using DD.Persistence.ModelsAbstractions;
|
||||
using DD.Persistence.Database.EntityAbstractions;
|
||||
|
||||
namespace DD.Persistence.Database.Model;
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using DD.Persistence.Database.EntityAbstractions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DD.Persistence.Database.Entity;
|
||||
|
||||
[PrimaryKey(nameof(DiscriminatorId), nameof(ParameterId), nameof(Timestamp))]
|
||||
public class ParameterData
|
||||
public class ParameterData : ITimestampedItem
|
||||
{
|
||||
[Required, Comment("Дискриминатор системы")]
|
||||
public Guid DiscriminatorId { get; set; }
|
||||
|
@ -1,10 +1,11 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using DD.Persistence.Database.EntityAbstractions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DD.Persistence.Database.Model
|
||||
{
|
||||
[PrimaryKey(nameof(Key), nameof(Created))]
|
||||
public class Setpoint
|
||||
[PrimaryKey(nameof(Key), nameof(Timestamp))]
|
||||
public class Setpoint : ITimestampedItem
|
||||
{
|
||||
[Comment("Ключ")]
|
||||
public Guid Key { get; set; }
|
||||
@ -13,7 +14,7 @@ namespace DD.Persistence.Database.Model
|
||||
public required object Value { get; set; }
|
||||
|
||||
[Comment("Дата создания уставки")]
|
||||
public DateTimeOffset Created { get; set; }
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
[Comment("Id автора последнего изменения")]
|
||||
public Guid IdUser { get; set; }
|
||||
|
@ -1,10 +1,11 @@
|
||||
using DD.Persistence.Database.EntityAbstractions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DD.Persistence.Database.Entity
|
||||
{
|
||||
public class TechMessage
|
||||
public class TechMessage : ITimestampedItem
|
||||
{
|
||||
[Key, Comment("Id события")]
|
||||
public Guid EventId { get; set; }
|
||||
|
@ -1,11 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DD.Persistence.Database.Entity;
|
||||
|
||||
[Comment("Общая таблица данных временных рядов")]
|
||||
[PrimaryKey(nameof(IdDiscriminator), nameof(Timestamp))]
|
||||
public record TimestampedSet(
|
||||
[property: Comment("Дискриминатор ссылка на тип сохраняемых данных")] Guid IdDiscriminator,
|
||||
[property: Comment("Отметка времени, строго в UTC")] DateTimeOffset Timestamp,
|
||||
[property: Column(TypeName = "jsonb"), Comment("Набор сохраняемых данных")] IDictionary<string, object> Set);
|
@ -1,18 +1,19 @@
|
||||
using DD.Persistence.Database.Model;
|
||||
using DD.Persistence.Database.EntityAbstractions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DD.Persistence.Database.Entity;
|
||||
|
||||
[PrimaryKey(nameof(BagId), nameof(Timestamp))]
|
||||
public class TagBag : ITimestampedData
|
||||
[PrimaryKey(nameof(DiscriminatorId), nameof(Timestamp))]
|
||||
public class TimestampedValues : ITimestampedItem
|
||||
{
|
||||
[Comment("Временная отметка"), Key]
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
public Guid BagId { get; set; }
|
||||
[Comment("Дискриминатор системы"),]
|
||||
public Guid DiscriminatorId { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
[Comment("Данные"), Column(TypeName = "jsonb")]
|
||||
public required object[] Values { get; set; }
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
|
||||
namespace DD.Persistence.Database.Model;
|
||||
namespace DD.Persistence.Database.EntityAbstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Часть записи, описывающая изменение
|
@ -1,5 +1,5 @@
|
||||
namespace DD.Persistence.Database.Model;
|
||||
public interface ITimestampedData
|
||||
namespace DD.Persistence.Database.EntityAbstractions;
|
||||
public interface ITimestampedItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Дата (должна быть обязательно в UTC)
|
@ -2,8 +2,8 @@ using DD.Persistence.Client;
|
||||
using DD.Persistence.Client.Clients;
|
||||
using DD.Persistence.Client.Clients.Interfaces;
|
||||
using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Database.Model;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Database.EntityAbstractions;
|
||||
using DD.Persistence.ModelsAbstractions;
|
||||
using Mapster;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@ -12,8 +12,8 @@ using Xunit;
|
||||
namespace DD.Persistence.IntegrationTests.Controllers;
|
||||
|
||||
public abstract class TimeSeriesBaseControllerTest<TEntity, TDto> : BaseIntegrationTest
|
||||
where TEntity : class, ITimestampedData, new()
|
||||
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||
where TEntity : class, ITimestampedItem, new()
|
||||
where TDto : class, ITimestampAbstractDto, new()
|
||||
{
|
||||
private readonly ITimeSeriesClient<TDto> timeSeriesClient;
|
||||
|
||||
|
@ -6,6 +6,7 @@ using DD.Persistence.Repositories;
|
||||
using DD.Persistence.Repository.Repositories;
|
||||
using DD.Persistence.Database.Entity;
|
||||
using System.Reflection;
|
||||
using DD.Persistence.Repository.RepositoriesCached;
|
||||
|
||||
namespace DD.Persistence.Repository;
|
||||
public static class DependencyInjection
|
||||
@ -35,9 +36,9 @@ public static class DependencyInjection
|
||||
|
||||
MapsterSetup();
|
||||
|
||||
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TagBagDataRepository>();
|
||||
services.AddTransient<ITimestampedValuesRepository<DataSaubDto>, TagBagDataRepository>();
|
||||
services.AddTransient<ISetpointRepository, SetpointRepository>();
|
||||
//services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataCachedRepository<DataSaub, DataSaubDto>>();
|
||||
//services.AddTransient<ITimestampedValuesRepository<DataSaubDto>, TimeSeriesDataCachedRepository<DataSaub, DataSaubDto>>();
|
||||
services.AddTransient<IChangeLogRepository, ChangeLogRepository>();
|
||||
services.AddTransient<ITimestampedSetRepository, TimestampedSetRepository>();
|
||||
services.AddTransient<ITechMessagesRepository, TechMessagesRepository>();
|
||||
|
@ -1,7 +1,8 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using DD.Persistence.Database.Model;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using DD.Persistence.Models.Common;
|
||||
using DD.Persistence.ModelsAbstractions;
|
||||
using DD.Persistence.Database.EntityAbstractions;
|
||||
|
||||
namespace DD.Persistence.Repository;
|
||||
|
||||
|
@ -5,6 +5,7 @@ using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using DD.Persistence.Repositories;
|
||||
using UuidExtensions;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Repository.Repositories;
|
||||
public class ChangeLogRepository : IChangeLogRepository
|
||||
|
@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using DD.Persistence.Database.Entity;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Repositories;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Repository.Repositories;
|
||||
public class ParameterRepository : IParameterRepository
|
||||
|
@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using DD.Persistence.Database.Model;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Repositories;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Repository.Repositories
|
||||
{
|
||||
@ -35,8 +36,8 @@ namespace DD.Persistence.Repository.Repositories
|
||||
.ToArrayAsync(token);
|
||||
var filteredEntities = entities
|
||||
.GroupBy(e => e.Key)
|
||||
.Select(e => e.OrderBy(o => o.Created))
|
||||
.Select(e => e.Where(e => e.Created <= historyMoment).Last());
|
||||
.Select(e => e.OrderBy(o => o.Timestamp))
|
||||
.Select(e => e.Where(e => e.Timestamp <= historyMoment).Last());
|
||||
var dtos = filteredEntities
|
||||
.Select(e => e.Adapt<SetpointValueDto>());
|
||||
|
||||
@ -47,7 +48,7 @@ namespace DD.Persistence.Repository.Repositories
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
.Where(e => e.Created >= dateBegin)
|
||||
.Where(e => e.Timestamp >= dateBegin)
|
||||
.Take(take)
|
||||
.ToArrayAsync(token);
|
||||
var dtos = entities
|
||||
@ -62,8 +63,8 @@ namespace DD.Persistence.Repository.Repositories
|
||||
.GroupBy(e => 1)
|
||||
.Select(group => new
|
||||
{
|
||||
Min = group.Min(e => e.Created),
|
||||
Max = group.Max(e => e.Created),
|
||||
Min = group.Min(e => e.Timestamp),
|
||||
Max = group.Max(e => e.Timestamp),
|
||||
});
|
||||
var values = await query.FirstOrDefaultAsync(token);
|
||||
var result = new DatesRangeDto()
|
||||
@ -95,7 +96,7 @@ namespace DD.Persistence.Repository.Repositories
|
||||
Key = setpointKey,
|
||||
Value = newValue,
|
||||
IdUser = idUser,
|
||||
Created = DateTimeOffset.UtcNow
|
||||
Timestamp = DateTimeOffset.UtcNow
|
||||
};
|
||||
|
||||
await db.Set<Setpoint>().AddAsync(entity, token);
|
||||
|
@ -7,6 +7,7 @@ using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using DD.Persistence.Repositories;
|
||||
using UuidExtensions;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Repository.Repositories
|
||||
{
|
||||
|
@ -1,103 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using DD.Persistence.Database.Model;
|
||||
using DD.Persistence.Models;
|
||||
|
||||
namespace DD.Persistence.Repository.Repositories;
|
||||
|
||||
public class TimeSeriesDataCachedRepository<TEntity, TDto> : TimeSeriesDataRepository<TEntity, TDto>
|
||||
where TEntity : class, ITimestampedData, new()
|
||||
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||
{
|
||||
public static TDto? FirstByDate { get; private set; }
|
||||
public static CyclicArray<TDto> LastData { get; } = new CyclicArray<TDto>(CacheItemsCount);
|
||||
|
||||
private const int CacheItemsCount = 3600;
|
||||
|
||||
public TimeSeriesDataCachedRepository(DbContext db) : base(db)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var firstDateItem = await base.GetFirstAsync(CancellationToken.None);
|
||||
if (firstDateItem == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FirstByDate = firstDateItem;
|
||||
|
||||
var dtos = await base.GetLastAsync(CacheItemsCount, CancellationToken.None);
|
||||
dtos = dtos.OrderBy(d => d.Date);
|
||||
LastData.AddRange(dtos);
|
||||
}).Wait();
|
||||
}
|
||||
|
||||
public override async Task<IEnumerable<TDto>> GetGtDate(DateTimeOffset dateBegin, CancellationToken token)
|
||||
{
|
||||
|
||||
if (LastData.Count == 0 || LastData[0].Date > dateBegin)
|
||||
{
|
||||
var dtos = await base.GetGtDate(dateBegin, token);
|
||||
return dtos;
|
||||
}
|
||||
|
||||
var items = LastData
|
||||
.Where(i => i.Date >= dateBegin);
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public override async Task<int> AddRange(IEnumerable<TDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = await base.AddRange(dtos, token);
|
||||
if (result > 0)
|
||||
{
|
||||
|
||||
dtos = dtos.OrderBy(x => x.Date);
|
||||
|
||||
FirstByDate = dtos.First();
|
||||
LastData.AddRange(dtos);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override async Task<DatesRangeDto?> GetDatesRange(CancellationToken token)
|
||||
{
|
||||
if (FirstByDate == null)
|
||||
return null;
|
||||
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
return new DatesRangeDto
|
||||
{
|
||||
From = FirstByDate.Date,
|
||||
To = LastData[^1].Date
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task<IEnumerable<TDto>> GetResampledData(
|
||||
DateTimeOffset dateBegin,
|
||||
double intervalSec = 600d,
|
||||
int approxPointsCount = 1024,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var dtos = LastData.Where(i => i.Date >= dateBegin);
|
||||
if (LastData.Count == 0 || LastData[0].Date > dateBegin)
|
||||
{
|
||||
dtos = await base.GetGtDate(dateBegin, token);
|
||||
}
|
||||
|
||||
var dateEnd = dateBegin.AddSeconds(intervalSec);
|
||||
dtos = dtos
|
||||
.Where(i => i.Date <= dateEnd);
|
||||
|
||||
var ratio = dtos.Count() / approxPointsCount;
|
||||
if (ratio > 1)
|
||||
dtos = dtos
|
||||
.Where((_, index) => index % ratio == 0);
|
||||
|
||||
return dtos;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using DD.Persistence.Database.Entity;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Repositories;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Repository.Repositories;
|
||||
|
||||
|
@ -1,20 +1,22 @@
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using DD.Persistence.Database.Model;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Database.Entity;
|
||||
using DD.Persistence.Models.Common;
|
||||
using DD.Persistence.ModelsAbstractions;
|
||||
using DD.Persistence.Repositories;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DD.Persistence.Repository.Repositories;
|
||||
public class TagBagRepository : ITimeSeriesDataRepository
|
||||
public class TimestampedValuesRepository<TDto> : ITimestampedValuesRepository<TDto>
|
||||
where TDto : class, ITimestampAbstractDto, new()
|
||||
{
|
||||
private readonly DbContext db;
|
||||
|
||||
public TagBagRepository(DbContext db)
|
||||
public TimestampedValuesRepository(DbContext db)
|
||||
{
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
protected virtual IQueryable<TEntity> GetQueryReadOnly() => this.db.Set<TEntity>();
|
||||
protected virtual IQueryable<TimestampedValues> GetQueryReadOnly() => this.db.Set<TimestampedValues>();
|
||||
|
||||
public virtual async Task<DatesRangeDto?> GetDatesRange(CancellationToken token)
|
||||
{
|
||||
@ -31,7 +33,7 @@ public class TagBagRepository : ITimeSeriesDataRepository
|
||||
|
||||
public virtual async Task<IEnumerable<TDto>> GetGtDate(DateTimeOffset date, CancellationToken token)
|
||||
{
|
||||
var query = this.db.Set<TEntity>().Where(e => e.Timestamp > date);
|
||||
var query = GetQueryReadOnly().Where(e => e.Timestamp > date);
|
||||
var entities = await query.ToArrayAsync(token);
|
||||
|
||||
var dtos = entities.Select(e => e.Adapt<TDto>());
|
||||
@ -41,9 +43,9 @@ public class TagBagRepository : ITimeSeriesDataRepository
|
||||
|
||||
public virtual async Task<int> AddRange(IEnumerable<TDto> dtos, CancellationToken token)
|
||||
{
|
||||
var entities = dtos.Select(d => d.Adapt<TEntity>());
|
||||
var entities = dtos.Select(d => d.Adapt<TimestampedValues>());
|
||||
|
||||
await db.Set<TEntity>().AddRangeAsync(entities, token);
|
||||
await db.Set<TimestampedValues>().AddRangeAsync(entities, token);
|
||||
var result = await db.SaveChangesAsync(token);
|
||||
|
||||
return result;
|
||||
@ -85,7 +87,7 @@ public class TagBagRepository : ITimeSeriesDataRepository
|
||||
|
||||
var dateEnd = dateBegin.AddSeconds(intervalSec);
|
||||
dtos = dtos
|
||||
.Where(i => i.Date <= dateEnd);
|
||||
.Where(i => i.Timestamp <= dateEnd);
|
||||
|
||||
var ratio = dtos.Count() / approxPointsCount;
|
||||
if (ratio > 1)
|
@ -1,8 +1,9 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Repository.Repositories;
|
||||
|
||||
namespace DD.Persistence.Repository.Repositories;
|
||||
namespace DD.Persistence.Repository.RepositoriesCached;
|
||||
public class DataSourceSystemCachedRepository : DataSourceSystemRepository
|
||||
{
|
||||
private static readonly string SystemCacheKey = $"{typeof(Database.Entity.DataSourceSystem).FullName}CacheKey";
|
@ -0,0 +1,104 @@
|
||||
//using Microsoft.EntityFrameworkCore;
|
||||
//using DD.Persistence.Models.Common;
|
||||
//using DD.Persistence.ModelsAbstractions;
|
||||
//using DD.Persistence.Database.EntityAbstractions;
|
||||
|
||||
//namespace DD.Persistence.Repository.Repositories;
|
||||
|
||||
//public class TimestampedValuesCachedRepository<TEntity, TDto> : TimeSeriesDataRepository<TEntity, TDto>
|
||||
// where TEntity : class, ITimestampedItem, new()
|
||||
// where TDto : class, ITimestampAbstractDto, new()
|
||||
//{
|
||||
// public static TDto? FirstByDate { get; private set; }
|
||||
// public static CyclicArray<TDto> LastData { get; } = new CyclicArray<TDto>(CacheItemsCount);
|
||||
|
||||
// private const int CacheItemsCount = 3600;
|
||||
|
||||
// public TimestampedValuesCachedRepository(DbContext db) : base(db)
|
||||
// {
|
||||
// Task.Run(async () =>
|
||||
// {
|
||||
// var firstDateItem = await base.GetFirstAsync(CancellationToken.None);
|
||||
// if (firstDateItem == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// FirstByDate = firstDateItem;
|
||||
|
||||
// var dtos = await base.GetLastAsync(CacheItemsCount, CancellationToken.None);
|
||||
// dtos = dtos.OrderBy(d => d.Timestamp);
|
||||
// LastData.AddRange(dtos);
|
||||
// }).Wait();
|
||||
// }
|
||||
|
||||
// public override async Task<IEnumerable<TDto>> GetGtDate(DateTimeOffset dateBegin, CancellationToken token)
|
||||
// {
|
||||
|
||||
// if (LastData.Count == 0 || LastData[0].Timestamp > dateBegin)
|
||||
// {
|
||||
// var dtos = await base.GetGtDate(dateBegin, token);
|
||||
// return dtos;
|
||||
// }
|
||||
|
||||
// var items = LastData
|
||||
// .Where(i => i.Timestamp >= dateBegin);
|
||||
|
||||
// return items;
|
||||
// }
|
||||
|
||||
// public override async Task<int> AddRange(IEnumerable<TDto> dtos, CancellationToken token)
|
||||
// {
|
||||
// var result = await base.AddRange(dtos, token);
|
||||
// if (result > 0)
|
||||
// {
|
||||
|
||||
// dtos = dtos.OrderBy(x => x.Timestamp);
|
||||
|
||||
// FirstByDate = dtos.First();
|
||||
// LastData.AddRange(dtos);
|
||||
// }
|
||||
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// public override async Task<DatesRangeDto?> GetDatesRange(CancellationToken token)
|
||||
// {
|
||||
// if (FirstByDate == null)
|
||||
// return null;
|
||||
|
||||
// return await Task.Run(() =>
|
||||
// {
|
||||
// return new DatesRangeDto
|
||||
// {
|
||||
// From = FirstByDate.Timestamp,
|
||||
// To = LastData[^1].Timestamp
|
||||
// };
|
||||
// });
|
||||
// }
|
||||
|
||||
// public override async Task<IEnumerable<TDto>> GetResampledData(
|
||||
// DateTimeOffset dateBegin,
|
||||
// double intervalSec = 600d,
|
||||
// int approxPointsCount = 1024,
|
||||
// CancellationToken token = default)
|
||||
// {
|
||||
// var dtos = LastData.Where(i => i.Timestamp >= dateBegin);
|
||||
// if (LastData.Count == 0 || LastData[0].Timestamp > dateBegin)
|
||||
// {
|
||||
// dtos = await base.GetGtDate(dateBegin, token);
|
||||
// }
|
||||
|
||||
// var dateEnd = dateBegin.AddSeconds(intervalSec);
|
||||
// dtos = dtos
|
||||
// .Where(i => i.Timestamp <= dateEnd);
|
||||
|
||||
// var ratio = dtos.Count() / approxPointsCount;
|
||||
// if (ratio > 1)
|
||||
// dtos = dtos
|
||||
// .Where((_, index) => index % ratio == 0);
|
||||
|
||||
// return dtos;
|
||||
// }
|
||||
//}
|
||||
|
@ -1,5 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.API;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.API;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.ModelsAbstractions;
|
||||
|
||||
namespace DD.Persistence.API;
|
||||
|
||||
@ -7,7 +7,7 @@ namespace DD.Persistence.API;
|
||||
/// Интерфейс для работы с API временных данных
|
||||
/// </summary>
|
||||
public interface ITimeSeriesDataApi<TDto> : ITimeSeriesBaseDataApi<TDto>
|
||||
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||
where TDto : class, ITimestampAbstractDto, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить список объектов, удовлетворяющий диапазон дат
|
||||
|
@ -66,7 +66,7 @@ public static class EFExtensions
|
||||
/// и опционально указания направления сортировки "asc" или "desc"
|
||||
/// </param>
|
||||
/// <example>
|
||||
/// var query = query("Date desc");
|
||||
/// var query = query("Timestamp desc");
|
||||
/// </example>
|
||||
/// <returns>Запрос с примененной сортировкой</returns>
|
||||
public static IOrderedQueryable<TSource> SortBy<TSource>(
|
||||
|
@ -1,4 +1,4 @@
|
||||
namespace DD.Persistence.Models;
|
||||
namespace DD.Persistence.Models.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Диапазон дат
|
@ -1,4 +1,4 @@
|
||||
namespace DD.Persistence.Models;
|
||||
namespace DD.Persistence.Models.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Контейнер для поддержки постраничного просмотра таблиц
|
@ -1,41 +0,0 @@
|
||||
namespace DD.Persistence.Models;
|
||||
public class DataSaubDto : ITimeSeriesAbstractDto
|
||||
{
|
||||
public DateTimeOffset Date { get; set; } = DateTimeOffset.UtcNow;
|
||||
|
||||
public int? Mode { get; set; }
|
||||
|
||||
public string? User { get; set; }
|
||||
|
||||
public double? WellDepth { get; set; }
|
||||
|
||||
public double? BitDepth { get; set; }
|
||||
|
||||
public double? BlockPosition { get; set; }
|
||||
|
||||
public double? BlockSpeed { get; set; }
|
||||
|
||||
public double? Pressure { get; set; }
|
||||
|
||||
public double? AxialLoad { get; set; }
|
||||
|
||||
public double? HookWeight { get; set; }
|
||||
|
||||
public double? RotorTorque { get; set; }
|
||||
|
||||
public double? RotorSpeed { get; set; }
|
||||
|
||||
public double? Flow { get; set; }
|
||||
|
||||
public short MseState { get; set; }
|
||||
|
||||
public int IdFeedRegulator { get; set; }
|
||||
|
||||
public double? Mse { get; set; }
|
||||
|
||||
public double? Pump0Flow { get; set; }
|
||||
|
||||
public double? Pump1Flow { get; set; }
|
||||
|
||||
public double? Pump2Flow { get; set; }
|
||||
}
|
@ -1,8 +1,17 @@
|
||||
namespace DD.Persistence.Models;
|
||||
|
||||
/// <summary>
|
||||
/// набор данных с отметкой времени
|
||||
/// Набор данных с отметкой времени
|
||||
/// </summary>
|
||||
/// <param name="Timestamp">отметка времени</param>
|
||||
/// <param name="Set">набор данных</param>
|
||||
public record TimestampedSetDto(DateTimeOffset Timestamp, IDictionary<string, object> Set);
|
||||
public class TimestampedSetDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Временная отметка
|
||||
/// </summary>
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Набор данных
|
||||
/// </summary>
|
||||
public required object[] Set { get; set; }
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
namespace DD.Persistence.Models;
|
||||
namespace DD.Persistence.ModelsAbstractions;
|
||||
|
||||
/// <summary>
|
||||
/// Интерфейс, описывающий временные данные
|
||||
/// </summary>
|
||||
public interface ITimeSeriesAbstractDto
|
||||
public interface ITimestampAbstractDto
|
||||
{
|
||||
/// <summary>
|
||||
/// временная отметка
|
||||
/// </summary>
|
||||
DateTimeOffset Date { get; set; }
|
||||
DateTimeOffset Timestamp { get; set; }
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
namespace DD.Persistence.Models;
|
||||
namespace DD.Persistence.ModelsAbstractions;
|
||||
public interface IWithSectionPart
|
||||
{
|
||||
public double DepthStart { get; set; }
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using DD.Persistence.Models.Requests;
|
||||
|
||||
namespace DD.Persistence.Repositories;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Repositories;
|
||||
public interface IParameterRepository
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Repositories;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Repositories;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Repositories;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using DD.Persistence.Models.Requests;
|
||||
|
||||
namespace DD.Persistence.Repositories
|
||||
|
@ -1,10 +1,11 @@
|
||||
namespace DD.Persistence.Repositories;
|
||||
using DD.Persistence.Models;
|
||||
|
||||
namespace DD.Persistence.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Интерфейс по работе с прореженными данными
|
||||
/// </summary>
|
||||
public interface ITimeSeriesBaseRepository<TDto>
|
||||
where TDto : class, new()
|
||||
public interface ITimeSeriesBaseRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить список объектов с прореживанием
|
||||
@ -12,7 +13,7 @@ public interface ITimeSeriesBaseRepository<TDto>
|
||||
/// <param name="dateBegin">дата начала</param>
|
||||
/// <param name="approxPointsCount"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<TDto>> GetResampledData(
|
||||
Task<IEnumerable<TimestampedSetDto>> GetResampledData(
|
||||
DateTimeOffset dateBegin,
|
||||
double intervalSec = 600d,
|
||||
int approxPointsCount = 1024,
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Repositories;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.ModelsAbstractions;
|
||||
|
||||
namespace DD.Persistence.Repositories;
|
||||
|
||||
@ -6,8 +7,8 @@ namespace DD.Persistence.Repositories;
|
||||
/// Интерфейс по работе с временными данными
|
||||
/// </summary>
|
||||
/// <typeparam name="TDto"></typeparam>
|
||||
public interface ITimeSeriesDataRepository<TDto> : ISyncRepository<TDto>, ITimeSeriesBaseRepository<TDto>
|
||||
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||
public interface ITimestampedValuesRepository<TDto> : ISyncRepository<TDto>, ITimeSeriesBaseRepository
|
||||
where TDto : class, ITimestampAbstractDto, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// Добавление записей
|
||||
@ -15,5 +16,5 @@ public interface ITimeSeriesDataRepository<TDto> : ISyncRepository<TDto>, ITimeS
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> AddRange(IEnumerable<TDto> dtos, CancellationToken token);
|
||||
Task<int> AddRange(IEnumerable<TimestampedSetDto> dtos, CancellationToken token);
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
|
||||
namespace DD.Persistence.Services.Interfaces;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using DD.Persistence.Models.Configurations;
|
||||
using DD.Persistence.Models.Enumerations;
|
||||
using DD.Persistence.Repositories;
|
||||
|
Loading…
Reference in New Issue
Block a user