1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
using System.Text.RegularExpressions;
namespace CRMInterface
{
public class AQLParser
{
private readonly CRMInterfaceClient Client;
private readonly Request Request;
public AQLParser(CRMInterfaceClient client, Request request)
{
Client = client;
Request = request;
}
public Query Parse(string aql)
{
List<Table> tables = new();
Query query = new(Client);
string pattern = @"([^\(\)]*) \(([^\(\)]*)\)"; // Marche pas avec les conditions complexes (contenant des parenthèses)
MatchCollection matches = Regex.Matches(aql, pattern);
Match matchFrom = matches.First(a => a.Groups[1].Value.Trim() == "from");
Table from = new(Client, matchFrom.Groups[2].Value.Trim());
query.Tables.Add(from);
tables.Add(from);
for (int i = 0; i < matches.Count; i++)
{
if (matches[i].Groups[1].Value.Trim() == "with")
{
Table with = new(Client, matches[i].Groups[2].Value.Trim());
from.Tables.Add(with);
tables.Add(with);
if (matches[i + 1].Groups[1].Value.Trim() == "where")
{
Condition condition = new(with);
query.Conditions.Add(condition);
string[] conds = matches[i + 1].Groups[2].Value.Split("AND", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
foreach (string cond in conds)
{
string pat = @"([^=<>]*)([=<>]*)([^=<>]*)";
MatchCollection ms = Regex.Matches(cond, pat);
string fieldName = ms[0].Groups[1].Value.Trim().Replace("\"", "").Replace("'", "");
if (!int.TryParse(fieldName, out _))
{
fieldName = Client.GetFieldId(with, fieldName);
}
condition.AddCondition(fieldName, ms[0].Groups[2].Value.Trim(), ms[0].Groups[3].Value.Trim().Replace("\"", "").Replace("'", ""));
}
}
}
else if (matches[i].Groups[1].Value.Trim() == "from")
{
if (matches[i + 1].Groups[1].Value.Trim() == "where")
{
Condition condition = new(from);
query.Conditions.Add(condition);
string[] conds = matches[i + 1].Groups[2].Value.Split("AND", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
foreach (string cond in conds)
{
string pat = @"([^=<>]*)([=<>]*)([^=<>]*)";
MatchCollection ms = Regex.Matches(cond, pat);
string fieldName = ms[0].Groups[1].Value.Trim().Replace("\"", "").Replace("'", "");
if (!int.TryParse(fieldName, out _))
{
fieldName = Client.GetFieldId(from, fieldName);
}
condition.AddCondition(fieldName, ms[0].Groups[2].Value.Trim(), ms[0].Groups[3].Value.Trim().Replace("\"", "").Replace("'", ""));
}
}
}
}
Match matchSelect = matches.First(a => a.Groups[1].Value.Trim() == "select");
string[] fields = matchSelect.Groups[2].Value.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
foreach (Table table in tables)
{
if (table == from)
{
string[] fs = fields.Where(a => !a.Contains('.')).ToArray();
for (int i = 0; i < fs.Length; i++)
{
if (!int.TryParse(fs[i], out _))
{
fs[i] = Client.GetFieldId(table, fs[i]);
}
}
query.Fields.Add(new Fields(table, string.Join(',', fs)));
}
else
{
string[] fs = fields.Where(a => a.StartsWith(string.Concat(table.Code, '.'))).Select(a => a.Substring(a.IndexOf('.') + 1)).ToArray();
for (int i = 0; i < fs.Length; i++)
{
if (!int.TryParse(fs[i], out _))
{
fs[i] = Client.GetFieldId(table, fs[i]);
}
}
query.Fields.Add(new Fields(table, string.Join(',', fs)));
}
}
return query;
}
}
} |