erp-platform/api/src/Erp.Platform.Domain/Queries/QueryManager.cs
2025-12-07 01:03:53 +03:00

237 lines
10 KiB
C#

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<T> GenerateAndRunQueryAsync<T>(
string listFormCode,
OperationEnum op,
dynamic inputParams = null,
object[] keys = null,
Dictionary<string, StringValues> queryParameters = null);
string GenerateQuery(
ListForm listForm,
Dictionary<string, object> parameters,
OperationEnum op,
DataSourceTypeEnum dataSourceType,
object[] keys = null);
}
public class QueryManager : PlatformDomainService, IQueryManager
{
private readonly IStringLocalizer<PlatformResource> 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<PlatformResource> 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<T> GenerateAndRunQueryAsync<T>(
string listFormCode,
OperationEnum op,
dynamic inputParams = null,
object[] keys = null,
Dictionary<string, StringValues> 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)
{
if (!string.IsNullOrEmpty(listForm.InsertBeforeCommand))
{
var beforeSql = GenerateQuery(listForm, parameters, OperationEnum.InsertBefore, dataSourceType, keys);
await dynamicDataRepository.ExecuteAsync(beforeSql, connectionString, parameters);
}
var result = await dynamicDataRepository.ExecuteScalarAsync<T>(sql, connectionString, parameters);
if (!string.IsNullOrEmpty(listForm.InsertAfterCommand))
{
var afterSql = GenerateQuery(listForm, parameters, OperationEnum.InsertAfter, dataSourceType, keys);
await dynamicDataRepository.ExecuteAsync(afterSql, connectionString, parameters);
}
return result;
}
else if (op == OperationEnum.Update || op == OperationEnum.Delete)
{
// Before komutlari varsa calistir
if (op == OperationEnum.Update && !string.IsNullOrEmpty(listForm.UpdateBeforeCommand))
{
var beforeSql = GenerateQuery(listForm, parameters, OperationEnum.UpdateBefore, dataSourceType, keys);
await dynamicDataRepository.ExecuteAsync(beforeSql, connectionString, parameters);
}
else if (op == OperationEnum.Delete && !string.IsNullOrEmpty(listForm.DeleteBeforeCommand))
{
var beforeSql = GenerateQuery(listForm, parameters, OperationEnum.DeleteBefore, dataSourceType, keys);
await dynamicDataRepository.ExecuteAsync(beforeSql, connectionString, parameters);
}
// Ana komutu calistir
var result = (T)(object)await dynamicDataRepository.ExecuteAsync(sql, connectionString, parameters);
// After komutlari varsa calistir
if (op == OperationEnum.Update && !string.IsNullOrEmpty(listForm.UpdateAfterCommand))
{
var afterSql = GenerateQuery(listForm, parameters, OperationEnum.UpdateAfter, dataSourceType, keys);
await dynamicDataRepository.ExecuteAsync(afterSql, connectionString, parameters);
}
else if (op == OperationEnum.Delete && !string.IsNullOrEmpty(listForm.DeleteAfterCommand))
{
var afterSql = GenerateQuery(listForm, parameters, OperationEnum.DeleteAfter, dataSourceType, keys);
await dynamicDataRepository.ExecuteAsync(afterSql, connectionString, parameters);
}
return result;
}
}
return default;
}
public string GenerateQuery(
ListForm listForm,
Dictionary<string, object> parameters,
OperationEnum op,
DataSourceTypeEnum dataSourceType,
object[] keys = null)
{
var command = op switch
{
OperationEnum.Insert => listForm.InsertCommand,
OperationEnum.InsertBefore => listForm.InsertBeforeCommand,
OperationEnum.InsertAfter => listForm.InsertAfterCommand,
OperationEnum.Update => listForm.UpdateCommand,
OperationEnum.UpdateBefore => listForm.UpdateBeforeCommand,
OperationEnum.UpdateAfter => listForm.UpdateAfterCommand,
OperationEnum.Delete => listForm.DeleteCommand,
OperationEnum.DeleteBefore => listForm.DeleteBeforeCommand,
OperationEnum.DeleteAfter => listForm.DeleteAfterCommand,
_ => "",
};
// 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);
if (!parameters.ContainsKey(listForm.KeyFieldName))
{
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;
}
}