erp-platform/api/src/Erp.Platform.Domain/Queries/SelectQueryManager.cs

821 lines
32 KiB
C#
Raw Normal View History

2025-05-06 06:45:49 +00:00
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Text.Json;
2025-11-11 19:49:52 +00:00
using Erp.Platform.Entities;
using Erp.Platform.Enums;
using Erp.Platform.Extensions;
using Erp.Platform.ListForms;
using Erp.Platform.Localization;
using Erp.Platform.OrganizationUnits;
2025-05-06 06:45:49 +00:00
using Microsoft.Extensions.Localization;
2025-06-15 20:57:14 +00:00
using Volo.Abp.Domain.Repositories;
2025-05-06 06:45:49 +00:00
using Volo.Abp.ObjectMapping;
using Volo.Abp.Settings;
using Volo.Abp.Users;
2025-11-11 19:49:52 +00:00
namespace Erp.Platform.Queries;
2025-05-06 06:45:49 +00:00
public interface ISelectQueryManager
{
List<SelectField> SelectFields { get; }
string SelectQuery { get; }
Dictionary<string, object> SelectQueryParameters { get; }
string TotalCountQuery { get; }
string GroupQuery { get; }
string ChartQuery { get; }
2025-05-06 06:45:49 +00:00
public string DeleteQuery { get; }
List<(int Index, string Field, string SelectExpr, string Sort, bool IsExpanded, string GroupInterval)> GroupTuples { get; }
List<(int Index, string Field, string SelectExpr, string SummaryType)> GroupSummaryTuples { get; }
List<string> SummaryQueries { get; }
public bool IsAppliedGridFilter { get; }
public bool IsAppliedServerFilter { get; }
void PrepareQueries(ListForm listform,
List<ListFormField> listFormFields,
DataSourceTypeEnum dataSourceType,
List<ListFormCustomization> listFormCustomizations = null,
QueryParameters queryParams = null);
}
public class SelectField
{
public SelectField() { }
public SelectField(ListFormField item, string baseTableName)
{
FieldName = item.FieldName;
if (!string.IsNullOrEmpty(item.JoinTableJson))
JoinOptions = JsonSerializer.Deserialize<JoinTable>(item.JoinTableJson);
if (JoinOptions != null && !string.IsNullOrWhiteSpace(JoinOptions.TableName))
{
if (!string.IsNullOrEmpty(JoinOptions.FieldNameAlias))
SelectFieldName = $"\"{JoinOptions.TableName}\".\"{JoinOptions.SelectFieldName}\" AS \"{JoinOptions.FieldNameAlias}\"";
else
SelectFieldName = $"\"{JoinOptions.TableName}\".\"{JoinOptions.SelectFieldName}\" AS \"{FieldName}\"";
JoinSql = $"{JoinOptions.JoinType} \"{JoinOptions.TableName}\" ON \"{JoinOptions.TableName}\".\"{JoinOptions.JoinFieldName}\" = \"{baseTableName}\".\"{JoinOptions.BaseTableJoinFieldName}\"";
// JOIN bolumunde birden fazla condition var ise
if (!string.IsNullOrEmpty(JoinOptions.JoinFieldName2))
{
JoinSql += $" {JoinOptions.JoinCondition2} \"{JoinOptions.JoinFieldName2}\" = {JoinOptions.BaseTableJoinFieldName2_OrValue}";
}
IsJoined = true;
}
else
{
SelectFieldName = $"\"{baseTableName}\".\"{this.FieldName}\" AS \"{FieldName}\"";
IsJoined = false;
}
}
public string FieldName { get; set; } // UserName
public string SelectFieldName { get; set; } // ListForm.UserName as UserName
public bool IsJoined { get; set; }
public JoinTable JoinOptions { get; set; }
public string JoinSql { get; set; }
}
public class SelectQueryManager : PlatformDomainService, ISelectQueryManager
{
private string SelectCommand { get; set; }
private string TableName { get; set; }
private string From { get { return SelectCommandType == SelectCommandTypeEnum.Query ? $"({SelectCommand})" : SelectCommand; } }
private SelectCommandTypeEnum SelectCommandType { get; set; }
private string KeyFieldName { get; set; }
private List<string> JoinParts { get; set; }
private List<string> WhereParts { get; set; }
private List<string> SortParts { get; set; }
private DataSourceTypeEnum DataSourceType { get; set; }
public List<SelectField> SelectFields { get; private set; }
public string SelectQuery { get; private set; }
public Dictionary<string, object> SelectQueryParameters { get; private set; }
public string TotalCountQuery { get; private set; }
public string GroupQuery { get; private set; }
public string DeleteQuery { get; private set; }
public string ChartQuery { get; private set; }
2025-05-06 06:45:49 +00:00
public List<(int Index, string Field, string SelectExpr, string Sort, bool IsExpanded, string GroupInterval)> GroupTuples { get; private set; } = [];
public List<(int Index, string Field, string SelectExpr, string SummaryType)> GroupSummaryTuples { get; private set; } = [];
public List<string> SummaryQueries { get; private set; }
public bool IsAppliedGridFilter { get; private set; }
public bool IsAppliedServerFilter { get; private set; }
public IPlatformOuRepository OuRepository { get; }
2025-06-15 20:57:14 +00:00
public IRepository<BranchUsers, Guid> BranchUsersRepository { get; }
public DefaultValueHelper DefaultValueHelper { get; }
2025-05-06 06:45:49 +00:00
public SelectQueryManager(
ISettingProvider settingProvider,
IStringLocalizer<PlatformResource> localizer,
ICurrentUser currentUser,
IObjectMapper objectMapper,
IListFormAuthorizationManager authManager,
IPlatformOuRepository ouRepository,
IRepository<BranchUsers, Guid> branchUsersRepository,
DefaultValueHelper defaultValueHelper)
2025-05-06 06:45:49 +00:00
: base(settingProvider, localizer, currentUser, objectMapper, authManager)
{
SelectFields = [];
JoinParts = [];
WhereParts = [];
SortParts = [];
SummaryQueries = [];
OuRepository = ouRepository;
2025-06-15 20:57:14 +00:00
BranchUsersRepository = branchUsersRepository;
DefaultValueHelper = defaultValueHelper;
2025-05-06 06:45:49 +00:00
}
public void PrepareQueries(ListForm listform,
List<ListFormField> listFormFields,
DataSourceTypeEnum dataSourceType,
List<ListFormCustomization> listFormCustomizations = null,
QueryParameters queryParams = null)
{
if (listform == null)
{
return;
}
int take = queryParams?.Take > 0
? queryParams.Take
: listform.PageSize > 0
? listform.PageSize
: PlatformConsts.GridOptions.RowsPerPage;
int skip = queryParams?.Skip ?? 0;
DataSourceType = dataSourceType;
SelectCommand = DefaultValueHelper.GetDefaultValue(listform.SelectCommand);
2025-05-06 06:45:49 +00:00
TableName = listform.TableName.IsNullOrEmpty() ? SelectCommand : listform.TableName;
KeyFieldName = listform.KeyFieldName;
SelectCommandType = listform.SelectCommandType;
var KeyField = new SelectField
{
FieldName = KeyFieldName,
SelectFieldName = $"\"{TableName}\".\"{KeyFieldName}\" AS \"{KeyFieldName}\"",
IsJoined = false
};
SelectFields.AddRange(GetSelectAndJoinFields(listFormFields));
if (!SelectFields.Any(a => a.FieldName == KeyField.FieldName))
{
SelectFields.Add(KeyField);
}
var joinParts = SelectFields.Where(c => !string.IsNullOrEmpty(c.JoinSql)).Select(c => c.JoinSql).Distinct();
JoinParts.AddRange(joinParts);
List<string> whereFields = GetWhereFields(listform, listFormFields, queryParams);
WhereParts.AddRange(whereFields);
List<string> sortFields = GetSortFields(listform, listFormFields, queryParams?.Sort);
SortParts.AddRange(sortFields);
SelectQuery = GetSelectString();
SetJoinStringFromCustomizations(listFormCustomizations);
SelectQuery += GetJoinString();
SetWhereStringFromCustomizations(listFormCustomizations);
SelectQuery += GetWhereString();
SelectQuery += GetSortString();
// queryParams null ise grid olusturmak icin gelmistir, paging yapma
if (queryParams != null && queryParams.Take > 0)
{
SelectQuery += GetPagingString(take, skip);
}
TotalCountQuery = GetTotalCountQuery();
GroupQuery = GetGroupQuery(listFormFields, queryParams);
DeleteQuery = GetDeleteQuery(queryParams);
ChartQuery = GetChartQuery(listform, queryParams);
2025-05-06 06:45:49 +00:00
#region Total Summary Queries
if (queryParams != null && !queryParams.TotalSummary.IsNullOrWhiteSpace())
{
var items = new List<object>();
var summaries = queryParams.TotalSummary.Split(PlatformConsts.MultiValueDelimiter);
for (int i = 0; i < summaries.Length; i++)
{
var summary = summaries[i].Split(' ');
var fieldName = summary[0];
var summmaryType = summary[1]; // asc, desc
fieldName = ConvertAliasToFieldName(fieldName, listFormFields);
if (fieldName == "undefined")
{
continue;
}
SummaryQueries.Add(GetSummaryQuery(fieldName, summmaryType));
}
}
#endregion
}
private List<SelectField> GetSelectAndJoinFields(List<ListFormField> listFormFields)
{
List<SelectField> selectFields = [];
foreach (var itemField in listFormFields.OrderBy(c => c.JoinTableJson))
{
if (!itemField.IsActive.HasValue || !itemField.IsActive.Value || itemField.IsDeleted)
{
continue;
}
selectFields.Add(new(itemField, TableName));
}
return selectFields;
}
/// <summary> Sadece join li alanlar icin gercek SqlField bigisini verir
/// </summary>
/// <param name="filterName"></param>
/// <param name="listFormFields"></param>
/// <returns></returns>
private string ConvertAliasToFieldName(string filterName, List<ListFormField> listFormFields, string groupInterval = null)
{
var format = groupInterval switch
{
"year" =>
DataSourceType == DataSourceTypeEnum.Mssql ? "DATEPART(YEAR, {0})" :
DataSourceType == DataSourceTypeEnum.Postgresql ? "DATE_PART('YEAR', {0})" : "",
"quarter" =>
DataSourceType == DataSourceTypeEnum.Mssql ? "DATEPART(QUARTER, {0})" :
DataSourceType == DataSourceTypeEnum.Postgresql ? "DATE_PART('QUARTER', {0})" : "",
"month" =>
DataSourceType == DataSourceTypeEnum.Mssql ? "DATEPART(MONTH, {0})" :
DataSourceType == DataSourceTypeEnum.Postgresql ? "DATE_PART('MONTH', {0})" : "",
"day" =>
DataSourceType == DataSourceTypeEnum.Mssql ? "DATEPART(DAY, {0})" :
DataSourceType == DataSourceTypeEnum.Postgresql ? "DATE_PART('DAY', {0})" : "",
"dayOfWeek" =>
DataSourceType == DataSourceTypeEnum.Mssql ? "DATEPART(DW, {0})" :
DataSourceType == DataSourceTypeEnum.Postgresql ? "DATE_PART('DOW', {0})" : "",
_ => "{0}"
};
var field = listFormFields.FirstOrDefault(a => a.FieldName == filterName && !string.IsNullOrWhiteSpace(a.JoinTableJson));
if (field is not null)
{
var jt = JsonSerializer.Deserialize<JoinTable>(field.JoinTableJson);
if (!jt.TableName.IsNullOrWhiteSpace())
{
return string.Format(format, $"\"{jt.TableName}\".\"{jt.SelectFieldName}\"");
}
}
return string.Format(format, $"\"{TableName}\".\"{filterName}\"");
}
private string GetSelectString()
{
return $"SELECT {string.Join(',', SelectFields.Select(c => $"{c.SelectFieldName}"))} FROM \"{From}\" AS \"{TableName}\"";
}
private string SetJoinStringFromCustomizations(List<ListFormCustomization> listFormCustomizations)
{
if (listFormCustomizations.IsNullOrEmpty())
{
return string.Empty;
}
var customizations = listFormCustomizations
.Where(a => a.CustomizationType == ListFormCustomizationTypeEnum.ServerJoin)
.Select(a => a.CustomizationData)
.ToList();
JoinParts.AddRange(customizations);
return string.Join(' ', customizations);
}
/// <summary>
/// WhereParts icerisine ListFormCustomization tanimindan gelen filtreleri ekler
/// </summary>
/// <param name="listFormCustomization"></param>
private void SetWhereStringFromCustomizations(List<ListFormCustomization> listFormCustomizations)
{
if (listFormCustomizations.IsNullOrEmpty())
{
return;
}
var customizations = listFormCustomizations
.Where(a => a.CustomizationType == ListFormCustomizationTypeEnum.ServerWhere)
.Select(a => a.CustomizationData)
.ToList();
foreach (var item in customizations)
{
if (WhereParts.Any())
{
WhereParts.Add("AND");
}
WhereParts.Add(DefaultValueHelper.GetDefaultValue(item));
2025-05-06 06:45:49 +00:00
IsAppliedServerFilter = true;
}
}
private List<string> GetWhereFields(ListForm listform, List<ListFormField> listFormFields, QueryParameters queryParams = null)
{
var whereParts = new List<string>();
if (!string.IsNullOrEmpty(queryParams?.Filter))
{
var filters = queryParams.Filter.Replace('[', '(')
.Replace(']', ')')
.Replace("\"\"", "''") // (empty string) "" -> ''
.Replace("\"", "")
.Replace(",\"or\",", " or ")
.Replace(",\"and\",", " and ");
var filterItems = filters.Split(",").ToList();
if (filterItems
.Where(a => !a.Contains('!') && a != "and" && a != "or")
.ToList().Count % 3 == 0) //Eğer gelen veri 'and', 'or' veya '!' dışında kalan item adedi 3 ün katıysa
{
SelectQueryParameters = new Dictionary<string, object>();
var forDeger = 3;
for (int i = 0; i < filterItems.Count; i += forDeger)
{
if (filterItems[i].Contains('!'))
{
forDeger = 1;
whereParts.Add(filterItems[i].Replace("!", "NOT"));
IsAppliedGridFilter = true;
}
else if (filterItems[i] == "and" || filterItems[i] == "or")
{
forDeger = 1;
whereParts.Add(filterItems[i]);
IsAppliedGridFilter = true;
}
else
{
forDeger = 3;
var fieldName = filterItems[i];
var op = filterItems[i + 1];
var fieldValue = filterItems[i + 2];
var filter = ParseFilter(fieldName, op, fieldValue, listFormFields, i);
if (filter != "")
{
whereParts.Add(filter);
IsAppliedGridFilter = true;
}
}
}
}
}
if (!listform.DefaultFilter.IsNullOrWhiteSpace())
{
if (whereParts.Any())
{
whereParts.Add("AND");
}
whereParts.Add(DefaultValueHelper.GetDefaultValue(listform.DefaultFilter));
2025-05-06 06:45:49 +00:00
IsAppliedServerFilter = true;
}
if (PlatformConsts.IsMultiTenant && listform.IsTenant)
{
if (whereParts.Any())
{
whereParts.Add("AND");
}
if (CurrentTenant.IsAvailable)
{
whereParts.Add($"\"TenantId\" = '{CurrentTenant.Id}'");
}
else
{
whereParts.Add($"\"TenantId\" IS NULL");
}
}
if (listform.IsBranch)
{
if (whereParts.Any())
{
whereParts.Add("AND");
}
2025-06-15 20:57:14 +00:00
var ids = BranchUsersRepository.GetListAsync((a) => a.UserId == CurrentUser.Id.Value).Result;
if (ids.Count > 0)
{
2025-06-15 20:57:14 +00:00
whereParts.Add($"\"BranchId\" IN ({string.Join(",", ids.Select(a => $"'{a.BranchId}'"))})");
}
else
{
whereParts.Add($"\"BranchId\" = '{Guid.Empty}'");
}
}
2025-05-06 06:45:49 +00:00
if (listform.IsOrganizationUnit)
{
if (whereParts.Any())
{
whereParts.Add("AND");
}
var ids = OuRepository.GetOrganizationUnitIdsWithChildren(CurrentUser.Id.Value).Result;
if (ids.Count > 0)
{
whereParts.Add($"\"OrganizationUnitId\" IN ({string.Join(",", ids.Select(a => $"'{a}'"))})");
}
else
{
whereParts.Add($"\"OrganizationUnitId\" = '{Guid.Empty}'");
}
}
if (!whereParts.Any())
{
whereParts.Add("1 = 1");
}
return whereParts;
}
/// <summary> FieldName operator Id seklinde olan filtreleri ayirir
/// </summary>
/// <param name="filter"></param>
/// <returns></returns>
private string ParseFilter(
string fieldName,
string op,
string fieldValue,
List<ListFormField> listFormFields,
int customKey)
{
string sqlPart = string.Empty;
if (string.IsNullOrWhiteSpace(fieldName) || string.IsNullOrWhiteSpace(op))
{
return sqlPart;
}
var fieldDbType = DbType.String;
2025-05-06 06:45:49 +00:00
var fieldFilter = fieldName.Split('.');
var filterFieldName = fieldFilter.First().RemoveParentheses();
var filterGroupInterval = fieldFilter.Length > 1 ? fieldFilter.Last().ToLower() : null;
var filterParamKey = $"@{filterFieldName}{customKey}";
var filterParamKeyLower = filterParamKey;
var filterOperator = op.RemoveParentheses();
var filterValue = fieldValue.RemoveParentheses();
2025-05-06 06:45:49 +00:00
var listFormField = listFormFields.FirstOrDefault(c => c.FieldName == filterFieldName);
if (listFormField == null)
{
fieldDbType = ListFormManager.InferDbTypeFromString(filterValue);
2025-05-06 06:45:49 +00:00
}
else
2025-05-06 06:45:49 +00:00
{
// filterGroupInterval sayı olduğu için (örn OrderDate.Month), eğer bu gelirse sayıya parse ediyoruz,
// diğer durumlarda field tipine parse ediyoruz
fieldDbType = filterGroupInterval switch
{
"year" or "quarter" or "month" or "day" or "dayOfWeek" => DbType.Int32,
_ => listFormField.SourceDbType
};
}
2025-05-06 06:45:49 +00:00
if (filterValue == "null")
{
if (filterOperator == "=") filterOperator = "isblank";
if (filterOperator == "<>") filterOperator = "isnotblank";
}
var lastCharacters = fieldValue.Replace(filterValue, string.Empty); // Sadece parantezleri almak için
var filterSqlFieldName = ConvertAliasToFieldName(filterFieldName, listFormFields, filterGroupInterval);
if (filterOperator == "=" && DataSourceType == DataSourceTypeEnum.Postgresql && (
fieldDbType == DbType.String ||
fieldDbType == DbType.AnsiString))
2025-05-06 06:45:49 +00:00
{
filterSqlFieldName = $"lower({filterSqlFieldName})";
filterParamKeyLower = $"lower({filterParamKeyLower})";
filterValue = filterValue.Replace('I', 'ı');
}
filterSqlFieldName = fieldFilter.First().Replace(filterFieldName, filterSqlFieldName);
var sqlOperator = "";
string formatSql = "{0} {1} {2}";
string concatOp =
DataSourceType == DataSourceTypeEnum.Mssql ? "+" :
DataSourceType == DataSourceTypeEnum.Postgresql ? "||"
: "";
string likeOp =
DataSourceType == DataSourceTypeEnum.Mssql ? "LIKE" :
DataSourceType == DataSourceTypeEnum.Postgresql ? "ILIKE"
: "";
if (filterOperator == "=") sqlOperator = "=";
else if (filterOperator == "<>") sqlOperator = "<>";
else if (filterOperator == "<") sqlOperator = "<";
else if (filterOperator == "<=") sqlOperator = "<=";
else if (filterOperator == ">") sqlOperator = ">";
else if (filterOperator == ">=") sqlOperator = ">=";
else if (filterOperator == "contains") formatSql = "{0} " + likeOp + " '%' " + concatOp + " {2} " + concatOp + " '%'";
else if (filterOperator == "notcontains") formatSql = "{0} NOT " + likeOp + " '%' " + concatOp + " {2} " + concatOp + " '%'";
else if (filterOperator == "startswith") formatSql = "{0} " + likeOp + " {2} " + concatOp + " '%'";
else if (filterOperator == "endswith") formatSql = "{0} " + likeOp + " '%' " + concatOp + " {2}";
else if (filterOperator == "isblank") formatSql = "{0} IS NULL";
else if (filterOperator == "isnotblank") formatSql = "{0} IS NOT NULL";
sqlPart = string.Format(formatSql, filterSqlFieldName, sqlOperator, filterParamKeyLower);
if (lastCharacters.Any())
{
sqlPart += lastCharacters;
}
if (formatSql.Contains("{2}"))
{
SelectQueryParameters.Add(filterParamKey, QueryHelper.GetFormattedValue(fieldDbType, filterValue));
2025-05-06 06:45:49 +00:00
}
return sqlPart;
}
private List<string> GetSortFields(ListForm listform,
List<ListFormField> listFormFields,
string sort = null)
{
var sortFields = new List<string>();
if (listform.SortMode == PlatformConsts.GridOptions.SortModeNone)
{
sortFields.Add("CURRENT_TIMESTAMP");
return SortParts;
}
// kullanicinin islemi ile siralama yapiliyor ise
if (!string.IsNullOrEmpty(sort))
{
var sorts = sort.Split(PlatformConsts.MultiValueDelimiter, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < sorts.Length; i++)
{
// sorts[i] su sekilde gelir: "AlanIsmi desc"
var sortElem = sorts[i].Trim().Split(' ', StringSplitOptions.RemoveEmptyEntries);
sortElem[0] = $"\"{sortElem[0].Trim()}\""; // Grid uzerinden gelen siralama istegi icin alan ismini koseli parantes icerisine al (Anahtar isimdeki alanlar icin Bug olusmasini onler, ornegin Key isminde bir alana ait siralama istegi gelebilir)
sortFields.Add(sortElem.JoinAsString(" ")); // Gelen istegi su sekle donusturur: [AlanIsmi] desc
}
}
else // ekran tanimi ile siralama yapiliyor ise
{
foreach (var itemField in listFormFields.Where(c => c.SortIndex.HasValue && c.SortIndex > 0).OrderBy(c => c.SortIndex))
{
sortFields.Add($"\"{itemField.FieldName}\" {itemField.SortDirection}");
}
}
// Varsayilan olarak siramalama yok ise siralamayi etkilemeyecek bir alan ekle (paging islemlerinde Order By bolumu istenildigi icin eklendi)
if (sortFields.Count == 0)
{
sortFields.Add("CURRENT_TIMESTAMP");
}
return sortFields;
}
private string GetJoinString()
{
return " " + string.Join(' ', JoinParts);
}
private string GetWhereString()
{
if (WhereParts.Count == 0)
return "";
return " WHERE " + string.Join(' ', WhereParts);
}
private string GetSortString()
{
return " ORDER BY " + string.Join(',', SortParts);
}
private string GetPagingString(int take, int? skip = 0)
{
return $" OFFSET {skip} ROWS FETCH NEXT {take} ROWS ONLY";
}
private string GetTotalCountQuery()
{
var sql = $"SELECT COUNT(\"{TableName}\".\"{KeyFieldName}\") FROM \"{From}\" AS \"{TableName}\"";
sql += GetJoinString();
sql += GetWhereString();
return sql;
}
private string GetSummaryQuery(string fieldName, string summaryType)
{
var sql = $"SELECT {summaryType}({fieldName}) FROM \"{From}\" AS \"{TableName}\"";
sql += GetJoinString();
sql += GetWhereString();
return sql;
}
private string GetGroupQuery(List<ListFormField> listFormFields, QueryParameters queryParams = null)
{
if (queryParams == null || queryParams.Group.IsNullOrWhiteSpace())
{
return null;
}
var validSummaryTypes = new string[] { "sum", "avg", "min", "max", "count" };
var validSortTypes = new string[] { "asc", "desc" };
var validGroupIntervals = new string[] { "day", "dayOfWeek", "month", "quarter", "year" };
// queryParams.Group veri yapisi:
// AlanIsmi desc isExpanded groupInterval
// Örn: group:IsEnabled asc false|TextDate asc false year|TextDate asc false month|CultureName asc false
// yapilan grup islemlerinde her bir gruplama icin bir ya da birden fazla istek geliyor.
var groups = queryParams.Group?.Split(PlatformConsts.MultiValueDelimiter);
foreach (var (group, i) in groups.Select((a, i) => (a, i)))
{
var items = group.Trim().Split(' ');
if (!items.Length.IsBetween(2, 4))
{
continue;
}
var field = items[0];
var sort = validSortTypes.Contains(items[1]) ? items[1] : "asc";
var isExpanded = items.Length > 2 && items[2] == "true";
var groupInterval = items.Length > 3 ? validGroupIntervals.Contains(items[3]) ? items[3] : null : null;
var fieldName = ConvertAliasToFieldName(field, listFormFields, groupInterval);// Alias li bir alan ise gercek alani bul
GroupTuples.Add((i, fieldName, $"Group_{i}", sort, isExpanded, groupInterval));
}
// gruplanan bir alan icin grup satirinda summary bilgisinin gorunmesi icin gerekli veri yapisidir,
// grup sorgusu ile birlikte calistirilir.
// Gelen veri yapisi: FieldName SummaryType|FieldName SummaryType
// Örn: groupSummary:TextCount sum|TextCount count
// Not: Gelen sira ile ayni sekilde geri dondurulmelidir! GroupSummaryItems bunun icin kullaniliyor
var groupSummaries = queryParams.GroupSummary?.Split(PlatformConsts.MultiValueDelimiter);
if (!groupSummaries.IsNullOrEmpty())
{
foreach (var (groupSummary, i) in groupSummaries.Select((a, i) => (a, i)))
{
var gs = groupSummary.Trim().Split(' ');
if (gs.Length != 2)
{
continue;
}
var field = gs[0].ToString();
var summaryType = gs[1].ToString();
if (!validSummaryTypes.Contains(summaryType))
{
continue;
}
var fieldName = ConvertAliasToFieldName(field, listFormFields);// Alias li bir alan ise gercek alani bul
GroupSummaryTuples.Add((i, fieldName, $"Summary_{i}", summaryType));
}
}
var sqlSub = new StringBuilder();
sqlSub.Append("SELECT ");
sqlSub.Append(string.Join(',', GroupTuples.Select((a) => $"{a.Field} AS \"{a.SelectExpr}\"")));
sqlSub.Append(string.Join(',', GroupSummaryTuples.Select((a) => $",{a.SummaryType}({a.Field}) AS \"{a.SelectExpr}\"")));
sqlSub.Append(",COUNT(1) AS \"Summary_Count\"");
sqlSub.Append($" FROM \"{From}\" AS \"{TableName}\"");
sqlSub.Append(GetJoinString());
sqlSub.Append(GetWhereString());
sqlSub.Append($" GROUP BY {string.Join(',', GroupTuples.Select((a) => a.Field))}");
sqlSub.Append($" ORDER BY {string.Join(',', GroupTuples.Select((a, i) => $"\"{a.SelectExpr}\" {a.Sort}"))}");
if (queryParams.Take > 0)
{
sqlSub.Append(GetPagingString(queryParams.Take, queryParams.Skip));
}
else
{
sqlSub.Append(" OFFSET 0 ROWS");
}
var sqlMain = new StringBuilder();
sqlMain.Append("SELECT ");
sqlMain.Append(string.Join(',', GroupTuples.Select((a) => $"\"{a.SelectExpr}\"")));
foreach (var item in GroupTuples.Select((groupTuple, i) => (groupTuple, i)))
{
var prevItems = GroupTuples.Take(item.i + 1);
if (prevItems.Count() == 1)
{
sqlMain.Append($",\"{item.groupTuple.SelectExpr}\" AS \"{item.groupTuple.SelectExpr}_Key\"");
}
else
{
sqlMain.Append($",CONCAT({string.Join(",'" + PlatformConsts.MultiValueDelimiter + "',", prevItems.Select(a => $"\"{a.SelectExpr}\""))}) AS \"{item.groupTuple.SelectExpr}_Key\"");
}
}
sqlMain.Append(", \"Summary_Count\"");
foreach (var summaryTuple in GroupSummaryTuples)
{
var sType = summaryTuple.SummaryType == "count" ? "sum" : summaryTuple.SummaryType;
var summarySelect = $"{sType}(\"{summaryTuple.SelectExpr}\")";
sqlMain.Append($",{summarySelect} OVER() AS \"{summaryTuple.SelectExpr}_All\"");
var partitionBy = new List<string>();
foreach (var groupTuple in GroupTuples)
{
partitionBy.Add($"\"{groupTuple.SelectExpr}\"");
sqlMain.Append($",{summarySelect} OVER(PARTITION BY {string.Join(',', partitionBy)}) AS \"{summaryTuple.SelectExpr}_{groupTuple.Index}\"");
}
partitionBy.Clear();
}
// foreach (var summaryTuple in GroupSummaryTuples)
// {
// var summarySelect = $"{summaryTuple.SummaryType}({summaryTuple.SelectExpr})";
// sqlMain.Append($",{summarySelect} OVER() AS {summaryTuple.SelectExpr}_All");
// foreach (var item in GroupTuples.Select((tuple, i) => (tuple, i)))
// {
// var groupTuple = item.tuple;
// if (item.i == 0)
// {
// sqlMain.Append($",{summaryTuple.SelectExpr} AS {summaryTuple.SelectExpr}_{groupTuple.Index}");
// }
// else
// {
// sqlMain.Append($",{summarySelect} OVER(PARTITION BY {groupTuple.SelectExpr}) AS {summaryTuple.SelectExpr}_{groupTuple.Index}");
// }
// }
// }
sqlMain.Append($" FROM ({sqlSub}) AS \"Sub\"");
sqlMain.Append($" ORDER BY {string.Join(',', GroupTuples.Select((a, i) => $"\"{a.SelectExpr}\" {a.Sort}"))}");
return sqlMain.ToString();
}
private string GetDeleteQuery(QueryParameters queryParams = null)
{
if (queryParams == null || queryParams.CreateDeleteQuery == false)
return null;
return $"DELETE \"{TableName}\" FROM {SelectCommand} AS \"{TableName}\" {GetWhereString()}";
}
public string GetChartQuery(ListForm listform, QueryParameters queryParams = null)
{
if (listform == null || string.IsNullOrWhiteSpace(listform.SeriesJson) || queryParams == null)
return null;
var seriesList = JsonSerializer.Deserialize<List<ChartSeries>>(listform.SeriesJson);
2025-09-30 13:11:23 +00:00
if (seriesList == null || seriesList.Count == 0)
return null;
// ArgumentField listesi
var argumentFields = seriesList.Select(s => s.ArgumentField).Distinct().ToList();
// ArgumentField ifadesini oluştur
string argumentExpression;
if (argumentFields.Count == 1)
{
// Tek ArgumentField
argumentExpression = $"[{argumentFields.First()}]";
}
else
{
// Birden fazla → '|' ile birleştir
argumentExpression = string.Join(" + '|' + ", argumentFields.Select(f => $"[{f}]"));
}
// Select sütunlarını oluştur
var selectParts = new List<string> { $"{argumentExpression} AS ArgumentField" };
foreach (var series in seriesList)
{
string sqlFunc = series.SummaryType.ToUpper() switch
{
"COUNT" => $"COUNT([{series.ValueField}])",
"SUM" => $"SUM([{series.ValueField}])",
"AVG" => $"AVG([{series.ValueField}])",
"MIN" => $"MIN([{series.ValueField}])",
"MAX" => $"MAX([{series.ValueField}])",
_ => throw new NotSupportedException($"Unsupported SummaryType: {series.SummaryType}")
};
selectParts.Add($"{sqlFunc} AS [{series.Name}]");
}
// SQL cümlesi
var sql = $@"
SELECT {string.Join(", ", selectParts)}
FROM [{listform.SelectCommand}]
2025-09-29 08:33:51 +00:00
{GetWhereString()}
GROUP BY {argumentExpression}";
return sql;
}
2025-11-11 19:49:52 +00:00
}