using Microsoft.Data.SqlClient; using System.Data; using System.Text; namespace ReC.Application.Common.Procedures; internal sealed class StoredProcedureBuilder(string procedureName, string? returnVariable = null) { private readonly StringBuilder _execSql = returnVariable is not null ? new StringBuilder($"EXEC @{returnVariable} = {procedureName}") : new StringBuilder($"EXEC {procedureName}"); private readonly List _parameters = []; private char _separator = ' '; public StoredProcedureBuilder Add(string name, object? value, SqlDbType? dbType = null) { if (value is null) return this; _execSql.AppendLine($"{_separator}@{name} = @{name}"); _separator = ','; if (dbType.HasValue) _parameters.Add(new SqlParameter($"@{name}", dbType.Value) { Value = value }); else _parameters.Add(new SqlParameter($"@{name}", value)); return this; } public StoredProcedureBuilder AddOutput(string name, SqlDbType dbType) { _execSql.AppendLine($"{_separator}@{name} = @{name} OUTPUT"); _separator = ','; _parameters.Add(new SqlParameter { ParameterName = $"@{name}", SqlDbType = dbType, Direction = ParameterDirection.Output }); return this; } public string BuildSql() { if (returnVariable is null) return _execSql.ToString(); return new StringBuilder() .AppendLine($"DECLARE @{returnVariable} SMALLINT = 0;") .Append(_execSql).AppendLine(";") .AppendLine($"SELECT @{returnVariable};") .ToString(); } public SqlParameter[] BuildParameters() => [.. _parameters]; public SqlParameter? GetParameter(string name) => _parameters.Find(p => p.ParameterName == $"@{name}"); }