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