diff --git a/Persistence.API/Controllers/WitsDataController.cs b/Persistence.API/Controllers/WitsDataController.cs
new file mode 100644
index 0000000..6e74b2b
--- /dev/null
+++ b/Persistence.API/Controllers/WitsDataController.cs
@@ -0,0 +1,81 @@
+using System.Net;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Persistence.Models;
+using Persistence.Services.Interfaces;
+
+namespace Persistence.API.Controllers;
+
+[ApiController]
+[Authorize]
+[Route("api/[controller]")]
+public class WitsDataController : ControllerBase, IWitsDataApi
+{
+ private readonly IWitsDataService witsDataService;
+
+ public WitsDataController(IWitsDataService witsDataService)
+ {
+ this.witsDataService = witsDataService;
+ }
+
+ ///
+ /// Получить диапазон дат, для которых есть данные в репозитории
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("datesRange")]
+ public async Task> GetDatesRangeAsync([FromQuery] int discriminatorId, CancellationToken token)
+ {
+ var result = await witsDataService.GetDatesRangeAsync(discriminatorId, token);
+
+ return Ok(result);
+ }
+
+ ///
+ /// Получить порцию записей, начиная с заданной даты
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("part")]
+ public async Task>> GetPart([FromQuery] int discriminatorId, [FromQuery] DateTimeOffset dateBegin, [FromQuery] int take, CancellationToken token)
+ {
+ var result = await witsDataService.GetPart(discriminatorId, dateBegin, take, token);
+
+ return Ok(result);
+ }
+
+ ///
+ /// Получить набор параметров (Wits) для построения графика
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("graph")]
+ public async Task>> GetValuesForGraph([FromQuery] DateTimeOffset dateFrom, [FromQuery] DateTimeOffset dateTo, [FromQuery] int limit, CancellationToken token)
+ {
+ var result = await witsDataService.GetValuesForGraph(dateFrom, dateTo);
+
+ return Ok(result);
+ }
+
+ ///
+ /// Сохранить набор параметров (Wits)
+ ///
+ ///
+ ///
+ ///
+ [HttpPost]
+ [ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
+ public async Task InsertRange([FromBody] IEnumerable dtos, CancellationToken token)
+ {
+ var result = await witsDataService.InsertRange(dtos, token);
+
+ return CreatedAtAction(nameof(InsertRange), result);
+ }
+}
diff --git a/Persistence.API/DependencyInjection.cs b/Persistence.API/DependencyInjection.cs
index 19cedc9..8506b4c 100644
--- a/Persistence.API/DependencyInjection.cs
+++ b/Persistence.API/DependencyInjection.cs
@@ -8,6 +8,8 @@ using Microsoft.OpenApi.Models;
using Persistence.Database.Entity;
using Persistence.Models;
using Persistence.Models.Configurations;
+using Persistence.Services;
+using Persistence.Services.Interfaces;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace Persistence.API;
@@ -55,6 +57,11 @@ public static class DependencyInjection
});
}
+ public static void AddServices(this IServiceCollection services)
+ {
+ services.AddTransient();
+ }
+
#region Authentication
public static void AddJWTAuthentication(this IServiceCollection services, IConfiguration configuration)
{
diff --git a/Persistence.API/Startup.cs b/Persistence.API/Startup.cs
index 98ad4aa..9869754 100644
--- a/Persistence.API/Startup.cs
+++ b/Persistence.API/Startup.cs
@@ -24,13 +24,13 @@ public class Startup
services.AddPersistenceDbContext(Configuration);
services.AddJWTAuthentication(Configuration);
services.AddMemoryCache();
+ services.AddServices();
DependencyInjection.MapsterSetup();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
-
app.UseSwagger();
app.UseSwaggerUI();
diff --git a/Persistence.Client/Clients/IWitsDataClient.cs b/Persistence.Client/Clients/IWitsDataClient.cs
new file mode 100644
index 0000000..d7b2035
--- /dev/null
+++ b/Persistence.Client/Clients/IWitsDataClient.cs
@@ -0,0 +1,20 @@
+using Persistence.Models;
+using Refit;
+
+namespace Persistence.Client.Clients;
+public interface IWitsDataClient
+{
+ private const string BaseRoute = "/api/witsData";
+
+ [Get($"{BaseRoute}/graph")]
+ Task>> GetValuesForGraph([Query] DateTimeOffset dateFrom, [Query] DateTimeOffset dateTo, [Query] int limit, CancellationToken token);
+
+ [Post($"{BaseRoute}/")]
+ Task> InsertRange([Body] IEnumerable dtos, CancellationToken token);
+
+ [Get($"{BaseRoute}/part")]
+ Task>> GetPart([Query] int discriminatorId, [Query] DateTimeOffset dateBegin, [Query] int take = 24 * 60 * 60, CancellationToken token = default);
+
+ [Get($"{BaseRoute}/datesRange")]
+ Task> GetDatesRangeAsync([Query] int discriminatorId, CancellationToken token);
+}
diff --git a/Persistence.Database.Postgres/Migrations/20241203120141_ParameterDataMigration.Designer.cs b/Persistence.Database.Postgres/Migrations/20241203120141_ParameterDataMigration.Designer.cs
new file mode 100644
index 0000000..c0f01fc
--- /dev/null
+++ b/Persistence.Database.Postgres/Migrations/20241203120141_ParameterDataMigration.Designer.cs
@@ -0,0 +1,257 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using Persistence.Database.Model;
+
+#nullable disable
+
+namespace Persistence.Database.Postgres.Migrations
+{
+ [DbContext(typeof(PersistenceDbContext))]
+ [Migration("20241203120141_ParameterDataMigration")]
+ partial class ParameterDataMigration
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .UseCollation("Russian_Russia.1251")
+ .HasAnnotation("ProductVersion", "8.0.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Persistence.Database.Entity.DrillingSystem", b =>
+ {
+ b.Property("SystemId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasComment("Id системы автобурения");
+
+ b.Property("Description")
+ .HasColumnType("text")
+ .HasComment("Описание системы автобурения");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(256)")
+ .HasComment("Наименование системы автобурения");
+
+ b.HasKey("SystemId");
+
+ b.ToTable("DrillingSystem");
+ });
+
+ modelBuilder.Entity("Persistence.Database.Entity.ParameterData", b =>
+ {
+ b.Property("DiscriminatorId")
+ .HasColumnType("integer")
+ .HasComment("Дискриминатор системы");
+
+ b.Property("ParameterId")
+ .HasColumnType("integer")
+ .HasComment("Id параметра");
+
+ b.Property("Timestamp")
+ .HasColumnType("timestamp with time zone")
+ .HasComment("Временная отметка");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasColumnType("varchar(256)")
+ .HasComment("Значение параметра в виде строки");
+
+ b.HasKey("DiscriminatorId", "ParameterId", "Timestamp");
+
+ b.ToTable("ParameterData");
+ });
+
+ modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
+ {
+ b.Property("EventId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasComment("Id события");
+
+ b.Property("CategoryId")
+ .HasColumnType("integer")
+ .HasComment("Id Категории важности");
+
+ b.Property("Depth")
+ .HasColumnType("double precision")
+ .HasComment("Глубина забоя");
+
+ b.Property("MessageText")
+ .IsRequired()
+ .HasColumnType("varchar(512)")
+ .HasComment("Текст сообщения");
+
+ b.Property("SystemId")
+ .HasColumnType("uuid")
+ .HasComment("Id системы автобурения, к которой относится сообщение");
+
+ b.Property("Timestamp")
+ .HasColumnType("timestamp with time zone")
+ .HasComment("Дата возникновения");
+
+ b.Property("UserId")
+ .HasColumnType("uuid")
+ .HasComment("Id пользователя за пультом бурильщика");
+
+ b.HasKey("EventId");
+
+ b.HasIndex("SystemId");
+
+ b.ToTable("TechMessage");
+ });
+
+ modelBuilder.Entity("Persistence.Database.Entity.TimestampedSet", b =>
+ {
+ b.Property("IdDiscriminator")
+ .HasColumnType("uuid")
+ .HasComment("Дискриминатор ссылка на тип сохраняемых данных");
+
+ b.Property("Timestamp")
+ .HasColumnType("timestamp with time zone")
+ .HasComment("Отметка времени, строго в UTC");
+
+ b.Property("Set")
+ .IsRequired()
+ .HasColumnType("jsonb")
+ .HasComment("Набор сохраняемых данных");
+
+ b.HasKey("IdDiscriminator", "Timestamp");
+
+ b.ToTable("TimestampedSets", t =>
+ {
+ t.HasComment("Общая таблица данных временных рядов");
+ });
+ });
+
+ modelBuilder.Entity("Persistence.Database.Model.DataSaub", b =>
+ {
+ b.Property("Date")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("date");
+
+ b.Property("AxialLoad")
+ .HasColumnType("double precision")
+ .HasColumnName("axialLoad");
+
+ b.Property("BitDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("bitDepth");
+
+ b.Property("BlockPosition")
+ .HasColumnType("double precision")
+ .HasColumnName("blockPosition");
+
+ b.Property("BlockSpeed")
+ .HasColumnType("double precision")
+ .HasColumnName("blockSpeed");
+
+ b.Property("Flow")
+ .HasColumnType("double precision")
+ .HasColumnName("flow");
+
+ b.Property("HookWeight")
+ .HasColumnType("double precision")
+ .HasColumnName("hookWeight");
+
+ b.Property("IdFeedRegulator")
+ .HasColumnType("integer")
+ .HasColumnName("idFeedRegulator");
+
+ b.Property("Mode")
+ .HasColumnType("integer")
+ .HasColumnName("mode");
+
+ b.Property("Mse")
+ .HasColumnType("double precision")
+ .HasColumnName("mse");
+
+ b.Property("MseState")
+ .HasColumnType("smallint")
+ .HasColumnName("mseState");
+
+ b.Property("Pressure")
+ .HasColumnType("double precision")
+ .HasColumnName("pressure");
+
+ b.Property("Pump0Flow")
+ .HasColumnType("double precision")
+ .HasColumnName("pump0Flow");
+
+ b.Property("Pump1Flow")
+ .HasColumnType("double precision")
+ .HasColumnName("pump1Flow");
+
+ b.Property("Pump2Flow")
+ .HasColumnType("double precision")
+ .HasColumnName("pump2Flow");
+
+ b.Property("RotorSpeed")
+ .HasColumnType("double precision")
+ .HasColumnName("rotorSpeed");
+
+ b.Property("RotorTorque")
+ .HasColumnType("double precision")
+ .HasColumnName("rotorTorque");
+
+ b.Property("User")
+ .HasColumnType("text")
+ .HasColumnName("user");
+
+ b.Property("WellDepth")
+ .HasColumnType("double precision")
+ .HasColumnName("wellDepth");
+
+ b.HasKey("Date");
+
+ b.ToTable("DataSaub");
+ });
+
+ modelBuilder.Entity("Persistence.Database.Model.Setpoint", b =>
+ {
+ b.Property("Key")
+ .HasColumnType("uuid")
+ .HasComment("Ключ");
+
+ b.Property("Created")
+ .HasColumnType("timestamp with time zone")
+ .HasComment("Дата создания уставки");
+
+ b.Property("IdUser")
+ .HasColumnType("uuid")
+ .HasComment("Id автора последнего изменения");
+
+ b.Property