using Microsoft.ApplicationInsights; using Microsoft.ApplicationInsights.DataContracts; using Microsoft.ApplicationInsights.Extensibility; using PlanTempus.Database.ModuleRegistry; using System.Data; namespace PlanTempus.Database.Core.Sql { public class DatabaseScope : IDisposable { private readonly IDbConnection _connection; private readonly IOperationHolder _operation; public DatabaseScope(IDbConnection connection, IOperationHolder operation) { _connection = connection; _operation = operation; } public IDbConnection Connection => _connection; public void Success() { _operation.Telemetry.Success = true; } public void Error(Exception ex) { _operation.Telemetry.Success = false; _operation.Telemetry.Properties["Error"] = ex.Message; } public void Dispose() { _operation.Dispose(); _connection.Dispose(); } } public interface IDatabaseOperations { DatabaseScope CreateScope(string operationName); Task ExecuteAsync(Func> operation, string operationName); Task ExecuteAsync(Func operation, string operationName); } public class SqlOperations : IDatabaseOperations { private readonly ConnectionFactory.IDbConnectionFactory _connectionFactory; private readonly TelemetryClient _telemetryClient; public SqlOperations(ConnectionFactory.IDbConnectionFactory connectionFactory, TelemetryClient telemetryClient) { _connectionFactory = connectionFactory; _telemetryClient = telemetryClient; } public DatabaseScope CreateScope(string operationName) { var connection = _connectionFactory.Create(); var operation = _telemetryClient.StartOperation(operationName); operation.Telemetry.Type = "SQL"; operation.Telemetry.Target = "PostgreSQL"; return new DatabaseScope(connection, operation); } public async Task ExecuteAsync(Func> operation, string operationName) { using var scope = CreateScope(operationName); try { var result = await operation(scope.Connection); scope.Success(); return result; } catch (Exception ex) { scope.Error(ex); throw; } } public async Task ExecuteAsync(Func operation, string operationName) { using var scope = CreateScope(operationName); try { await operation(scope.Connection); scope.Success(); } catch (Exception ex) { scope.Error(ex); throw; } } } }