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);
        }