Вынести партиционирование, добавить тест наименований сущностей
All checks were successful
Unit tests / test (push) Successful in 54s

This commit is contained in:
Roman Efremov 2025-01-23 12:46:34 +05:00
parent b09d2dd704
commit 79818dfa8f
16 changed files with 131 additions and 62 deletions

View File

@ -1,5 +1,5 @@
using DD.Persistence.Database.Model;
using DD.Persistence.Database.Postgres;
using DD.Persistence.Database.Postgres.Extensions;
using DD.Persistence.Repository;
namespace DD.Persistence.API;
@ -59,7 +59,6 @@ public class Startup
var context = provider.GetRequiredService<PersistencePostgresContext>();
context.Database.EnsureCreatedAndMigrated();
context.Database.AddPartitioning();
}
}

View File

@ -2,7 +2,7 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using System.Diagnostics;
namespace DD.Persistence.Database.Postgres;
namespace DD.Persistence.Database.Postgres.Extensions;
public static class EFExtensionsInitialization
{
public static void EnsureCreatedAndMigrated(this DatabaseFacade db)

View File

@ -0,0 +1,44 @@
using DD.Persistence.Database.Entity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection;
namespace DD.Persistence.Database.Postgres.Extensions;
public static class EFExtensionsPartitioning
{
public static void AddPartitioning(this DatabaseFacade db)
{
db.CreateTimescaledbExtension();
db.AddParameterDataPartitioning();
}
private static void CreateTimescaledbExtension(this DatabaseFacade db)
{
var sqlString = $"CREATE EXTENSION IF NOT EXISTS timescaledb;";
db.ExecuteSqlRaw(sqlString);
}
/// <summary>
/// Добавить партиционирование таблицы ParameterData (Wits - данные)
/// </summary>
/// <param name="db"></param>
private static void AddParameterDataPartitioning(this DatabaseFacade db)
{
var type = typeof(ParameterData);
var tableAttribute = type.GetCustomAttribute<TableAttribute>();
if (tableAttribute is null)
{
return;
}
const int sectionsNumber = 2;
const int chunkTimeInterval = 5;
var sqlString = $"SELECT create_hypertable({tableAttribute.Name}," +
$"'{nameof(ParameterData.Timestamp)}'," +
$"'{nameof(ParameterData.ParameterId)}'," +
$"{sectionsNumber}," +
$"chunk_time_interval => INTERVAL '{chunkTimeInterval} day');";
db.ExecuteSqlRaw(sqlString);
}
}

View File

@ -131,9 +131,6 @@ namespace DD.Persistence.Database.Postgres.Migrations
name: "IX_tech_message_SystemId",
table: "tech_message",
column: "SystemId");
migrationBuilder.Sql
("SELECT create_hypertable('parameter_data','Timestamp','ParameterId',2,chunk_time_interval => INTERVAL '5 day');");
}
/// <inheritdoc />

View File

@ -1,11 +1,11 @@

using DD.Persistence.Database.EntityAbstractions;
using DD.Persistence.ModelsAbstractions;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using DD.Persistence.ModelsAbstractions;
using DD.Persistence.Database.EntityAbstractions;
namespace DD.Persistence.Database.Model;
namespace DD.Persistence.Database.Entity;
/// <summary>
/// Часть записи, описывающая изменение

View File

@ -3,22 +3,21 @@ using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
namespace DD.Persistence.Database.Model
namespace DD.Persistence.Database.Entity;
[Table("setpoint")]
[PrimaryKey(nameof(Key), nameof(Timestamp))]
public class Setpoint : ITimestampedItem
{
[Table("setpoint")]
[PrimaryKey(nameof(Key), nameof(Timestamp))]
public class Setpoint : ITimestampedItem
{
[Comment("Ключ")]
public Guid Key { get; set; }
[Comment("Ключ")]
public Guid Key { get; set; }
[Column(TypeName = "jsonb"), Comment("Значение уставки")]
public required JsonElement Value { get; set; }
[Column(TypeName = "jsonb"), Comment("Значение уставки")]
public required JsonElement Value { get; set; }
[Comment("Дата создания уставки")]
public DateTimeOffset Timestamp { get; set; }
[Comment("Дата создания уставки")]
public DateTimeOffset Timestamp { get; set; }
[Comment("Id автора последнего изменения")]
public Guid IdUser { get; set; }
}
[Comment("Id автора последнего изменения")]
public Guid IdUser { get; set; }
}

View File

@ -3,19 +3,19 @@ using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DD.Persistence.Database.Entity
namespace DD.Persistence.Database.Entity;
[Table("tech_message")]
public class TechMessage : ITimestampedItem
{
[Table("tech_message")]
public class TechMessage : ITimestampedItem
{
[Key, Comment("Id события")]
public Guid EventId { get; set; }
[Key, Comment("Id события")]
public Guid EventId { get; set; }
[Comment("Id Категории важности")]
public int CategoryId { get; set; }
[Comment("Id Категории важности")]
public int CategoryId { get; set; }
[Comment("Дата возникновения")]
public DateTimeOffset Timestamp { get; set; }
[Comment("Дата возникновения")]
public DateTimeOffset Timestamp { get; set; }
[Column(TypeName = "varchar(512)"), Comment("Текст сообщения")]
public required string Text { get; set; }
@ -29,4 +29,3 @@ namespace DD.Persistence.Database.Entity
[Comment("Статус события")]
public int EventState { get; set; }
}
}

View File

@ -1,6 +1,5 @@
using Microsoft.EntityFrameworkCore;
using DD.Persistence.Database.Entity;
using DD.Persistence.Database.Model;
using Microsoft.EntityFrameworkCore;
namespace DD.Persistence.Database;

View File

@ -1,17 +1,15 @@
using DD.Persistence.Client;
using DD.Persistence.Client.Clients;
using DD.Persistence.Client.Clients.Interfaces;
using DD.Persistence.Client.Clients.Interfaces.Refit;
using DD.Persistence.Database.Entity;
using DD.Persistence.Models;
using DD.Persistence.Models.Requests;
using Mapster;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using DD.Persistence.Database.Model;
using DD.Persistence.Models;
using DD.Persistence.Models.Requests;
using Xunit;
using DD.Persistence.Client.Clients.Interfaces;
using DD.Persistence.Client;
using DD.Persistence.Client.Clients.Interfaces.Refit;
using DD.Persistence.Client.Clients;
using Microsoft.Extensions.Logging;
using Refit;
using System.Net.Http;
using Xunit;
namespace DD.Persistence.IntegrationTests.Controllers;
public class ChangeLogControllerTest : BaseIntegrationTest

View File

@ -2,7 +2,7 @@ using DD.Persistence.Client;
using DD.Persistence.Client.Clients;
using DD.Persistence.Client.Clients.Interfaces;
using DD.Persistence.Client.Clients.Interfaces.Refit;
using DD.Persistence.Database.Model;
using DD.Persistence.Database.Entity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.Text.Json;

View File

@ -8,12 +8,12 @@ using Microsoft.Extensions.Logging;
using DD.Persistence.API;
using DD.Persistence.Client;
using DD.Persistence.Database.Model;
using DD.Persistence.Database.Postgres;
using RestSharp;
using DD.Persistence.App;
using DD.Persistence.Client.Helpers;
using DD.Persistence.Factories;
using System.Net;
using DD.Persistence.Database.Postgres.Extensions;
namespace DD.Persistence.IntegrationTests;
public class WebAppFactoryFixture : WebApplicationFactory<Program>

View File

@ -1,12 +1,11 @@
using Mapster;
using Microsoft.Extensions.DependencyInjection;
using DD.Persistence.Database.Model;
using DD.Persistence.Database.Entity;
using DD.Persistence.Models;
using DD.Persistence.Repositories;
using DD.Persistence.Repository.Repositories;
using DD.Persistence.Database.Entity;
using System.Reflection;
using DD.Persistence.Repository.RepositoriesCached;
using Mapster;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
namespace DD.Persistence.Repository;
public static class DependencyInjection

View File

@ -1,11 +1,11 @@
using Mapster;
using Microsoft.EntityFrameworkCore;
using DD.Persistence.Database.Model;
using DD.Persistence.Database.Entity;
using DD.Persistence.Models;
using DD.Persistence.Models.Common;
using DD.Persistence.Models.Requests;
using DD.Persistence.Repositories;
using Mapster;
using Microsoft.EntityFrameworkCore;
using UuidExtensions;
using DD.Persistence.Models.Common;
namespace DD.Persistence.Repository.Repositories;
public class ChangeLogRepository : IChangeLogRepository

View File

@ -1,10 +1,10 @@
using DD.Persistence.Database.Entity;
using DD.Persistence.Models;
using DD.Persistence.Models.Common;
using DD.Persistence.Repositories;
using Mapster;
using Microsoft.EntityFrameworkCore;
using DD.Persistence.Database.Model;
using DD.Persistence.Models;
using DD.Persistence.Repositories;
using System.Text.Json;
using DD.Persistence.Models.Common;
namespace DD.Persistence.Repository.Repositories
{

View File

@ -16,6 +16,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DD.Persistence.Database\DD.Persistence.Database.csproj" />
<ProjectReference Include="..\DD.Persistence\DD.Persistence.csproj" />
</ItemGroup>

View File

@ -0,0 +1,34 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.Globalization;
using System.Reflection;
using System.Text.RegularExpressions;
namespace DD.Persistence.Test;
public class TableAttributeShould
{
private const string Separator = "_";
private const string TargetAssembly = "DD.Persistence.Database";
private const string TargetNamespace = "DD.Persistence.Database.Entity";
[Fact]
public void Test()
{
Assembly assembly = Assembly.Load(TargetAssembly);
var typesInNamespace = assembly.GetTypes()
.Where(t => t.IsClass && t.Namespace == TargetNamespace)
.ToList();
foreach (var type in typesInNamespace)
{
var tableAttribute = type.GetCustomAttribute<TableAttribute>();
Assert.NotNull(tableAttribute);
var partsOfClassName = Regex
.Split(type.Name, @"(?=[A-Z])")
.Where(s => s != string.Empty)
.Select(s => s.ToLower(CultureInfo.InvariantCulture));
var expectedClassName = string.Join(Separator, partsOfClassName);
Assert.Equal(expectedClassName, tableAttribute.Name);
}
}
}