private static void ParseGroupBy(string apply, QuerySpec spec, TableSpec tabSpec) { if (string.IsNullOrEmpty(apply)) { return; } var lexer = new ODataTranslatorLexer(new AntlrInputStream(apply), tabSpec, spec); CommonTokenStream tokens = new CommonTokenStream(lexer); // Pass the tokens to the parser var parser = new ODataTranslatorParser(tokens, tabSpec, spec); // Run root rule ("apply" in this grammar) parser.apply(); if (parser.Aggregates.Count == 0) { _log.ErrorFormat("Cannot extract agregates from $apply= {apply} value. ", apply); throw new ArgumentException("Cannot parse $apply operator.", "$apply"); } spec.select = parser.GroupBy; foreach (var a in parser.Aggregates) { spec.select += ((spec.select == null) ?"":",") + a.AggregateColumnAlias + "=" + a.AggregateMethod + "(" + a.AggregateColumn + ")"; } spec.groupBy = parser.GroupBy; }
internal static void SetValidationScope(this ODataTranslatorParser parser, string tableName) { if (!parser.tableSpec.Relations.ContainsKey(tableName)) { throw new InvalidOperationException("Cannot validate entity " + tableName + " because it is not registered as a relation."); } parser.currentTableScopeSpec = parser.tableSpec.Relations[tableName]; }
internal static void AddAggregateExpression(this ODataTranslatorParser parser, string Method, string Column, string Alias) { var agg = new Aggregate() { AggregateMethod = Method, AggregateColumn = Column, AggregateColumnAlias = Alias }; parser.Aggregates.AddLast(agg); }
private static void ParseExpand(StringValues expand, QuerySpec spec, TableSpec tabSpec) { if (string.IsNullOrEmpty(expand)) { return; } var lexer = new ODataTranslatorLexer(new AntlrInputStream(expand), tabSpec, spec); CommonTokenStream tokens = new CommonTokenStream(lexer); // Pass the tokens to the parser var parser = new ODataTranslatorParser(tokens, tabSpec, spec); spec.expand = new System.Collections.Generic.Dictionary <string, QuerySpec>(); // Run rule "expandItems" in this grammar parser.expandItems(); spec.expand = parser.Relations; }
private static void ParseOrderBy(TableSpec tabSpec, string orderby, QuerySpec spec) { if (!string.IsNullOrWhiteSpace(orderby)) { spec.order = new Hashtable(); foreach (var colDir in orderby.Split(',')) { string dir = "asc", column = colDir; if (colDir.EndsWith(" desc")) { dir = "desc"; column = colDir.Substring(0, colDir.Length - 5).Trim(); } else if (colDir.EndsWith(" asc")) { column = colDir.Substring(0, colDir.Length - 4).Trim(); } if (EnableODataExtensions) { var lexer = new ODataTranslatorLexer(new AntlrInputStream(column), tabSpec, spec); CommonTokenStream tokens = new CommonTokenStream(lexer); // Pass the tokens to the parser var parser = new ODataTranslatorParser(tokens, tabSpec, spec); parser.ErrorHandler = FastFail; var orderBy = parser.orderBy(); column = orderBy.Expression + " " + orderBy.Direction; if (string.IsNullOrWhiteSpace(column)) { _log.ErrorFormat("Cannot extract order by clause from $orderby= {orderby} value. ", orderby); throw new ArgumentException("Cannot parse $orderby parameter.", "$orderby"); } } else { tabSpec.HasColumn(column); } spec.order.Add(column, dir); } spec.IsOrderClauseValidated = true; } }
internal static void ValidateColumn(this ODataTranslatorParser parser, string name) { parser.currentTableScopeSpec.HasColumn(name); }
internal static void ResetValidationScope(this ODataTranslatorParser parser) { parser.currentTableScopeSpec = parser.tableSpec; }
internal static void AddExpandRelation(this ODataTranslatorParser parser, string name, Dictionary <string, string> props) { if (parser.tableSpec.Relations == null) { throw new System.Exception("Relations are not specified in the table."); } if (!parser.tableSpec.Relations.ContainsKey(name)) { throw new System.Exception("Relation " + name + " is not found in the table."); } TableSpec relation = parser.tableSpec.Relations[name]; QuerySpec s = null; if (props != null && props.Count > 0) { var top = -1; var skip = -1; if ((props.ContainsKey("top") && props["top"] != null) || (props.ContainsKey("skip") && props["skip"] != null)) // recover actual value that lexer sanitized and replaced with parameter. { foreach (var p in parser.querySpec.parameters) { if (props.ContainsKey("top") && props["top"] != null && p.ParameterName == props["top"]) { top = System.Convert.ToInt16(p.Value); } if (props.ContainsKey("skip") && props["skip"] != null && p.ParameterName == props["skip"]) { skip = System.Convert.ToInt16(p.Value); } // if top is not provided or already set and if $skip is not provided or already set, skip the further search. if ((!props.ContainsKey("top") || props["top"] == null || top != -1) && (!props.ContainsKey("skip") || props["skip"] == null || skip != -1)) { break; } } } s = new QuerySpec() { select = props.ContainsKey("select") ? props["select"] : relation.columnList, top = top, skip = skip, predicate = props.ContainsKey("filter") ? relation.primaryKey + " AND (" + props["filter"] + ")": relation.primaryKey }; if (props.ContainsKey("orderBy")) { s.order = new System.Collections.Hashtable(); s.order.Add(props["orderBy"], ""); } } else { s = new QuerySpec() { select = relation.columnList, predicate = relation.primaryKey } }; parser.Relations.Add(name, s); }