feat(dal,templateUpdater): Сохранение шаблонов для переименования в таблицу TemplateRenamePending

This commit is contained in:
Mikhail Trubnikov
2026-07-22 09:49:27 +10:00
parent 5094945c8e
commit 0b0c0b04ad
6 changed files with 132 additions and 16 deletions

View File

@@ -6,7 +6,8 @@
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information",
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning",
"Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware": "None"
} }
}, },
"Serilog": { "Serilog": {
@@ -14,7 +15,8 @@
"Default": "Information", "Default": "Information",
"Override": { "Override": {
"Microsoft": "Warning", "Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information" "Microsoft.Hosting.Lifetime": "Information",
"Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware": "Fatal"
} }
} }
}, },

View File

@@ -0,0 +1,10 @@
using PARR.Domain.Entities.TemplateEntities;
namespace PARR.Core.Repositories.Interfaces.TemplateRepositories
{
public interface ITemplateRenamePendingRepository
{
Task<bool> CreateAsync(TemplateRenamePending obj);
IQueryable<TemplateRenamePending> Get();
}
}

View File

@@ -8,6 +8,7 @@ using PARR.Core.Repositories.Interfaces.JobRepositories;
using PARR.Core.Repositories.Interfaces.RobotRepositories; using PARR.Core.Repositories.Interfaces.RobotRepositories;
using PARR.Core.Repositories.Interfaces.Schedule; using PARR.Core.Repositories.Interfaces.Schedule;
using PARR.Core.Repositories.Interfaces.TaskRepositories; using PARR.Core.Repositories.Interfaces.TaskRepositories;
using PARR.Core.Repositories.Interfaces.TemplateRepositories;
using PARR.Core.Repositories.Interfaces.Unit; using PARR.Core.Repositories.Interfaces.Unit;
using PARR.DAL.Configurations.DbSettings; using PARR.DAL.Configurations.DbSettings;
using PARR.DAL.Context; using PARR.DAL.Context;
@@ -18,6 +19,7 @@ using PARR.DAL.Repositories.JobRepositories;
using PARR.DAL.Repositories.RobotRepositories; using PARR.DAL.Repositories.RobotRepositories;
using PARR.DAL.Repositories.Schedule; using PARR.DAL.Repositories.Schedule;
using PARR.DAL.Repositories.TaskRepositories; using PARR.DAL.Repositories.TaskRepositories;
using PARR.DAL.Repositories.TemplateRepositories;
using PARR.DAL.Repositories.Unit; using PARR.DAL.Repositories.Unit;
using PARR.Domain.Settings; using PARR.Domain.Settings;
@@ -142,6 +144,12 @@ namespace PARR.DAL
#endregion #endregion
#region Templates
services.AddScoped<ITemplateRenamePendingRepository, TemplateRenamePendingRepository>();
#endregion
//services.AddTransient<INextRunModifierService, NextRunModifierService>(); //services.AddTransient<INextRunModifierService, NextRunModifierService>();
#region NextRun Services #region NextRun Services

View File

@@ -15,16 +15,6 @@ namespace PARR.DAL.Repositories.Base
{ {
internal abstract class BaseRepository<T> : IBaseRepository<T> where T : class, IBaseEntity internal abstract class BaseRepository<T> : IBaseRepository<T> where T : class, IBaseEntity
{ {
//private readonly ILogger<BaseRepository<T>> logger;
//protected abstract DbSet<T> EntitySet { get; }
//protected abstract DataContext EntitiContext { get; }
//public BaseRepository(ILogger<BaseRepository<T>> logger)
//{
// this.logger = logger;
//}
protected readonly ILogger logger; protected readonly ILogger logger;
protected readonly DbSet<T> EntitySet; protected readonly DbSet<T> EntitySet;
protected readonly DataContext EntityContext; protected readonly DataContext EntityContext;

View File

@@ -0,0 +1,42 @@
using Microsoft.Extensions.Logging;
using PARR.Core.Repositories.Interfaces.TemplateRepositories;
using PARR.DAL.Context;
using PARR.Domain.Entities.TemplateEntities;
namespace PARR.DAL.Repositories.TemplateRepositories
{
internal class TemplateRenamePendingRepository : ITemplateRenamePendingRepository
{
private readonly DataContext _dataContext;
private readonly ILogger<TemplateRenamePendingRepository> _logger;
public TemplateRenamePendingRepository(
DataContext dataContext,
ILogger<TemplateRenamePendingRepository> logger
)
{
_dataContext = dataContext;
_logger = logger;
}
public IQueryable<TemplateRenamePending> Get()
{
return _dataContext.TemplateRenamePendings;
}
public async Task<bool> CreateAsync(TemplateRenamePending obj)
{
try
{
await _dataContext.TemplateRenamePendings.AddAsync(obj);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка при добавлении объекта типа TemplateRenamePending в БД");
return false;
}
}
}
}

View File

@@ -3,10 +3,13 @@ using Microsoft.Extensions.Logging;
using PARR.Core.Extensions; using PARR.Core.Extensions;
using PARR.Core.Repositories.Interfaces; using PARR.Core.Repositories.Interfaces;
using PARR.Core.Repositories.Interfaces.JobRepositories; using PARR.Core.Repositories.Interfaces.JobRepositories;
using PARR.Core.Repositories.Interfaces.TemplateRepositories;
using PARR.Core.Repositories.Interfaces.Unit; using PARR.Core.Repositories.Interfaces.Unit;
using PARR.Core.Services.NextRunServices; using PARR.Core.Services.NextRunServices;
using PARR.Domain.Common.Rabbit.Messages.TemplateMatching; using PARR.Domain.Common.Rabbit.Messages.TemplateMatching;
using PARR.Domain.Entities;
using PARR.Domain.Entities.JobEntities; using PARR.Domain.Entities.JobEntities;
using PARR.Domain.Entities.TemplateEntities;
using PARR.Domain.Enums; using PARR.Domain.Enums;
namespace PARR.TemplateUpdater.Services namespace PARR.TemplateUpdater.Services
@@ -20,6 +23,7 @@ namespace PARR.TemplateUpdater.Services
private readonly IRobotConfigurationRepository robotConfigurationService; private readonly IRobotConfigurationRepository robotConfigurationService;
private readonly INextRunService nextRunService; private readonly INextRunService nextRunService;
private readonly IUnitInValueRepository unitInValueService; private readonly IUnitInValueRepository unitInValueService;
private readonly ITemplateRenamePendingRepository _templateRenamePendingRepository;
public TemplateUpdaterService( public TemplateUpdaterService(
ILogger<TemplateUpdaterService> logger, ILogger<TemplateUpdaterService> logger,
@@ -28,7 +32,8 @@ namespace PARR.TemplateUpdater.Services
IUnitRepository unitService, IUnitRepository unitService,
IRobotConfigurationRepository robotConfigurationService, IRobotConfigurationRepository robotConfigurationService,
INextRunService nextRunService, INextRunService nextRunService,
IUnitInValueRepository unitInValueService IUnitInValueRepository unitInValueService,
ITemplateRenamePendingRepository templateRenamePendingRepository
) )
{ {
this.logger = logger; this.logger = logger;
@@ -38,6 +43,7 @@ namespace PARR.TemplateUpdater.Services
this.robotConfigurationService = robotConfigurationService; this.robotConfigurationService = robotConfigurationService;
this.nextRunService = nextRunService; this.nextRunService = nextRunService;
this.unitInValueService = unitInValueService; this.unitInValueService = unitInValueService;
_templateRenamePendingRepository = templateRenamePendingRepository;
} }
@@ -53,7 +59,8 @@ namespace PARR.TemplateUpdater.Services
var template = await templateService.Get() var template = await templateService.Get()
.Include(t => t.RobotConfigurations) .Include(t => t.RobotConfigurations)
.Include(t => t.UnitsInTemplate) .Include(t => t.UnitsInTemplate)
.AsSplitQuery() //.AsSplitQuery()
.AsSingleQuery()
.FirstOrDefaultAsync(t => t.Id == query.TemplateId); .FirstOrDefaultAsync(t => t.Id == query.TemplateId);
if (template == null) if (template == null)
{ {
@@ -64,9 +71,14 @@ namespace PARR.TemplateUpdater.Services
var templateIsChanged = false; var templateIsChanged = false;
var scheduleIsChanged = false; var scheduleIsChanged = false;
if (template.Name != query.Name.Trim()) var trimmedNewName = query.Name.Trim();
if (template.Name != trimmedNewName)
{ {
template.Name = query.Name.Trim(); var prepareOldNameResult = await PrepareOldTemplateNameAsync(template.Name, trimmedNewName, template);
if (!prepareOldNameResult)
return;
template.Name = trimmedNewName;
templateIsChanged = true; templateIsChanged = true;
scheduleIsChanged = true; scheduleIsChanged = true;
} }
@@ -276,5 +288,57 @@ namespace PARR.TemplateUpdater.Services
return true; return true;
} }
/// <summary>
/// Добавление записи в таблицу ожидания переименования
/// </summary>
/// <param name="oldName"></param>
/// <param name="newName"></param>
/// <param name="template"></param>
/// <returns></returns>
private async Task<bool> PrepareOldTemplateNameAsync(string oldName, string newName, Template template)
{
// Проверяем, не запущено ли уже переименование для этого шаблона
var alreadyPending = await _templateRenamePendingRepository.Get()
.AsNoTracking()
.FirstOrDefaultAsync(t => t.TemplateId == template.Id);
if (alreadyPending != null)
{
logger.LogError("При попытке переименования шаблона {TemplateId}, из '{OldName}' в '{NewName}', " +
"произошла ошибка, этот шаблон уже находится в процессе переименования (старое имя {PendingName})", template.Id, oldName, newName, alreadyPending.OldName);
return false;
}
// Уникально ли имя в таблице ожидания переименования
var existPendingOldName = await _templateRenamePendingRepository.Get()
.AsNoTracking()
.FirstOrDefaultAsync(t => t.OldName == oldName);
if (existPendingOldName != null)
{
logger.LogError("При добавлении старого имени в таблицу ожидания для шаблона {TemplateId} обнаружен конфликт: " +
"имя '{ExistOldName}' уже зарезервировано другим процессом для шаблона {ExistTemplateId}",
template.Id, existPendingOldName.OldName, existPendingOldName.TemplateId);
return false;
}
// Все нормально, добавляем запись в таблицу
var pendingRename = new TemplateRenamePending
{
TemplateId = template.Id,
DateCreated = DateTimeOffset.UtcNow,
OldName = oldName,
Template = template
};
var addResult = await _templateRenamePendingRepository.CreateAsync(pendingRename);
if (!addResult)
return false;
return true;
}
} }
} }