using ECMJobRunner.Application.Common.Constants; using ECMJobRunner.Application.Common.Dtos; using ECMJobRunner.Application.Common.Exceptions; using ECMJobRunner.Application.Common.Interfaces; using ECMJobRunner.Application.Common.Options; using ECMJobRunner.Application.Profiles.Commands; using MediatR; using Microsoft.Extensions.Options; using System; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; namespace ECMJobRunner.Application.Profiles.Commands.Behaviors { /// /// Pipeline behavior that executes the main SQL query for DEX jobs /// Runs before the command handler and validates query results /// /// The request type /// The response type public class MainQueryExecutionBehavior : IPipelineBehavior where TRequest : notnull { private readonly ISQLExecutor _executor; private readonly DexJobOptions _options; /// /// Initializes a new instance of MainQueryExecutionBehavior /// /// SQL executor for query execution /// DEX job configuration options public MainQueryExecutionBehavior(ISQLExecutor executor, IOptions options) { _executor = executor; _options = options.Value; } /// /// Handles the pipeline behavior /// Executes main query if request is TriggeringDEXJobCommand /// #if NET48 public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next) #else public async Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) #endif { if (request is TriggeringProfileJobCommand command) { await ExecuteMainQueryAsync(command, cancellationToken); } return await next(); } private async Task ExecuteMainQueryAsync(TriggeringProfileJobCommand command, CancellationToken cancel) { if (!string.IsNullOrWhiteSpace(command.Job.SqlMainQuery)) { var sqlMainQuery = Regex.Replace( command.Job.SqlMainQuery!, _options.Placeholders.BatchId.Pattern, command.BatchId, _options.Placeholders.BatchId.RegexOptions); try { var result = await _executor.ExecuteQueryAsync(sqlMainQuery, cancel); if (_options.Error.MainQuery.OnUnexpectedResult == ErrorAction.Stop) { if (result is null) throw new JobSqlException( profileId: command.Job.ProfileId, jobName: "Triggering DEX", processName: "Main Query", batchId: command.BatchId, reason: "Main Query returned nothing.", query: sqlMainQuery, innerException: null); else if (result.ReturnValue is not null) throw new JobSqlException( profileId: command.Job.ProfileId, jobName: "Triggering DEX", processName: "Main Query", batchId: command.BatchId, reason: $"The query unexpectedly returned the value {result.ReturnValue}. The expected value was null.", query: sqlMainQuery, innerException: null); } } catch (Exception ex) { if (_options.Error.MainQuery.OnExecution == ErrorAction.Stop) throw new JobSqlException( profileId: command.Job.ProfileId, jobName: "Triggering DEX", processName: "Main Query", batchId: command.BatchId, reason: null, query: sqlMainQuery, innerException: ex); } } else if (_options.Error.MainQuery.IfNullOrWhiteSpace == ErrorAction.Stop) { throw new JobSqlException( profileId: command.Job.ProfileId, jobName: "Triggering DEX", processName: "Main Query", batchId: command.BatchId, reason: "SQL Check Query is null or empty", query: null, innerException: null); } } } }