public override bool Visit(ILinqBody body, ILinqBody context)
 {
     _stack.Push(body);
     try
     {
         return(base.Visit(body, context));
     }
     finally
     {
         _stack.Pop();
     }
 }
コード例 #2
0
 /// <summary>
 /// Creates a new <see cref="LinqFusionSelectBody"/> with the
 /// <paramref name="selection"/>, <paramref name="target"/>,
 /// and <paramref name="next"/> provided.
 /// </summary>
 /// <param name="selection">The <see cref="IExpression"/>
 /// which denotes what is selected as a result of the
 /// language integrated query.</param>
 /// <param name="target">The <see cref="String"/> representing the name of the
 /// range variable that the data from the grouped query is stored into.</param>
 /// <param name="next">The <see cref="ILinqBody"/> which
 /// continues the language integrated query.</param>
 public LinqFusionSelectBody(IExpression selection, string target, ILinqBody next)
     : base(selection)
 {
     this.target = new LinqRangeVariable(this, target);
     this.Next   = next;
 }
コード例 #3
0
 /// <summary>
 /// Creates a new <see cref="LinqFusionGroupBody"/> with
 /// the <paramref name="selection"/>, <paramref name="key"/>,
 /// <paramref name="target"/> and <paramref name="next"/>
 /// provided.
 /// </summary>
 /// <param name="selection">The <see cref="IExpression"/> which
 /// acts as a selector on the data set to retrieve the data for the query.</param>
 /// <param name="key">The <see cref="IExpression"/> which acts
 /// as the key for grouping the <see cref="ILinqSelectBody.Selection"/>s.</param>
 /// <param name="target">The <see cref="String"/> representing the name of the
 /// range variable that the data from the grouped query is stored into.</param>
 /// <param name="next">The <see cref="ILinqBody"/> which
 /// continues the language integrated query.</param>
 public LinqFusionGroupBody(IExpression selection, IExpression key, string target, ILinqBody next)
     : base(selection, target, next)
 {
     this.Key = key;
 }
コード例 #4
0
        public ILinqExpression Build()
        {
            var path = new Stack <ILinqBodyBuilderParent>();

            //Build a reverse-order listing of the current expression graph.
            for (ILinqBodyBuilderParent current = this; current != null; path.Push(current), current = current.Parent)
            {
                ;
            }

            ILinqExpression result    = new LinqExpression();
            int             bodyCount = 0;
            var             pathNodes = path.ToArray();

            const int selectBody     = 1,
                      selectFuseBody = 3;
            const int groupBody      = 2,
                      groupFuseBody  = 4;

            //Count the number of body continuations.
            for (int i = 0; i < pathNodes.Length; i++)
            {
                if (pathNodes[i] is ILinqTailBodyBuilder)
                {
                    bodyCount++;
                }
            }

            int[] bodyTypes = new int[bodyCount];
            int   bodyIndex = 0;

            /* *
             * Iterate through and, from the tails, discern
             * the kind of body to use.
             * */
            for (int i = 0; i < pathNodes.Length; i++)
            {
                if (pathNodes[i] is ILinqTailBodyBuilder)
                {
                    bool last = i == pathNodes.Length - 1;

                    if (pathNodes[i] is LinqTailGroupBodyBuilder)
                    {
                        bodyTypes[bodyIndex++] = last ? groupBody : groupFuseBody;
                    }
                    else
                    {
                        bodyTypes[bodyIndex++] = last ? selectBody : selectFuseBody;
                    }
                }
            }
            ILinqBody currentBody = null;

            bodyIndex = 0;
            var selector = pathNodes[0] as LinqTypedFromBodyBuilder;

            /* *
             * The first element is always a from clause, either typed or
             * untyped.
             * *
             * This is why initialization pipeline is closed.
             * */
            if (selector == null)
            {
                result.From = BuildFromClause(pathNodes[0] as LinqFromBodyBuilder);
            }
            else
            {
                result.From = BuildFromClause(selector);
            }

            /* *
             * Iterate through the elements and build the bodies,
             * linking the clauses in between.
             * */
            for (int i = 1; i < pathNodes.Length; i++)
            {
                bool last = i == pathNodes.Length - 1;

                /* *
                 * Create the initial body from the current element.
                 * */
                if (currentBody == null)
                {
                    currentBody = result.Body = GetBody(bodyTypes[bodyIndex++]);
                    if (currentBody == null)
                    {
                        throw new InvalidOperationException("Unknown error.");
                    }
                }

                /* *
                 * This breaks programming practice rules, bite me.
                 * */
                var fromClauseT = pathNodes[i] as LinqTypedFromBodyBuilder;
                if (fromClauseT != null)
                {
                    currentBody.Clauses.From(fromClauseT.RangeVariableInfo, fromClauseT.RangeSource);
                    continue;
                }
                var fromClause = pathNodes[i] as LinqFromBodyBuilder;
                if (fromClause != null)
                {
                    currentBody.Clauses.From(fromClause.RangeVariableName, fromClause.RangeSource);
                    continue;
                }
                var joinClauseT = pathNodes[i] as LinqTypedJoinBodyBuilder;
                if (joinClauseT != null)
                {
                    currentBody.Clauses.Join(joinClauseT.RangeVariableInfo, joinClauseT.RangeSource, joinClauseT.LeftConditionSelector, joinClauseT.RightConditionSelector, joinClauseT.IntoTarget);
                    continue;
                }
                var joinClause = pathNodes[i] as LinqJoinBodyBuilder;
                if (joinClause != null)
                {
                    currentBody.Clauses.Join(joinClause.RangeVariableName, joinClause.RangeSource, joinClause.LeftConditionSelector, joinClause.RightConditionSelector, joinClause.IntoTarget);
                    continue;
                }
                var letClause = pathNodes[i] as LinqLetBodyBuilder;
                if (letClause != null)
                {
                    currentBody.Clauses.Let(letClause.RangeVariableName, letClause.RangeSource);
                    continue;
                }
                var dOrderClause = pathNodes[i] as LinqDirectedOrderByBodyBuilder;
                if (dOrderClause != null)
                {
                    /* *
                     * Special case, forward glance needs made to determine the proper
                     * clause to construct.
                     * */
                    int lastClause = -1;
                    for (int j = i + 1; j < pathNodes.Length; j++)
                    {
                        if (pathNodes[j] is LinqThenByBodyBuilder ||
                            pathNodes[j] is LinqDirectedThenByBodyBuilder)
                        {
                            lastClause = j;
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (lastClause == -1)
                    {
                        currentBody.Clauses.OrderBy(dOrderClause.OrderKey, dOrderClause.Direction);
                    }
                    else
                    {
                        var pairs = new LinqOrderingPair[(lastClause + 1) - i];
                        pairs[0] = new LinqOrderingPair(dOrderClause.OrderKey, dOrderClause.Direction);
                        int lastValid = i;
                        for (int j = i + 1; j <= lastClause; j++)
                        {
                            var dThenBy = pathNodes[j] as LinqDirectedThenByBodyBuilder;
                            if (dThenBy != null)
                            {
                                pairs[j - i] = new LinqOrderingPair(dThenBy.OrderKey, dThenBy.Direction);
                                lastValid    = j;
                                continue;
                            }
                            var thenBy = pathNodes[j] as LinqThenByBodyBuilder;
                            if (thenBy != null)
                            {
                                pairs[j - i] = new LinqOrderingPair(thenBy.OrderKey);
                                lastValid    = j;
                                continue;
                            }
                            break;
                        }
                        i = lastValid;
                        currentBody.Clauses.OrderBy(pairs);
                    }
                    continue;
                }
                var orderClause = pathNodes[i] as LinqOrderByBodyBuilder;
                if (orderClause != null)
                {
                    int lastClause = -1;
                    for (int j = i + 1; j < pathNodes.Length; j++)
                    {
                        if (pathNodes[j] is LinqThenByBodyBuilder ||
                            pathNodes[j] is LinqDirectedThenByBodyBuilder)
                        {
                            lastClause = j;
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (lastClause == -1)
                    {
                        currentBody.Clauses.OrderBy(orderClause.OrderKey);
                    }
                    else
                    {
                        var pairs = new LinqOrderingPair[(lastClause + 1) - i];
                        pairs[0] = new LinqOrderingPair(orderClause.OrderKey);
                        int lastValid = i;
                        for (int j = i + 1; j <= lastClause; j++)
                        {
                            var dThenBy = pathNodes[j] as LinqDirectedThenByBodyBuilder;
                            if (dThenBy != null)
                            {
                                pairs[j - i] = new LinqOrderingPair(dThenBy.OrderKey, dThenBy.Direction);
                                lastValid    = j;
                                continue;
                            }
                            var thenBy = pathNodes[j] as LinqThenByBodyBuilder;
                            if (thenBy != null)
                            {
                                pairs[j - i] = new LinqOrderingPair(thenBy.OrderKey);
                                lastValid    = j;
                                continue;
                            }
                            break;
                        }
                        i = lastValid;
                        currentBody.Clauses.OrderBy(pairs);
                    }
                    continue;
                }


                var whereClause = pathNodes[i] as LinqWhereBodyBuilder;
                if (whereClause != null)
                {
                    currentBody.Clauses.Where(whereClause.BooleanCondition);
                    continue;
                }
                var groupBuilder = pathNodes[i] as LinqTailGroupBodyBuilder;
                LinqTailSelectBodyBuilder selectBuilder;

                /* *
                 * If we're working with a group builder...
                 * */
                if (groupBuilder != null)
                {
                    var gbCurrent = currentBody as ILinqGroupBody;
                    if (gbCurrent == null)
                    {
                        break;
                    }

                    /* *
                     * No continuation, we're finished.
                     * */
                    if (last)
                    {
                        gbCurrent.Key       = groupBuilder.Key;
                        gbCurrent.Selection = groupBuilder.Selection;
                        break;
                    }
                    else
                    {
                        /* *
                         * Link the current to the next, and set its
                         * target 'into' range variable name.
                         * */
                        var gfbCurrent = gbCurrent as ILinqFusionGroupBody;
                        if (gfbCurrent == null)
                        {
                            break;
                        }
                        gfbCurrent.Key       = groupBuilder.Key;
                        gfbCurrent.Selection = groupBuilder.Selection;
                        var next = pathNodes[++i] as LinqFusionBodyBuilder;
                        if (next == null)
                        {
                            break;
                        }
                        gfbCurrent.Target.Name = next.IntoRangeName;
                        gfbCurrent.Next        = currentBody = GetBody(bodyTypes[bodyIndex++]);
                    }
                }
                else if ((selectBuilder = pathNodes[i] as LinqTailSelectBodyBuilder) != null)
                {
                    var sbCurrent = currentBody as ILinqSelectBody;
                    if (sbCurrent == null)
                    {
                        break;
                    }

                    /* *
                     * No continuation, we're finished.
                     * */
                    if (last)
                    {
                        sbCurrent.Selection = selectBuilder.Selection;
                        break;
                    }
                    else
                    {
                        /* *
                         * Link the current to the next, and set its
                         * target 'into' range variable name.
                         * */
                        var sfbCurrent = sbCurrent as ILinqFusionSelectBody;
                        if (sfbCurrent == null)
                        {
                            break;
                        }
                        sfbCurrent.Selection = selectBuilder.Selection;
                        var next = pathNodes[++i] as LinqFusionBodyBuilder;
                        if (next == null)
                        {
                            break;
                        }
                        sfbCurrent.Target.Name = next.IntoRangeName;
                        sfbCurrent.Next        = currentBody = GetBody(bodyTypes[bodyIndex++]);
                    }
                }
            }
            return(result);
        }