private void HandleMapFunction(ConstructorDeclaration ctor, string map)
        {
            string entityName;

            VariableInitializer mapDefinition = map.Trim().StartsWith("from") ?
                                                TransformMapDefinitionFromLinqQuerySyntax(map, out entityName) :
                                                TransformMapDefinitionFromLinqMethodSyntax(map, out entityName);

            if (string.IsNullOrEmpty(entityName) == false)
            {
                //this.ForEntityNames.Add(entityName);
                ctor.Body.Statements.Add(new ExpressionStatement(
                                             new InvocationExpression(
                                                 new MemberReferenceExpression(
                                                     new MemberReferenceExpression(new ThisReferenceExpression(), "ForEntityNames"), "Add"),
                                                 new List <Expression> {
                    new StringLiteralExpression(entityName)
                })
                                             ));
            }
            // this.AddMapDefinition(from doc in docs ...);
            ctor.Body.Statements.Add(new ExpressionStatement(
                                         new InvocationExpression(
                                             new MemberReferenceExpression(new ThisReferenceExpression(), "AddMapDefinition"),
                                             new List <Expression>
            {
                new LambdaExpression
                {
                    Parameters =
                    {
                        new ParameterDeclaration(null, "docs")
                    },
                    Body = mapDefinition.Initializer.Clone()
                }
            }
                                             )));


            if (firstMap)
            {
                mapDefinition.Initializer.AcceptVisitor(captureSelectNewFieldNamesVisitor, null);
                firstMap = false;
            }
            else
            {
                var secondMapFieldNames = new CaptureSelectNewFieldNamesVisitor();
                mapDefinition.Initializer.AcceptVisitor(secondMapFieldNames, null);
                if (secondMapFieldNames.FieldNames.SetEquals(captureSelectNewFieldNamesVisitor.FieldNames) == false)
                {
                    var message = string.Format(@"Map functions defined as part of a multi map index must return identical types.
Baseline map		: {0}
Non matching map	: {1}

Common fields		: {2}
Missing fields		: {3}
Additional fields	: {4}"    , indexDefinition.Maps.First(),
                                                map,
                                                string.Join(", ", captureSelectNewFieldNamesVisitor.FieldNames.Intersect(secondMapFieldNames.FieldNames)),
                                                string.Join(", ", captureSelectNewFieldNamesVisitor.FieldNames.Except(secondMapFieldNames.FieldNames)),
                                                string.Join(", ", secondMapFieldNames.FieldNames.Except(captureSelectNewFieldNamesVisitor.FieldNames))
                                                );
                    throw new InvalidOperationException(message);
                }
            }

            mapDefinition.Initializer.AcceptVisitor(new ThrowOnInvalidMethodCalls(null), null);
            mapDefinition.Initializer.AcceptVisitor(captureQueryParameterNamesVisitorForMap, null);
        }
示例#2
0
        private void TransformQueryToClass()
        {
            string entityName;
            var mapDefinition = TransformMapDefinition(out entityName);

            CSharpSafeName = "Index_"+ Regex.Replace(Name, @"[^\w\d]", "_");
            var type = new TypeDeclaration(Modifiers.Public, new List<AttributeSection>())
            {
                BaseTypes =
                    {
                        new TypeReference("AbstractViewGenerator")
                    },
                Name = CSharpSafeName,
                Type = ClassType.Class
            };

            var ctor = new ConstructorDeclaration(CSharpSafeName,
                                                  Modifiers.Public,
                                                  new List<ParameterDeclarationExpression>(), null);
            type.Children.Add(ctor);
            ctor.Body = new BlockStatement();
            //this.ForEntityName = entityName;
            ctor.Body.AddChild(new ExpressionStatement(
                                new AssignmentExpression(
                                    new MemberReferenceExpression(new ThisReferenceExpression(), "ForEntityName"),
                                    AssignmentOperatorType.Assign,
                                    new PrimitiveExpression(entityName, entityName))));

            // this.ViewText = "96E65595-1C9E-4BFB-A0E5-80BF2D6FC185"; // Will be replaced later
            ctor.Body.AddChild(new ExpressionStatement(
                               	new AssignmentExpression(
                               		new MemberReferenceExpression(new ThisReferenceExpression(), "ViewText"),
                               		AssignmentOperatorType.Assign,
                               		new PrimitiveExpression(mapReduceTextToken, mapReduceTextToken))));

            // this.MapDefinition = from doc in docs ...;
            ctor.Body.AddChild(new ExpressionStatement(
                               	new AssignmentExpression(
                               		new MemberReferenceExpression(new ThisReferenceExpression(), "MapDefinition"),
                               		AssignmentOperatorType.Assign,
                               		new LambdaExpression
                               		{
                               			Parameters =
                               				{
                               					new ParameterDeclarationExpression(null, "docs")
                               				},
                               			ExpressionBody = mapDefinition.Initializer
                               		})));

            var captureSelectNewFieldNamesVisitor = new CaptureSelectNewFieldNamesVisitor();

            mapDefinition.Initializer.AcceptVisitor(captureSelectNewFieldNamesVisitor, null);

            if(indexDefinition.TransformResults != null)
            {
                VariableDeclaration translatorDeclaration;

                if (indexDefinition.TransformResults.Trim().StartsWith("from"))
                {
                    translatorDeclaration = QueryParsingUtils.GetVariableDeclarationForLinqQuery(indexDefinition.TransformResults, requiresSelectNewAnonymousType:false);
                }
                else
                {
                    translatorDeclaration = QueryParsingUtils.GetVariableDeclarationForLinqMethods(indexDefinition.TransformResults);
                }

                // this.Translator = (Database,results) => from doc in results ...;
                ctor.Body.AddChild(new ExpressionStatement(
                                    new AssignmentExpression(
                                        new MemberReferenceExpression(new ThisReferenceExpression(), "TransformResultsDefinition"),
                                        AssignmentOperatorType.Assign,
                                        new LambdaExpression
                                        {
                                            Parameters =
                               				{
                               					new ParameterDeclarationExpression(null, "Database"),
                                                new ParameterDeclarationExpression(null, "results")
                               				},
                                            ExpressionBody = translatorDeclaration.Initializer
                                        })));
            }

            if (indexDefinition.IsMapReduce)
            {
                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);
                    var invocation = ((InvocationExpression) reduceDefiniton.Initializer);
                    var target = (MemberReferenceExpression) invocation.TargetObject;
                    while(target.MemberName!="GroupBy")
                    {
                        invocation = (InvocationExpression) target.TargetObject;
                        target = (MemberReferenceExpression)invocation.TargetObject;
                    }
                    var lambdaExpression = ((LambdaExpression)invocation.Arguments[0]);
                    groupByParamter = lambdaExpression.Parameters[0].ParameterName;
                    groupBySource = lambdaExpression.ExpressionBody;
                }

                captureSelectNewFieldNamesVisitor.FieldNames.Clear();// reduce override the map fields
                reduceDefiniton.Initializer.AcceptVisitor(captureSelectNewFieldNamesVisitor, null);

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

            foreach (var fieldName in captureSelectNewFieldNamesVisitor.FieldNames)
            {
                ctor.Body.AddChild(
                    new ExpressionStatement(
                        new InvocationExpression(
                            new MemberReferenceExpression(
                                new ThisReferenceExpression(),
                                "AddField"
                                ),
                            new List<Expression> { new PrimitiveExpression(fieldName, fieldName) }
                            )
                        )
                    );
            }

            CompiledQueryText = QueryParsingUtils.GenerateText(type, extensions);
            var compiledQueryText = "@\"" + indexDefinition.Map.Replace("\"", "\"\"");
            if (indexDefinition.Reduce != null)
            {
                compiledQueryText += Environment.NewLine + indexDefinition.Reduce.Replace("\"", "\"\"");
            }

            if (indexDefinition.TransformResults != null)
            {
                compiledQueryText += Environment.NewLine + indexDefinition.TransformResults.Replace("\"", "\"\"");
            }

            compiledQueryText += "\"";
            CompiledQueryText = CompiledQueryText.Replace("\"" + mapReduceTextToken + "\"",
                                                          compiledQueryText);
        }