Тестовые проект(ы) для реализации интерфейсов Persistence:
- Persistence.API - Persistence.Database - Persistence.Repository - Persistence.IntegrationTests
This commit is contained in:
parent
3c94d55caf
commit
828864c112
30
.dockerignore
Normal file
30
.dockerignore
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
**/.classpath
|
||||||
|
**/.dockerignore
|
||||||
|
**/.env
|
||||||
|
**/.git
|
||||||
|
**/.gitignore
|
||||||
|
**/.project
|
||||||
|
**/.settings
|
||||||
|
**/.toolstarget
|
||||||
|
**/.vs
|
||||||
|
**/.vscode
|
||||||
|
**/*.*proj.user
|
||||||
|
**/*.dbmdl
|
||||||
|
**/*.jfm
|
||||||
|
**/azds.yaml
|
||||||
|
**/bin
|
||||||
|
**/charts
|
||||||
|
**/docker-compose*
|
||||||
|
**/Dockerfile*
|
||||||
|
**/node_modules
|
||||||
|
**/npm-debug.log
|
||||||
|
**/obj
|
||||||
|
**/secrets.dev.yaml
|
||||||
|
**/values.dev.yaml
|
||||||
|
LICENSE
|
||||||
|
README.md
|
||||||
|
!**/.gitignore
|
||||||
|
!.git/HEAD
|
||||||
|
!.git/config
|
||||||
|
!.git/packed-refs
|
||||||
|
!.git/refs/heads/**
|
15
Persistence.API/Controllers/DataSaubController.cs
Normal file
15
Persistence.API/Controllers/DataSaubController.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Persistence.API;
|
||||||
|
using Persistence.Repositories;
|
||||||
|
using Persistence.Repository.Data;
|
||||||
|
|
||||||
|
namespace Persistence.API.Controllers;
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
public class DataSaubController : TimeSeriesController<DataSaubDto>
|
||||||
|
{
|
||||||
|
public DataSaubController(ITimeSeriesDataRepository<DataSaubDto> timeSeriesDataRepository) : base(timeSeriesDataRepository)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
38
Persistence.API/Controllers/TimeSeriesController.cs
Normal file
38
Persistence.API/Controllers/TimeSeriesController.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Persistence.Models;
|
||||||
|
using Persistence.Repositories;
|
||||||
|
|
||||||
|
namespace Persistence.API.Controllers;
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
public class TimeSeriesController<TDto> : ControllerBase, ITimeSeriesDataApi<TDto>
|
||||||
|
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||||
|
{
|
||||||
|
private ITimeSeriesDataRepository<TDto> timeSeriesDataRepository;
|
||||||
|
|
||||||
|
public TimeSeriesController(ITimeSeriesDataRepository<TDto> timeSeriesDataRepository)
|
||||||
|
{
|
||||||
|
this.timeSeriesDataRepository = timeSeriesDataRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetAsync(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token)
|
||||||
|
{
|
||||||
|
var result = await this.timeSeriesDataRepository.GetAsync(dateBegin, dateEnd, token);
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("datesRange")]
|
||||||
|
public Task<IActionResult> GetDatesRangeAsync(CancellationToken token)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> InsertRangeAsync(IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
|
{
|
||||||
|
var result = await this.timeSeriesDataRepository.InsertRange(dtos, token);
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
}
|
24
Persistence.API/Dockerfile
Normal file
24
Persistence.API/Dockerfile
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
|
||||||
|
USER app
|
||||||
|
WORKDIR /app
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
||||||
|
ARG BUILD_CONFIGURATION=Release
|
||||||
|
WORKDIR /src
|
||||||
|
COPY ["Persistence.API/Persistence.API.csproj", "Persistence.API/"]
|
||||||
|
RUN dotnet restore "./Persistence.API/Persistence.API.csproj"
|
||||||
|
COPY . .
|
||||||
|
WORKDIR "/src/Persistence.API"
|
||||||
|
RUN dotnet build "./Persistence.API.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
||||||
|
|
||||||
|
FROM build AS publish
|
||||||
|
ARG BUILD_CONFIGURATION=Release
|
||||||
|
RUN dotnet publish "./Persistence.API.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||||
|
|
||||||
|
FROM base AS final
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=publish /app/publish .
|
||||||
|
ENTRYPOINT ["dotnet", "Persistence.API.dll"]
|
20
Persistence.API/Persistence.API.csproj
Normal file
20
Persistence.API/Persistence.API.csproj
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.6" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Persistence.Repository\Persistence.Repository.csproj" />
|
||||||
|
<ProjectReference Include="..\Persistence\Persistence.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
6
Persistence.API/Persistence.API.http
Normal file
6
Persistence.API/Persistence.API.http
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
@Persistence.API_HostAddress = http://localhost:5032
|
||||||
|
|
||||||
|
GET {{Persistence.API_HostAddress}}/weatherforecast/
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
###
|
26
Persistence.API/Program.cs
Normal file
26
Persistence.API/Program.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Persistence.Repositories;
|
||||||
|
using Persistence.Repository;
|
||||||
|
using Persistence.Repository.Data;
|
||||||
|
using Persistence.Repository.Repositories;
|
||||||
|
|
||||||
|
namespace Persistence.API;
|
||||||
|
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
var host = CreateHostBuilder(args).Build();
|
||||||
|
Persistence.Repository.Startup.BeforeRunHandler(host);
|
||||||
|
host.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||||
|
Host.CreateDefaultBuilder(args)
|
||||||
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
|
{
|
||||||
|
webBuilder.UseStartup<Startup>();
|
||||||
|
});
|
||||||
|
}
|
40
Persistence.API/Properties/launchSettings.json
Normal file
40
Persistence.API/Properties/launchSettings.json
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"applicationUrl": "http://localhost:5032"
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Container (Dockerfile)": {
|
||||||
|
"commandName": "Docker",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_HTTP_PORTS": "8080"
|
||||||
|
},
|
||||||
|
"publishAllPorts": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:13616",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
Persistence.API/Startup.cs
Normal file
40
Persistence.API/Startup.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using Persistence.Repository;
|
||||||
|
|
||||||
|
namespace Persistence.API;
|
||||||
|
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public IConfiguration Configuration { get; }
|
||||||
|
public Startup(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
Configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
// Add services to the container.
|
||||||
|
|
||||||
|
services.AddControllers();
|
||||||
|
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||||
|
services.AddEndpointsApiExplorer();
|
||||||
|
services.AddSwaggerGen();
|
||||||
|
|
||||||
|
services.AddInfrastructure(Configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
|
{
|
||||||
|
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
|
//app.UseAuthorization();
|
||||||
|
|
||||||
|
app.UseEndpoints(endpoints =>
|
||||||
|
{
|
||||||
|
endpoints.MapControllers();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
12
Persistence.API/WeatherForecast.cs
Normal file
12
Persistence.API/WeatherForecast.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace Persistence.API;
|
||||||
|
|
||||||
|
public class WeatherForecast
|
||||||
|
{
|
||||||
|
public DateOnly Date { get; set; }
|
||||||
|
|
||||||
|
public int TemperatureC { get; set; }
|
||||||
|
|
||||||
|
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||||
|
|
||||||
|
public string? Summary { get; set; }
|
||||||
|
}
|
8
Persistence.API/appsettings.Development.json
Normal file
8
Persistence.API/appsettings.Development.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
Persistence.API/appsettings.Tests.json
Normal file
8
Persistence.API/appsettings.Tests.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"DbConnection": {
|
||||||
|
"Host": "localhost",
|
||||||
|
"Port": 5432,
|
||||||
|
"Username": "postgres",
|
||||||
|
"Password": "q"
|
||||||
|
}
|
||||||
|
}
|
12
Persistence.API/appsettings.json
Normal file
12
Persistence.API/appsettings.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"DefaultConnection": "Host=localhost;Database=persistence;Username=postgres;Password=q;Persist Security Info=True",
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
58
Persistence.Database/EFExtensionsInitialization.cs
Normal file
58
Persistence.Database/EFExtensionsInitialization.cs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Persistence.Database;
|
||||||
|
public static class EFExtensionsInitialization
|
||||||
|
{
|
||||||
|
public static void EnsureCreatedAndMigrated(this DatabaseFacade db)
|
||||||
|
{
|
||||||
|
var connectionString = db.GetConnectionString();
|
||||||
|
Trace.TraceInformation($"connectionString: {connectionString}");
|
||||||
|
db.SetCommandTimeout(TimeSpan.FromMinutes(5));
|
||||||
|
if (db.EnsureCreated())
|
||||||
|
{
|
||||||
|
Trace.TraceInformation("Creating DB");
|
||||||
|
Console.WriteLine("Creating DB");
|
||||||
|
db.CreateMigrationTable();
|
||||||
|
db.WriteMigrationsInfo();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Trace.TraceInformation("Migrating DB");
|
||||||
|
db.SetCommandTimeout(TimeSpan.FromMinutes(20));
|
||||||
|
Console.WriteLine("db.Migrate()");
|
||||||
|
db.Migrate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateMigrationTable(this DatabaseFacade db)
|
||||||
|
{
|
||||||
|
var sqlCreateMigrationTable =
|
||||||
|
$"CREATE TABLE public.\"__EFMigrationsHistory\" " +
|
||||||
|
$"(\"MigrationId\" varchar(150) NOT NULL, " +
|
||||||
|
$" \"ProductVersion\" varchar(32) NOT NULL, " +
|
||||||
|
$" CONSTRAINT \"PK___EFMigrationsHistory\" PRIMARY KEY (\"MigrationId\"));";
|
||||||
|
db.ExecuteSqlRaw(sqlCreateMigrationTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteMigrationsInfo(this DatabaseFacade db)
|
||||||
|
{
|
||||||
|
var efVersion = db.GetType().Assembly.GetName().Version!;
|
||||||
|
var efVersionString = $"{efVersion.Major}.{efVersion.Minor}.{efVersion.Build}";
|
||||||
|
|
||||||
|
var migrations = db.GetPendingMigrations()
|
||||||
|
.Select(migration => $" ('{migration}', '{efVersionString}')");
|
||||||
|
|
||||||
|
var sqlAddLastMigration =
|
||||||
|
$"INSERT INTO public.\"__EFMigrationsHistory\" " +
|
||||||
|
$"(\"MigrationId\", \"ProductVersion\") " +
|
||||||
|
$"VALUES {string.Join(',', migrations)};";
|
||||||
|
db.ExecuteSqlRaw(sqlAddLastMigration);
|
||||||
|
}
|
||||||
|
}
|
65
Persistence.Database/Model/DataSaub.cs
Normal file
65
Persistence.Database/Model/DataSaub.cs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Persistence.Database.Model;
|
||||||
|
public class DataSaub : ITimestampedData
|
||||||
|
{
|
||||||
|
[Column("id")]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[Column("timestamp")]
|
||||||
|
public int TimeStamp { get; set; }
|
||||||
|
|
||||||
|
[Column("mode")]
|
||||||
|
public int? Mode { get; set; }
|
||||||
|
|
||||||
|
[Column("user")]
|
||||||
|
public string? User { get; set; }
|
||||||
|
|
||||||
|
[Column("wellDepth")]
|
||||||
|
public double? WellDepth { get; set; }
|
||||||
|
|
||||||
|
[Column("bitDepth")]
|
||||||
|
public double? BitDepth { get; set; }
|
||||||
|
|
||||||
|
[Column("blockPosition")]
|
||||||
|
public double? BlockPosition { get; set; }
|
||||||
|
|
||||||
|
[Column("blockSpeed")]
|
||||||
|
public double? BlockSpeed { get; set; }
|
||||||
|
|
||||||
|
[Column("pressure")]
|
||||||
|
public double? Pressure { get; set; }
|
||||||
|
|
||||||
|
[Column("axialLoad")]
|
||||||
|
public double? AxialLoad { get; set; }
|
||||||
|
|
||||||
|
[Column("hookWeight")]
|
||||||
|
public double? HookWeight { get; set; }
|
||||||
|
|
||||||
|
[Column("rotorTorque")]
|
||||||
|
public double? RotorTorque { get; set; }
|
||||||
|
|
||||||
|
[Column("rotorSpeed")]
|
||||||
|
public double? RotorSpeed { get; set; }
|
||||||
|
|
||||||
|
[Column("flow")]
|
||||||
|
public double? Flow { get; set; }
|
||||||
|
|
||||||
|
[Column("mseState")]
|
||||||
|
public short MseState { get; set; }
|
||||||
|
|
||||||
|
[Column("idFeedRegulator")]
|
||||||
|
public int IdFeedRegulator { get; set; }
|
||||||
|
|
||||||
|
[Column("mse")]
|
||||||
|
public double? Mse { get; set; }
|
||||||
|
|
||||||
|
[Column("pump0Flow")]
|
||||||
|
public double? Pump0Flow { get; set; }
|
||||||
|
|
||||||
|
[Column("pump1Flow")]
|
||||||
|
public double? Pump1Flow { get; set; }
|
||||||
|
|
||||||
|
[Column("pump2Flow")]
|
||||||
|
public double? Pump2Flow { get; set; }
|
||||||
|
}
|
21
Persistence.Database/Model/IDbContextManager.cs
Normal file
21
Persistence.Database/Model/IDbContextManager.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Persistence.Database.Model;
|
||||||
|
public interface IDbContextManager
|
||||||
|
{
|
||||||
|
//IConnectionManager ConnectionManager { get; }
|
||||||
|
|
||||||
|
DbContext GetReadonlyDbContext();
|
||||||
|
|
||||||
|
DbContext GetDbContext();
|
||||||
|
|
||||||
|
DbContext CreateAndInitializeNewContext();
|
||||||
|
|
||||||
|
DbContext CreateAndInitializeNewContext(DbConnection connection);
|
||||||
|
}
|
16
Persistence.Database/Model/IPersistenceDbContext.cs
Normal file
16
Persistence.Database/Model/IPersistenceDbContext.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
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; }
|
||||||
|
DatabaseFacade Database { get; }
|
||||||
|
Task<int> SaveChangesAsync(CancellationToken cancellationToken);
|
||||||
|
}
|
11
Persistence.Database/Model/ITimestampedData.cs
Normal file
11
Persistence.Database/Model/ITimestampedData.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Persistence.Database.Model;
|
||||||
|
public interface ITimestampedData
|
||||||
|
{
|
||||||
|
int TimeStamp { get; set; }
|
||||||
|
}
|
34
Persistence.Database/Model/PersistenceDbContext.cs
Normal file
34
Persistence.Database/Model/PersistenceDbContext.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.Metrics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
|
||||||
|
|
||||||
|
namespace Persistence.Database.Model;
|
||||||
|
public partial class PersistenceDbContext : DbContext, IPersistenceDbContext
|
||||||
|
{
|
||||||
|
public DbSet<DataSaub> DataSaub => Set<DataSaub>();
|
||||||
|
|
||||||
|
public PersistenceDbContext(DbContextOptions<PersistenceDbContext> options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
|
{
|
||||||
|
if (!optionsBuilder.IsConfigured)
|
||||||
|
optionsBuilder.UseNpgsql("Host=localhost;Database=persistence;Username=postgres;Password=q;Persist Security Info=True;Include Error Detail=True;"
|
||||||
|
//, builder=>builder.EnableRetryOnFailure(2, System.TimeSpan.FromMinutes(1))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
modelBuilder.HasPostgresExtension("adminpack")
|
||||||
|
.HasAnnotation("Relational:Collation", "Russian_Russia.1251");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
17
Persistence.Database/Persistence.Database.csproj
Normal file
17
Persistence.Database/Persistence.Database.csproj
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
43
Persistence.IntegrationTests/ApiTokenHelper.cs
Normal file
43
Persistence.IntegrationTests/ApiTokenHelper.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
namespace Persistence.IntegrationTests;
|
||||||
|
public static class ApiTokenHelper
|
||||||
|
{
|
||||||
|
//public static string GetAdminUserToken()
|
||||||
|
//{
|
||||||
|
// var user = new User()
|
||||||
|
// {
|
||||||
|
// Id = 1,
|
||||||
|
// IdCompany = 1,
|
||||||
|
// Login = "test_user"
|
||||||
|
// };
|
||||||
|
// var roles = new[] { "root" };
|
||||||
|
|
||||||
|
// return CreateToken(user, roles);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//private static string CreateToken(User user, IEnumerable<string> roles)
|
||||||
|
//{
|
||||||
|
// var claims = new List<Claim>
|
||||||
|
// {
|
||||||
|
// new("id", user.Id.ToString()),
|
||||||
|
// new(ClaimsIdentity.DefaultNameClaimType, user.Login),
|
||||||
|
// new("idCompany", user.IdCompany.ToString()),
|
||||||
|
// };
|
||||||
|
|
||||||
|
// claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role)));
|
||||||
|
|
||||||
|
// const string secret = "супер секретный ключ для шифрования";
|
||||||
|
|
||||||
|
// var key = Encoding.ASCII.GetBytes(secret);
|
||||||
|
// var tokenDescriptor = new SecurityTokenDescriptor
|
||||||
|
// {
|
||||||
|
// Issuer = "a",
|
||||||
|
// Audience = "a",
|
||||||
|
// Subject = new ClaimsIdentity(claims),
|
||||||
|
// Expires = DateTime.UtcNow.AddHours(1),
|
||||||
|
// SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
|
||||||
|
// };
|
||||||
|
// var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
|
// var token = tokenHandler.CreateToken(tokenDescriptor);
|
||||||
|
// return tokenHandler.WriteToken(token);
|
||||||
|
//}
|
||||||
|
}
|
30
Persistence.IntegrationTests/BaseIntegrationTest.cs
Normal file
30
Persistence.IntegrationTests/BaseIntegrationTest.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Persistence.Database.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Persistence.IntegrationTests;
|
||||||
|
public abstract class BaseIntegrationTest : IClassFixture<WebAppFactoryFixture>,
|
||||||
|
IDisposable
|
||||||
|
{
|
||||||
|
protected readonly IServiceScope scope;
|
||||||
|
|
||||||
|
protected readonly PersistenceDbContext dbContext;
|
||||||
|
|
||||||
|
protected BaseIntegrationTest(WebAppFactoryFixture factory)
|
||||||
|
{
|
||||||
|
//scope = factory.Services.CreateScope();
|
||||||
|
|
||||||
|
//dbContext = scope.ServiceProvider.GetRequiredService<PersistenceDbContext>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
scope.Dispose();
|
||||||
|
dbContext.Dispose();
|
||||||
|
}
|
||||||
|
}
|
16
Persistence.IntegrationTests/Clients/ITimeSeriesClient.cs
Normal file
16
Persistence.IntegrationTests/Clients/ITimeSeriesClient.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Persistence.Repository.Data;
|
||||||
|
using Refit;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Persistence.IntegrationTests.Clients;
|
||||||
|
public interface ITimeSeriesClient<TDto>
|
||||||
|
where TDto : class, new()
|
||||||
|
{
|
||||||
|
[Post("/api/dataSaub")]
|
||||||
|
Task<IApiResponse<int>> InsertRangeAsync(IEnumerable<TDto> dtos);
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
using Persistence.Repository.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Persistence.IntegrationTests.Controllers;
|
||||||
|
public class DataSaubControllerTest : TimeSeriesBaseControllerTest<DataSaubDto>
|
||||||
|
{
|
||||||
|
private readonly DataSaubDto dto = new DataSaubDto()
|
||||||
|
{
|
||||||
|
AxialLoad = 1,
|
||||||
|
BitDepth = 2,
|
||||||
|
BlockPosition = 3,
|
||||||
|
BlockSpeed = 4,
|
||||||
|
Date = DateTimeOffset.Now,
|
||||||
|
Flow = 5,
|
||||||
|
HookWeight = 6,
|
||||||
|
Id = 7,
|
||||||
|
IdFeedRegulator = 8,
|
||||||
|
Mode = 9,
|
||||||
|
Mse = 10,
|
||||||
|
MseState = 11,
|
||||||
|
Pressure = 12,
|
||||||
|
Pump0Flow = 13,
|
||||||
|
Pump1Flow = 14,
|
||||||
|
Pump2Flow = 15,
|
||||||
|
RotorSpeed = 16,
|
||||||
|
RotorTorque = 17,
|
||||||
|
User = string.Empty,
|
||||||
|
WellDepth = 18,
|
||||||
|
};
|
||||||
|
|
||||||
|
public DataSaubControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InsertRange_returns_success()
|
||||||
|
{
|
||||||
|
await InsertRangeSuccess(dto);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
using Mapster;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Persistence.IntegrationTests.Clients;
|
||||||
|
using Persistence.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Persistence.IntegrationTests.Controllers;
|
||||||
|
public abstract class TimeSeriesBaseControllerTest<TDto> : BaseIntegrationTest
|
||||||
|
where TDto : class, new()
|
||||||
|
{
|
||||||
|
private ITimeSeriesClient<TDto> client;
|
||||||
|
|
||||||
|
public TimeSeriesBaseControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||||
|
{
|
||||||
|
//dbContext.CleanupDbSet<TEntity>();
|
||||||
|
client = factory.GetHttpClient<ITimeSeriesClient<TDto>>(string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InsertRangeSuccess(TDto dto)
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var expected = dto.Adapt<TDto>();
|
||||||
|
|
||||||
|
//act
|
||||||
|
var response = await client.InsertRangeAsync(new TDto[] { expected });
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.Equal(1, response.Content);
|
||||||
|
|
||||||
|
//var entity = GetByWellId();
|
||||||
|
|
||||||
|
//Assert.NotNull(entity);
|
||||||
|
|
||||||
|
//var actual = entity.Adapt<ChangeLogDto<TDto>>();
|
||||||
|
//Assert.Equal(ProcessMapPlanBase.IdStateActual, actual.IdState);
|
||||||
|
|
||||||
|
//var excludeProps = new[] {
|
||||||
|
// nameof(ProcessMapPlanBaseDto.Id),
|
||||||
|
// nameof(ProcessMapPlanBaseDto.Section)
|
||||||
|
//};
|
||||||
|
//MatchHelper.Match(expected, actual.Item, excludeProps);
|
||||||
|
}
|
||||||
|
}
|
20
Persistence.IntegrationTests/DbConnection.cs
Normal file
20
Persistence.IntegrationTests/DbConnection.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Persistence.IntegrationTests;
|
||||||
|
public class DbConnection
|
||||||
|
{
|
||||||
|
public string Host { get; set; } = null!;
|
||||||
|
|
||||||
|
public int Port { get; set; }
|
||||||
|
|
||||||
|
public string Username { get; set; } = null!;
|
||||||
|
|
||||||
|
public string Password { get; set; } = null!;
|
||||||
|
|
||||||
|
public string GetConnectionString() =>
|
||||||
|
$"Host={Host};Database={Guid.NewGuid()};Port={Port};Username={Username};Password={Password};Persist Security Info=True;Include Error Detail=True";
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<IsTestProject>true</IsTestProject>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.10" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||||
|
<PackageReference Include="Refit" Version="8.0.0" />
|
||||||
|
<PackageReference Include="xunit" Version="2.9.2" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Persistence.API\Persistence.API.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
101
Persistence.IntegrationTests/WebAppFactoryFixture.cs
Normal file
101
Persistence.IntegrationTests/WebAppFactoryFixture.cs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Testing;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Persistence.Database.Model;
|
||||||
|
using Persistence.API;
|
||||||
|
using Refit;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace Persistence.IntegrationTests;
|
||||||
|
public class WebAppFactoryFixture : WebApplicationFactory<Startup>
|
||||||
|
{
|
||||||
|
private static readonly JsonSerializerOptions JsonSerializerOptions = new()
|
||||||
|
{
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
PropertyNameCaseInsensitive = true,
|
||||||
|
//Converters = { new ValidationResultConverter() }
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly RefitSettings RefitSettings = new(new SystemTextJsonContentSerializer(JsonSerializerOptions));
|
||||||
|
|
||||||
|
private readonly string connectionString;
|
||||||
|
|
||||||
|
public WebAppFactoryFixture()
|
||||||
|
{
|
||||||
|
var configuration = new ConfigurationBuilder()
|
||||||
|
.AddJsonFile("appsettings.Tests.json")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var dbConnection = configuration.GetSection("DbConnection").Get<DbConnection>()!;
|
||||||
|
connectionString = dbConnection.GetConnectionString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
||||||
|
{
|
||||||
|
builder.ConfigureServices(services =>
|
||||||
|
{
|
||||||
|
var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<PersistenceDbContext>));
|
||||||
|
|
||||||
|
if (descriptor != null)
|
||||||
|
services.Remove(descriptor);
|
||||||
|
|
||||||
|
services.AddDbContext<PersistenceDbContext>(options =>
|
||||||
|
options.UseNpgsql(connectionString));
|
||||||
|
|
||||||
|
var serviceProvider = services.BuildServiceProvider();
|
||||||
|
|
||||||
|
using var scope = serviceProvider.CreateScope();
|
||||||
|
var scopedServices = scope.ServiceProvider;
|
||||||
|
var dbContext = scopedServices.GetRequiredService<PersistenceDbContext>();
|
||||||
|
|
||||||
|
//dbContext.Database.EnsureCreatedAndMigrated();
|
||||||
|
//dbContext.Deposits.AddRange(Data.Defaults.Deposits);
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async ValueTask DisposeAsync()
|
||||||
|
{
|
||||||
|
var dbContext = new PersistenceDbContext(
|
||||||
|
new DbContextOptionsBuilder<PersistenceDbContext>()
|
||||||
|
.UseNpgsql(connectionString)
|
||||||
|
.Options);
|
||||||
|
|
||||||
|
await dbContext.Database.EnsureDeletedAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T GetHttpClient<T>(string uriSuffix)
|
||||||
|
{
|
||||||
|
var httpClient = CreateClient();
|
||||||
|
if (string.IsNullOrEmpty(uriSuffix))
|
||||||
|
return RestService.For<T>(httpClient, RefitSettings);
|
||||||
|
|
||||||
|
if (httpClient.BaseAddress is not null)
|
||||||
|
httpClient.BaseAddress = new Uri(httpClient.BaseAddress, uriSuffix);
|
||||||
|
|
||||||
|
return RestService.For<T>(httpClient, RefitSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
//public T GetAuthorizedHttpClient<T>(string uriSuffix)
|
||||||
|
//{
|
||||||
|
// var httpClient = GetAuthorizedHttpClient();
|
||||||
|
// if (string.IsNullOrEmpty(uriSuffix))
|
||||||
|
// return RestService.For<T>(httpClient, RefitSettings);
|
||||||
|
|
||||||
|
// if (httpClient.BaseAddress is not null)
|
||||||
|
// httpClient.BaseAddress = new Uri(httpClient.BaseAddress, uriSuffix);
|
||||||
|
|
||||||
|
// return RestService.For<T>(httpClient, RefitSettings);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//private HttpClient GetAuthorizedHttpClient()
|
||||||
|
//{
|
||||||
|
// var httpClient = CreateClient();
|
||||||
|
// var jwtToken = ApiTokenHelper.GetAdminUserToken();
|
||||||
|
// httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken);
|
||||||
|
// return httpClient;
|
||||||
|
//}
|
||||||
|
}
|
46
Persistence.Repository/Data/DataSaubDto.cs
Normal file
46
Persistence.Repository/Data/DataSaubDto.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using Persistence.Models;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Persistence.Repository.Data;
|
||||||
|
public class DataSaubDto : ITimeSeriesAbstractDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public DateTimeOffset Date { get; set; } = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
|
public int? Mode { get; set; }
|
||||||
|
|
||||||
|
public string? User { get; set; }
|
||||||
|
|
||||||
|
public double? WellDepth { get; set; }
|
||||||
|
|
||||||
|
public double? BitDepth { get; set; }
|
||||||
|
|
||||||
|
public double? BlockPosition { get; set; }
|
||||||
|
|
||||||
|
public double? BlockSpeed { get; set; }
|
||||||
|
|
||||||
|
public double? Pressure { get; set; }
|
||||||
|
|
||||||
|
public double? AxialLoad { get; set; }
|
||||||
|
|
||||||
|
public double? HookWeight { get; set; }
|
||||||
|
|
||||||
|
public double? RotorTorque { get; set; }
|
||||||
|
|
||||||
|
public double? RotorSpeed { get; set; }
|
||||||
|
|
||||||
|
public double? Flow { get; set; }
|
||||||
|
|
||||||
|
public short MseState { get; set; }
|
||||||
|
|
||||||
|
public int IdFeedRegulator { get; set; }
|
||||||
|
|
||||||
|
public double? Mse { get; set; }
|
||||||
|
|
||||||
|
public double? Pump0Flow { get; set; }
|
||||||
|
|
||||||
|
public double? Pump1Flow { get; set; }
|
||||||
|
|
||||||
|
public double? Pump2Flow { get; set; }
|
||||||
|
}
|
30
Persistence.Repository/DependencyInjection.cs
Normal file
30
Persistence.Repository/DependencyInjection.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Persistence.Repositories;
|
||||||
|
using Persistence.Database.Model;
|
||||||
|
using Persistence.Repository.Data;
|
||||||
|
using Persistence.Repository.Repositories;
|
||||||
|
|
||||||
|
namespace Persistence.Repository;
|
||||||
|
public static class DependencyInjection
|
||||||
|
{
|
||||||
|
public static void MapsterSetup()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
MapsterSetup();
|
||||||
|
|
||||||
|
string connectionStringName = "DefaultConnection";
|
||||||
|
|
||||||
|
services.AddDbContext<PersistenceDbContext>(options =>
|
||||||
|
options.UseNpgsql(configuration.GetConnectionString(connectionStringName)));
|
||||||
|
|
||||||
|
services.AddScoped<IPersistenceDbContext>(provider => provider.GetRequiredService<PersistenceDbContext>());
|
||||||
|
|
||||||
|
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataRepository<DataSaub, DataSaubDto>>();
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
}
|
18
Persistence.Repository/Persistence.Repository.csproj
Normal file
18
Persistence.Repository/Persistence.Repository.csproj
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Persistence.Database\Persistence.Database.csproj" />
|
||||||
|
<ProjectReference Include="..\Persistence\Persistence.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -0,0 +1,50 @@
|
|||||||
|
using Mapster;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Persistence.Models;
|
||||||
|
using Persistence.Repositories;
|
||||||
|
using Persistence.Database.Model;
|
||||||
|
using Persistence.Repository.Data;
|
||||||
|
|
||||||
|
namespace Persistence.Repository.Repositories;
|
||||||
|
public abstract class TimeSeriesDataRepository<TEntity, TDto> : ITimeSeriesDataRepository<TDto>
|
||||||
|
where TEntity : class
|
||||||
|
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||||
|
{
|
||||||
|
private DbContext db;
|
||||||
|
|
||||||
|
public TimeSeriesDataRepository(DbContext db)
|
||||||
|
{
|
||||||
|
this.db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual IQueryable<TEntity> GetQueryReadOnly() => db.Set<TEntity>();
|
||||||
|
|
||||||
|
public async Task<IEnumerable<TDto>> GetAsync(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token)
|
||||||
|
{
|
||||||
|
var query = GetQueryReadOnly();
|
||||||
|
var entities = await query.ToArrayAsync(token);
|
||||||
|
var dtos = entities.Select(e => e.Adapt<TDto>());
|
||||||
|
|
||||||
|
return dtos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<IEnumerable<TDto>> GetGtDate(DateTimeOffset date, CancellationToken token)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> InsertRange(IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
|
{
|
||||||
|
var entities = dtos.Select(d => d.Adapt<TEntity>());
|
||||||
|
|
||||||
|
await db.Set<TEntity>().AddRangeAsync(entities, token);
|
||||||
|
var result = await db.SaveChangesAsync(token);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
19
Persistence.Repository/Startup.cs
Normal file
19
Persistence.Repository/Startup.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Persistence.Database;
|
||||||
|
using Persistence.Database.Model;
|
||||||
|
|
||||||
|
namespace Persistence.Repository;
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public static void BeforeRunHandler(IHost host)
|
||||||
|
{
|
||||||
|
using var scope = host.Services.CreateScope();
|
||||||
|
var provider = scope.ServiceProvider;
|
||||||
|
|
||||||
|
var context = provider.GetRequiredService<DbContext>();
|
||||||
|
context.Database.EnsureCreatedAndMigrated();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.9.34714.143
|
VisualStudioVersion = 17.9.34714.143
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Persistence", "Persistence\Persistence.csproj", "{417177AE-A27E-445B-B3B9-D5EFCEC812A0}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Persistence", "Persistence\Persistence.csproj", "{417177AE-A27E-445B-B3B9-D5EFCEC812A0}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Persistence.API", "Persistence.API\Persistence.API.csproj", "{8650A227-929E-45F0-AEF7-2C91F45FE884}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Persistence.Repository", "Persistence.Repository\Persistence.Repository.csproj", "{493D6D92-231B-4CB6-831B-BE13884B0DE4}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Persistence.Database", "Persistence.Database\Persistence.Database.csproj", "{F77475D1-D074-407A-9D69-2FADDDAE2056}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Persistence.IntegrationTests", "Persistence.IntegrationTests\Persistence.IntegrationTests.csproj", "{10752C25-3773-4081-A1F2-215A1D950126}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@ -15,6 +23,22 @@ Global
|
|||||||
{417177AE-A27E-445B-B3B9-D5EFCEC812A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{417177AE-A27E-445B-B3B9-D5EFCEC812A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{417177AE-A27E-445B-B3B9-D5EFCEC812A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{417177AE-A27E-445B-B3B9-D5EFCEC812A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{417177AE-A27E-445B-B3B9-D5EFCEC812A0}.Release|Any CPU.Build.0 = Release|Any CPU
|
{417177AE-A27E-445B-B3B9-D5EFCEC812A0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{8650A227-929E-45F0-AEF7-2C91F45FE884}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{8650A227-929E-45F0-AEF7-2C91F45FE884}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{8650A227-929E-45F0-AEF7-2C91F45FE884}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{8650A227-929E-45F0-AEF7-2C91F45FE884}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{493D6D92-231B-4CB6-831B-BE13884B0DE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{493D6D92-231B-4CB6-831B-BE13884B0DE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{493D6D92-231B-4CB6-831B-BE13884B0DE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{493D6D92-231B-4CB6-831B-BE13884B0DE4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{F77475D1-D074-407A-9D69-2FADDDAE2056}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{F77475D1-D074-407A-9D69-2FADDDAE2056}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{F77475D1-D074-407A-9D69-2FADDDAE2056}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{F77475D1-D074-407A-9D69-2FADDDAE2056}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{10752C25-3773-4081-A1F2-215A1D950126}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{10752C25-3773-4081-A1F2-215A1D950126}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{10752C25-3773-4081-A1F2-215A1D950126}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{10752C25-3773-4081-A1F2-215A1D950126}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -6,7 +6,7 @@ namespace Persistence.API;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс для работы с API журнала изменений
|
/// Интерфейс для работы с API журнала изменений
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IApiChangeLog<TDto, TChangeLogDto>
|
public interface IChangeLogApi<TDto, TChangeLogDto>
|
||||||
where TDto : class, new()
|
where TDto : class, new()
|
||||||
where TChangeLogDto : ChangeLogDto<TDto>
|
where TChangeLogDto : ChangeLogDto<TDto>
|
||||||
{
|
{
|
@ -5,7 +5,7 @@ namespace Persistence.API;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс для API, предназначенного для работы с элементами справочников
|
/// Интерфейс для API, предназначенного для работы с элементами справочников
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IApiDictionaryElement<TDto> where TDto : class, new()
|
public interface IDictionaryElementApi<TDto> where TDto : class, new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить все данные справочника
|
/// Получить все данные справочника
|
@ -6,7 +6,7 @@ namespace Persistence.API;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс для работы с API графиков
|
/// Интерфейс для работы с API графиков
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IGraphData<TDto>
|
public interface IGraphDataApi<TDto>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить список объектов с прореживанием, удовлетворящий диапазону дат
|
/// Получить список объектов с прореживанием, удовлетворящий диапазону дат
|
@ -6,7 +6,7 @@ namespace Persistence.API;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс для API, предназначенного для работы с уставками
|
/// Интерфейс для API, предназначенного для работы с уставками
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IApiSetpoint
|
public interface ISetpointApi
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить актуальные значения уставок
|
/// Получить актуальные значения уставок
|
@ -6,7 +6,7 @@ namespace Persistence.API;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс для API, предназначенного для синхронизации данных
|
/// Интерфейс для API, предназначенного для синхронизации данных
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IApiSync<TDto> where TDto : class, new()
|
public interface ISyncApi<TDto> where TDto : class, new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить порцию записей, начиная с заданной даты
|
/// Получить порцию записей, начиная с заданной даты
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
|||||||
namespace Persistence.API;
|
namespace Persistence.API;
|
||||||
|
|
||||||
/// Интерфейс для API, предназначенного для работы с табличными данными
|
/// Интерфейс для API, предназначенного для работы с табличными данными
|
||||||
public interface IApiTableData<TDto, TRequest>
|
public interface ITableDataApi<TDto, TRequest>
|
||||||
where TDto : class, new()
|
where TDto : class, new()
|
||||||
where TRequest : RequestDto
|
where TRequest : RequestDto
|
||||||
{
|
{
|
@ -11,24 +11,24 @@ namespace Persistence.API;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Интерфейс для работы с API временных данных
|
/// Интерфейс для работы с API временных данных
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IApiTimeSeriesData<TDto>
|
public interface ITimeSeriesDataApi<TDto>
|
||||||
where TDto : class, new()
|
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить спискок объектов, удовлетворяющий диапазон дат
|
/// Получить список объектов, удовлетворяющий диапазон дат
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dateBegin">дата начала</param>
|
/// <param name="dateBegin">дата начала</param>
|
||||||
/// <param name="dateEnd">дата окончания</param>
|
/// <param name="dateEnd">дата окончания</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<ActionResult<IEnumerable<TDto>>> GetAsync(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token);
|
Task<IActionResult> GetAsync(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить диапазон дат, для которых есть данные в репозитории
|
/// Получить диапазон дат, для которых есть данные в репозитории
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<ActionResult<DatesRangeDto>> GetDatesRangeAsync(CancellationToken token);
|
Task<IActionResult> GetDatesRangeAsync(CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавление записей
|
/// Добавление записей
|
||||||
@ -36,7 +36,7 @@ public interface IApiTimeSeriesData<TDto>
|
|||||||
/// <param name="dtos"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<ActionResult<int>> InsertRange(IEnumerable<TDto> dtos, CancellationToken token);
|
Task<IActionResult> InsertRangeAsync(IEnumerable<TDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -4,162 +4,162 @@ using Persistence.Models;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Persistence.Repositories;
|
namespace Persistence.Repositories;
|
||||||
public abstract class AbstractChangeLogRepository<TEntity, TChangeLogDto, TDto> : IChangeLogRepository<TDto, TChangeLogDto>
|
//public abstract class AbstractChangeLogRepository<TEntity, TChangeLogDto, TDto> : IChangeLogRepository<TDto, TChangeLogDto>
|
||||||
where TDto : class, new()
|
// where TDto : class, new()
|
||||||
where TEntity : class, IChangeLogAbstract
|
// where TEntity : class, IChangeLogAbstract
|
||||||
where TChangeLogDto : ChangeLogDto<TDto>
|
// where TChangeLogDto : ChangeLogDto<TDto>
|
||||||
{
|
//{
|
||||||
private readonly DbContext dbContext;
|
// private readonly DbContext dbContext;
|
||||||
|
|
||||||
protected AbstractChangeLogRepository(DbContext dbContext)
|
// protected AbstractChangeLogRepository(DbContext dbContext)
|
||||||
{
|
// {
|
||||||
this.dbContext = dbContext;
|
// this.dbContext = dbContext;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public abstract TEntity Convert(TDto entity);
|
// public abstract TEntity Convert(TDto entity);
|
||||||
public async Task<int> Clear(int idUser,CancellationToken token)
|
// public async Task<int> Clear(int idUser,CancellationToken token)
|
||||||
{
|
// {
|
||||||
throw new NotImplementedException();
|
// throw new NotImplementedException();
|
||||||
|
|
||||||
//var updateTime = DateTimeOffset.UtcNow;
|
// //var updateTime = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
////todo
|
// ////todo
|
||||||
//var query = BuildQuery(request);
|
// //var query = BuildQuery(request);
|
||||||
//query = query.Where(e => e.Obsolete == null);
|
// //query = query.Where(e => e.Obsolete == null);
|
||||||
|
|
||||||
//var entitiesToDelete = await query.ToArrayAsync(token);
|
// //var entitiesToDelete = await query.ToArrayAsync(token);
|
||||||
|
|
||||||
//foreach (var entity in entitiesToDelete)
|
// //foreach (var entity in entitiesToDelete)
|
||||||
//{
|
// //{
|
||||||
// entity.IdState = IChangeLogAbstract.IdCleared;
|
// // entity.IdState = IChangeLogAbstract.IdCleared;
|
||||||
// entity.Obsolete = updateTime;
|
// // entity.Obsolete = updateTime;
|
||||||
// entity.IdEditor = idUser;
|
// // entity.IdEditor = idUser;
|
||||||
//}
|
// //}
|
||||||
|
|
||||||
//var result = await SaveChangesWithExceptionHandling(token);
|
// //var result = await SaveChangesWithExceptionHandling(token);
|
||||||
//return result;
|
// //return result;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public async Task<int> ClearAndInsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
// public async Task<int> ClearAndInsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
{
|
// {
|
||||||
var result = 0;
|
// var result = 0;
|
||||||
using var transaction = await dbContext.Database.BeginTransactionAsync(token);
|
// using var transaction = await dbContext.Database.BeginTransactionAsync(token);
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
result += await Clear(idUser, token);
|
// result += await Clear(idUser, token);
|
||||||
result += await InsertRangeWithoutTransaction(idUser, dtos, token);
|
// result += await InsertRangeWithoutTransaction(idUser, dtos, token);
|
||||||
|
|
||||||
await transaction.CommitAsync(token);
|
// await transaction.CommitAsync(token);
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
catch
|
// catch
|
||||||
{
|
// {
|
||||||
await transaction.RollbackAsync(token);
|
// await transaction.RollbackAsync(token);
|
||||||
throw;
|
// throw;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
public Task<IEnumerable<TDto>> GetCurrent(DateTimeOffset moment, CancellationToken token)
|
// public Task<IEnumerable<TDto>> GetCurrent(DateTimeOffset moment, CancellationToken token)
|
||||||
{
|
// {
|
||||||
throw new NotImplementedException();
|
// throw new NotImplementedException();
|
||||||
}
|
// }
|
||||||
|
|
||||||
public Task<IEnumerable<DateOnly>> GetDatesChange(CancellationToken token)
|
// public Task<IEnumerable<DateOnly>> GetDatesChange(CancellationToken token)
|
||||||
{
|
// {
|
||||||
throw new NotImplementedException();
|
// throw new NotImplementedException();
|
||||||
}
|
// }
|
||||||
|
|
||||||
public Task<IEnumerable<TDto>> GetGtDate(DateTimeOffset date, CancellationToken token)
|
// public Task<IEnumerable<TDto>> GetGtDate(DateTimeOffset date, CancellationToken token)
|
||||||
{
|
// {
|
||||||
throw new NotImplementedException();
|
// throw new NotImplementedException();
|
||||||
}
|
// }
|
||||||
|
|
||||||
public async Task<int> InsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
// public async Task<int> InsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
{
|
// {
|
||||||
using var transaction = dbContext.Database.BeginTransaction();
|
// using var transaction = dbContext.Database.BeginTransaction();
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
var result = await InsertRangeWithoutTransaction(idUser, dtos, token);
|
// var result = await InsertRangeWithoutTransaction(idUser, dtos, token);
|
||||||
await transaction.CommitAsync(token);
|
// await transaction.CommitAsync(token);
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
catch
|
// catch
|
||||||
{
|
// {
|
||||||
await transaction.RollbackAsync(token);
|
// await transaction.RollbackAsync(token);
|
||||||
throw;
|
// throw;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
protected abstract DatabaseFacade GetDataBase();
|
// protected abstract DatabaseFacade GetDataBase();
|
||||||
|
|
||||||
public Task<int> MarkAsDeleted(int idUser, IEnumerable<int> ids, CancellationToken token)
|
// public Task<int> MarkAsDeleted(int idUser, IEnumerable<int> ids, CancellationToken token)
|
||||||
{
|
// {
|
||||||
throw new NotImplementedException();
|
// throw new NotImplementedException();
|
||||||
}
|
// }
|
||||||
|
|
||||||
public Task<int> UpdateOrInsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
// public Task<int> UpdateOrInsertRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
{
|
// {
|
||||||
throw new NotImplementedException();
|
// throw new NotImplementedException();
|
||||||
}
|
// }
|
||||||
|
|
||||||
public Task<int> UpdateRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
// public Task<int> UpdateRange(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
{
|
// {
|
||||||
throw new NotImplementedException();
|
// throw new NotImplementedException();
|
||||||
}
|
// }
|
||||||
|
|
||||||
public Task<IEnumerable<TChangeLogDto>> GetChangeLogForDate(DateTimeOffset? updateFrom, CancellationToken token)
|
// public Task<IEnumerable<TChangeLogDto>> GetChangeLogForDate(DateTimeOffset? updateFrom, CancellationToken token)
|
||||||
{
|
// {
|
||||||
throw new NotImplementedException();
|
// throw new NotImplementedException();
|
||||||
}
|
// }
|
||||||
|
|
||||||
private async Task<int> InsertRangeWithoutTransaction(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
// private async Task<int> InsertRangeWithoutTransaction(int idUser, IEnumerable<TDto> dtos, CancellationToken token)
|
||||||
{
|
// {
|
||||||
var result = 0;
|
// var result = 0;
|
||||||
if (dtos.Any())
|
// if (dtos.Any())
|
||||||
{
|
// {
|
||||||
var entities = dtos.Select(Convert);
|
// var entities = dtos.Select(Convert);
|
||||||
var creation = DateTimeOffset.UtcNow;
|
// var creation = DateTimeOffset.UtcNow;
|
||||||
var dbSet = dbContext.Set<TEntity>();
|
// var dbSet = dbContext.Set<TEntity>();
|
||||||
foreach (var entity in entities)
|
// foreach (var entity in entities)
|
||||||
{
|
// {
|
||||||
entity.Id = default;
|
// entity.Id = default;
|
||||||
entity.IdAuthor = idUser;
|
// entity.IdAuthor = idUser;
|
||||||
entity.Creation = creation;
|
// entity.Creation = creation;
|
||||||
entity.IdState = IChangeLogAbstract.IdStateActual;
|
// entity.IdState = IChangeLogAbstract.IdStateActual;
|
||||||
entity.IdEditor = null;
|
// entity.IdEditor = null;
|
||||||
entity.IdPrevious = null;
|
// entity.IdPrevious = null;
|
||||||
entity.Obsolete = null;
|
// entity.Obsolete = null;
|
||||||
dbSet.Add(entity);
|
// dbSet.Add(entity);
|
||||||
}
|
// }
|
||||||
|
|
||||||
result += await SaveChangesWithExceptionHandling(token);
|
// result += await SaveChangesWithExceptionHandling(token);
|
||||||
}
|
// }
|
||||||
|
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
|
|
||||||
private async Task<int> SaveChangesWithExceptionHandling(CancellationToken token)
|
// private async Task<int> SaveChangesWithExceptionHandling(CancellationToken token)
|
||||||
{
|
// {
|
||||||
var result = await dbContext.SaveChangesAsync(token);
|
// var result = await dbContext.SaveChangesAsync(token);
|
||||||
return result;
|
// return result;
|
||||||
//try
|
// //try
|
||||||
//{
|
// //{
|
||||||
// var result = await dbContext.SaveChangesAsync(token);
|
// // var result = await dbContext.SaveChangesAsync(token);
|
||||||
// return result;
|
// // return result;
|
||||||
//}
|
// //}
|
||||||
//catch (DbUpdateException ex)
|
// //catch (DbUpdateException ex)
|
||||||
//{
|
// //{
|
||||||
// if (ex.InnerException is PostgresException pgException)
|
// // if (ex.InnerException is PostgresException pgException)
|
||||||
// TryConvertPostgresExceptionToValidateException(pgException);
|
// // TryConvertPostgresExceptionToValidateException(pgException);
|
||||||
// throw;
|
// // throw;
|
||||||
//}
|
// //}
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//private static void TryConvertPostgresExceptionToValidateException(PostgresException pgException)
|
// //private static void TryConvertPostgresExceptionToValidateException(PostgresException pgException)
|
||||||
//{
|
// //{
|
||||||
// if (pgException.SqlState == PostgresErrorCodes.ForeignKeyViolation)
|
// // if (pgException.SqlState == PostgresErrorCodes.ForeignKeyViolation)
|
||||||
// throw new ArgumentInvalidException("dtos", pgException.Message + "\r\n" + pgException.Detail);
|
// // throw new ArgumentInvalidException("dtos", pgException.Message + "\r\n" + pgException.Detail);
|
||||||
//}
|
// //}
|
||||||
}
|
//}
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Persistence.Models;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Persistence.Repositories;
|
|
||||||
public abstract class AbstractTimeSeriesDataRepository<TEntity, TDto> : ITimeSeriesDataRepository<TDto>
|
|
||||||
where TDto : class, ITimeSeriesAbstractDto
|
|
||||||
where TEntity : class, IChangeLogAbstract
|
|
||||||
{
|
|
||||||
private readonly DbContext dbContext;
|
|
||||||
|
|
||||||
protected AbstractTimeSeriesDataRepository(DbContext dbContext)
|
|
||||||
{
|
|
||||||
this.dbContext = dbContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<IEnumerable<TDto>> GetAsync(DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<DatesRangeDto> GetDatesRangeAsync(CancellationToken token)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<IEnumerable<TDto>> GetGtDate(DateTimeOffset date, CancellationToken token)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<int> InsertRange(IEnumerable<TDto> dtos, CancellationToken token)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,7 +7,7 @@ namespace Persistence.Repositories;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TDto"></typeparam>
|
/// <typeparam name="TDto"></typeparam>
|
||||||
public interface IChangeLogRepository<TDto, TChangeLogDto> : ISyncRepository<TDto>
|
public interface IChangeLogRepository<TDto, TChangeLogDto> : ISyncRepository<TDto>
|
||||||
where TDto : class
|
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||||
where TChangeLogDto : ChangeLogDto<TDto>
|
where TChangeLogDto : ChangeLogDto<TDto>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TDto"></typeparam>
|
/// <typeparam name="TDto"></typeparam>
|
||||||
public interface ISyncRepository<TDto>
|
public interface ISyncRepository<TDto>
|
||||||
|
where TDto : class, new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить данные, начиная с определенной даты
|
/// Получить данные, начиная с определенной даты
|
||||||
|
@ -7,7 +7,7 @@ namespace Persistence.Repositories;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TDto"></typeparam>
|
/// <typeparam name="TDto"></typeparam>
|
||||||
public interface ITimeSeriesDataRepository<TDto> : ISyncRepository<TDto>
|
public interface ITimeSeriesDataRepository<TDto> : ISyncRepository<TDto>
|
||||||
where TDto : class, ITimeSeriesAbstractDto
|
where TDto : class, ITimeSeriesAbstractDto, new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить страницу списка объектов
|
/// Получить страницу списка объектов
|
||||||
|
Loading…
Reference in New Issue
Block a user