diff --git a/DD.Persistence.API/Startup.cs b/DD.Persistence.API/Startup.cs
index a3c3efe..f19e6cf 100644
--- a/DD.Persistence.API/Startup.cs
+++ b/DD.Persistence.API/Startup.cs
@@ -14,7 +14,7 @@ public class Startup
public void ConfigureServices(IServiceCollection services)
{
- // Add services to the container.
+ // AddRange services to the container.
services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
diff --git a/DD.Persistence.Database.Postgres/Migrations/20250204044050_Init.Designer.cs b/DD.Persistence.Database.Postgres/Migrations/20250205114037_Init.Designer.cs
similarity index 88%
rename from DD.Persistence.Database.Postgres/Migrations/20250204044050_Init.Designer.cs
rename to DD.Persistence.Database.Postgres/Migrations/20250205114037_Init.Designer.cs
index 60e6e92..b90d452 100644
--- a/DD.Persistence.Database.Postgres/Migrations/20250204044050_Init.Designer.cs
+++ b/DD.Persistence.Database.Postgres/Migrations/20250205114037_Init.Designer.cs
@@ -13,7 +13,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace DD.Persistence.Database.Postgres.Migrations
{
[DbContext(typeof(PersistencePostgresContext))]
- [Migration("20250204044050_Init")]
+ [Migration("20250205114037_Init")]
partial class Init
{
///
@@ -67,28 +67,6 @@ namespace DD.Persistence.Database.Postgres.Migrations
b.ToTable("change_log");
});
- modelBuilder.Entity("DD.Persistence.Database.Entity.DataScheme", b =>
- {
- b.Property("DiscriminatorId")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid")
- .HasComment("Идентификатор схемы данных");
-
- b.Property("PropNames")
- .IsRequired()
- .HasColumnType("jsonb")
- .HasComment("Наименования полей в порядке индексации");
-
- b.PrimitiveCollection("PropTypes")
- .IsRequired()
- .HasColumnType("integer[]")
- .HasComment("Типы полей в порядке индексации");
-
- b.HasKey("DiscriminatorId");
-
- b.ToTable("data_scheme");
- });
-
modelBuilder.Entity("DD.Persistence.Database.Entity.DataSourceSystem", b =>
{
b.Property("SystemId")
@@ -134,6 +112,30 @@ namespace DD.Persistence.Database.Postgres.Migrations
b.ToTable("parameter_data");
});
+ modelBuilder.Entity("DD.Persistence.Database.Entity.SchemeProperty", b =>
+ {
+ b.Property("DiscriminatorId")
+ .HasColumnType("uuid")
+ .HasComment("Идентификатор схемы данных");
+
+ b.Property("Index")
+ .HasColumnType("integer")
+ .HasComment("Индекс поля");
+
+ b.Property("PropertyKind")
+ .HasColumnType("smallint")
+ .HasComment("Тип индексируемого поля");
+
+ b.Property("PropertyName")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasComment("Наименования индексируемого поля");
+
+ b.HasKey("DiscriminatorId", "Index");
+
+ b.ToTable("scheme_property");
+ });
+
modelBuilder.Entity("DD.Persistence.Database.Entity.Setpoint", b =>
{
b.Property("Key")
@@ -222,17 +224,6 @@ namespace DD.Persistence.Database.Postgres.Migrations
b.Navigation("System");
});
-
- modelBuilder.Entity("DD.Persistence.Database.Entity.TimestampedValues", b =>
- {
- b.HasOne("DD.Persistence.Database.Entity.DataScheme", "DataScheme")
- .WithMany()
- .HasForeignKey("DiscriminatorId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("DataScheme");
- });
#pragma warning restore 612, 618
}
}
diff --git a/DD.Persistence.Database.Postgres/Migrations/20250204044050_Init.cs b/DD.Persistence.Database.Postgres/Migrations/20250205114037_Init.cs
similarity index 90%
rename from DD.Persistence.Database.Postgres/Migrations/20250204044050_Init.cs
rename to DD.Persistence.Database.Postgres/Migrations/20250205114037_Init.cs
index 24a310d..c872547 100644
--- a/DD.Persistence.Database.Postgres/Migrations/20250204044050_Init.cs
+++ b/DD.Persistence.Database.Postgres/Migrations/20250205114037_Init.cs
@@ -30,19 +30,6 @@ namespace DD.Persistence.Database.Postgres.Migrations
table.PrimaryKey("PK_change_log", x => x.Id);
});
- migrationBuilder.CreateTable(
- name: "data_scheme",
- columns: table => new
- {
- DiscriminatorId = table.Column(type: "uuid", nullable: false, comment: "Идентификатор схемы данных"),
- PropNames = table.Column(type: "jsonb", nullable: false, comment: "Наименования полей в порядке индексации"),
- PropTypes = table.Column(type: "integer[]", nullable: false, comment: "Типы полей в порядке индексации")
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_data_scheme", x => x.DiscriminatorId);
- });
-
migrationBuilder.CreateTable(
name: "data_source_system",
columns: table => new
@@ -70,6 +57,20 @@ namespace DD.Persistence.Database.Postgres.Migrations
table.PrimaryKey("PK_parameter_data", x => new { x.DiscriminatorId, x.ParameterId, x.Timestamp });
});
+ migrationBuilder.CreateTable(
+ name: "scheme_property",
+ columns: table => new
+ {
+ DiscriminatorId = table.Column(type: "uuid", nullable: false, comment: "Идентификатор схемы данных"),
+ Index = table.Column(type: "integer", nullable: false, comment: "Индекс поля"),
+ PropertyName = table.Column(type: "text", nullable: false, comment: "Наименования индексируемого поля"),
+ PropertyKind = table.Column(type: "smallint", nullable: false, comment: "Тип индексируемого поля")
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_scheme_property", x => new { x.DiscriminatorId, x.Index });
+ });
+
migrationBuilder.CreateTable(
name: "setpoint",
columns: table => new
@@ -95,12 +96,6 @@ namespace DD.Persistence.Database.Postgres.Migrations
constraints: table =>
{
table.PrimaryKey("PK_timestamped_values", x => new { x.DiscriminatorId, x.Timestamp });
- table.ForeignKey(
- name: "FK_timestamped_values_data_scheme_DiscriminatorId",
- column: x => x.DiscriminatorId,
- principalTable: "data_scheme",
- principalColumn: "DiscriminatorId",
- onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
@@ -140,6 +135,9 @@ namespace DD.Persistence.Database.Postgres.Migrations
migrationBuilder.DropTable(
name: "parameter_data");
+ migrationBuilder.DropTable(
+ name: "scheme_property");
+
migrationBuilder.DropTable(
name: "setpoint");
@@ -151,9 +149,6 @@ namespace DD.Persistence.Database.Postgres.Migrations
migrationBuilder.DropTable(
name: "data_source_system");
-
- migrationBuilder.DropTable(
- name: "data_scheme");
}
}
}
diff --git a/DD.Persistence.Database.Postgres/Migrations/PersistencePostgresContextModelSnapshot.cs b/DD.Persistence.Database.Postgres/Migrations/PersistencePostgresContextModelSnapshot.cs
index ca319a5..e2b0921 100644
--- a/DD.Persistence.Database.Postgres/Migrations/PersistencePostgresContextModelSnapshot.cs
+++ b/DD.Persistence.Database.Postgres/Migrations/PersistencePostgresContextModelSnapshot.cs
@@ -64,28 +64,6 @@ namespace DD.Persistence.Database.Postgres.Migrations
b.ToTable("change_log");
});
- modelBuilder.Entity("DD.Persistence.Database.Entity.DataScheme", b =>
- {
- b.Property("DiscriminatorId")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid")
- .HasComment("Идентификатор схемы данных");
-
- b.Property("PropNames")
- .IsRequired()
- .HasColumnType("jsonb")
- .HasComment("Наименования полей в порядке индексации");
-
- b.PrimitiveCollection("PropTypes")
- .IsRequired()
- .HasColumnType("integer[]")
- .HasComment("Типы полей в порядке индексации");
-
- b.HasKey("DiscriminatorId");
-
- b.ToTable("data_scheme");
- });
-
modelBuilder.Entity("DD.Persistence.Database.Entity.DataSourceSystem", b =>
{
b.Property("SystemId")
@@ -131,6 +109,30 @@ namespace DD.Persistence.Database.Postgres.Migrations
b.ToTable("parameter_data");
});
+ modelBuilder.Entity("DD.Persistence.Database.Entity.SchemeProperty", b =>
+ {
+ b.Property("DiscriminatorId")
+ .HasColumnType("uuid")
+ .HasComment("Идентификатор схемы данных");
+
+ b.Property("Index")
+ .HasColumnType("integer")
+ .HasComment("Индекс поля");
+
+ b.Property("PropertyKind")
+ .HasColumnType("smallint")
+ .HasComment("Тип индексируемого поля");
+
+ b.Property("PropertyName")
+ .IsRequired()
+ .HasColumnType("text")
+ .HasComment("Наименования индексируемого поля");
+
+ b.HasKey("DiscriminatorId", "Index");
+
+ b.ToTable("scheme_property");
+ });
+
modelBuilder.Entity("DD.Persistence.Database.Entity.Setpoint", b =>
{
b.Property("Key")
@@ -219,17 +221,6 @@ namespace DD.Persistence.Database.Postgres.Migrations
b.Navigation("System");
});
-
- modelBuilder.Entity("DD.Persistence.Database.Entity.TimestampedValues", b =>
- {
- b.HasOne("DD.Persistence.Database.Entity.DataScheme", "DataScheme")
- .WithMany()
- .HasForeignKey("DiscriminatorId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("DataScheme");
- });
#pragma warning restore 612, 618
}
}
diff --git a/DD.Persistence.Database/DependencyInjection.cs b/DD.Persistence.Database/DependencyInjection.cs
index c04d9e5..ca140d8 100644
--- a/DD.Persistence.Database/DependencyInjection.cs
+++ b/DD.Persistence.Database/DependencyInjection.cs
@@ -2,6 +2,7 @@
using DD.Persistence.Database.Postgres.Repositories;
using DD.Persistence.Database.Postgres.RepositoriesCached;
using DD.Persistence.Database.Repositories;
+using DD.Persistence.Database.RepositoriesCached;
using DD.Persistence.Models;
using DD.Persistence.Repositories;
using Mapster;
@@ -24,6 +25,12 @@ public static class DependencyInjection
Value = src.Value,
Id = src.Id
});
+
+ TypeAdapterConfig, SchemeProperty>.NewConfig()
+ .Map(dest => dest.DiscriminatorId, src => src.Key)
+ .Map(dest => dest.Index, src => src.Value.Index)
+ .Map(dest => dest.PropertyKind, src => src.Value.PropertyKind)
+ .Map(dest => dest.PropertyName, src => src.Value.PropertyName);
}
public static IServiceCollection AddInfrastructure(this IServiceCollection services)
@@ -40,7 +47,7 @@ public static class DependencyInjection
services.AddTransient();
services.AddTransient();
services.AddTransient();
- services.AddTransient();
+ services.AddTransient();
return services;
}
diff --git a/DD.Persistence.Database/Entity/DataScheme.cs b/DD.Persistence.Database/Entity/SchemeProperty.cs
similarity index 71%
rename from DD.Persistence.Database/Entity/DataScheme.cs
rename to DD.Persistence.Database/Entity/SchemeProperty.cs
index 3ce46a2..6ef5bdb 100644
--- a/DD.Persistence.Database/Entity/DataScheme.cs
+++ b/DD.Persistence.Database/Entity/SchemeProperty.cs
@@ -1,12 +1,13 @@
using Microsoft.EntityFrameworkCore;
+using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
namespace DD.Persistence.Database.Entity;
-[Table("prop_scheme")]
+[Table("scheme_property")]
[PrimaryKey(nameof(DiscriminatorId), nameof(Index))]
-public class PropScheme
+public class SchemeProperty
{
[Comment("Идентификатор схемы данных")]
public Guid DiscriminatorId { get; set; }
@@ -15,8 +16,8 @@ public class PropScheme
public int Index { get; set; }
[Comment("Наименования индексируемого поля")]
- public required string PropName { get; set; }
+ public required string PropertyName { get; set; }
[Comment("Тип индексируемого поля")]
- public required JsonValueKind PropKind { get; set; }
+ public required JsonValueKind PropertyKind { get; set; }
}
diff --git a/DD.Persistence.Database/Entity/TimestampedValues.cs b/DD.Persistence.Database/Entity/TimestampedValues.cs
index a2835f7..d28e1cf 100644
--- a/DD.Persistence.Database/Entity/TimestampedValues.cs
+++ b/DD.Persistence.Database/Entity/TimestampedValues.cs
@@ -17,7 +17,4 @@ public class TimestampedValues : ITimestampedItem
[Comment("Данные"), Column(TypeName = "jsonb")]
public required object[] Values { get; set; }
-
- [Required, ForeignKey(nameof(DiscriminatorId)), Comment("Идентификаторы")]
- public virtual DataScheme? DataScheme { get; set; }
}
diff --git a/DD.Persistence.Database/PersistenceDbContext.cs b/DD.Persistence.Database/PersistenceDbContext.cs
index fbbc057..4b0a874 100644
--- a/DD.Persistence.Database/PersistenceDbContext.cs
+++ b/DD.Persistence.Database/PersistenceDbContext.cs
@@ -10,7 +10,7 @@ public class PersistenceDbContext : DbContext
{
public DbSet Setpoint => Set();
- public DbSet DataSchemes => Set();
+ public DbSet SchemeProperty => Set();
public DbSet TimestampedValues => Set();
@@ -30,10 +30,6 @@ public class PersistenceDbContext : DbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
- modelBuilder.Entity()
- .Property(e => e.PropNames)
- .HasJsonConversion();
-
modelBuilder.Entity()
.Property(e => e.Values)
.HasJsonConversion();
diff --git a/DD.Persistence.Database/Repositories/DataSchemeRepository.cs b/DD.Persistence.Database/Repositories/DataSchemeRepository.cs
deleted file mode 100644
index ba5ccd7..0000000
--- a/DD.Persistence.Database/Repositories/DataSchemeRepository.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using DD.Persistence.Database.Entity;
-using DD.Persistence.Models;
-using DD.Persistence.Repositories;
-using Mapster;
-using Microsoft.EntityFrameworkCore;
-
-namespace DD.Persistence.Database.Postgres.Repositories;
-public class DataSchemeRepository : IDataSchemeRepository
-{
- protected DbContext db;
- public DataSchemeRepository(DbContext db)
- {
- this.db = db;
- }
- protected virtual IQueryable GetQueryReadOnly() => db.Set();
-
- public virtual async Task Add(DataSchemeDto dataSourceSystemDto, CancellationToken token)
- {
- var entity = dataSourceSystemDto.Adapt();
-
- await db.Set().AddAsync(entity, token);
- await db.SaveChangesAsync(token);
- }
-
- public virtual async Task Get(Guid dataSchemeId, CancellationToken token)
- {
- var query = GetQueryReadOnly()
- .Where(e => e.DiscriminatorId == dataSchemeId);
- var entity = await query.ToArrayAsync();
- var dto = entity.Select(e => e.Adapt()).FirstOrDefault();
-
- return dto;
- }
-}
diff --git a/DD.Persistence.Database/Repositories/SchemePropertyRepository.cs b/DD.Persistence.Database/Repositories/SchemePropertyRepository.cs
new file mode 100644
index 0000000..26bb8aa
--- /dev/null
+++ b/DD.Persistence.Database/Repositories/SchemePropertyRepository.cs
@@ -0,0 +1,43 @@
+using DD.Persistence.Database.Entity;
+using DD.Persistence.Models;
+using DD.Persistence.Repositories;
+using Mapster;
+using Microsoft.EntityFrameworkCore;
+
+namespace DD.Persistence.Database.Repositories;
+public class SchemePropertyRepository : ISchemePropertyRepository
+{
+ protected DbContext db;
+ public SchemePropertyRepository(DbContext db)
+ {
+ this.db = db;
+ }
+ protected virtual IQueryable GetQueryReadOnly() => db.Set();
+
+ public virtual async Task AddRange(DataSchemeDto dataSchemeDto, CancellationToken token)
+ {
+ var entities = dataSchemeDto.Select(e =>
+ KeyValuePair.Create(dataSchemeDto.DiscriminatorId, e)
+ .Adapt()
+ );
+
+ await db.Set().AddRangeAsync(entities, token);
+ await db.SaveChangesAsync(token);
+ }
+
+ public virtual async Task Get(Guid dataSchemeId, CancellationToken token)
+ {
+ var query = GetQueryReadOnly()
+ .Where(e => e.DiscriminatorId == dataSchemeId);
+ var entities = await query.ToArrayAsync(token);
+
+ DataSchemeDto? result = null;
+ if (entities.Length != 0)
+ {
+ var properties = entities.Select(e => e.Adapt()).ToArray();
+ result = new DataSchemeDto(dataSchemeId, properties);
+ }
+
+ return result;
+ }
+}
diff --git a/DD.Persistence.Database/Repositories/TimestampedValuesRepository.cs b/DD.Persistence.Database/Repositories/TimestampedValuesRepository.cs
index 1239b4a..5f3f60e 100644
--- a/DD.Persistence.Database/Repositories/TimestampedValuesRepository.cs
+++ b/DD.Persistence.Database/Repositories/TimestampedValuesRepository.cs
@@ -14,8 +14,7 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
this.db = db;
}
- protected virtual IQueryable GetQueryReadOnly() => this.db.Set()
- .Include(e => e.DataScheme);
+ protected virtual IQueryable GetQueryReadOnly() => this.db.Set();
public async virtual Task AddRange(Guid discriminatorId, IEnumerable dtos, CancellationToken token)
{
diff --git a/DD.Persistence.Database/RepositoriesCached/DataSchemeCachedRepository.cs b/DD.Persistence.Database/RepositoriesCached/SchemePropertyCachedRepository.cs
similarity index 57%
rename from DD.Persistence.Database/RepositoriesCached/DataSchemeCachedRepository.cs
rename to DD.Persistence.Database/RepositoriesCached/SchemePropertyCachedRepository.cs
index f4cec62..64d9c01 100644
--- a/DD.Persistence.Database/RepositoriesCached/DataSchemeCachedRepository.cs
+++ b/DD.Persistence.Database/RepositoriesCached/SchemePropertyCachedRepository.cs
@@ -1,21 +1,21 @@
using DD.Persistence.Models;
-using DD.Persistence.Database.Postgres.Repositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
+using DD.Persistence.Database.Repositories;
-namespace DD.Persistence.Database.Postgres.RepositoriesCached;
-public class DataSchemeCachedRepository : DataSchemeRepository
+namespace DD.Persistence.Database.RepositoriesCached;
+public class SchemePropertyCachedRepository : SchemePropertyRepository
{
private readonly IMemoryCache memoryCache;
- public DataSchemeCachedRepository(DbContext db, IMemoryCache memoryCache) : base(db)
+ public SchemePropertyCachedRepository(DbContext db, IMemoryCache memoryCache) : base(db)
{
this.memoryCache = memoryCache;
}
- public override async Task Add(DataSchemeDto dataSourceSystemDto, CancellationToken token)
+ public override async Task AddRange(DataSchemeDto dataSourceSystemDto, CancellationToken token)
{
- await base.Add(dataSourceSystemDto, token);
+ await base.AddRange(dataSourceSystemDto, token);
memoryCache.Set(dataSourceSystemDto.DiscriminatorId, dataSourceSystemDto);
}
diff --git a/DD.Persistence.IntegrationTests/Controllers/TimestampedValuesControllerTest.cs b/DD.Persistence.IntegrationTests/Controllers/TimestampedValuesControllerTest.cs
index 526b372..9bb1d58 100644
--- a/DD.Persistence.IntegrationTests/Controllers/TimestampedValuesControllerTest.cs
+++ b/DD.Persistence.IntegrationTests/Controllers/TimestampedValuesControllerTest.cs
@@ -406,8 +406,12 @@ public class TimestampedValuesControllerTest : BaseIntegrationTest
private void Cleanup()
{
+ foreach (var item in discriminatorIds)
+ {
+ memoryCache.Remove(item);
+ }
discriminatorIds = [];
dbContext.CleanupDbSet();
- dbContext.CleanupDbSet();
+ dbContext.CleanupDbSet();
}
}
diff --git a/DD.Persistence.Models/DataSchemeDto.cs b/DD.Persistence.Models/DataSchemeDto.cs
index 7f238aa..d20ffaa 100644
--- a/DD.Persistence.Models/DataSchemeDto.cs
+++ b/DD.Persistence.Models/DataSchemeDto.cs
@@ -1,9 +1,11 @@
-namespace DD.Persistence.Models;
+using System.Collections;
+
+namespace DD.Persistence.Models;
///
/// Схема для набора данных
///
-public class DataSchemeDto
+public class DataSchemeDto : IEnumerable, IEquatable>
{
///
/// Дискриминатор
@@ -11,12 +13,30 @@ public class DataSchemeDto
public Guid DiscriminatorId { get; set; }
///
- /// Наименования полей
+ /// Поля
///
- public string[] PropNames { get; set; } = [];
+ private IEnumerable Properties { get; } = [];
- ///
- /// Типы полей
- ///
- public PropTypeEnum[] PropTypes { get; set; } = [];
+ ///
+ public DataSchemeDto(Guid discriminatorId, SchemePropertyDto[] Properties)
+ {
+ DiscriminatorId = discriminatorId;
+ this.Properties = Properties;
+ }
+
+ ///
+ public IEnumerator GetEnumerator()
+ => Properties.GetEnumerator();
+
+ IEnumerator IEnumerable.GetEnumerator()
+ => GetEnumerator();
+
+ ///
+ public bool Equals(IEnumerable? otherProperties)
+ {
+ //if (otherProperties is null)
+ // return false;
+
+ return Properties.SequenceEqual(otherProperties);
+ }
}
diff --git a/DD.Persistence.Models/Enumerations/PropTypeEnum.cs b/DD.Persistence.Models/Enumerations/PropTypeEnum.cs
deleted file mode 100644
index 5379929..0000000
--- a/DD.Persistence.Models/Enumerations/PropTypeEnum.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace DD.Persistence.Models;
-
-///
-/// Типы для набора данных
-///
-public enum PropTypeEnum
-{
- ///
- String = 0,
- ///
- Double = 1,
- ///
- DateTime = 2
-}
diff --git a/DD.Persistence.Models/SchemePropertyDto.cs b/DD.Persistence.Models/SchemePropertyDto.cs
new file mode 100644
index 0000000..0c34ba7
--- /dev/null
+++ b/DD.Persistence.Models/SchemePropertyDto.cs
@@ -0,0 +1,30 @@
+using System.Text.Json;
+
+namespace DD.Persistence.Models;
+
+///
+/// Индексируемого поле из схемы для набора данных
+///
+public class SchemePropertyDto : IEquatable
+{
+ ///
+ /// Индекс поля
+ ///
+ public required int Index { get; set; }
+
+ ///
+ /// Наименование индексируемого поля
+ ///
+ public required string PropertyName { get; set; }
+
+ ///
+ /// Тип индексируемого поля
+ ///
+ public required JsonValueKind PropertyKind { get; set; }
+
+ ///
+ public bool Equals(SchemePropertyDto? other)
+ {
+ return Index == other?.Index && PropertyName == other?.PropertyName && PropertyKind == other?.PropertyKind;
+ }
+}
diff --git a/DD.Persistence.Test/TimestampedValuesServiceShould.cs b/DD.Persistence.Test/TimestampedValuesServiceShould.cs
index 0acb6de..ad26d14 100644
--- a/DD.Persistence.Test/TimestampedValuesServiceShould.cs
+++ b/DD.Persistence.Test/TimestampedValuesServiceShould.cs
@@ -7,7 +7,7 @@ namespace DD.Persistence.Repository.Test;
public class TimestampedValuesServiceShould
{
private readonly ITimestampedValuesRepository timestampedValuesRepository = Substitute.For();
- private readonly IDataSchemeRepository dataSchemeRepository = Substitute.For();
+ private readonly ISchemePropertyRepository dataSchemeRepository = Substitute.For();
private TimestampedValuesService timestampedValuesService;
public TimestampedValuesServiceShould()
diff --git a/DD.Persistence/Repositories/IDataSchemeRepository.cs b/DD.Persistence/Repositories/ISchemePropertyRepository.cs
similarity index 84%
rename from DD.Persistence/Repositories/IDataSchemeRepository.cs
rename to DD.Persistence/Repositories/ISchemePropertyRepository.cs
index c14a9cf..458f5cd 100644
--- a/DD.Persistence/Repositories/IDataSchemeRepository.cs
+++ b/DD.Persistence/Repositories/ISchemePropertyRepository.cs
@@ -5,7 +5,7 @@ namespace DD.Persistence.Repositories;
///
/// Репозиторий для работы со схемами наборов данных
///
-public interface IDataSchemeRepository
+public interface ISchemePropertyRepository
{
///
/// Добавить схему
@@ -13,7 +13,7 @@ public interface IDataSchemeRepository
///
///
///
- Task Add(DataSchemeDto dataSourceSystemDto, CancellationToken token);
+ Task AddRange(DataSchemeDto dataSourceSystemDto, CancellationToken token);
///
/// Вычитать схему
diff --git a/DD.Persistence/Services/TimestampedValuesService.cs b/DD.Persistence/Services/TimestampedValuesService.cs
index 264fdc5..5e6f9ed 100644
--- a/DD.Persistence/Services/TimestampedValuesService.cs
+++ b/DD.Persistence/Services/TimestampedValuesService.cs
@@ -10,10 +10,10 @@ namespace DD.Persistence.Services;
public class TimestampedValuesService : ITimestampedValuesService
{
private readonly ITimestampedValuesRepository timestampedValuesRepository;
- private readonly IDataSchemeRepository dataSchemeRepository;
+ private readonly ISchemePropertyRepository dataSchemeRepository;
///
- public TimestampedValuesService(ITimestampedValuesRepository timestampedValuesRepository, IDataSchemeRepository relatedDataRepository)
+ public TimestampedValuesService(ITimestampedValuesRepository timestampedValuesRepository, ISchemePropertyRepository relatedDataRepository)
{
this.timestampedValuesRepository = timestampedValuesRepository;
this.dataSchemeRepository = relatedDataRepository;
@@ -38,7 +38,7 @@ public class TimestampedValuesService : ITimestampedValuesService
{
var result = await timestampedValuesRepository.Get(discriminatorIds, geTimestamp, columnNames, skip, take, token);
- var dtos = await Materialize(result, token);
+ var dtos = await BindingToDataScheme(result, token);
if (!columnNames.IsNullOrEmpty())
{
@@ -53,9 +53,9 @@ public class TimestampedValuesService : ITimestampedValuesService
{
var result = await timestampedValuesRepository.GetFirst(discriminatorId, takeCount, token);
- var resultToMaterialize = new[] { KeyValuePair.Create(discriminatorId, result) }
+ var resultBeforeBinding = new[] { KeyValuePair.Create(discriminatorId, result) }
.ToDictionary();
- var dtos = await Materialize(resultToMaterialize, token);
+ var dtos = await BindingToDataScheme(resultBeforeBinding, token);
return dtos;
}
@@ -65,9 +65,9 @@ public class TimestampedValuesService : ITimestampedValuesService
{
var result = await timestampedValuesRepository.GetLast(discriminatorId, takeCount, token);
- var resultToMaterialize = new[] { KeyValuePair.Create(discriminatorId, result) }
+ var resultBeforeBinding = new[] { KeyValuePair.Create(discriminatorId, result) }
.ToDictionary();
- var dtos = await Materialize(resultToMaterialize, token);
+ var dtos = await BindingToDataScheme(resultBeforeBinding, token);
return dtos;
}
@@ -82,9 +82,9 @@ public class TimestampedValuesService : ITimestampedValuesService
{
var result = await timestampedValuesRepository.GetResampledData(discriminatorId, beginTimestamp, intervalSec, approxPointsCount, token);
- var resultToMaterialize = new[] { KeyValuePair.Create(discriminatorId, result) }
+ var resultBeforeBinding = new[] { KeyValuePair.Create(discriminatorId, result) }
.ToDictionary();
- var dtos = await Materialize(resultToMaterialize, token);
+ var dtos = await BindingToDataScheme(resultBeforeBinding, token);
return dtos;
}
@@ -94,9 +94,9 @@ public class TimestampedValuesService : ITimestampedValuesService
{
var result = await timestampedValuesRepository.GetGtDate(discriminatorId, beginTimestamp, token);
- var resultToMaterialize = new[] { KeyValuePair.Create(discriminatorId, result) }
+ var resultBeforeBinding = new[] { KeyValuePair.Create(discriminatorId, result) }
.ToDictionary();
- var dtos = await Materialize(resultToMaterialize, token);
+ var dtos = await BindingToDataScheme(resultBeforeBinding, token);
return dtos;
}
@@ -108,28 +108,22 @@ public class TimestampedValuesService : ITimestampedValuesService
///
///
///
- private async Task> Materialize(IDictionary> queryResult, CancellationToken token)
+ private async Task> BindingToDataScheme(IDictionary> queryResult, CancellationToken token)
{
IEnumerable result = [];
foreach (var keyValuePair in queryResult)
{
var dataScheme = await dataSchemeRepository.Get(keyValuePair.Key, token);
if (dataScheme is null)
- {
continue;
- }
foreach (var tuple in keyValuePair.Value)
{
- var identity = dataScheme!.PropNames;
- var indexedIdentity = identity
- .Select((value, index) => new { index, value });
-
var dto = new TimestampedValuesDto()
{
Timestamp = tuple.Timestamp.ToUniversalTime(),
- Values = indexedIdentity
- .ToDictionary(x => x.value, x => tuple.Values[x.index])
+ Values = dataScheme
+ .ToDictionary(k => k.PropertyName, v => tuple.Values[v.Index])
};
result = result.Append(dto);
@@ -149,61 +143,29 @@ public class TimestampedValuesService : ITimestampedValuesService
/// Некорректный набор наименований полей
private async Task CreateDataSchemeIfNotExist(Guid discriminatorId, TimestampedValuesDto dto, CancellationToken token)
{
- var propNames = dto.Values.Keys.ToArray();
- var propTypes = GetPropTypes(dto);
+ var valuesList = dto.Values.ToList();
+ var properties = valuesList.ToList().Select(e => new SchemePropertyDto() {
+ Index = valuesList.IndexOf(e),
+ PropertyName = e.Key,
+ PropertyKind = ((JsonElement) e.Value).ValueKind
+ }).ToArray();
var dataScheme = await dataSchemeRepository.Get(discriminatorId, token);
if (dataScheme is null)
{
- dataScheme = new DataSchemeDto()
- {
- DiscriminatorId = discriminatorId,
- PropNames = propNames,
- PropTypes = propTypes
- };
- await dataSchemeRepository.Add(dataScheme, token);
+ dataScheme = new DataSchemeDto(discriminatorId, properties);
+ await dataSchemeRepository.AddRange(dataScheme, token);
return;
}
- if (!dataScheme.PropNames.SequenceEqual(propNames))
+ if (!dataScheme.Equals(properties))
{
- var expectedFieldNames = string.Join(", ", dataScheme.PropNames);
- var actualFieldNames = string.Join(", ", propNames);
throw new InvalidOperationException($"Для системы {discriminatorId.ToString()} " +
- $"характерен набор данных: [{expectedFieldNames}], однако был передан набор: [{actualFieldNames}]");
+ $"был передан нехарактерный набор данных");
}
}
- ///
- /// Получить типы для набора данных в соответствии с индексацией
- ///
- ///
- ///
- ///
- private PropTypeEnum[] GetPropTypes(TimestampedValuesDto dto)
- {
- var types = dto.Values.Select(e =>
- {
- var objectKind = ((JsonElement) e.Value).ValueKind;
- var valueString = e.Value.ToString();
-
- if (valueString is null)
- throw new ArgumentNullException("Переданный набор данных содержит null, в следствии чего не удаётся определить типы полей");
-
- if (DateTimeOffset.TryParse(valueString, out _))
- return PropTypeEnum.DateTime;
-
- var doubleString = valueString.Replace('.', ',');
- if (double.TryParse(doubleString, out _))
- return PropTypeEnum.Double;
-
- return PropTypeEnum.String;
- });
-
- return types.ToArray();
- }
-
///
/// Отсеить лишние поля в соответствии с заданным фильтром
///