Compare commits
No commits in common. "featute/ChangeLog" and "master" have entirely different histories.
featute/Ch
...
master
@ -1,166 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Persistence.Models;
|
|
||||||
using Persistence.Models.Requests;
|
|
||||||
using Persistence.Repositories;
|
|
||||||
using System.Net;
|
|
||||||
|
|
||||||
namespace Persistence.API.Controllers;
|
|
||||||
|
|
||||||
[ApiController]
|
|
||||||
[Authorize]
|
|
||||||
[Route("api/[controller]")]
|
|
||||||
public class ChangeLogController : ControllerBase, IChangeLogApi
|
|
||||||
{
|
|
||||||
private IChangeLogRepository repository;
|
|
||||||
|
|
||||||
public ChangeLogController(IChangeLogRepository repository)
|
|
||||||
{
|
|
||||||
this.repository = repository;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> Add(
|
|
||||||
Guid idDiscriminator,
|
|
||||||
[FromBody] DataWithWellDepthAndSectionDto dto,
|
|
||||||
CancellationToken token)
|
|
||||||
{
|
|
||||||
var userId = User.GetUserId<Guid>();
|
|
||||||
var result = await repository.InsertRange(userId, idDiscriminator, [dto], token);
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost("range")]
|
|
||||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> AddRange(
|
|
||||||
Guid idDiscriminator,
|
|
||||||
[FromBody] IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token)
|
|
||||||
{
|
|
||||||
var userId = User.GetUserId<Guid>();
|
|
||||||
var result = await repository.InsertRange(userId, idDiscriminator, dtos, token);
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpDelete]
|
|
||||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> Delete(Guid id, CancellationToken token)
|
|
||||||
{
|
|
||||||
var userId = User.GetUserId<Guid>();
|
|
||||||
var result = await repository.MarkAsDeleted(userId, [id], token);
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpDelete("range")]
|
|
||||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> DeleteRange(IEnumerable<Guid> ids, CancellationToken token)
|
|
||||||
{
|
|
||||||
var userId = User.GetUserId<Guid>();
|
|
||||||
var result = await repository.MarkAsDeleted(userId, ids, token);
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost("replace")]
|
|
||||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> ClearAndInsertRange(
|
|
||||||
Guid idDiscriminator,
|
|
||||||
IEnumerable<DataWithWellDepthAndSectionDto> dtos,
|
|
||||||
CancellationToken token)
|
|
||||||
{
|
|
||||||
var userId = User.GetUserId<Guid>();
|
|
||||||
var result = await repository.ClearAndInsertRange(userId, idDiscriminator, dtos, token);
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPut]
|
|
||||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> Update(
|
|
||||||
Guid idDiscriminator,
|
|
||||||
DataWithWellDepthAndSectionDto dto,
|
|
||||||
CancellationToken token)
|
|
||||||
{
|
|
||||||
var userId = User.GetUserId<Guid>();
|
|
||||||
var result = await repository.UpdateRange(userId, idDiscriminator, [dto], token);
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPut("range")]
|
|
||||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> UpdateRange(
|
|
||||||
Guid idDiscriminator,
|
|
||||||
IEnumerable<DataWithWellDepthAndSectionDto> dtos,
|
|
||||||
CancellationToken token)
|
|
||||||
{
|
|
||||||
var userId = User.GetUserId<Guid>();
|
|
||||||
var result = await repository.UpdateRange(userId, idDiscriminator, dtos, token);
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
[ProducesResponseType(typeof(PaginationContainer<DataWithWellDepthAndSectionDto>), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetCurrent(
|
|
||||||
Guid idDiscriminator,
|
|
||||||
[FromQuery]SectionPartRequest request,
|
|
||||||
CancellationToken token)
|
|
||||||
{
|
|
||||||
var moment = new DateTimeOffset(3000, 1, 1, 0, 0, 0, TimeSpan.Zero);
|
|
||||||
var result = await repository.GetByDate(idDiscriminator, moment, request, token);
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("moment")]
|
|
||||||
[ProducesResponseType(typeof(PaginationContainer<DataWithWellDepthAndSectionDto>), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetByDate(
|
|
||||||
Guid idDiscriminator,
|
|
||||||
DateTimeOffset moment,
|
|
||||||
SectionPartRequest request,
|
|
||||||
CancellationToken token)
|
|
||||||
{
|
|
||||||
var result = await repository.GetByDate(idDiscriminator, moment, request, token);
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("history")]
|
|
||||||
[ProducesResponseType(typeof(IEnumerable<ChangeLogDto>), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetChangeLogForDate(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token)
|
|
||||||
{
|
|
||||||
var result = await repository.GetChangeLogForDate(idDiscriminator, dateBegin, dateEnd, token);
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("datesChange")]
|
|
||||||
[ProducesResponseType(typeof(IEnumerable<DateOnly>), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetDatesChange(Guid idDiscriminator, CancellationToken token)
|
|
||||||
{
|
|
||||||
var result = await repository.GetDatesChange(idDiscriminator, token);
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("part")]
|
|
||||||
[ProducesResponseType(typeof(IEnumerable<DataWithWellDepthAndSectionDto>), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetPart(Guid idDiscriminator, DateTimeOffset dateBegin, int take = 86400, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
var result = await repository.GetGtDate(idDiscriminator, dateBegin, token);
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("datesRange")]
|
|
||||||
[ProducesResponseType(typeof(DatesRangeDto), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetDatesRangeAsync(Guid idDiscriminator, CancellationToken token)
|
|
||||||
{
|
|
||||||
var result = await repository.GetDatesRange(idDiscriminator, token);
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
}
|
|
@ -59,7 +59,7 @@ public static class DependencyInjection
|
|||||||
|
|
||||||
private static void AddKeyCloakAuthentication(this IServiceCollection services, IConfiguration configuration)
|
private static void AddKeyCloakAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||||
.AddJwtBearer(options =>
|
.AddJwtBearer(options =>
|
||||||
{
|
{
|
||||||
options.RequireHttpsMetadata = false;
|
options.RequireHttpsMetadata = false;
|
||||||
@ -69,7 +69,7 @@ public static class DependencyInjection
|
|||||||
{
|
{
|
||||||
ValidIssuer = configuration["Authentication:ValidIssuer"],
|
ValidIssuer = configuration["Authentication:ValidIssuer"],
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddDefaultAuthentication(this IServiceCollection services, IConfiguration configuration)
|
private static void AddDefaultAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.11" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.10" />
|
||||||
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.2.1" />
|
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.6" />
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.6" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -22,7 +22,6 @@ public class Startup
|
|||||||
services.AddSwagger(Configuration);
|
services.AddSwagger(Configuration);
|
||||||
services.AddInfrastructure();
|
services.AddInfrastructure();
|
||||||
services.AddPersistenceDbContext(Configuration);
|
services.AddPersistenceDbContext(Configuration);
|
||||||
services.AddAuthorization();
|
|
||||||
services.AddJWTAuthentication(Configuration);
|
services.AddJWTAuthentication(Configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,9 +38,6 @@ public class Startup
|
|||||||
app.UseDeveloperExceptionPage();
|
app.UseDeveloperExceptionPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
|
||||||
|
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Npgsql;
|
|
||||||
|
|
||||||
namespace Persistence.Database.Model;
|
namespace Persistence.Database.Model;
|
||||||
|
|
||||||
@ -11,12 +10,8 @@ public static class DependencyInjection
|
|||||||
{
|
{
|
||||||
string connectionStringName = "DefaultConnection";
|
string connectionStringName = "DefaultConnection";
|
||||||
|
|
||||||
services.AddDbContext<PersistenceDbContext>(options =>
|
services.AddDbContext<PersistenceDbContext>(options =>
|
||||||
{
|
options.UseNpgsql(configuration.GetConnectionString(connectionStringName)));
|
||||||
var dataSourceBuilder = new NpgsqlDataSourceBuilder(configuration.GetConnectionString(connectionStringName));
|
|
||||||
dataSourceBuilder.EnableDynamicJson();
|
|
||||||
options.UseNpgsql(dataSourceBuilder.Build());
|
|
||||||
});
|
|
||||||
|
|
||||||
services.AddScoped<DbContext>(provider => provider.GetRequiredService<PersistenceDbContext>());
|
services.AddScoped<DbContext>(provider => provider.GetRequiredService<PersistenceDbContext>());
|
||||||
|
|
||||||
|
@ -1,169 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
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("20241126071115_Add_ChangeLog")]
|
|
||||||
partial class Add_ChangeLog
|
|
||||||
{
|
|
||||||
/// <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.ChangeLog", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("Id");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("Creation")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("Creation");
|
|
||||||
|
|
||||||
b.Property<double>("DepthEnd")
|
|
||||||
.HasColumnType("double precision")
|
|
||||||
.HasColumnName("DepthEnd");
|
|
||||||
|
|
||||||
b.Property<double>("DepthStart")
|
|
||||||
.HasColumnType("double precision")
|
|
||||||
.HasColumnName("DepthStart");
|
|
||||||
|
|
||||||
b.Property<Guid>("IdAuthor")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("IdAuthor");
|
|
||||||
|
|
||||||
b.Property<Guid>("IdDiscriminator")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("IdDiscriminator");
|
|
||||||
|
|
||||||
b.Property<Guid?>("IdEditor")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("IdEditor");
|
|
||||||
|
|
||||||
b.Property<Guid?>("IdNext")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("IdNext");
|
|
||||||
|
|
||||||
b.Property<Guid>("IdSection")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("IdSection");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("Obsolete")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("Obsolete");
|
|
||||||
|
|
||||||
b.Property<IDictionary<string, object>>("Value")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("Value");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("ChangeLog");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Persistence.Database.Model.DataSaub", b =>
|
|
||||||
{
|
|
||||||
b.Property<DateTimeOffset>("Date")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("date");
|
|
||||||
|
|
||||||
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<string>("User")
|
|
||||||
.HasColumnType("text")
|
|
||||||
.HasColumnName("user");
|
|
||||||
|
|
||||||
b.Property<double?>("WellDepth")
|
|
||||||
.HasColumnType("double precision")
|
|
||||||
.HasColumnName("wellDepth");
|
|
||||||
|
|
||||||
b.HasKey("Date");
|
|
||||||
|
|
||||||
b.ToTable("DataSaub");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace Persistence.Database.Postgres.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class Add_ChangeLog : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "ChangeLog",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
||||||
IdDiscriminator = table.Column<Guid>(type: "uuid", nullable: false),
|
|
||||||
IdAuthor = table.Column<Guid>(type: "uuid", nullable: false),
|
|
||||||
IdEditor = table.Column<Guid>(type: "uuid", nullable: true),
|
|
||||||
Creation = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
|
|
||||||
Obsolete = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
||||||
IdNext = table.Column<Guid>(type: "uuid", nullable: true),
|
|
||||||
DepthStart = table.Column<double>(type: "double precision", nullable: false),
|
|
||||||
DepthEnd = table.Column<double>(type: "double precision", nullable: false),
|
|
||||||
IdSection = table.Column<Guid>(type: "uuid", nullable: false),
|
|
||||||
Value = table.Column<IDictionary<string, object>>(type: "jsonb", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_ChangeLog", x => x.Id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "ChangeLog");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,5 @@
|
|||||||
// <auto-generated />
|
// <auto-generated />
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
@ -25,59 +24,6 @@ namespace Persistence.Database.Postgres.Migrations
|
|||||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
|
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity("Persistence.Database.Model.ChangeLog", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("Id");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("Creation")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("Creation");
|
|
||||||
|
|
||||||
b.Property<double>("DepthEnd")
|
|
||||||
.HasColumnType("double precision")
|
|
||||||
.HasColumnName("DepthEnd");
|
|
||||||
|
|
||||||
b.Property<double>("DepthStart")
|
|
||||||
.HasColumnType("double precision")
|
|
||||||
.HasColumnName("DepthStart");
|
|
||||||
|
|
||||||
b.Property<Guid>("IdAuthor")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("IdAuthor");
|
|
||||||
|
|
||||||
b.Property<Guid>("IdDiscriminator")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("IdDiscriminator");
|
|
||||||
|
|
||||||
b.Property<Guid?>("IdEditor")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("IdEditor");
|
|
||||||
|
|
||||||
b.Property<Guid?>("IdNext")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("IdNext");
|
|
||||||
|
|
||||||
b.Property<Guid>("IdSection")
|
|
||||||
.HasColumnType("uuid")
|
|
||||||
.HasColumnName("IdSection");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("Obsolete")
|
|
||||||
.HasColumnType("timestamp with time zone")
|
|
||||||
.HasColumnName("Obsolete");
|
|
||||||
|
|
||||||
b.Property<IDictionary<string, object>>("Value")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
|
||||||
.HasColumnName("Value");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("ChangeLog");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Persistence.Database.Model.DataSaub", b =>
|
modelBuilder.Entity("Persistence.Database.Model.DataSaub", b =>
|
||||||
{
|
{
|
||||||
b.Property<DateTimeOffset>("Date")
|
b.Property<DateTimeOffset>("Date")
|
||||||
|
@ -7,7 +7,6 @@ namespace Persistence.Database.Model;
|
|||||||
public partial class PersistenceDbContext : DbContext
|
public partial class PersistenceDbContext : DbContext
|
||||||
{
|
{
|
||||||
public DbSet<DataSaub> DataSaub => Set<DataSaub>();
|
public DbSet<DataSaub> DataSaub => Set<DataSaub>();
|
||||||
public DbSet<ChangeLog> ChangeLog => Set<ChangeLog>();
|
|
||||||
|
|
||||||
public DbSet<Setpoint> Setpoint => Set<Setpoint>();
|
public DbSet<Setpoint> Setpoint => Set<Setpoint>();
|
||||||
|
|
||||||
|
@ -2,10 +2,4 @@
|
|||||||
```
|
```
|
||||||
dotnet ef migrations add <MigrationName> --project Persistence.Database.Postgres
|
dotnet ef migrations add <MigrationName> --project Persistence.Database.Postgres
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Откатить миграцию
|
|
||||||
```
|
|
||||||
dotnet ef migrations remove --project Persistence.Database.Postgres
|
|
||||||
```
|
|
||||||
Удаляется последняя созданная миграция.
|
|
@ -1,77 +0,0 @@
|
|||||||
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace Persistence.Database.Model;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Часть записи, описывающая изменение
|
|
||||||
/// </summary>
|
|
||||||
public class ChangeLog : IChangeLog
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Ключ записи
|
|
||||||
/// </summary>
|
|
||||||
[Key, Column("Id")]
|
|
||||||
public Guid Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Дискриминатор таблицы
|
|
||||||
/// </summary>
|
|
||||||
[Column("IdDiscriminator")]
|
|
||||||
public Guid IdDiscriminator { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Автор изменения
|
|
||||||
/// </summary>
|
|
||||||
[Column("IdAuthor")]
|
|
||||||
public Guid IdAuthor { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Редактор
|
|
||||||
/// </summary>
|
|
||||||
[Column("IdEditor")]
|
|
||||||
public Guid? IdEditor { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Дата создания записи
|
|
||||||
/// </summary>
|
|
||||||
[Column("Creation")]
|
|
||||||
public DateTimeOffset Creation { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Дата устаревания (например при удалении)
|
|
||||||
/// </summary>
|
|
||||||
[Column("Obsolete")]
|
|
||||||
public DateTimeOffset? Obsolete { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Id заменяющей записи
|
|
||||||
/// </summary>
|
|
||||||
[Column("IdNext")]
|
|
||||||
public Guid? IdNext { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Глубина забоя на дату начала интервала
|
|
||||||
/// </summary>
|
|
||||||
[Column("DepthStart")]
|
|
||||||
public double DepthStart { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Глубина забоя на дату окончания интервала
|
|
||||||
/// </summary>
|
|
||||||
[Column("DepthEnd")]
|
|
||||||
public double DepthEnd { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ключ секции
|
|
||||||
/// </summary>
|
|
||||||
[Column("IdSection")]
|
|
||||||
public Guid IdSection { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Значение
|
|
||||||
/// </summary>
|
|
||||||
[Column("Value", TypeName = "jsonb")]
|
|
||||||
public required IDictionary<string, object> Value { get; set; }
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
|
|
||||||
namespace Persistence.Database.Model;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Часть записи, описывающая изменение
|
|
||||||
/// </summary>
|
|
||||||
public interface IChangeLog
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Ключ записи
|
|
||||||
/// </summary>
|
|
||||||
public Guid Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Автор изменения
|
|
||||||
/// </summary>
|
|
||||||
public Guid IdAuthor { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Редактор
|
|
||||||
/// </summary>
|
|
||||||
public Guid? IdEditor { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Дата создания записи
|
|
||||||
/// </summary>
|
|
||||||
public DateTimeOffset Creation { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Дата устаревания (например при удалении)
|
|
||||||
/// </summary>
|
|
||||||
public DateTimeOffset? Obsolete { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Id заменяющей записи
|
|
||||||
/// </summary>
|
|
||||||
public Guid? IdNext { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Дискриминатор таблицы
|
|
||||||
/// </summary>
|
|
||||||
public Guid IdDiscriminator { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Значение
|
|
||||||
/// </summary>
|
|
||||||
public IDictionary<string, object> Value { get; set; }
|
|
||||||
}
|
|
@ -1,7 +1,5 @@
|
|||||||
using Mapster;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Persistence.Database.Model;
|
using Persistence.Database.Model;
|
||||||
using Persistence.Models;
|
|
||||||
using Persistence.Repositories;
|
using Persistence.Repositories;
|
||||||
using Persistence.Repository.Data;
|
using Persistence.Repository.Data;
|
||||||
using Persistence.Repository.Repositories;
|
using Persistence.Repository.Repositories;
|
||||||
@ -11,17 +9,6 @@ public static class DependencyInjection
|
|||||||
{
|
{
|
||||||
public static void MapsterSetup()
|
public static void MapsterSetup()
|
||||||
{
|
{
|
||||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
|
||||||
.ForType<ChangeLog, ChangeLogDto>()
|
|
||||||
.Map(dest => dest.Value, src => new DataWithWellDepthAndSectionDto()
|
|
||||||
{
|
|
||||||
DepthEnd = src.DepthEnd,
|
|
||||||
DepthStart = src.DepthStart,
|
|
||||||
IdSection = src.IdSection,
|
|
||||||
Value = src.Value,
|
|
||||||
Id = src.Id
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IServiceCollection AddInfrastructure(this IServiceCollection services)
|
public static IServiceCollection AddInfrastructure(this IServiceCollection services)
|
||||||
@ -31,7 +18,6 @@ public static class DependencyInjection
|
|||||||
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataRepository<DataSaub, DataSaubDto>>();
|
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataRepository<DataSaub, DataSaubDto>>();
|
||||||
services.AddTransient<ISetpointRepository, SetpointRepository>();
|
services.AddTransient<ISetpointRepository, SetpointRepository>();
|
||||||
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataCachedRepository<DataSaub, DataSaubDto>>();
|
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataCachedRepository<DataSaub, DataSaubDto>>();
|
||||||
services.AddTransient<IChangeLogRepository, ChangeLogRepository>();
|
|
||||||
services.AddTransient<ITimestampedSetRepository, TimestampedSetRepository>();
|
services.AddTransient<ITimestampedSetRepository, TimestampedSetRepository>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
|
@ -1,285 +0,0 @@
|
|||||||
using Mapster;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Persistence.Database.Model;
|
|
||||||
using Persistence.Models;
|
|
||||||
using Persistence.Models.Requests;
|
|
||||||
using Persistence.Repositories;
|
|
||||||
|
|
||||||
namespace Persistence.Repository.Repositories;
|
|
||||||
public class ChangeLogRepository : IChangeLogRepository
|
|
||||||
{
|
|
||||||
private DbContext db;
|
|
||||||
|
|
||||||
public ChangeLogRepository(DbContext db)
|
|
||||||
{
|
|
||||||
this.db = db;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<int> InsertRange(Guid idUser, Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token)
|
|
||||||
{
|
|
||||||
foreach (var dto in dtos)
|
|
||||||
{
|
|
||||||
var entity = CreateEntityFromDto(idUser, idDiscriminator, dto);
|
|
||||||
db.Set<ChangeLog>().Add(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = db.SaveChangesAsync(token);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> MarkAsDeleted(Guid idUser, IEnumerable<Guid> ids, CancellationToken token)
|
|
||||||
{
|
|
||||||
var query = db.Set<ChangeLog>().Where(s => ids.Contains(s.Id));
|
|
||||||
var entities = await query.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var result = await Clear(idUser, entities, token);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> MarkAsDeleted(Guid idUser, Guid idDiscriminator, CancellationToken token)
|
|
||||||
{
|
|
||||||
var query = db.Set<ChangeLog>()
|
|
||||||
.Where(s => s.IdDiscriminator == idDiscriminator)
|
|
||||||
.Where(e => e.Obsolete == null);
|
|
||||||
var entities = await query.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var result = await Clear(idUser, entities, token);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<int> Clear(Guid idUser, IEnumerable<ChangeLog> entities, CancellationToken token)
|
|
||||||
{
|
|
||||||
var updateTime = DateTimeOffset.UtcNow;
|
|
||||||
|
|
||||||
foreach (var entity in entities)
|
|
||||||
{
|
|
||||||
entity.Obsolete = updateTime;
|
|
||||||
entity.IdEditor = idUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
return await db.SaveChangesAsync(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> ClearAndInsertRange(Guid idUser, Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token)
|
|
||||||
{
|
|
||||||
var result = 0;
|
|
||||||
using var transaction = await db.Database.BeginTransactionAsync(token);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result += await MarkAsDeleted(idUser, idDiscriminator, token);
|
|
||||||
result += await InsertRange(idUser, idDiscriminator, dtos, token);
|
|
||||||
|
|
||||||
await transaction.CommitAsync(token);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
await transaction.RollbackAsync(token);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> UpdateRange(Guid idUser, Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token)
|
|
||||||
{
|
|
||||||
var dbSet = db.Set<ChangeLog>();
|
|
||||||
|
|
||||||
var updatedIds = dtos.Select(d => d.Id);
|
|
||||||
var updatedEntities = dbSet
|
|
||||||
.Where(s => updatedIds.Contains(s.Id))
|
|
||||||
.ToDictionary(s => s.Id);
|
|
||||||
|
|
||||||
var result = 0;
|
|
||||||
using var transaction = await db.Database.BeginTransactionAsync(token);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (var dto in dtos)
|
|
||||||
{
|
|
||||||
var newEntity = CreateEntityFromDto(idUser, idDiscriminator, dto);
|
|
||||||
dbSet.Add(newEntity);
|
|
||||||
|
|
||||||
var updatedEntity = updatedEntities.GetValueOrDefault(dto.Id)!;
|
|
||||||
updatedEntity.IdNext = newEntity.Id;
|
|
||||||
updatedEntity.Obsolete = DateTimeOffset.UtcNow;
|
|
||||||
updatedEntity.IdEditor = idUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
await db.SaveChangesAsync(token);
|
|
||||||
await transaction.CommitAsync(token);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
await transaction.RollbackAsync(token);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<PaginationContainer<DataWithWellDepthAndSectionDto>> GetByDate(
|
|
||||||
Guid idDiscriminator,
|
|
||||||
DateTimeOffset momentUtc,
|
|
||||||
SectionPartRequest request,
|
|
||||||
CancellationToken token)
|
|
||||||
{
|
|
||||||
var query = BuildQuery(idDiscriminator, momentUtc, request);
|
|
||||||
var result = await BuildPaginationContainer(query, request, token);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IQueryable<ChangeLog> BuildQuery(Guid idDiscriminator, DateTimeOffset momentUtc, SectionPartRequest request)
|
|
||||||
{
|
|
||||||
var query = db.Set<ChangeLog>()
|
|
||||||
.Where(e => e.IdDiscriminator == idDiscriminator)
|
|
||||||
.Where(e => e.Creation <= momentUtc)
|
|
||||||
.Where(e => e.Obsolete == null || e.Obsolete >= momentUtc);
|
|
||||||
|
|
||||||
if (request.IdSection.HasValue)
|
|
||||||
{
|
|
||||||
query = query.Where(e => e.IdSection == request.IdSection);
|
|
||||||
}
|
|
||||||
if (request.DepthStart.HasValue)
|
|
||||||
{
|
|
||||||
query = query.Where(e => e.DepthStart >= request.DepthStart);
|
|
||||||
}
|
|
||||||
if (request.DepthEnd.HasValue)
|
|
||||||
{
|
|
||||||
query = query.Where(e => e.DepthEnd <= request.DepthEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<ChangeLogDto>> GetChangeLogForDate(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token)
|
|
||||||
{
|
|
||||||
var query = db.Set<ChangeLog>().Where(s => s.IdDiscriminator == idDiscriminator);
|
|
||||||
|
|
||||||
var min = new DateTimeOffset(dateBegin.Year, dateBegin.Month, dateBegin.Day, 0, 0, 0, TimeSpan.Zero);
|
|
||||||
var max = new DateTimeOffset(dateEnd.Year, dateEnd.Month, dateEnd.Day, 0, 0, 0, TimeSpan.Zero);
|
|
||||||
|
|
||||||
var createdQuery = query.Where(e => e.Creation >= min && e.Creation <= max);
|
|
||||||
var editedQuery = query.Where(e => e.Obsolete != null && e.Obsolete >= min && e.Obsolete <= max);
|
|
||||||
|
|
||||||
query = createdQuery.Union(editedQuery);
|
|
||||||
var entities = await query.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var dtos = entities.Select(e => e.Adapt<ChangeLogDto>());
|
|
||||||
|
|
||||||
return dtos;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private async Task<PaginationContainer<DataWithWellDepthAndSectionDto>> BuildPaginationContainer(IQueryable<ChangeLog> query, SectionPartRequest request, CancellationToken token)
|
|
||||||
{
|
|
||||||
var result = new PaginationContainer<DataWithWellDepthAndSectionDto>
|
|
||||||
{
|
|
||||||
Skip = request.Skip ?? 0,
|
|
||||||
Take = request.Take ?? 32,
|
|
||||||
Items = Enumerable.Empty<DataWithWellDepthAndSectionDto>(),
|
|
||||||
Count = await query.CountAsync(token)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!String.IsNullOrEmpty(request.SortSettings))
|
|
||||||
{
|
|
||||||
query = query.SortBy(request.SortSettings);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
query = query
|
|
||||||
.OrderBy(e => e.IdSection)
|
|
||||||
.ThenBy(e => e.DepthStart)
|
|
||||||
.ThenBy(e => e.DepthEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
var entities = await query
|
|
||||||
.Skip(result.Skip)
|
|
||||||
.Take(result.Take)
|
|
||||||
.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var dtos = entities.Select(e => e.Adapt<DataWithWellDepthAndSectionDto>());
|
|
||||||
result.Items = dtos;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<DateOnly>> GetDatesChange(Guid idDiscriminator, CancellationToken token)
|
|
||||||
{
|
|
||||||
var query = db.Set<ChangeLog>().Where(e => e.IdDiscriminator == idDiscriminator);
|
|
||||||
|
|
||||||
var datesCreateQuery = query
|
|
||||||
.Select(e => e.Creation)
|
|
||||||
.Distinct();
|
|
||||||
|
|
||||||
var datesCreate = await datesCreateQuery.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var datesUpdateQuery = query
|
|
||||||
.Where(e => e.Obsolete != null)
|
|
||||||
.Select(e => e.Obsolete!.Value)
|
|
||||||
.Distinct();
|
|
||||||
|
|
||||||
var datesUpdate = await datesUpdateQuery.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var dates = Enumerable.Concat(datesCreate, datesUpdate);
|
|
||||||
var datesOnly = dates
|
|
||||||
.Select(d => new DateOnly(d.Year, d.Month, d.Day))
|
|
||||||
.Distinct()
|
|
||||||
.OrderBy(d => d);
|
|
||||||
|
|
||||||
return datesOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<IEnumerable<IDictionary<string, object>>> GetGtDate(DateTimeOffset dateBegin, CancellationToken token)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ChangeLog CreateEntityFromDto(Guid idUser, Guid idDiscriminator, DataWithWellDepthAndSectionDto dto)
|
|
||||||
{
|
|
||||||
var entity = new ChangeLog()
|
|
||||||
{
|
|
||||||
Id = default,
|
|
||||||
Creation = DateTimeOffset.UtcNow,
|
|
||||||
IdAuthor = idUser,
|
|
||||||
IdDiscriminator = idDiscriminator,
|
|
||||||
IdEditor = idUser,
|
|
||||||
|
|
||||||
Value = dto.Value,
|
|
||||||
IdSection = dto.IdSection,
|
|
||||||
DepthStart = dto.DepthStart,
|
|
||||||
DepthEnd = dto.DepthEnd,
|
|
||||||
};
|
|
||||||
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<DataWithWellDepthAndSectionDto>> GetGtDate(Guid idDiscriminator, DateTimeOffset dateBegin, CancellationToken token)
|
|
||||||
{
|
|
||||||
var date = dateBegin.ToUniversalTime();
|
|
||||||
var query = this.db.Set<ChangeLog>()
|
|
||||||
.Where(e => e.IdDiscriminator == idDiscriminator)
|
|
||||||
.Where(e => e.Creation >= date || e.Obsolete >= date);
|
|
||||||
|
|
||||||
var entities = await query.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var dtos = entities.Select(e => e.Adapt<DataWithWellDepthAndSectionDto>());
|
|
||||||
|
|
||||||
return dtos;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token)
|
|
||||||
{
|
|
||||||
var query = this.db.Set<ChangeLog>().Where(e => e.IdDiscriminator == idDiscriminator);
|
|
||||||
var minDate = await query.MinAsync(o => o.Creation, token);
|
|
||||||
var maxDate = await query.MaxAsync(o => o.Creation, token);
|
|
||||||
|
|
||||||
return new DatesRangeDto
|
|
||||||
{
|
|
||||||
From = minDate,
|
|
||||||
To = maxDate
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,87 +1,61 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
using Persistence.Models.Requests;
|
|
||||||
|
|
||||||
namespace Persistence.API;
|
namespace Persistence.API;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс для работы с API журнала изменений
|
/// Интерфейс для работы с API журнала изменений
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IChangeLogApi : ISyncWithDiscriminatorApi<DataWithWellDepthAndSectionDto>
|
public interface IChangeLogApi<TDto, TChangeLogDto>
|
||||||
|
where TDto : class, new()
|
||||||
|
where TChangeLogDto : ChangeLogDto<TDto>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Импорт с заменой: удаление старых строк и добавление новых
|
/// Получение исторических данных на текущую дату
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator"></param>
|
|
||||||
/// <param name="dtos"></param>
|
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IActionResult> ClearAndInsertRange(Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token);
|
Task<ActionResult<IEnumerable<TDto>>> GetChangeLogCurrent(CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение данных на текущую дату (с пагинацией)
|
/// Получение исторических данных на определенную дату
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator"></param>
|
/// <param name="historyMoment"></param>
|
||||||
/// <param name="request">параметры запроса</param>
|
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IActionResult> GetCurrent(Guid idDiscriminator, SectionPartRequest request, CancellationToken token);
|
Task<ActionResult<IEnumerable<TChangeLogDto>>> GetChangeLogForDate(DateTimeOffset historyMoment, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получение данных на определенную дату (с пагинацией)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idDiscriminator"></param>
|
|
||||||
/// <param name="moment"></param>
|
|
||||||
/// <param name="request">параметры запроса</param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<IActionResult> GetByDate(Guid idDiscriminator, DateTimeOffset moment, SectionPartRequest request, CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получение исторических данных за определенный период времени
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idDiscriminator"></param>
|
|
||||||
/// <param name="dateBegin"></param>
|
|
||||||
/// <param name="dateEnd"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<IActionResult> GetChangeLogForDate(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавить одну запись
|
/// Добавить одну запись
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator"></param>
|
|
||||||
/// <param name="dto"></param>
|
/// <param name="dto"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IActionResult> Add(Guid idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token);
|
Task<ActionResult<int>> Add(TDto dto, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавить несколько записей
|
/// Добавить несколько записей
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator"></param>
|
|
||||||
/// <param name="dtos"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IActionResult> AddRange(Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token);
|
Task<ActionResult<int>> AddRange(IEnumerable<TDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Обновить одну запись
|
/// Обновить одну запись
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator"></param>
|
|
||||||
/// <param name="dto"></param>
|
/// <param name="dto"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IActionResult> Update(Guid idDiscriminator, DataWithWellDepthAndSectionDto dto, CancellationToken token);
|
Task<ActionResult<int>> Update(TDto dto, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Обновить несколько записей
|
/// Обновить несколько записей
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator"></param>
|
|
||||||
/// <param name="dtos"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IActionResult> UpdateRange(Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token);
|
Task<ActionResult<int>> UpdateRange(IEnumerable<TDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Удалить одну запись
|
/// Удалить одну запись
|
||||||
@ -89,7 +63,7 @@ public interface IChangeLogApi : ISyncWithDiscriminatorApi<DataWithWellDepthAndS
|
|||||||
/// <param name="id"></param>
|
/// <param name="id"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IActionResult> Delete(Guid id, CancellationToken token);
|
Task<ActionResult<int>> Delete(int id, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Удалить несколько записей
|
/// Удалить несколько записей
|
||||||
@ -97,13 +71,5 @@ public interface IChangeLogApi : ISyncWithDiscriminatorApi<DataWithWellDepthAndS
|
|||||||
/// <param name="ids"></param>
|
/// <param name="ids"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IActionResult> DeleteRange(IEnumerable<Guid> ids, CancellationToken token);
|
Task<ActionResult<int>> DeleteRange(IEnumerable<int> ids, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получение списка дат, в которые происходили изменения (день, месяц, год, без времени)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idDiscriminator"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<IActionResult> GetDatesChange(Guid idDiscriminator, CancellationToken token);
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ namespace Persistence.API;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс для API, предназначенного для синхронизации данных
|
/// Интерфейс для API, предназначенного для синхронизации данных
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ISyncApi<TDto> where TDto : class
|
public interface ISyncApi<TDto> where TDto : class, new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить порцию записей, начиная с заданной даты
|
/// Получить порцию записей, начиная с заданной даты
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Persistence.Models;
|
|
||||||
|
|
||||||
namespace Persistence.API;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Интерфейс для API, предназначенного для синхронизации данных, у которых есть дискриминатор
|
|
||||||
/// </summary>
|
|
||||||
public interface ISyncWithDiscriminatorApi<TDto>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Получить порцию записей, начиная с заданной даты
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idDiscriminator"></param>
|
|
||||||
/// <param name="dateBegin"></param>
|
|
||||||
/// <param name="take">количество записей</param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<IActionResult> GetPart(Guid idDiscriminator, DateTimeOffset dateBegin, int take = 24 * 60 * 60, CancellationToken token = default);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idDiscriminator"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<IActionResult> GetDatesRangeAsync(Guid idDiscriminator, CancellationToken token);
|
|
||||||
}
|
|
@ -1,13 +1,17 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
using Persistence.Models.Requests;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Persistence.API;
|
namespace Persistence.API;
|
||||||
|
|
||||||
/// Интерфейс для API, предназначенного для работы с табличными данными
|
/// Интерфейс для API, предназначенного для работы с табличными данными
|
||||||
public interface ITableDataApi<TDto, TRequest>
|
public interface ITableDataApi<TDto, TRequest>
|
||||||
where TDto : class, new()
|
where TDto : class, new()
|
||||||
where TRequest : Request
|
where TRequest : RequestDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить страницу списка объектов
|
/// Получить страницу списка объектов
|
||||||
|
@ -1,114 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Persistence;
|
|
||||||
public static class EFExtensions
|
|
||||||
{
|
|
||||||
struct TypeAcessor
|
|
||||||
{
|
|
||||||
public LambdaExpression KeySelector { get; set; }
|
|
||||||
public MethodInfo OrderBy { get; set; }
|
|
||||||
public MethodInfo OrderByDescending { get; set; }
|
|
||||||
public MethodInfo ThenBy { get; set; }
|
|
||||||
public MethodInfo ThenByDescending { get; set; }
|
|
||||||
}
|
|
||||||
private static readonly MethodInfo methodOrderBy = GetExtOrderMethod("OrderBy");
|
|
||||||
|
|
||||||
private static readonly MethodInfo methodOrderByDescending = GetExtOrderMethod("OrderByDescending");
|
|
||||||
|
|
||||||
private static readonly MethodInfo methodThenBy = GetExtOrderMethod("ThenBy");
|
|
||||||
|
|
||||||
private static readonly MethodInfo methodThenByDescending = GetExtOrderMethod("ThenByDescending");
|
|
||||||
private static ConcurrentDictionary<Type, Dictionary<string, TypeAcessor>> TypePropSelectors { get; set; } = new();
|
|
||||||
|
|
||||||
private static MethodInfo GetExtOrderMethod(string methodName)
|
|
||||||
=> typeof(System.Linq.Queryable)
|
|
||||||
.GetMethods()
|
|
||||||
.Where(m => m.Name == methodName &&
|
|
||||||
m.IsGenericMethodDefinition &&
|
|
||||||
m.GetParameters().Length == 2 &&
|
|
||||||
m.GetParameters()[1].ParameterType.IsAssignableTo(typeof(LambdaExpression)))
|
|
||||||
.Single();
|
|
||||||
private static Dictionary<string, TypeAcessor> MakeTypeAcessors(Type type)
|
|
||||||
{
|
|
||||||
var propContainer = new Dictionary<string, TypeAcessor>();
|
|
||||||
var properties = type.GetProperties();
|
|
||||||
foreach (var propertyInfo in properties)
|
|
||||||
{
|
|
||||||
var name = propertyInfo.Name.ToLower();
|
|
||||||
ParameterExpression arg = Expression.Parameter(type, "x");
|
|
||||||
MemberExpression property = Expression.Property(arg, propertyInfo.Name);
|
|
||||||
var selector = Expression.Lambda(property, new ParameterExpression[] { arg });
|
|
||||||
var typeAccessor = new TypeAcessor
|
|
||||||
{
|
|
||||||
KeySelector = selector,
|
|
||||||
OrderBy = methodOrderBy.MakeGenericMethod(type, propertyInfo.PropertyType),
|
|
||||||
OrderByDescending = methodOrderByDescending.MakeGenericMethod(type, propertyInfo.PropertyType),
|
|
||||||
ThenBy = methodThenBy.MakeGenericMethod(type, propertyInfo.PropertyType),
|
|
||||||
ThenByDescending = methodThenByDescending.MakeGenericMethod(type, propertyInfo.PropertyType),
|
|
||||||
};
|
|
||||||
|
|
||||||
propContainer.Add(name, typeAccessor);
|
|
||||||
}
|
|
||||||
return propContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Добавить в запрос сортировку по возрастанию или убыванию.
|
|
||||||
/// Этот метод сбросит ранее наложенные сортировки.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TSource"></typeparam>
|
|
||||||
/// <param name="query"></param>
|
|
||||||
/// <param name="propertySort">
|
|
||||||
/// Свойство сортировки.
|
|
||||||
/// Состоит из названия свойства (в любом регистре)
|
|
||||||
/// и опционально указания направления сортировки "asc" или "desc"
|
|
||||||
/// </param>
|
|
||||||
/// <example>
|
|
||||||
/// var query = query("Date desc");
|
|
||||||
/// </example>
|
|
||||||
/// <returns>Запрос с примененной сортировкой</returns>
|
|
||||||
public static IOrderedQueryable<TSource> SortBy<TSource>(
|
|
||||||
this IQueryable<TSource> query,
|
|
||||||
string propertySort)
|
|
||||||
{
|
|
||||||
var parts = propertySort.Split(" ", 2, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
var isDesc = parts.Length >= 2 && parts[1].ToLower().Trim() == "desc";
|
|
||||||
var propertyName = parts[0];
|
|
||||||
|
|
||||||
var newQuery = query.SortBy(propertyName, isDesc);
|
|
||||||
return newQuery;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Добавить в запрос сортировку по возрастанию или убыванию
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TSource"></typeparam>
|
|
||||||
/// <param name="query"></param>
|
|
||||||
/// <param name="propertyName">Название свойства (в любом регистре)</param>
|
|
||||||
/// <param name="isDesc">Сортировать по убыванию</param>
|
|
||||||
/// <returns>Запрос с примененной сортировкой</returns>
|
|
||||||
public static IOrderedQueryable<TSource> SortBy<TSource>(
|
|
||||||
this IQueryable<TSource> query,
|
|
||||||
string propertyName,
|
|
||||||
bool isDesc)
|
|
||||||
{
|
|
||||||
var typePropSelector = TypePropSelectors.GetOrAdd(typeof(TSource), MakeTypeAcessors);
|
|
||||||
var propertyNamelower = propertyName.ToLower();
|
|
||||||
var typeAccessor = typePropSelector[propertyNamelower];
|
|
||||||
|
|
||||||
var genericMethod = isDesc
|
|
||||||
? typeAccessor.OrderByDescending
|
|
||||||
: typeAccessor.OrderBy;
|
|
||||||
|
|
||||||
var newQuery = (IOrderedQueryable<TSource>)genericMethod
|
|
||||||
.Invoke(genericMethod, new object[] { query, typeAccessor.KeySelector })!;
|
|
||||||
return newQuery;
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,40 +3,40 @@ namespace Persistence.Models;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Часть записи описывающая изменение
|
/// Часть записи описывающая изменение
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ChangeLogDto
|
public class ChangeLogDto<T> where T: class
|
||||||
{
|
{
|
||||||
public ChangeLogDto()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Создатель записи
|
/// Запись
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid IdAuthor { get; set; }
|
public required T Item { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Пользователь, изменивший запись
|
/// Автор
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid? IdEditor { get; set; }
|
public UserDto? Author { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Дата создания
|
/// Автор
|
||||||
|
/// </summary>
|
||||||
|
public UserDto? Editor { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Дата создания записи
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset Creation { get; set; }
|
public DateTimeOffset Creation { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Дата устаревания
|
/// Дата устаревания (например, при удалении)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset? Obsolete { get; set; }
|
public DateTimeOffset? Obsolete { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ключ следующей записи
|
/// Id состояния
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid? IdNext { get; set; }
|
public int IdState { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Объект записи
|
/// Id заменяемой записи
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataWithWellDepthAndSectionDto Value { get; set; }
|
public int? IdPrevious { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Persistence.Models;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Dto для хранения записей, содержащих начальную и конечную глубину забоя, а также секцию
|
|
||||||
/// </summary>
|
|
||||||
public class DataWithWellDepthAndSectionDto
|
|
||||||
{
|
|
||||||
public DataWithWellDepthAndSectionDto()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ключ записи
|
|
||||||
/// </summary>
|
|
||||||
public Guid Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Глубина забоя на дату начала интервала
|
|
||||||
/// </summary>
|
|
||||||
public double DepthStart { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Глубина забоя на дату окончания интервала
|
|
||||||
/// </summary>
|
|
||||||
public double DepthEnd { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ключ секции
|
|
||||||
/// </summary>
|
|
||||||
public Guid IdSection { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Объект записи
|
|
||||||
/// </summary>
|
|
||||||
public required IDictionary<string, object> Value { get; set; } = default!;
|
|
||||||
}
|
|
62
Persistence/Models/IChangeLogAbstract.cs
Normal file
62
Persistence/Models/IChangeLogAbstract.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
namespace Persistence.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Часть записи описывающая изменение
|
||||||
|
/// </summary>
|
||||||
|
public interface IChangeLogAbstract
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Актуальная
|
||||||
|
/// </summary>
|
||||||
|
public const int IdStateActual = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Замененная
|
||||||
|
/// </summary>
|
||||||
|
public const int IdStateReplaced = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Удаленная
|
||||||
|
/// </summary>
|
||||||
|
public const int IdStateDeleted = 2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Очищено при импорте
|
||||||
|
/// </summary>
|
||||||
|
public const int IdCleared = 3;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ид записи
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Автор изменения
|
||||||
|
/// </summary>
|
||||||
|
public int IdAuthor { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Редактор
|
||||||
|
/// </summary>
|
||||||
|
public int? IdEditor { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Дата создания записи
|
||||||
|
/// </summary>
|
||||||
|
public DateTimeOffset Creation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Дата устаревания (например при удалении)
|
||||||
|
/// </summary>
|
||||||
|
public DateTimeOffset? Obsolete { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "ИД состояния записи: \n0 - актуальная\n1 - замененная\n2 - удаленная
|
||||||
|
/// </summary>
|
||||||
|
public int IdState { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Id заменяемой записи
|
||||||
|
/// </summary>
|
||||||
|
public int? IdPrevious { get; set; }
|
||||||
|
}
|
@ -1,42 +0,0 @@
|
|||||||
namespace Persistence.Models;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Часть записи описывающая изменение
|
|
||||||
/// </summary>
|
|
||||||
public interface IChangeLogDto
|
|
||||||
{
|
|
||||||
///// <summary>
|
|
||||||
///// Ид записи
|
|
||||||
///// </summary>
|
|
||||||
//public int Id { get; set; }
|
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Автор изменения
|
|
||||||
///// </summary>
|
|
||||||
//public int IdAuthor { get; set; }
|
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Редактор
|
|
||||||
///// </summary>
|
|
||||||
//public int? IdEditor { get; set; }
|
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Дата создания записи
|
|
||||||
///// </summary>
|
|
||||||
//public DateTimeOffset Creation { get; set; }
|
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Дата устаревания (например при удалении)
|
|
||||||
///// </summary>
|
|
||||||
//public DateTimeOffset? Obsolete { get; set; }
|
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Id заменяющей записи
|
|
||||||
///// </summary>
|
|
||||||
//public int? IdNext { get; set; }
|
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Значение
|
|
||||||
///// </summary>
|
|
||||||
//public object Value { get; set; }
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Persistence.Models;
|
|
||||||
public class ProcessMapRotorDto : IChangeLogDto
|
|
||||||
{
|
|
||||||
public string Caption { get; set; }
|
|
||||||
}
|
|
@ -1,25 +1,23 @@
|
|||||||
namespace Persistence.Models.Requests;
|
namespace Persistence.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Контейнер для поддержки постраничного просмотра таблиц
|
/// Контейнер для поддержки постраничного просмотра таблиц
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
public class Request
|
public class RequestDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Кол-во записей пропущенных с начала таблицы в запросе от api
|
/// Кол-во записей пропущенных с начала таблицы в запросе от api
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? Skip { get; set; }
|
public int Skip { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Кол-во записей в запросе от api
|
/// Кол-во записей в запросе от api
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? Take { get; set; }
|
public int Take { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Сортировки:
|
/// Настройки сортировки
|
||||||
/// Содержат список названий полей сортировки
|
|
||||||
/// Указать направление сортировки можно через пробел "asc" или "desc"
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SortSettings { get; set; } = string.Empty;
|
public string SortSettings { get; set; } = string.Empty;
|
||||||
}
|
}
|
@ -1,22 +0,0 @@
|
|||||||
namespace Persistence.Models.Requests;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Запрос для фильтрации данных по секции и глубине
|
|
||||||
/// </summary>
|
|
||||||
public class SectionPartRequest : Request
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Глубина забоя на дату начала интервала
|
|
||||||
/// </summary>
|
|
||||||
public double? DepthStart { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Глубина забоя на дату окончания интервала
|
|
||||||
/// </summary>
|
|
||||||
public double? DepthEnd { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ключ секции
|
|
||||||
/// </summary>
|
|
||||||
public Guid? IdSection { get; set; }
|
|
||||||
}
|
|
@ -1,5 +1,4 @@
|
|||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
using Persistence.Models.Requests;
|
|
||||||
|
|
||||||
namespace Persistence.Repositories;
|
namespace Persistence.Repositories;
|
||||||
|
|
||||||
@ -7,81 +6,84 @@ namespace Persistence.Repositories;
|
|||||||
/// Интерфейс для работы с историческими данными
|
/// Интерфейс для работы с историческими данными
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TDto"></typeparam>
|
/// <typeparam name="TDto"></typeparam>
|
||||||
public interface IChangeLogRepository : ISyncWithDiscriminatorRepository<DataWithWellDepthAndSectionDto>
|
public interface IChangeLogRepository<TDto, TChangeLogDto> : ISyncRepository<TDto>
|
||||||
|
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||||
|
where TChangeLogDto : ChangeLogDto<TDto>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавление записей
|
/// Добавление записей
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idUser">пользователь, который добавляет</param>
|
/// <param name="idUser">пользователь, который добавляет</param>
|
||||||
/// <param name="idDiscriminator">ключ справочника</param>
|
|
||||||
/// <param name="dtos"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<int> InsertRange(Guid idUser, Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token);
|
Task<int> InsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Пометить записи как удаленные
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idUser"></param>
|
|
||||||
/// <param name="ids">ключи записей</param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<int> MarkAsDeleted(Guid idUser, IEnumerable<Guid> ids, CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Пометить записи как удаленные
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idUser"></param>
|
|
||||||
/// <param name="idDiscriminator">дискриминатор таблицы</param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<int> MarkAsDeleted(Guid idUser, Guid idDiscriminator, CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Очистить и добавить новые
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idUser"></param>
|
|
||||||
/// <param name="idDiscriminator"></param>
|
|
||||||
/// <param name="dtos"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<int> ClearAndInsertRange(Guid idUser, Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Редактирование записей
|
/// Редактирование записей
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idUser">пользователь, который редактирует</param>
|
/// <param name="idUser">пользователь, который редактирует</param>
|
||||||
/// <param name="idDiscriminator"></param>
|
|
||||||
/// <param name="dtos"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<int> UpdateRange(Guid idUser, Guid idDiscriminator, IEnumerable<DataWithWellDepthAndSectionDto> dtos, CancellationToken token);
|
Task<int> UpdateRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение актуальных записей на определенный момент времени (с пагинацией)
|
/// Добавляет Dto у которых id == 0, изменяет dto у которых id != 0
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator"></param>
|
/// <param name="idUser">пользователь, который редактирует или добавляет</param>
|
||||||
/// <param name="moment">текущий момент времени</param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="request">параметры запроса</param>
|
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<PaginationContainer<DataWithWellDepthAndSectionDto>> GetByDate(Guid idDiscriminator, DateTimeOffset moment, SectionPartRequest request, CancellationToken token);
|
Task<int> UpdateOrInsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение измененных записей за период времени
|
/// Помечает записи как удаленные
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator"></param>
|
/// <param name="idUser">пользователь, который чистит</param>
|
||||||
/// <param name="dateBegin"></param>
|
|
||||||
/// <param name="dateEnd"></param>
|
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<ChangeLogDto>> GetChangeLogForDate(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token);
|
Task<int> Clear(int idUser, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение списка дат, в которые происходили изменения (день, месяц, год, без времени)
|
/// Очистить и добавить новые
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator"></param>
|
/// <param name="idUser"></param>
|
||||||
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<DateOnly>> GetDatesChange(Guid idDiscriminator, CancellationToken token);
|
Task<int> ClearAndInsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Пометить записи как удаленные
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idUser"></param>
|
||||||
|
/// <param name="ids"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<int> MarkAsDeleted(int idUser, IEnumerable<int> ids, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение дат изменений записей
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<DateOnly>> GetDatesChange(CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение измененных записей за определенную дату
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="updateFrom"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<TChangeLogDto>> GetChangeLogForDate(DateTimeOffset? updateFrom, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение текущих сейчас записей по параметрам
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<TDto>> GetCurrent(DateTimeOffset moment, CancellationToken token);
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,17 @@
|
|||||||
using Persistence.Models;
|
namespace Persistence.Repositories;
|
||||||
|
|
||||||
namespace Persistence.Repositories;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс по работе с данными
|
/// Интерфейс по работе с данными
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TDto"></typeparam>
|
/// <typeparam name="TDto"></typeparam>
|
||||||
public interface ISyncRepository<TDto>
|
public interface ISyncRepository<TDto>
|
||||||
|
where TDto : class, new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить данные, начиная с определенной даты
|
/// Получить данные, начиная с определенной даты
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dateBegin">дата начала</param>
|
/// <param name="dateBegin">дата начала</param>
|
||||||
/// <param name="token"></param> /// <returns></returns>
|
|
||||||
Task<IEnumerable<TDto>> GetGtDate(DateTimeOffset dateBegin, CancellationToken token);
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<DatesRangeDto?> GetDatesRange(CancellationToken token);
|
Task<IEnumerable<TDto>> GetGtDate(DateTimeOffset dateBegin, CancellationToken token);
|
||||||
}
|
}
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
using Persistence.Models;
|
|
||||||
|
|
||||||
namespace Persistence.Repositories;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Интерфейс по работе с данными, у которых есть дискриминатор
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDto"></typeparam>
|
|
||||||
public interface ISyncWithDiscriminatorRepository<TDto>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Получить данные, начиная с определенной даты
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idDiscriminator">дискриминатор таблицы</param>
|
|
||||||
/// <param name="dateBegin">дата начала</param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// /// <returns></returns>
|
|
||||||
Task<IEnumerable<TDto>> GetGtDate(Guid idDiscriminator, DateTimeOffset dateBegin, CancellationToken token);
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idDiscriminator">дискриминатор таблицы</param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token);
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
using Persistence.Models.Requests;
|
using Persistence.Models;
|
||||||
|
|
||||||
namespace Persistence.Repositories;
|
namespace Persistence.Repositories;
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ namespace Persistence.Repositories;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ITableDataRepository<TDto, TRequest>
|
public interface ITableDataRepository<TDto, TRequest>
|
||||||
where TDto : class, new()
|
where TDto : class, new()
|
||||||
where TRequest : Request
|
where TRequest : RequestDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить страницу списка объектов
|
/// Получить страницу списка объектов
|
||||||
|
@ -19,4 +19,11 @@ public interface ITimeSeriesBaseRepository<TDto>
|
|||||||
double intervalSec = 600d,
|
double intervalSec = 600d,
|
||||||
int approxPointsCount = 1024,
|
int approxPointsCount = 1024,
|
||||||
CancellationToken token = default);
|
CancellationToken token = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<DatesRangeDto?> GetDatesRange(CancellationToken token);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user