using System; using System.Threading.Tasks; using Erp.SqlQueryManager.Application.Contracts; using Erp.SqlQueryManager.Domain.Entities; using Erp.SqlQueryManager.Domain.Services; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Repositories; namespace Erp.SqlQueryManager.Application; public class SqlFunctionAppService : CrudAppService< SqlFunction, SqlFunctionDto, Guid, PagedAndSortedResultRequestDto, CreateSqlFunctionDto, UpdateSqlFunctionDto>, ISqlFunctionAppService { private readonly ISqlExecutorService _sqlExecutorService; public SqlFunctionAppService( IRepository repository, ISqlExecutorService sqlExecutorService) : base(repository) { _sqlExecutorService = sqlExecutorService; } public override async Task CreateAsync(CreateSqlFunctionDto input) { var entity = new SqlFunction( GuidGenerator.Create(), input.FunctionName, input.SchemaName ?? "dbo", input.DisplayName, input.FunctionType, input.FunctionBody, input.ReturnType, input.DataSourceCode, CurrentTenant.Id) { Description = input.Description, Category = input.Category, Parameters = input.Parameters }; await Repository.InsertAsync(entity); return ObjectMapper.Map(entity); } public override async Task UpdateAsync(Guid id, UpdateSqlFunctionDto input) { var entity = await Repository.GetAsync(id); entity.DisplayName = input.DisplayName; entity.Description = input.Description; entity.UpdateBody(input.FunctionBody); entity.ReturnType = input.ReturnType; entity.Category = input.Category; entity.Parameters = input.Parameters; await Repository.UpdateAsync(entity); return ObjectMapper.Map(entity); } public async Task DeployAsync(DeployFunctionDto input) { var function = await Repository.GetAsync(input.Id); // Drop if exists and requested if (input.DropIfExists) { var objectType = function.FunctionType.ToString().ToUpperInvariant().Replace("FUNCTION", "_FUNCTION"); await _sqlExecutorService.DropObjectAsync( function.FunctionName, $"SQL_{objectType}", function.DataSourceCode, function.SchemaName); } // Deploy the function var result = await _sqlExecutorService.DeployFunctionAsync( function.FunctionBody, function.DataSourceCode); if (result.Success) { function.MarkAsDeployed(); await Repository.UpdateAsync(function); } return MapExecutionResult(result); } public async Task CheckExistsAsync(Guid id) { var function = await Repository.GetAsync(id); var objectType = function.FunctionType.ToString().ToUpperInvariant().Replace("FUNCTION", "_FUNCTION"); return await _sqlExecutorService.CheckObjectExistsAsync( function.FunctionName, $"SQL_{objectType}", function.DataSourceCode, function.SchemaName); } public async Task DropAsync(Guid id) { var function = await Repository.GetAsync(id); var objectType = function.FunctionType.ToString().ToUpperInvariant().Replace("FUNCTION", "_FUNCTION"); var result = await _sqlExecutorService.DropObjectAsync( function.FunctionName, $"SQL_{objectType}", function.DataSourceCode, function.SchemaName); if (result.Success) { function.IsDeployed = false; await Repository.UpdateAsync(function); } return MapExecutionResult(result); } private SqlQueryExecutionResultDto MapExecutionResult(SqlExecutionResult result) { return new SqlQueryExecutionResultDto { Success = result.Success, Message = result.Message, Data = result.Data, RowsAffected = result.RowsAffected, ExecutionTimeMs = result.ExecutionTimeMs, Metadata = result.Metadata }; } }