using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Threading.Tasks; using Erp.Platform.DynamicData; using Erp.Platform.Entities; using Erp.Platform.Enums; using Erp.Platform.ListForms; using Erp.Platform.Localization; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Primitives; using Volo.Abp.ObjectMapping; using Volo.Abp.Settings; using Volo.Abp.Users; namespace Erp.Platform.Queries; public interface IQueryManager { Task GenerateAndRunQueryAsync( string listFormCode, OperationEnum op, dynamic inputParams = null, object[] keys = null, Dictionary queryParameters = null); string GenerateQuery( ListForm listForm, Dictionary parameters, OperationEnum op, DataSourceTypeEnum dataSourceType, object[] keys = null); } public class QueryManager : PlatformDomainService, IQueryManager { private readonly IStringLocalizer localizer; private readonly IListFormManager listFormManager; private readonly IListFormFieldManager listFormFieldManager; private readonly IDefaultValueManager defaultValueManager; private readonly IDataSourceManager dataSourceManager; private readonly IDynamicDataManager dynamicDataManager; public QueryManager( ISettingProvider settingProvider, IStringLocalizer localizer, ICurrentUser currentUser, IObjectMapper objectMapper, IListFormAuthorizationManager authManager, IListFormManager listFormManager, IListFormFieldManager listFormFieldManager, IDefaultValueManager defaultValueManager, IDataSourceManager dataSourceManager, IDynamicDataManager dynamicDataManager) : base(settingProvider, localizer, currentUser, objectMapper, authManager) { this.localizer = localizer; this.listFormManager = listFormManager; this.listFormFieldManager = listFormFieldManager; this.defaultValueManager = defaultValueManager; this.dataSourceManager = dataSourceManager; this.dynamicDataManager = dynamicDataManager; } public async Task GenerateAndRunQueryAsync( string listFormCode, OperationEnum op, dynamic inputParams = null, object[] keys = null, Dictionary queryParameters = null) //TODO SEND QUERY PARAMS { // kullaniciya ait ListForm verisini al var listForm = await listFormManager.GetUserListForm(listFormCode); // kullaniciya ait ListFormField verisini al var listFormFields = await listFormFieldManager.GetUserListFormFields(listFormCode); var parameters = await listFormManager.GetParametersAsync(listForm, listFormFields, inputParams, op, keys, queryParameters); // if (parameters == null || parameters.Count == 0) // { // throw new UserFriendlyException(localizer[AppErrorCodes.ParameterNotValid]); // } var (dynamicDataRepository, connectionString, dataSourceType) = await dynamicDataManager.GetAsync(listForm.IsTenant, listForm.DataSourceCode); var sql = GenerateQuery(listForm, parameters, op, dataSourceType, keys); // Sorguyu calistir if (!string.IsNullOrEmpty(sql)) { // TODO: Log if (op == OperationEnum.Insert) { return await dynamicDataRepository.ExecuteScalarAsync(sql, connectionString, parameters); } else if (op == OperationEnum.Update || op == OperationEnum.Delete) { return (T)(object)await dynamicDataRepository.ExecuteAsync(sql, connectionString, parameters); } } return default; } public string GenerateQuery( ListForm listForm, Dictionary parameters, OperationEnum op, DataSourceTypeEnum dataSourceType, object[] keys = null) { var command = op switch { OperationEnum.Insert => listForm.InsertCommand, OperationEnum.Update => listForm.UpdateCommand, OperationEnum.Delete => listForm.DeleteCommand, _ => "", }; // Sorguyu generate et var sql = string.Empty; // oncelik Command alanindadir, dolu ise silme islemi buradaki sorguya yonlendirilir if (!string.IsNullOrEmpty(command)) { sql = command; } else { var fieldString = string.Join(',', parameters.Keys.Select(a => $"\"{a}\"").ToList()); var fieldParams = string.Join(',', parameters.Keys.Select(a => $"@{a}")); if (op == OperationEnum.Insert) { sql = dataSourceType switch { DataSourceTypeEnum.Mssql => $"INSERT INTO \"{listForm.SelectCommand}\" ({fieldString}) OUTPUT Inserted.{listForm.KeyFieldName} VALUES ({fieldParams})", DataSourceTypeEnum.Postgresql => $"INSERT INTO \"{listForm.SelectCommand}\" ({fieldString}) VALUES ({fieldParams}) RETURNING \"{listForm.KeyFieldName}\"", _ => string.Empty, }; } else if (op == OperationEnum.Update) { var where = dataSourceType switch { DataSourceTypeEnum.Mssql => $"\"{listForm.KeyFieldName}\" IN (@{listForm.KeyFieldName})", DataSourceTypeEnum.Postgresql => $"\"{listForm.KeyFieldName}\" = ANY(@{listForm.KeyFieldName})", _ => string.Empty, }; var updateFields = parameters.Select(a => $"\"{a.Key}\" = @{a.Key}").ToList(); var val = QueryHelper.GetFormattedValue(listForm.KeyFieldDbSourceType, keys); parameters.Add( listForm.KeyFieldName, val.GetType().IsArray ? val : new object[] { val }); sql = $"UPDATE \"{listForm.SelectCommand}\" SET {string.Join(',', updateFields)} WHERE {where}"; } else if (op == OperationEnum.Delete) { // todo: softdelete string where = string.Empty; if (parameters.Any()) { where = string.Join(" AND ", parameters.Select(a => $"\"{a.Key}\" IN (@{a.Key})").ToList()); } else { var val = QueryHelper.GetFormattedValue(listForm.KeyFieldDbSourceType, keys); parameters.Add( listForm.KeyFieldName, val.GetType().IsArray ? val : new object[] { val }); where = dataSourceType switch { DataSourceTypeEnum.Mssql => $"\"{listForm.KeyFieldName}\" IN (@{listForm.KeyFieldName})", DataSourceTypeEnum.Postgresql => $"\"{listForm.KeyFieldName}\" = ANY(@{listForm.KeyFieldName})", _ => "1 = 0", }; } sql = $"DELETE FROM \"{listForm.SelectCommand}\" WHERE {where}"; Console.WriteLine(sql); } } return sql; } }