From c8a9245b54cd63481f313417e0ed50ee5ba92c65 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Fri, 16 Jan 2026 00:58:11 +0100 Subject: [PATCH] Add UpdateObjectProcedure for entity updates Introduce `UpdateObjectProcedure` to handle updates for various entities using a stored procedure. Implement MediatR-based request/response pattern with `IRequest` and add the `UpdateObjectProcedureHandler` to execute the update logic. Include an extension method `ExecuteUpdateProcedure` for simplified execution of update requests. Add exception handling via `UpdateObjectFailedException` to manage update failures. Integrate dependencies on `DigitalData.Core.Abstraction.Application.Repository`, `MediatR`, and `Microsoft.Data.SqlClient`. Ensure extensibility and reliability in the update process. --- .../UpdateProcedure/UpdateObjectProcedure.cs | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/ReC.Application/Common/Procedures/UpdateProcedure/UpdateObjectProcedure.cs diff --git a/src/ReC.Application/Common/Procedures/UpdateProcedure/UpdateObjectProcedure.cs b/src/ReC.Application/Common/Procedures/UpdateProcedure/UpdateObjectProcedure.cs new file mode 100644 index 0000000..70c3eaf --- /dev/null +++ b/src/ReC.Application/Common/Procedures/UpdateProcedure/UpdateObjectProcedure.cs @@ -0,0 +1,131 @@ +using DigitalData.Core.Abstraction.Application.Repository; +using MediatR; +using Microsoft.Data.SqlClient; +using ReC.Application.Common.Exceptions; + +namespace ReC.Application.Common.Procedures.UpdateProcedure; + +public record UpdateObjectProcedure : IRequest +{ + /// + /// Target entity: ACTION, ENDPOINT, ENDPOINT_AUTH, ENDPOINT_PARAMS, PROFILE, RESULT + /// + public string Entity { get; set; } = null!; + + /// + /// Target GUID to update (required) + /// + public long Guid { get; set; } + + internal string? ChangedWho { get; private set; } + + public UpdateObjectProcedure ChangedBy(string? changedWho = null) + { + ChangedWho = changedWho ?? "ReC.API"; + return this; + } + + public UpdateActionProcedure Action { get; set; } = new(); + public UpdateEndpointProcedure Endpoint { get; set; } = new(); + public UpdateEndpointAuthProcedure EndpointAuth { get; set; } = new(); + public UpdateProfileProcedure Profile { get; set; } = new(); + public UpdateResultProcedure Result { get; set; } = new(); + public UpdateEndpointParamsProcedure EndpointParams { get; set; } = new(); +} + +public static class UpdateObjectProcedureExtensions +{ + public static Task ExecuteUpdateProcedure(this ISender sender, IUpdateProcedure procedure, long guid, string? changedWho = null, CancellationToken cancel = default) + { + return sender.Send(procedure.ToObjectProcedure(guid, changedWho ?? "ReC.API"), cancel); + } +} + +public class UpdateObjectProcedureHandler(IRepository repo) : IRequestHandler +{ + public async Task Handle(UpdateObjectProcedure request, CancellationToken cancel) + { + var parameters = new[] + { + new SqlParameter("@pENTITY", request.Entity ?? (object)DBNull.Value), + new SqlParameter("@pGUID", (object?)request.Guid ?? DBNull.Value), + + new SqlParameter("@pCHANGED_WHO", (object?)request.ChangedWho ?? DBNull.Value), + new SqlParameter("@pCHANGED_WHEN", (object?)DateTime.UtcNow ?? DBNull.Value), + + new SqlParameter("@pACTION_PROFILE_ID", (object?)request.Action.ProfileId ?? DBNull.Value), + new SqlParameter("@pACTION_ACTIVE", (object?)request.Action.Active ?? DBNull.Value), + new SqlParameter("@pACTION_SEQUENCE", (object?)request.Action.Sequence ?? DBNull.Value), + new SqlParameter("@pACTION_ENDPOINT_ID", (object?)request.Action.EndpointId ?? DBNull.Value), + new SqlParameter("@pACTION_ENDPOINT_AUTH_ID", (object?)request.Action.EndpointAuthId ?? DBNull.Value), + new SqlParameter("@pACTION_ENDPOINT_PARAMS_ID", (object?)request.Action.EndpointParamsId ?? DBNull.Value), + new SqlParameter("@pACTION_SQL_CONNECTION_ID", (object?)request.Action.SqlConnectionId ?? DBNull.Value), + new SqlParameter("@pACTION_TYPE_ID", (object?)request.Action.TypeId ?? DBNull.Value), + new SqlParameter("@pACTION_PRE_SQL", (object?)request.Action.PreSql ?? DBNull.Value), + new SqlParameter("@pACTION_HEADER_SQL", (object?)request.Action.HeaderSql ?? DBNull.Value), + new SqlParameter("@pACTION_BODY_SQL", (object?)request.Action.BodySql ?? DBNull.Value), + new SqlParameter("@pACTION_POST_SQL", (object?)request.Action.PostSql ?? DBNull.Value), + new SqlParameter("@pACTION_ERROR_ACTION_ID", (object?)request.Action.ErrorActionId ?? DBNull.Value), + + new SqlParameter("@pENDPOINT_ACTIVE", (object?)request.Endpoint.Active ?? DBNull.Value), + new SqlParameter("@pENDPOINT_DESCRIPTION", (object?)request.Endpoint.Description ?? DBNull.Value), + new SqlParameter("@pENDPOINT_URI", (object?)request.Endpoint.Uri ?? DBNull.Value), + + new SqlParameter("@pENDPOINT_AUTH_ACTIVE", (object?)request.EndpointAuth.Active ?? DBNull.Value), + new SqlParameter("@pENDPOINT_AUTH_DESCRIPTION", (object?)request.EndpointAuth.Description ?? DBNull.Value), + new SqlParameter("@pENDPOINT_AUTH_TYPE_ID", (object?)request.EndpointAuth.TypeId ?? DBNull.Value), + new SqlParameter("@pENDPOINT_AUTH_API_KEY", (object?)request.EndpointAuth.ApiKey ?? DBNull.Value), + new SqlParameter("@pENDPOINT_AUTH_API_VALUE", (object?)request.EndpointAuth.ApiValue ?? DBNull.Value), + new SqlParameter("@pENDPOINT_AUTH_API_KEY_ADD_TO_ID", (object?)request.EndpointAuth.ApiKeyAddToId ?? DBNull.Value), + new SqlParameter("@pENDPOINT_AUTH_TOKEN", (object?)request.EndpointAuth.Token ?? DBNull.Value), + new SqlParameter("@pENDPOINT_AUTH_USERNAME", (object?)request.EndpointAuth.Username ?? DBNull.Value), + new SqlParameter("@pENDPOINT_AUTH_PASSWORD", (object?)request.EndpointAuth.Password ?? DBNull.Value), + new SqlParameter("@pENDPOINT_AUTH_DOMAIN", (object?)request.EndpointAuth.Domain ?? DBNull.Value), + new SqlParameter("@pENDPOINT_AUTH_WORKSTATION", (object?)request.EndpointAuth.Workstation ?? DBNull.Value), + + new SqlParameter("@pENDPOINT_PARAMS_ACTIVE", (object?)request.EndpointParams.Active ?? DBNull.Value), + new SqlParameter("@pENDPOINT_PARAMS_DESCRIPTION", (object?)request.EndpointParams.Description ?? DBNull.Value), + new SqlParameter("@pENDPOINT_PARAMS_GROUP_ID", (object?)request.EndpointParams.GroupId ?? DBNull.Value), + new SqlParameter("@pENDPOINT_PARAMS_SEQUENCE", (object?)request.EndpointParams.Sequence ?? DBNull.Value), + new SqlParameter("@pENDPOINT_PARAMS_KEY", (object?)request.EndpointParams.Key ?? DBNull.Value), + new SqlParameter("@pENDPOINT_PARAMS_VALUE", (object?)request.EndpointParams.Value ?? DBNull.Value), + + new SqlParameter("@pPROFILE_ACTIVE", (object?)request.Profile.Active ?? DBNull.Value), + new SqlParameter("@pPROFILE_TYPE_ID", (object?)request.Profile.TypeId ?? DBNull.Value), + new SqlParameter("@pPROFILE_MANDANTOR", (object?)request.Profile.Mandantor ?? DBNull.Value), + new SqlParameter("@pPROFILE_NAME", (object?)request.Profile.Name ?? DBNull.Value), + new SqlParameter("@pPROFILE_DESCRIPTION", (object?)request.Profile.Description ?? DBNull.Value), + new SqlParameter("@pPROFILE_LOG_LEVEL_ID", (object?)request.Profile.LogLevelId ?? DBNull.Value), + new SqlParameter("@pPROFILE_LANGUAGE_ID", (object?)request.Profile.LanguageId ?? DBNull.Value), + new SqlParameter("@pPROFILE_FIRST_RUN", (object?)request.Profile.FirstRun ?? DBNull.Value), + new SqlParameter("@pPROFILE_LAST_RUN", (object?)request.Profile.LastRun ?? DBNull.Value), + new SqlParameter("@pPROFILE_LAST_RESULT", (object?)request.Profile.LastResult ?? DBNull.Value), + + new SqlParameter("@pRESULT_ACTION_ID", (object?)request.Result.ActionId ?? DBNull.Value), + new SqlParameter("@pRESULT_STATUS_ID", (object?)request.Result.StatusId ?? DBNull.Value), + new SqlParameter("@pRESULT_HEADER", (object?)request.Result.Header ?? DBNull.Value), + new SqlParameter("@pRESULT_BODY", (object?)request.Result.Body ?? DBNull.Value) + }; + + var result = await repo.ExecuteQueryRawAsync( + "EXEC @RC = [dbo].[PRREC_UPDATE_OBJECT] " + + "@pENTITY, @pGUID, @pCHANGED_WHO, @pCHANGED_WHEN, " + + "@pACTION_PROFILE_ID, @pACTION_ACTIVE, @pACTION_SEQUENCE, @pACTION_ENDPOINT_ID, @pACTION_ENDPOINT_AUTH_ID, @pACTION_ENDPOINT_PARAMS_ID, @pACTION_SQL_CONNECTION_ID, @pACTION_TYPE_ID, @pACTION_PRE_SQL, @pACTION_HEADER_SQL, @pACTION_BODY_SQL, @pACTION_POST_SQL, @pACTION_ERROR_ACTION_ID, " + + "@pENDPOINT_ACTIVE, @pENDPOINT_DESCRIPTION, @pENDPOINT_URI, " + + "@pENDPOINT_AUTH_ACTIVE, @pENDPOINT_AUTH_DESCRIPTION, @pENDPOINT_AUTH_TYPE_ID, @pENDPOINT_AUTH_API_KEY, @pENDPOINT_AUTH_API_VALUE, @pENDPOINT_AUTH_API_KEY_ADD_TO_ID, @pENDPOINT_AUTH_TOKEN, @pENDPOINT_AUTH_USERNAME, @pENDPOINT_AUTH_PASSWORD, @pENDPOINT_AUTH_DOMAIN, @pENDPOINT_AUTH_WORKSTATION, " + + "@pENDPOINT_PARAMS_ACTIVE, @pENDPOINT_PARAMS_DESCRIPTION, @pENDPOINT_PARAMS_GROUP_ID, @pENDPOINT_PARAMS_SEQUENCE, @pENDPOINT_PARAMS_KEY, @pENDPOINT_PARAMS_VALUE, " + + "@pPROFILE_ACTIVE, @pPROFILE_TYPE_ID, @pPROFILE_MANDANTOR, @pPROFILE_NAME, @pPROFILE_DESCRIPTION, @pPROFILE_LOG_LEVEL_ID, @pPROFILE_LANGUAGE_ID, @pPROFILE_FIRST_RUN, @pPROFILE_LAST_RUN, @pPROFILE_LAST_RESULT, " + + "@pRESULT_ACTION_ID, @pRESULT_STATUS_ID, @pRESULT_HEADER, @pRESULT_BODY; " + + "SELECT @RC;", + parameters, + cancel); + + // The stored procedure returns 0 on success, error codes > 0 on failure + if (result > 0) + { + throw new UpdateObjectFailedException(request, $"UpdateObject stored procedure failed with error code: {result}"); + } + + return result; + } +}