Merge pull request 'Setpoint API' (#1) from Setpoint into master
Reviewed-on: #1
This commit is contained in:
commit
afe7310f73
51
Persistence.API/Controllers/SetpointController.cs
Normal file
51
Persistence.API/Controllers/SetpointController.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Persistence.Models;
|
||||||
|
using Persistence.Repositories;
|
||||||
|
|
||||||
|
namespace Persistence.API.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
public class SetpointController : ControllerBase, ISetpointApi
|
||||||
|
{
|
||||||
|
private readonly ISetpointRepository setpointRepository;
|
||||||
|
|
||||||
|
public SetpointController(ISetpointRepository setpointRepository)
|
||||||
|
{
|
||||||
|
this.setpointRepository = setpointRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("current")]
|
||||||
|
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetCurrent([FromQuery] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||||
|
{
|
||||||
|
var result = await setpointRepository.GetCurrent(setpointKeys, token);
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("history")]
|
||||||
|
public async Task<ActionResult<IEnumerable<SetpointValueDto>>> GetHistory([FromQuery] IEnumerable<Guid> setpointKeys, [FromQuery] DateTimeOffset historyMoment, CancellationToken token)
|
||||||
|
{
|
||||||
|
var result = await setpointRepository.GetHistory(setpointKeys, historyMoment, token);
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("log")]
|
||||||
|
public async Task<ActionResult<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog([FromQuery] IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||||
|
{
|
||||||
|
var result = await setpointRepository.GetLog(setpointKeys, token);
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<ActionResult<int>> Save(Guid setpointKey, object newValue, CancellationToken token)
|
||||||
|
{
|
||||||
|
// ToDo: вычитка idUser
|
||||||
|
await setpointRepository.Save(setpointKey, newValue, 0, token);
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
146
Persistence.Database.Postgres/Migrations/20241118052225_SetpointMigration.Designer.cs
generated
Normal file
146
Persistence.Database.Postgres/Migrations/20241118052225_SetpointMigration.Designer.cs
generated
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
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("20241118052225_SetpointMigration")]
|
||||||
|
partial class SetpointMigration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
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.Model.DataSaub", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<double?>("AxialLoad")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("axialLoad");
|
||||||
|
|
||||||
|
b.Property<double?>("BitDepth")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("bitDepth");
|
||||||
|
|
||||||
|
b.Property<double?>("BlockPosition")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("blockPosition");
|
||||||
|
|
||||||
|
b.Property<double?>("BlockSpeed")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("blockSpeed");
|
||||||
|
|
||||||
|
b.Property<double?>("Flow")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("flow");
|
||||||
|
|
||||||
|
b.Property<double?>("HookWeight")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("hookWeight");
|
||||||
|
|
||||||
|
b.Property<int>("IdFeedRegulator")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("idFeedRegulator");
|
||||||
|
|
||||||
|
b.Property<int?>("Mode")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("mode");
|
||||||
|
|
||||||
|
b.Property<double?>("Mse")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("mse");
|
||||||
|
|
||||||
|
b.Property<short>("MseState")
|
||||||
|
.HasColumnType("smallint")
|
||||||
|
.HasColumnName("mseState");
|
||||||
|
|
||||||
|
b.Property<double?>("Pressure")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("pressure");
|
||||||
|
|
||||||
|
b.Property<double?>("Pump0Flow")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("pump0Flow");
|
||||||
|
|
||||||
|
b.Property<double?>("Pump1Flow")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("pump1Flow");
|
||||||
|
|
||||||
|
b.Property<double?>("Pump2Flow")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("pump2Flow");
|
||||||
|
|
||||||
|
b.Property<double?>("RotorSpeed")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("rotorSpeed");
|
||||||
|
|
||||||
|
b.Property<double?>("RotorTorque")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("rotorTorque");
|
||||||
|
|
||||||
|
b.Property<int>("TimeStamp")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("timestamp");
|
||||||
|
|
||||||
|
b.Property<string>("User")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("user");
|
||||||
|
|
||||||
|
b.Property<double?>("WellDepth")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("wellDepth");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("DataSaub");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Persistence.Database.Model.Setpoint", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Key")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasComment("Ключ");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("Created")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasComment("Дата изменения уставки");
|
||||||
|
|
||||||
|
b.Property<int>("IdUser")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasComment("Id автора последнего изменения");
|
||||||
|
|
||||||
|
b.Property<object>("Value")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("jsonb")
|
||||||
|
.HasComment("Значение уставки");
|
||||||
|
|
||||||
|
b.HasKey("Key", "Created");
|
||||||
|
|
||||||
|
b.ToTable("Setpoint");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Persistence.Database.Postgres.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class SetpointMigration : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Setpoint",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Key = table.Column<Guid>(type: "uuid", nullable: false, comment: "Ключ"),
|
||||||
|
Created = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата изменения уставки"),
|
||||||
|
Value = table.Column<object>(type: "jsonb", nullable: false, comment: "Значение уставки"),
|
||||||
|
IdUser = table.Column<int>(type: "integer", nullable: false, comment: "Id автора последнего изменения")
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Setpoint", x => new { x.Key, x.Created });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Setpoint");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -106,6 +106,30 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
|
|
||||||
b.ToTable("DataSaub");
|
b.ToTable("DataSaub");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Persistence.Database.Model.Setpoint", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Key")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasComment("Ключ");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("Created")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasComment("Дата изменения уставки");
|
||||||
|
|
||||||
|
b.Property<int>("IdUser")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasComment("Id автора последнего изменения");
|
||||||
|
|
||||||
|
b.Property<object>("Value")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("jsonb")
|
||||||
|
.HasComment("Значение уставки");
|
||||||
|
|
||||||
|
b.HasKey("Key", "Created");
|
||||||
|
|
||||||
|
b.ToTable("Setpoint");
|
||||||
|
});
|
||||||
#pragma warning restore 612, 618
|
#pragma warning restore 612, 618
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
|
|
||||||
namespace Persistence.Database.Model;
|
namespace Persistence.Database.Model;
|
||||||
@ -6,6 +6,8 @@ public partial class PersistenceDbContext : DbContext, IPersistenceDbContext
|
|||||||
{
|
{
|
||||||
public DbSet<DataSaub> DataSaub => Set<DataSaub>();
|
public DbSet<DataSaub> DataSaub => Set<DataSaub>();
|
||||||
|
|
||||||
|
public DbSet<Setpoint> Setpoint => Set<Setpoint>();
|
||||||
|
|
||||||
public PersistenceDbContext()
|
public PersistenceDbContext()
|
||||||
: base()
|
: base()
|
||||||
{
|
{
|
||||||
|
21
Persistence.Database/Entity/Setpoint.cs
Normal file
21
Persistence.Database/Entity/Setpoint.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Persistence.Database.Model
|
||||||
|
{
|
||||||
|
[PrimaryKey(nameof(Key), nameof(Created))]
|
||||||
|
public class Setpoint
|
||||||
|
{
|
||||||
|
[Comment("Ключ")]
|
||||||
|
public Guid Key { get; set; }
|
||||||
|
|
||||||
|
[Column(TypeName = "jsonb"), Comment("Значение уставки")]
|
||||||
|
public required object Value { get; set; }
|
||||||
|
|
||||||
|
[Comment("Дата создания уставки")]
|
||||||
|
public DateTimeOffset Created { get; set; }
|
||||||
|
|
||||||
|
[Comment("Id автора последнего изменения")]
|
||||||
|
public int IdUser { get; set; }
|
||||||
|
}
|
||||||
|
}
|
17
Persistence.Database/Model/IPersistenceDbContext.cs
Normal file
17
Persistence.Database/Model/IPersistenceDbContext.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.Metrics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Persistence.Database.Model;
|
||||||
|
public interface IPersistenceDbContext : IDisposable
|
||||||
|
{
|
||||||
|
DbSet<DataSaub> DataSaub { get; }
|
||||||
|
DbSet<Setpoint> Setpoint { get; }
|
||||||
|
DatabaseFacade Database { get; }
|
||||||
|
Task<int> SaveChangesAsync(CancellationToken cancellationToken);
|
||||||
|
}
|
25
Persistence.IntegrationTests/Clients/ISetpointClient.cs
Normal file
25
Persistence.IntegrationTests/Clients/ISetpointClient.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using Persistence.Models;
|
||||||
|
using Refit;
|
||||||
|
|
||||||
|
namespace Persistence.IntegrationTests.Clients
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Интерфейс для тестирования API, предназначенного для работы с уставками
|
||||||
|
/// </summary>
|
||||||
|
public interface ISetpointClient
|
||||||
|
{
|
||||||
|
private const string BaseRoute = "/api/setpoint";
|
||||||
|
|
||||||
|
[Get($"{BaseRoute}/current")]
|
||||||
|
Task<IApiResponse<IEnumerable<SetpointValueDto>>> GetCurrent([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys);
|
||||||
|
|
||||||
|
[Get($"{BaseRoute}/history")]
|
||||||
|
Task<IApiResponse<IEnumerable<SetpointValueDto>>> GetHistory([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys, [Query] DateTimeOffset historyMoment);
|
||||||
|
|
||||||
|
[Get($"{BaseRoute}/log")]
|
||||||
|
Task<IApiResponse<Dictionary<Guid, IEnumerable<SetpointLogDto>>>> GetLog([Query(CollectionFormat.Multi)] IEnumerable<Guid> setpointKeys);
|
||||||
|
|
||||||
|
[Post($"{BaseRoute}/")]
|
||||||
|
Task<IApiResponse> Save(Guid setpointKey, object newValue);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,153 @@
|
|||||||
|
using System.Net;
|
||||||
|
using Persistence.IntegrationTests.Clients;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Persistence.IntegrationTests.Controllers
|
||||||
|
{
|
||||||
|
public class SetpointControllerTest : BaseIntegrationTest
|
||||||
|
{
|
||||||
|
private ISetpointClient client;
|
||||||
|
private class TestObject
|
||||||
|
{
|
||||||
|
public string? value1 { get; set; }
|
||||||
|
public int? value2 { get; set; }
|
||||||
|
}
|
||||||
|
public SetpointControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||||
|
{
|
||||||
|
client = factory.GetHttpClient<ISetpointClient>(string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetCurrent_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var setpointKeys = new List<Guid>()
|
||||||
|
{
|
||||||
|
Guid.NewGuid(),
|
||||||
|
Guid.NewGuid()
|
||||||
|
};
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await client.GetCurrent(setpointKeys);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.Empty(response.Content);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetCurrent_AfterSave_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var setpointKey = await Save();
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await client.GetCurrent([setpointKey]);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.NotEmpty(response.Content);
|
||||||
|
Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetHistory_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var setpointKeys = new List<Guid>()
|
||||||
|
{
|
||||||
|
Guid.NewGuid(),
|
||||||
|
Guid.NewGuid()
|
||||||
|
};
|
||||||
|
var historyMoment = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await client.GetHistory(setpointKeys, historyMoment);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.Empty(response.Content);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetHistory_AfterSave_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var setpointKey = await Save();
|
||||||
|
var historyMoment = DateTimeOffset.UtcNow;
|
||||||
|
historyMoment = historyMoment.AddDays(1);
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await client.GetHistory([setpointKey], historyMoment);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.NotEmpty(response.Content);
|
||||||
|
Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetLog_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var setpointKeys = new List<Guid>()
|
||||||
|
{
|
||||||
|
Guid.NewGuid(),
|
||||||
|
Guid.NewGuid()
|
||||||
|
};
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await client.GetLog(setpointKeys);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.Empty(response.Content);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetLog_AfterSave_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var setpointKey = await Save();
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await client.GetLog([setpointKey]);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.NotEmpty(response.Content);
|
||||||
|
Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Save_returns_success()
|
||||||
|
{
|
||||||
|
await Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Guid> Save()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var setpointKey = Guid.NewGuid();
|
||||||
|
var setpointValue = new TestObject()
|
||||||
|
{
|
||||||
|
value1 = "1",
|
||||||
|
value2 = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await client.Save(setpointKey, setpointValue);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
return setpointKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ using Refit;
|
|||||||
using RestSharp;
|
using RestSharp;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using Persistence.Database.Postgres;
|
||||||
|
|
||||||
namespace Persistence.IntegrationTests;
|
namespace Persistence.IntegrationTests;
|
||||||
public class WebAppFactoryFixture : WebApplicationFactory<Startup>
|
public class WebAppFactoryFixture : WebApplicationFactory<Startup>
|
||||||
|
28
Persistence.Repository/Data/SetpointDto.cs
Normal file
28
Persistence.Repository/Data/SetpointDto.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
namespace Persistence.Repository.Data
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Модель для работы с уставкой
|
||||||
|
/// </summary>
|
||||||
|
public class SetpointDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Идентификатор уставки
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Значение уставки
|
||||||
|
/// </summary>
|
||||||
|
public required object Value { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Дата сохранения уставки
|
||||||
|
/// </summary>
|
||||||
|
public DateTimeOffset Edit { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ключ пользователя
|
||||||
|
/// </summary>
|
||||||
|
public int IdUser { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Persistence.Database.Model;
|
using Persistence.Database.Model;
|
||||||
using Persistence.Repositories;
|
using Persistence.Repositories;
|
||||||
using Persistence.Repository.Data;
|
using Persistence.Repository.Data;
|
||||||
@ -15,7 +15,8 @@ public static class DependencyInjection
|
|||||||
{
|
{
|
||||||
MapsterSetup();
|
MapsterSetup();
|
||||||
|
|
||||||
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataCachedRepository<DataSaub, DataSaubDto>>();
|
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataRepository<DataSaub, DataSaubDto>>();
|
||||||
|
services.AddTransient<ISetpointRepository, SetpointRepository>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
73
Persistence.Repository/Repositories/SetpointRepository.cs
Normal file
73
Persistence.Repository/Repositories/SetpointRepository.cs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
using Mapster;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Persistence.Database.Model;
|
||||||
|
using Persistence.Models;
|
||||||
|
using Persistence.Repositories;
|
||||||
|
|
||||||
|
namespace Persistence.Repository.Repositories
|
||||||
|
{
|
||||||
|
public class SetpointRepository : ISetpointRepository
|
||||||
|
{
|
||||||
|
private DbContext db;
|
||||||
|
public SetpointRepository(DbContext db)
|
||||||
|
{
|
||||||
|
this.db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual IQueryable<Setpoint> GetQueryReadOnly() => db.Set<Setpoint>();
|
||||||
|
|
||||||
|
public async Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||||
|
{
|
||||||
|
var query = GetQueryReadOnly();
|
||||||
|
var entities = await query
|
||||||
|
.Where(e => setpointKeys.Contains(e.Key))
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
var dtos = entities.Select(e => e.Adapt<SetpointValueDto>());
|
||||||
|
|
||||||
|
return dtos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token)
|
||||||
|
{
|
||||||
|
var query = GetQueryReadOnly();
|
||||||
|
var entities = await query
|
||||||
|
.Where(e => setpointKeys.Contains(e.Key))
|
||||||
|
.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());
|
||||||
|
var dtos = filteredEntities
|
||||||
|
.Select(e => e.Adapt<SetpointValueDto>());
|
||||||
|
|
||||||
|
return dtos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token)
|
||||||
|
{
|
||||||
|
var query = GetQueryReadOnly();
|
||||||
|
var entities = await query
|
||||||
|
.Where(e => setpointKeys.Contains(e.Key))
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
var dtos = entities
|
||||||
|
.GroupBy(e => e.Key)
|
||||||
|
.ToDictionary(e => e.Key, v => v.Select(z => z.Adapt<SetpointLogDto>()));
|
||||||
|
|
||||||
|
return dtos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Save(Guid setpointKey, object newValue, int idUser, CancellationToken token)
|
||||||
|
{
|
||||||
|
var entity = new Setpoint()
|
||||||
|
{
|
||||||
|
Key = setpointKey,
|
||||||
|
Value = newValue,
|
||||||
|
IdUser = idUser,
|
||||||
|
Created = DateTimeOffset.UtcNow
|
||||||
|
};
|
||||||
|
|
||||||
|
await db.Set<Setpoint>().AddAsync(entity, token);
|
||||||
|
await db.SaveChangesAsync(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
namespace Persistence.Models;
|
namespace Persistence.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Модель для описания лога уставки
|
/// Модель для описания лога уставки
|
||||||
@ -8,7 +8,7 @@ public class SetpointLogDto : SetpointValueDto
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Дата сохранения уставки
|
/// Дата сохранения уставки
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset DateEdit { get; set; }
|
public DateTimeOffset Created { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ключ пользователя
|
/// Ключ пользователя
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
namespace Persistence.Models;
|
namespace Persistence.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Модель для хранения значения уставки
|
/// Модель для хранения значения уставки
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SetpointValueDto
|
public class SetpointValueDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Идентификатор уставки
|
/// Идентификатор уставки
|
||||||
|
/// <summary>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Id { get; set; }
|
public Guid Key { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Значение уставки
|
/// Значение уставки
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object Value { get; set; }
|
public required object Value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
|
|
||||||
namespace Persistence.Repositories;
|
namespace Persistence.Repositories;
|
||||||
|
|
||||||
@ -7,23 +7,30 @@ namespace Persistence.Repositories;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ISetpointRepository
|
public interface ISetpointRepository
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Получить значения уставок по набору ключей
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="setpointKeys"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить значения уставок за определенный момент времени
|
/// Получить значения уставок за определенный момент времени
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="setpoitKeys"></param>
|
/// <param name="setpointKeys"></param>
|
||||||
/// <param name="historyMoment">дата, на которую получаем данные</param>
|
/// <param name="historyMoment">дата, на которую получаем данные</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpoitKeys, DateTimeOffset historyMoment, CancellationToken token);
|
Task<IEnumerable<SetpointValueDto>> GetHistory(IEnumerable<Guid> setpointKeys, DateTimeOffset historyMoment, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить историю изменений значений уставок
|
/// Получить историю изменений значений уставок
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="setpoitKeys"></param>
|
/// <param name="setpointKeys"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpoitKeys, CancellationToken token);
|
Task<Dictionary<Guid, IEnumerable<SetpointLogDto>>> GetLog(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Метод сохранения уставки
|
/// Метод сохранения уставки
|
||||||
@ -35,5 +42,5 @@ public interface ISetpointRepository
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// to do
|
/// to do
|
||||||
/// id User учесть в соответствующем методе репозитория
|
/// id User учесть в соответствующем методе репозитория
|
||||||
Task<int> Save(Guid setpointKey, int idUser, object newValue, CancellationToken token);
|
Task Save(Guid setpointKey, object newValue, int idUser, CancellationToken token);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user