Beispiel #1
0
    public static string?CanOrder(QueryToken token)
    {
        if (token == null)
        {
            return("No column selected");
        }

        if (token.Type.IsEmbeddedEntity() && !OrderAdapters.Any(a => a(token) != null))
        {
            return("{0} can not be ordered".FormatWith(token.Type.NicePluralName()));
        }

        if (QueryToken.IsCollection(token.Type))
        {
            return("Collections can not be ordered");
        }

        if (token.HasAllOrAny())
        {
            return("'{0}', '{1}', '{2}' or '{3}' can not be ordered".FormatWith(
                       CollectionAnyAllType.All.NiceToString(),
                       CollectionAnyAllType.Any.NiceToString(),
                       CollectionAnyAllType.NoOne.NiceToString(),
                       CollectionAnyAllType.AnyNo.NiceToString()));
        }

        return(null);
    }
Beispiel #2
0
        void ParseInternal()
        {
            try
            {
                this.mainBlock = new BlockNode(null);
                this.stack     = new Stack <BlockNode>();
                this.errors    = new List <TemplateError>();
                PushBlock(mainBlock);

                var matches = TemplateUtils.KeywordsRegex.Matches(text);

                if (matches.Count == 0)
                {
                    stack.Peek().Nodes.Add(new LiteralNode(text));
                    stack.Pop();
                    return;
                }

                int index = 0;
                foreach (Match match in matches.Cast <Match>())
                {
                    if (index < match.Index)
                    {
                        stack.Peek().Nodes.Add(new LiteralNode(text.Substring(index, match.Index - index)));
                    }
                    var expr     = match.Groups["expr"].Value;
                    var keyword  = match.Groups["keyword"].Value;
                    var variable = match.Groups["dec"].Value;
                    switch (keyword)
                    {
                    case "":
                    case "raw":
                        var s = TemplateUtils.SplitToken(expr);
                        if (s == null)
                        {
                            AddError(true, "{0} has invalid format".FormatWith(expr));
                        }
                        else
                        {
                            var t = ValueProviderBase.TryParse(s.Value.Token, variable, this);

                            stack.Peek().Nodes.Add(new ValueNode(t, s.Value.Format, isRaw: keyword.Contains("raw")));

                            DeclareVariable(t);
                        }
                        break;

                    case "declare":
                    {
                        var t = ValueProviderBase.TryParse(expr, variable, this);

                        stack.Peek().Nodes.Add(new DeclareNode(t, this.AddError));

                        DeclareVariable(t);
                    }
                    break;

                    case "any":
                    {
                        ConditionBase cond = TemplateUtils.ParseCondition(expr, variable, this);
                        AnyNode       any  = new AnyNode(cond);
                        stack.Peek().Nodes.Add(any);
                        PushBlock(any.AnyBlock);
                        if (cond is ConditionCompare cc)
                        {
                            DeclareVariable(cc.ValueProvider);
                        }
                        break;
                    }

                    case "notany":
                    {
                        var an = (AnyNode?)PopBlock(typeof(AnyNode))?.owner;
                        if (an != null)
                        {
                            PushBlock(an.CreateNotAny());
                        }
                        break;
                    }

                    case "endany":
                    {
                        PopBlock(typeof(AnyNode));
                        break;
                    }

                    case "foreach":
                    {
                        ValueProviderBase?vp = ValueProviderBase.TryParse(expr, variable, this);
                        if (vp is TokenValueProvider tvp && tvp.ParsedToken.QueryToken != null && QueryToken.IsCollection(tvp.ParsedToken.QueryToken.Type))
                        {
                            AddError(false, $"@foreach[{expr}] is a collection, missing 'Element' token at the end");
                        }

                        var fn = new ForeachNode(vp);
                        stack.Peek().Nodes.Add(fn);
                        PushBlock(fn.Block);
                        if (vp != null)
                        {
                            vp.IsForeach = true;
                        }
                        DeclareVariable(vp);
                        break;
                    }

                    case "endforeach":
                    {
                        PopBlock(typeof(ForeachNode));
                    }
                    break;

                    case "if":
                    {
                        ConditionBase cond = TemplateUtils.ParseCondition(expr, variable, this);
                        IfNode        ifn  = new IfNode(cond, this);
                        stack.Peek().Nodes.Add(ifn);
                        PushBlock(ifn.IfBlock);
                        if (cond is ConditionCompare cc)
                        {
                            DeclareVariable(cc.ValueProvider);
                        }
                        break;
                    }

                    case "else":
                    {
                        var ifn = (IfNode?)PopBlock(typeof(IfNode))?.owner;
                        if (ifn != null)
                        {
                            PushBlock(ifn.CreateElse());
                        }
                        break;
                    }

                    case "endif":
                    {
                        PopBlock(typeof(IfNode));
                        break;
                    }

                    default:
                        AddError(true, "'{0}' is deprecated".FormatWith(keyword));
                        break;
                    }
                    index = match.Index + match.Length;
                }

                if (stack.Count != 1)
                {
                    AddError(true, "Last block is not closed: {0}".FormatWith(stack.Peek()));
                }

                var lastM = matches.Cast <Match>().LastOrDefault();
                if (lastM != null && lastM.Index + lastM.Length < text.Length)
                {
                    stack.Peek().Nodes.Add(new LiteralNode(text.Substring(lastM.Index + lastM.Length)));
                }

                stack.Pop();
            }
            catch (Exception e)
            {
                AddError(true, e.Message);
            }
        }