using DigitalData.Core.Abstraction.Application.Repository; using MediatR; using Microsoft.Data.SqlClient; using ReC.Application.Common.Exceptions; namespace ReC.Application.Common.Procedures.DeleteProcedure; public record DeleteObjectProcedure : IRequest { /// /// Target entity: ACTION, ENDPOINT, ENDPOINT_AUTH, ENDPOINT_PARAMS, PROFILE, RESULT /// public string Entity { get; set; } = null!; /// /// Start GUID/ID (inclusive) /// public long Start { get; set; } /// /// End GUID/ID (inclusive). If 0, will be set to Start value. /// public long End { get; set; } /// /// If true, delete even if dependent data exists /// public bool Force { get; set; } } public static class DeleteObjectProcedureExtensions { public static Task ExecuteDeleteProcedure(this ISender sender, IDeleteProcedure procedure, CancellationToken cancel = default) { return sender.Send(procedure.ToObjectProcedure(), cancel); } public static Task ExecuteDeleteProcedure(this ISender sender, string entity, long start, long end = 0, bool force = false, CancellationToken cancel = default) { return sender.Send(new DeleteObjectProcedure { Entity = entity, Start = start, End = end, Force = force }, cancel); } } public class DeleteObjectProcedureHandler(IRepository repo) : IRequestHandler { public async Task Handle(DeleteObjectProcedure request, CancellationToken cancel) { var parameters = new[] { new SqlParameter("@pENTITY", request.Entity ?? (object)DBNull.Value), new SqlParameter("@pSTART", request.Start.ToString()), new SqlParameter("@pEND", request.End.ToString()), new SqlParameter("@pFORCE", (object?)request.Force ?? DBNull.Value) }; var result = await repo.ExecuteQueryRawAsync( "EXEC @RC = [dbo].[PRREC_DELETE_OBJECT] " + "@pENTITY, @pSTART, @pEND, @pFORCE; " + "SELECT @RC;", parameters, cancel); // The stored procedure returns 0 on success, error codes > 0 on failure if (result > 0) { throw new DeleteObjectFailedException(request, $"DeleteObject stored procedure failed with error code: {result}"); } return result; } }