93 lines
3.0 KiB
C#
93 lines
3.0 KiB
C#
using System.Data;
|
|
using System.Diagnostics;
|
|
using Microsoft.Data.SqlClient;
|
|
|
|
namespace Gateway.Data;
|
|
|
|
public class SqlService
|
|
{
|
|
private readonly IConfiguration _config;
|
|
private readonly ILogger<SqlService> _logger;
|
|
|
|
public SqlService(IConfiguration config, ILogger<SqlService> logger)
|
|
{
|
|
_config = config;
|
|
_logger = logger;
|
|
}
|
|
|
|
private string GetConnectionString()
|
|
{
|
|
// expects env var: ConnectionStrings__Sql
|
|
var cs = _config.GetConnectionString("Sql");
|
|
if (string.IsNullOrWhiteSpace(cs))
|
|
throw new InvalidOperationException("Missing connection string: ConnectionStrings:Sql (env var ConnectionStrings__Sql).");
|
|
return cs;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executes a stored procedure using the standard signature:
|
|
/// @action varchar(..),
|
|
/// @rqst nvarchar(max),
|
|
/// @resp nvarchar(max) OUTPUT
|
|
/// Returns the output JSON string (resp).
|
|
/// </summary>
|
|
public async Task<string> ExecProcAsync(
|
|
string procName,
|
|
string action,
|
|
string rqstJson,
|
|
int commandTimeoutSeconds = 60,
|
|
CancellationToken ct = default)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(procName))
|
|
throw new ArgumentException("procName is required.", nameof(procName));
|
|
if (string.IsNullOrWhiteSpace(action))
|
|
throw new ArgumentException("action is required.", nameof(action));
|
|
if (string.IsNullOrWhiteSpace(rqstJson))
|
|
rqstJson = "{}";
|
|
|
|
var sw = Stopwatch.StartNew();
|
|
|
|
try
|
|
{
|
|
await using var conn = new SqlConnection(GetConnectionString());
|
|
await conn.OpenAsync(ct);
|
|
|
|
await using var cmd = new SqlCommand(procName, conn)
|
|
{
|
|
CommandType = CommandType.StoredProcedure,
|
|
CommandTimeout = commandTimeoutSeconds
|
|
};
|
|
|
|
cmd.Parameters.Add(new SqlParameter("@action", SqlDbType.VarChar, 50) { Value = action });
|
|
cmd.Parameters.Add(new SqlParameter("@rqst", SqlDbType.NVarChar, -1) { Value = rqstJson });
|
|
|
|
var pResp = new SqlParameter("@resp", SqlDbType.NVarChar, -1)
|
|
{
|
|
Direction = ParameterDirection.Output
|
|
};
|
|
cmd.Parameters.Add(pResp);
|
|
|
|
await cmd.ExecuteNonQueryAsync(ct);
|
|
|
|
var resp = pResp.Value as string ?? "";
|
|
|
|
sw.Stop();
|
|
_logger.LogInformation("SQL ok: {Proc} action={Action} ms={Ms}", procName, action, sw.ElapsedMilliseconds);
|
|
|
|
return resp;
|
|
}
|
|
catch (SqlException ex)
|
|
{
|
|
sw.Stop();
|
|
_logger.LogError(ex, "SQL error: {Proc} action={Action} ms={Ms}", procName, action, sw.ElapsedMilliseconds);
|
|
throw;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
sw.Stop();
|
|
_logger.LogError(ex, "App error calling SQL: {Proc} action={Action} ms={Ms}", procName, action, sw.ElapsedMilliseconds);
|
|
throw;
|
|
}
|
|
}
|
|
}
|