Exemplo n.º 1
0
        private void HandleReduceDefinition(ConstructorDeclaration ctor)
        {
            try
            {
                if (!indexDefinition.IsMapReduce)
                {
                    return;
                }
                VariableInitializer reduceDefinition;
                AstNode             groupBySource;
                string groupByParameter;
                string groupByIdentifier;
                if (indexDefinition.Reduce.Trim().StartsWith("from"))
                {
                    reduceDefinition = QueryParsingUtils.GetVariableDeclarationForLinqQuery(indexDefinition.Reduce,
                                                                                            RequiresSelectNewAnonymousType);
                    var queryExpression         = ((QueryExpression)reduceDefinition.Initializer);
                    var queryContinuationClause = queryExpression.Clauses.OfType <QueryContinuationClause>().FirstOrDefault();
                    if (queryContinuationClause == null)
                    {
                        throw new IndexCompilationException("Reduce query must contain a 'group ... into ...' clause")
                              {
                                  ProblematicText         = indexDefinition.Reduce,
                                  IndexDefinitionProperty = "Reduce",
                              };
                    }

                    var queryGroupClause = queryContinuationClause.PrecedingQuery.Clauses.OfType <QueryGroupClause>().FirstOrDefault();
                    if (queryGroupClause == null)
                    {
                        throw new IndexCompilationException("Reduce query must contain a 'group ... into ...' clause")
                              {
                                  ProblematicText         = indexDefinition.Reduce,
                                  IndexDefinitionProperty = "Reduce",
                              };
                    }

                    groupByIdentifier = queryContinuationClause.Identifier;
                    groupBySource     = queryGroupClause.Key;
                    groupByParameter  =
                        queryContinuationClause.PrecedingQuery.Clauses.OfType <QueryFromClause>().First().Identifier;
                }
                else
                {
                    reduceDefinition = QueryParsingUtils.GetVariableDeclarationForLinqMethods(indexDefinition.Reduce,
                                                                                              RequiresSelectNewAnonymousType);
                    var initialInvocation = ((InvocationExpression)reduceDefinition.Initializer);
                    var invocation        = initialInvocation;
                    var target            = (MemberReferenceExpression)invocation.Target;
                    while (target.MemberName != "GroupBy")
                    {
                        if (!(target.Target is InvocationExpression))
                        {
                            // we've reached the initial results variable without encountering a GroupBy call
                            throw new IndexCompilationException("Reduce expression must contain a call to GroupBy")
                                  {
                                      ProblematicText         = indexDefinition.Reduce,
                                      IndexDefinitionProperty = "Reduce",
                                  };
                        }

                        invocation = (InvocationExpression)target.Target;
                        target     = (MemberReferenceExpression)invocation.Target;
                    }
                    var lambdaExpression = GetLambdaExpression(invocation);
                    groupByParameter  = lambdaExpression.Parameters.First().Name;
                    groupBySource     = lambdaExpression.Body;
                    groupByIdentifier = null;
                }

                var mapFields = captureSelectNewFieldNamesVisitor.FieldNames.ToList();
                captureSelectNewFieldNamesVisitor.Clear();         // reduce override the map fields
                reduceDefinition.Initializer.AcceptVisitor(captureSelectNewFieldNamesVisitor, null);
                reduceDefinition.Initializer.AcceptVisitor(captureQueryParameterNamesVisitorForReduce, null);
                reduceDefinition.Initializer.AcceptVisitor(new ThrowOnInvalidMethodCalls(groupByIdentifier), null);

                ValidateMapReduceFields(mapFields);

                // this.ReduceDefinition = from result in results...;
                ctor.Body.Statements.Add(new ExpressionStatement(
                                             new AssignmentExpression(
                                                 new MemberReferenceExpression(new ThisReferenceExpression(),
                                                                               "ReduceDefinition"),
                                                 AssignmentOperatorType.Assign,
                                                 new LambdaExpression
                {
                    Parameters =
                    {
                        new ParameterDeclaration(null, "results")
                    },
                    Body = reduceDefinition.Initializer.Clone()
                })));

                ctor.Body.Statements.Add(new ExpressionStatement(
                                             new AssignmentExpression(
                                                 new MemberReferenceExpression(new ThisReferenceExpression(),
                                                                               "GroupByExtraction"),
                                                 AssignmentOperatorType.Assign,
                                                 new LambdaExpression
                {
                    Parameters =
                    {
                        new ParameterDeclaration(null, groupByParameter)
                    },
                    Body = groupBySource.Clone()
                })));
            }
            catch (InvalidOperationException ex)
            {
                throw new IndexCompilationException(ex.Message)
                      {
                          ProblematicText         = indexDefinition.Reduce,
                          IndexDefinitionProperty = "Reduce",
                      };
            }
        }
Exemplo n.º 2
0
        private void HandleReduceDefintion(ConstructorDeclaration ctor)
        {
            if (!indexDefinition.IsMapReduce)
            {
                return;
            }
            VariableDeclaration reduceDefiniton;
            Expression          groupBySource;
            string groupByParamter;

            if (indexDefinition.Reduce.Trim().StartsWith("from"))
            {
                reduceDefiniton = QueryParsingUtils.GetVariableDeclarationForLinqQuery(indexDefinition.Reduce, RequiresSelectNewAnonymousType);
                var sourceSelect = (QueryExpression)((QueryExpression)reduceDefiniton.Initializer).FromClause.InExpression;
                groupBySource   = ((QueryExpressionGroupClause)sourceSelect.SelectOrGroupClause).GroupBy;
                groupByParamter = sourceSelect.FromClause.Identifier;
            }
            else
            {
                reduceDefiniton = QueryParsingUtils.GetVariableDeclarationForLinqMethods(indexDefinition.Reduce, RequiresSelectNewAnonymousType);
                var invocation = ((InvocationExpression)reduceDefiniton.Initializer);
                var target     = (MemberReferenceExpression)invocation.TargetObject;
                while (target.MemberName != "GroupBy")
                {
                    invocation = (InvocationExpression)target.TargetObject;
                    target     = (MemberReferenceExpression)invocation.TargetObject;
                }
                var lambdaExpression = GetLambdaExpression(invocation);
                groupByParamter = lambdaExpression.Parameters[0].ParameterName;
                groupBySource   = lambdaExpression.ExpressionBody;
            }

            var mapFields = captureSelectNewFieldNamesVisitor.FieldNames.ToList();

            captureSelectNewFieldNamesVisitor.Clear();            // reduce override the map fields
            reduceDefiniton.Initializer.AcceptVisitor(captureSelectNewFieldNamesVisitor, null);
            reduceDefiniton.Initializer.AcceptChildren(captureQueryParameterNamesVisitorForReduce, null);
            reduceDefiniton.Initializer.AcceptVisitor(new ThrowOnInvalidMethodCalls(), null);

            ValidateMapReduceFields(mapFields);

            // this.ReduceDefinition = from result in results...;
            ctor.Body.AddChild(new ExpressionStatement(
                                   new AssignmentExpression(
                                       new MemberReferenceExpression(new ThisReferenceExpression(),
                                                                     "ReduceDefinition"),
                                       AssignmentOperatorType.Assign,
                                       new LambdaExpression
            {
                Parameters =
                {
                    new ParameterDeclarationExpression(null, "results")
                },
                ExpressionBody = reduceDefiniton.Initializer
            })));

            ctor.Body.AddChild(new ExpressionStatement(
                                   new AssignmentExpression(
                                       new MemberReferenceExpression(new ThisReferenceExpression(),
                                                                     "GroupByExtraction"),
                                       AssignmentOperatorType.Assign,
                                       new LambdaExpression
            {
                Parameters =
                {
                    new ParameterDeclarationExpression(null, groupByParamter)
                },
                ExpressionBody = groupBySource
            })));
        }