diff --git a/src/ReC.Application/Common/Procedures/DeleteProcedure/DeleteObjectProcedure.cs b/src/ReC.Application/Common/Procedures/DeleteProcedure/DeleteObjectProcedure.cs new file mode 100644 index 0000000..9806d94 --- /dev/null +++ b/src/ReC.Application/Common/Procedures/DeleteProcedure/DeleteObjectProcedure.cs @@ -0,0 +1,77 @@ +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; + } +}