From 97f992aef597f5a5c468177e0bffbf35f176c46f Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Fri, 16 Jan 2026 01:05:28 +0100 Subject: [PATCH] Add DeleteObjectProcedure for entity deletion handling Introduce `DeleteObjectProcedure` to encapsulate parameters for delete operations, including entity, ID range, and force flag. Add `DeleteObjectProcedureExtensions` for convenient invocation via `ISender`. Implement `DeleteObjectProcedureHandler` to execute the `[dbo].[PRREC_DELETE_OBJECT]` stored procedure using dynamic SQL parameters. Throw `DeleteObjectFailedException` on failure and ensure `End` defaults to `Start` if unset. Add XML documentation for improved code clarity. Include necessary `using` directives for dependencies. --- .../DeleteProcedure/DeleteObjectProcedure.cs | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/ReC.Application/Common/Procedures/DeleteProcedure/DeleteObjectProcedure.cs 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; + } +}