Skip to content

Commit

Permalink
Merge pull request #855 from rappen/fluentqex
Browse files Browse the repository at this point in the history
QueryExpression styles and flavors
  • Loading branch information
rappen committed Jan 25, 2023
2 parents d687bb3 + 902b71c commit 47c221c
Show file tree
Hide file tree
Showing 28 changed files with 3,147 additions and 777 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,4 @@ ModelManifest.xml
/tmp
/.vs/config/applicationhost.config
/.vs
/QEx samples
6 changes: 3 additions & 3 deletions FXBTests/QueryExpressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public void StandardCondition()
qe.ColumnSet = new ColumnSet("fullname", "lastname");
qe.Criteria.AddCondition("modifiedon", ConditionOperator.GreaterThan, "2020-01-01");

var converted = QueryExpressionCodeGenerator.GetCSharpQueryExpression(qe, null, new FXBSettings());
var converted = CSharpCodeGenerator.GetCSharpQueryExpression(qe, null, new FXBSettings());

var expected = @"// Define Condition Values
var query_modifiedon = ""2020-01-01"";
Expand All @@ -40,7 +40,7 @@ public void ColumnComparisonCondition()
qe.ColumnSet = new ColumnSet("fullname", "lastname");
qe.Criteria.AddCondition(new ConditionExpression("modifiedon", ConditionOperator.GreaterThan, true, "createdon"));

var converted = QueryExpressionCodeGenerator.GetCSharpQueryExpression(qe, null, new FXBSettings());
var converted = CSharpCodeGenerator.GetCSharpQueryExpression(qe, null, new FXBSettings());

var expected = @"// Define Condition Values
var query_modifiedon = ""createdon"";
Expand All @@ -66,7 +66,7 @@ public void MultipleComparisonsOnSameField()
qe.Criteria.AddCondition("modifiedon", ConditionOperator.GreaterThan, "2020-01-01");
qe.Criteria.AddCondition(new ConditionExpression("modifiedon", ConditionOperator.GreaterThan, true, "createdon"));

var converted = QueryExpressionCodeGenerator.GetCSharpQueryExpression(qe, null, new FXBSettings());
var converted = CSharpCodeGenerator.GetCSharpQueryExpression(qe, null, new FXBSettings());

var expected = @"// Define Condition Values
var query_modifiedon = ""2020-01-01"";
Expand Down
1,366 changes: 1,330 additions & 36 deletions FetchXmlBuilder/Converters/CSharpCodeGenerator.cs

Large diffs are not rendered by default.

83 changes: 83 additions & 0 deletions FetchXmlBuilder/Converters/CSharpCodeGeneratorFetchXML.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using Rappen.XTB.FetchXmlBuilder.Settings;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.Text;
using System.Xml;

namespace Rappen.XTB.FetchXmlBuilder.Converters
{
public class CSharpCodeGeneratorFetchXML
{
public static string GetCSharpFetchXMLCode(string fetchXml, CodeGenerators codesettings)
{
var data = new Dictionary<string, string>();
var xml = new XmlDocument();
xml.LoadXml(fetchXml);

if (codesettings.FilterVariables)
{
var conditionAttributes = xml.SelectNodes("//condition/@value");

foreach (XmlAttribute attribute in conditionAttributes)
{
var value = AddData(attribute.OwnerElement.GetAttribute("attribute"), attribute.Value, data);
attribute.Value = $"{{{value}}}";
}

var conditionValues = xml.SelectNodes("//condition/value");

foreach (XmlElement val in conditionValues)
{
var value = AddData(((XmlElement)val.ParentNode).GetAttribute("attribute"), val.InnerText.Trim(), data);
val.InnerText = $"{{{value}}}";
}
}
var cs = "";

if (data.Count > 0)
{
cs = "var fetchData = new {\r\n " + string.Join(",\r\n ", data.Select(kvp => $"{kvp.Key} = \"{kvp.Value.Replace("\\", "\\\\").Replace("\"", "\\\"")}\"")) + "\r\n};\r\n";
}

var sb = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings
{
Indent = true,
IndentChars = " ",
NewLineChars = "\r\n",
NewLineHandling = NewLineHandling.Replace
};
using (var writer = XmlWriter.Create(sb, settings))
{
xml.Save(writer);
}

cs += "var fetchXml = $@\"" + sb.Replace("\"", "\"\"").ToString() + "\";";

cs = string.Join("\n", cs.Split('\n').Select(l => Indent(codesettings.Indents) + l));
return cs;
}

private static string Indent(int indents = 1)
{
return string.Concat(Enumerable.Repeat(" ", indents));
}

private static string AddData(string attribute, string value, Dictionary<string, string> data)
{
var key = attribute;

var suffix = 1;
while (data.ContainsKey(key))
{
suffix++;
key = attribute + suffix;
}

data[key] = SecurityElement.Escape(value);

return $"fetchData.{key}/*{value.Replace("*/", "")}*/";
}
}
}
31 changes: 31 additions & 0 deletions FetchXmlBuilder/Converters/LCG/CommonSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Collections.Generic;

namespace Rappen.XTB.LCG
{
public class CommonSettings
{
public CommonSettings()
{
}

internal string InlineConfigBegin = @"/***** LCG-configuration-BEGIN *****\";
internal string InlineConfigEnd = @"\***** LCG-configuration-END *****/";
public string[] CamelCaseWords { get; set; } = new string[] { "parent", "customer", "owner", "state", "status", "name", "phone", "address", "code", "postal", "mail", "modified", "created", "permission", "type", "method", "verson", "number", "first", "last", "middle", "contact", "account", "system", "user", "fullname", "preferred", "processing", "annual", "plugin", "step", "key", "details", "message", "description", "constructor", "execution", "secure", "configuration", "behalf", "count", "percent", "internal", "external", "trace", "entity", "primary", "secondary", "lastused", "credit", "credited", "donot", "exchange", "import", "invoke", "invoked", "private", "market", "marketing", "revenue", "business", "price", "level", "pricelevel", "territory", "version", "conversion", "workorder", "team" };
public string[] CamelCaseWordEnds { get; set; } = new string[] { "id" };
public string[] InternalAttributes { get; set; } = new string[] { "importsequencenumber", "owneridname", "owneridtype", "owneridyominame", "createdbyname", "createdbyyominame", "createdonbehalfby", "createdonbehalfbyname", "createdonbehalfbyyominame", "modifiedbyname", "modifiedbyyominame", "modifiedonbehalfby", "modifiedonbehalfbyname", "modifiedonbehalfbyyominame", "overriddencreatedon", "owningbusinessunit", "owningteam", "owninguser", "regardingobjectidname", "regardingobjectidyominame", "regardingobjecttypecode", "timezoneruleversionnumber", "transactioncurrencyidname", "utcconversiontimezonecode", "versionnumber" };
}
}

/*
FileContainer
FileHeader
DataContainer
EntityContainer
EntityDetails
Attributes
Relationships
OptionSets
OptionSetValues
*/
51 changes: 51 additions & 0 deletions FetchXmlBuilder/Converters/LCG/ConfigurationUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using McTools.Xrm.Connection;
using System.IO;

namespace Rappen.XTB.Helper
{
public static class ConfigurationUtils
{
public static T GetEmbeddedConfiguration<T>(string filename, string begintoken, string endtoken)
{
var csfile = File.ReadAllText(filename);
var configstr = csfile.GetTextBetween(begintoken, endtoken, false);
if (string.IsNullOrEmpty(configstr))
{
throw new FileLoadException("Could not find configuration token in file.", filename);
}
var configname = GetSimpleClassName<T>();
configstr = configstr.GetTextBetween($"<{configname}", $"</{configname}>", true);
if (string.IsNullOrEmpty(configstr))
{
throw new FileLoadException($"Could not find {configname} XML in file.", filename);
}
var inlinesettings = (T)XmlSerializerHelper.Deserialize(configstr, typeof(T));
return inlinesettings;
}

private static string GetSimpleClassName<T>()
{
var configname = typeof(T).ToString();
var confignameparts = configname.Split('.');
configname = confignameparts[confignameparts.Length - 1];
return configname;
}

private static string GetTextBetween(this string text, string begin, string end, bool includebeginend)
{
var beginpos = text.IndexOf(begin);
if (beginpos < 0)
{
return string.Empty;
}
text = text.Substring(beginpos + (includebeginend ? 0 : begin.Length));
var endpos = text.IndexOf(end);
if (endpos < 0)
{
return string.Empty;
}
text = text.Substring(0, endpos + (includebeginend ? end.Length : 0)).Trim();
return text;
}
}
}
Loading

0 comments on commit 47c221c

Please sign in to comment.