Skip to content

Commit

Permalink
Even nicer code, both in my code and in generated QueryExpressions
Browse files Browse the repository at this point in the history
  • Loading branch information
rappen committed Nov 18, 2022
1 parent bc7cd80 commit 95b2697
Showing 1 changed file with 85 additions and 46 deletions.
131 changes: 85 additions & 46 deletions FetchXmlBuilder/Converters/QueryExpressionCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Rappen.XTB.FetchXmlBuilder.Converters
public class QueryExpressionCodeGenerator
{
private const string CRLF = "\r\n";
private const string Indent = " ";
private List<string> varList;
private QueryExpression qex;
private List<EntityMetadata> metas;
Expand Down Expand Up @@ -73,17 +74,9 @@ private string CreateCSharpQueryExpression()
code.Append(GetQueryOptions());
code.Append(GetQueryCodeEnd());
code.Append(GetColumns(qex.EntityName, qex.ColumnSet, qename + ".ColumnSet"));
var links = new StringBuilder();
foreach (var link in qex.LinkEntities)
{
links.Append(GetLinkEntity(link, qename));
}
code.Append(GetFilter(qex.EntityName, qex.Criteria, qename, "Criteria"));
code.Append(links);
foreach (var order in qex.Orders)
{
code.AppendLine(qename + ".AddOrder(" + GetCodeAttribute(qex.EntityName, order.AttributeName) + ", OrderType." + order.OrderType.ToString() + ");");
}
code.Append(GetOrders(qex.EntityName, qex.Orders, qename, true));
code.Append(GetLinkEntities(qex.LinkEntities, qename));
var codestr = ReplaceValueTokens(code.ToString());
return codestr;
}
Expand Down Expand Up @@ -135,9 +128,13 @@ private string GetQueryOptions()
{
queryoptions.Add("TopCount = " + qex.TopCount.ToString());
}
if (!string.IsNullOrWhiteSpace(qex.PageInfo?.PagingCookie))
{
queryoptions.Add($"PageInfo = new PagingInfo{CRLF}{Indent}{{{CRLF}{Indent}{Indent}PageNumber = {qex.PageInfo.PageNumber},{CRLF}{Indent}{Indent}PagingCookie = \"{qex.PageInfo.PagingCookie}\"{CRLF}{Indent}}}");
}
if (queryoptions.Count > 0)
{
return CRLF + "{" + CRLF + string.Join("," + CRLF, queryoptions.Select(o => " " + o)) + CRLF + "}";
return CRLF + "{" + GetCodeParametersMaxWidth(0, queryoptions.ToArray()) + "}";
}
return string.Empty;
}
Expand Down Expand Up @@ -177,47 +174,54 @@ private string GetColumns(string entity, ColumnSet columns, string LineStart)
code.AppendLine();
code.AppendLine("// Add columns to " + LineStart);
}
var cols = string.Join(", ", columns.Columns.Select(c => GetCodeAttribute(entity, c))).Trim(' ');
if (cols.Length > 100)
{
cols = CRLF + " " + cols.Replace(", ", $",{CRLF} ") + CRLF;
}
if (settings.CodeGenerators.Style == CodeGenerationStyle.QueryExpressionFactory)
{
code.AppendLine(GetCodeEntityPrefix(entity) + " => new {");
code.AppendLine(cols);
code.AppendLine("}");
}
else
{
var method = ".AddColumn" + (columns.Columns.Count > 1 ? "s" : "");
code.AppendLine($"{LineStart}{method}({cols});");
}
LineStart =
settings.CodeGenerators.Style == CodeGenerationStyle.QueryExpressionFactory ?
GetCodeEntityPrefix(entity) + " => new { " :
LineStart + ".AddColumn" + (columns.Columns.Count > 1 ? "s" : "") + "(";
var LineEnd = settings.CodeGenerators.Style == CodeGenerationStyle.QueryExpressionFactory ? " }" : ");";
var cols = GetCodeParametersMaxWidth(120 - LineStart.Length, columns.Columns.Select(c => GetCodeAttribute(entity, c)).ToArray());
code.AppendLine(LineStart + cols + LineEnd);
}
return code.ToString();
}

private string GetLinkEntity(LinkEntity link, string LineStart)
private string GetLinkEntities(DataCollection<LinkEntity> linkEntities, string LineStart)
{
var code = new StringBuilder();
var linkname = GetVarName(string.IsNullOrEmpty(link.EntityAlias) ? LineStart + "_" + link.LinkToEntityName : link.EntityAlias);
code.AppendLine();
if (settings.CodeGenerators.IncludeComments)
if (linkEntities?.Count == 0)
{
code.AppendLine("// Add link-entity " + linkname);
return string.Empty;
}
var join = link.JoinOperator == JoinOperator.Inner ? "" : ", JoinOperator." + link.JoinOperator.ToString();
code.AppendLine($"var {linkname} = {LineStart}.AddLink({GetCodeEntity(link.LinkToEntityName)}, {GetCodeAttribute(link.LinkFromEntityName, link.LinkFromAttributeName)}, {GetCodeAttribute(link.LinkToEntityName, link.LinkToAttributeName)}{join});");
if (!string.IsNullOrWhiteSpace(link.EntityAlias))
{
entityaliases.Add(link.EntityAlias, link.LinkToEntityName);
code.AppendLine(linkname + ".EntityAlias = \"" + link.EntityAlias + "\";");
}
code.Append(GetColumns(link.LinkToEntityName, link.Columns, linkname + ".Columns"));
code.Append(GetFilter(link.LinkToEntityName, link.LinkCriteria, linkname, "LinkCriteria"));
foreach (var sublink in link.LinkEntities)
var code = new StringBuilder();
foreach (var link in linkEntities)
{
code.Append(GetLinkEntity(sublink, linkname));
var linkname = GetVarName(string.IsNullOrEmpty(link.EntityAlias) ? LineStart + "_" + link.LinkToEntityName : link.EntityAlias);
code.AppendLine();
if (settings.CodeGenerators.IncludeComments)
{
code.AppendLine("// Add link-entity " + linkname);
}
var join = link.JoinOperator == JoinOperator.Inner ? "" : "JoinOperator." + link.JoinOperator.ToString();
var varstart =
link.LinkEntities.Count > 0 ||
link.Columns.Columns.Count > 0 ||
link.LinkCriteria.Conditions.Count > 0 ||
link.Orders.Count > 0 ? $"var {linkname} = " : String.Empty;
var parms = GetCodeParametersMaxWidth(120 - varstart.Length - LineStart.Length,
GetCodeEntity(link.LinkToEntityName),
GetCodeAttribute(link.LinkFromEntityName,
link.LinkFromAttributeName),
GetCodeAttribute(link.LinkToEntityName, link.LinkToAttributeName),
join);
code.AppendLine($"{varstart}{LineStart}.AddLink({parms});");
if (!string.IsNullOrWhiteSpace(link.EntityAlias))
{
entityaliases.Add(link.EntityAlias, link.LinkToEntityName);
code.AppendLine(linkname + ".EntityAlias = \"" + link.EntityAlias + "\";");
}
code.Append(GetColumns(link.LinkToEntityName, link.Columns, linkname + ".Columns"));
code.Append(GetFilter(link.LinkToEntityName, link.LinkCriteria, linkname, "LinkCriteria"));
code.Append(GetOrders(link.LinkToEntityName, link.Orders, linkname));
code.Append(GetLinkEntities(link.LinkEntities, linkname));
}
return code.ToString();
}
Expand All @@ -231,7 +235,7 @@ private string GetFilter(string entity, FilterExpression filterExpression, strin
if (settings.CodeGenerators.IncludeComments)
{
code.AppendLine();
code.AppendLine("// Define filter " + LineStart);
code.AppendLine("// Add filter " + LineStart);
}
if (filterExpression.FilterOperator == LogicalOperator.Or)
{
Expand Down Expand Up @@ -274,6 +278,27 @@ private string GetFilter(string entity, FilterExpression filterExpression, strin
return code.ToString();
}

private string GetOrders(string entityname, DataCollection<OrderExpression> orders, string LineStart, bool root = false)
{
if (orders.Count == 0)
{
return string.Empty;
}
var code = new StringBuilder();
if (settings.CodeGenerators.IncludeComments)
{
code.AppendLine();
code.AppendLine("// Add orders");
}
LineStart += root ? ".AddOrder(" : ".Orders.Add(new OrderExpression(";
var LineEnd = root ? ");" : "));";
foreach (var order in orders)
{
code.AppendLine(LineStart + GetCodeAttribute(entityname, order.AttributeName) + ", OrderType." + order.OrderType.ToString() + LineEnd);
}
return code.ToString();
}

private string ReplaceValueTokens(string code)
{
if (!code.Contains("<<<"))
Expand All @@ -283,7 +308,7 @@ private string ReplaceValueTokens(string code)
var variables = new StringBuilder();
if (settings.CodeGenerators.IncludeComments)
{
variables.AppendLine("// Define Condition Values");
variables.AppendLine("// Set Condition Values");
}
while (code.Contains("<<<"))
{
Expand Down Expand Up @@ -351,6 +376,20 @@ private string GetCodeAttribute(string entityname, string attributename)
return "\"" + attributename + "\"";
}

private static string GetCodeParametersMaxWidth(int maxwidth, params string[] parameters)
{
var result = string.Join("", parameters.Where(p => !string.IsNullOrWhiteSpace(p)));
if (result.Length > maxwidth)
{
result = CRLF + Indent + result.Replace("", $",{CRLF}{Indent}") + CRLF;
}
else
{
result = result.Replace("", ", ");
}
return result;
}

private static string GetConditionValues(DataCollection<object> values, string token)
{
var strings = new List<string>();
Expand Down

0 comments on commit 95b2697

Please sign in to comment.