static Expression RecursivelyGetSubselects(GetExpression get, Expression filterexpr, bool includeFilter, Type itemType, int depth = 0) { if (get.Subselect == null) { var sourceExpr = includeFilter ? filterexpr : null; Expression reduceexpr = ReduceExpressionGeneration.GetMapreduceExpression(sourceExpr, get._selects.ToArray(), get._dimensions.Any() ? get._dimensions.ToArray() : null, itemType, get, null, "sc" + depth); return(reduceexpr); } else { var sub = RecursivelyGetSubselects(get.Subselect, filterexpr, includeFilter, itemType, depth + 1); var lambda = sub as LambdaExpression; var body = lambda.Body; var param = lambda.Parameters.FirstOrDefault(); var resultType = body.Type; var targetType = ReduceExpressionGeneration.GetTypeOfEnumerable(resultType); Expression reduceexpr = ReduceExpressionGeneration.GetMapreduceExpression(null, get._selects.ToArray(), get._dimensions.Any() ? get._dimensions.ToArray() : null, targetType, get, body, "sc" + depth); //reduceexpr = ParameterRebinder.ReplaceParameters(reduceexpr, "sc", param); //return reduceexpr; var reducebody = (reduceexpr as LambdaExpression).Body; var newlambda = Expression.Lambda(reducebody, param); return(newlambda); } }
public static Expression GetMergeExpression(string query, Type itemType, Type targetType) { EvoQLBuilder builder = new EvoQLBuilder(query); ParameterExpression parameterExpression; EvoQLExpression parse; var filterexpr = builder.CreateFilterExpression(out parse, out parameterExpression, itemType); var get = parse.Tree as GetExpression; //var selects = get._selects.Select(x => new SelectDescriptor { SourcePath = x.Source, Function = x.Function, TargetPath = x.Target } ).ToArray(); Type resultType = targetType; if (resultType == null) { if (itemType == null) { throw new Exception("Neither Target or Source Item Type specified"); } var mapreduceexpr = GetReduceExpression(query, itemType); //var mapreduceexpr = res.Expression; var enumType = mapreduceexpr.GetType().GetProperty("ReturnType").GetValue(mapreduceexpr, null) as Type; resultType = ReduceExpressionGeneration.GetTypeOfEnumerable(enumType); } //var resultElementType = ReduceExpressionGeneration.GetTypeOfEnumerable(resultType); //Expression mergeExpr = ReduceExpressionGeneration.GetMergeExpression(select, resultElementType); var mergeexpr = ReduceExpressionGeneration.GetMergeInvocationExpression(get._selects.ToArray(), get._dimensions.ToArray(), resultType); return(mergeexpr); //return new ExpressionResult { Expression = mergeexpr, Collections = GetCollections(parse) }; }
private static Expression CreateUnspecifiedStringExpression(Expression leftExpression, Type elementType, ParameterExpression xParam) { var stringFields = elementType.GetFields().Where(x => x.FieldType == typeof(string)); //Attribute.GetCustomAttributes(x, typeof(BermudaTextSearchMemberAttribute)) != null var stringContainsExpressions = stringFields.Where(x => x.Name == "Name" || x.Name == "Description").Select(x => CreateStringFieldContainsExpression(Expression.MakeMemberAccess(xParam, x), leftExpression)); var chainOrredExpression = ReduceExpressionGeneration.ChainOrExpressionCollection(stringContainsExpressions); return(chainOrredExpression); }
private Expression CreateInExpression(Expression rightExpression, ParameterExpression xParam, Expression leftExpression) { var asArray = rightExpression as NewArrayExpression; var conditions = asArray.Expressions.OfType <ConstantExpression>().Select ( x => Expression.Equal(leftExpression, Expression.Constant(Convert.ChangeType(x.Value, leftExpression.Type))) ); var chained = ReduceExpressionGeneration.ChainOrExpressionCollection(conditions); return(chained); }
//public static Expression GetFilterLambda(string query, Type itemType) //{ // EvoQLBuilder builder = new EvoQLBuilder(query); // ParameterExpression parameterExpression; // EvoQLExpression parse; // return builder.GetFilterLambda(out parse, out parameterExpression); //} //public static Expression GetFilterLambdaWithParameters(string query, Type itemType) //{ // EvoQLBuilder builder = new EvoQLBuilder(query); // ParameterExpression parameterExpression; // EvoQLExpression parse; // return builder.GetFilterLambdaWithParameters(out parse, out parameterExpression); //} public static Expression GetWhereExpression(string query, Type itemType) { EvoQLBuilder builder = new EvoQLBuilder(query); ParameterExpression parameterExpression; EvoQLExpression parse; var filterexpr = builder.CreateFilterExpression(out parse, out parameterExpression, itemType); var queryexpr = ReduceExpressionGeneration.GetWhereExpression(filterexpr, itemType); return(queryexpr); //return new ExpressionResult { Expression = queryexpr, Collections = GetCollections(parse) }; }
public Expression GetPagingExpression(Type itemType) { EvoQLExpression parse = ParseQuery(); if (parse.Tree is GetExpression) { GetExpression get = (GetExpression)parse.Tree; var res = ReduceExpressionGeneration.GetPagingExpression(get, itemType); return(res); //return new ExpressionResult { Expression = res, Collections = GetCollections(parse) }; } return(null); }
private static Expression CreateCollectionContainsExpression(Expression rightExpression, ParameterExpression xParam, Expression leftExpression) { var itemType = ReduceExpressionGeneration.GetTypeOfEnumerable(leftExpression.Type); Expression rhs = null; if (ReduceExpressionGeneration.IsTupleType(itemType)) { var anyMethodInfosGeneric = typeof(Enumerable).GetMethods().Where(x => x.Name == "Any" && x.GetParameters().Length == 2); var anyMethodInfoGeneric = anyMethodInfosGeneric.FirstOrDefault(); var anyMethodInfo = anyMethodInfoGeneric.MakeGenericMethod(itemType); var item2Info = itemType.GetProperty("Item2"); var itemParam = Expression.Parameter(itemType, "tpl"); var item2Access = Expression.MakeMemberAccess(itemParam, item2Info); var equalsExpr = Expression.Equal(item2Access, rightExpression); var lambda = Expression.Lambda ( delegateType: typeof(Func <,>).MakeGenericType(itemType, typeof(bool)), parameters: itemParam, body: equalsExpr ); rhs = Expression.Call ( method: anyMethodInfo, arg0: leftExpression, arg1: lambda ); } else { var containsMethodInfosGeneric = typeof(Enumerable).GetMethods().Where(x => x.Name == "Contains" && x.GetParameters().Length == 2); var containsMethodInfoGeneric = containsMethodInfosGeneric.FirstOrDefault(); var containsMethodInfo = containsMethodInfoGeneric.MakeGenericMethod(itemType); //var actualValue = Convert.ChangeType(Child, itemType); rhs = Expression.Call ( method: containsMethodInfo, arg0: leftExpression, arg1: rightExpression ); //var targetMemberAccess = Expression.MakeMemberAccess(xParam, targetField); } //return rhs; var result = Expression.AndAlso ( Expression.ReferenceNotEqual(leftExpression, Expression.Constant(null)), rhs ); return(result); }
public override Expression CreateExpression(object context) { //return null; //var literalRight = Right as LiteralExpression; //var valueRight = Right as ValueExpression; //var dimensionRight = Right as DimensionExpression; //var literalLeft = Left as LiteralExpression; //var valueLeft = Left as ValueExpression; //var dimensionLeft = Left as DimensionExpression; var leftExpression = Left == null ? null : Left.CreateExpression(new DimensionCreateExpressionParameter { QuoteUnknownIdentifiers = Right == null, Left = Left, Right = Right }); var rightExpression = Right == null ? null : Right.CreateExpression(new DimensionCreateExpressionParameter { QuoteUnknownIdentifiers = true, Left = Left, Right = Right }); var asLeftRange = leftExpression as NewArrayExpression; var asRightRange = rightExpression as NewArrayExpression; if (asLeftRange != null) { throw new BermudaExpressionGenerationException("Ranges are only supported on the right hand side"); } if (asRightRange == null && leftExpression != null && rightExpression != null && leftExpression.Type != rightExpression.Type) { var asLeftLiteral = leftExpression as ConstantExpression; Expression asLeftDimension = leftExpression; var asRightLiteral = rightExpression as ConstantExpression; Expression asRightDimension = rightExpression; //if (asLeftDimension == null) asLeftDimension = leftExpression as MethodCallExpression; //if (asRightDimension == null) asRightDimension = asRightDimension as MethodCallExpression; try { if (asLeftLiteral == null && asRightLiteral == null) { rightExpression = Expression.Convert(rightExpression, leftExpression.Type); } else if (asLeftDimension != null && asRightLiteral != null) { var targetType = leftExpression.Type; if (ReduceExpressionGeneration.IsCollectionType(targetType)) { targetType = ReduceExpressionGeneration.GetTypeOfEnumerable(targetType); } if (ReduceExpressionGeneration.IsTupleType(targetType)) { targetType = targetType.GetGenericArguments().Last(); } long num; if (targetType == typeof(long) && asRightLiteral.Value is string && !long.TryParse(asRightLiteral.Value as string, out num)) { var lookupKey = leftExpression.ToString().Split('.').LastOrDefault(); if (!string.IsNullOrWhiteSpace(lookupKey)) { num = GetLookup(lookupKey, asRightLiteral.Value as string); } } rightExpression = Expression.Constant(Convert.ChangeType(asRightLiteral.Value, targetType)); } else if (asLeftLiteral != null && asRightDimension != null) { var targetType = rightExpression.Type; if (ReduceExpressionGeneration.IsCollectionType(targetType)) { targetType = ReduceExpressionGeneration.GetTypeOfEnumerable(targetType); } if (!ReduceExpressionGeneration.IsTupleType(targetType)) { targetType = targetType.GetGenericArguments().Last(); } leftExpression = Expression.Constant(Convert.ChangeType(asLeftLiteral.Value, targetType)); } else if (asLeftLiteral != null && asRightLiteral != null) { leftExpression = Expression.Constant(Convert.ChangeType(asLeftLiteral.Value, rightExpression.Type)); } else { throw new BermudaExpressionGenerationException("Not supposed to happen"); } } catch (Exception ex) { if (ex is BermudaExpressionGenerationException) { throw ex; } //throw new BermudaExpressionGenerationException("Failed to convert: " + ex.Message); Root.AddWarning(ex.ToString()); return(null); } } //if (literalRight == null && valueRight == null) //{ // throw new Exception("The selector must specify an expression child or a literal child"); //} //object rightValue = literalRight != null ? (object)literalRight.Value : (object)valueRight.Value; //object leftValue = literalLeft != null ? (object)literalLeft.Value : (object)valueLeft.Value; var getExpression = (GetExpression)Root; Type elementType = Root.ElementType; var xParam = Expression.Parameter(elementType, "x"); //freeform strings inside the query switch (NodeType) { case SelectorTypes.Unspecified: { if (Parent is DimensionExpression) { return(rightExpression); } if (Right != null) { var name = Right.ToString(); var boolField = ReduceExpressionGeneration.GetField(elementType, name, false); if (boolField != null) { Expression boolFieldAccess = Expression.MakeMemberAccess(xParam, boolField); return(boolFieldAccess); } //var isTrue = Expression.Equal(boolFieldAccess, Expression.Constant(true)); } return(CreateUnspecifiedStringExpression(rightExpression, elementType, xParam)); } case SelectorTypes.Unknown: { if (leftExpression == null || rightExpression == null) { return(null); } switch (Modifier) { case ModifierTypes.Contains: return(CreateCollectionContainsExpression(rightExpression, xParam, leftExpression)); case ModifierTypes.In: return(CreateInExpression(rightExpression, xParam, leftExpression)); case ModifierTypes.Like: case ModifierTypes.Colon: if (leftExpression.Type == typeof(string)) { return(CreateStringFieldContainsExpression(leftExpression, rightExpression)); } else if (ReduceExpressionGeneration.IsCollectionType(leftExpression.Type)) { goto case ModifierTypes.Contains; } else { if (asRightRange != null) { goto case ModifierTypes.InRange; } else { goto case ModifierTypes.Equals; } } case ModifierTypes.InRange: return(CreateInRangeExpression(leftExpression, asRightRange)); case ModifierTypes.Equals: return(Expression.Equal(leftExpression, rightExpression)); case ModifierTypes.GreaterThan: if (asRightRange != null) { goto case ModifierTypes.InRange; } return(Expression.GreaterThan(leftExpression, rightExpression)); case ModifierTypes.LessThan: if (asRightRange != null) { goto case ModifierTypes.InRange; } return(Expression.LessThan(leftExpression, rightExpression)); case ModifierTypes.Add: return(Expression.Add(leftExpression, rightExpression)); case ModifierTypes.Subtract: return(Expression.Add(leftExpression, rightExpression)); case ModifierTypes.Multiply: return(Expression.Add(leftExpression, rightExpression)); case ModifierTypes.Divide: return(Expression.Add(leftExpression, rightExpression)); default: throw new BermudaExpressionGenerationException("Unsupported Operator " + Modifier + " for Operands " + leftExpression + " and " + rightExpression); } } } return(null); }
public override Expression CreateExpression(object context) { var param = context as DimensionCreateExpressionParameter; if (Child != null) { var result = Child.CreateExpression(context); if (IsNegated) { result = Expression.Negate(result); } if (IsNotted) { result = Expression.Not(result); } return(result); } if (!IsFunctionCall) { var elementType = Root.ElementType; var path = Source; var targetField = ReduceExpressionGeneration.GetField(elementType, path, false); if (targetField == null) { var asContext = context as DimensionCreateExpressionParameter; if (asContext != null) { long longResult = 0; double doubleResult = 0; if (long.TryParse(Source, out longResult)) { return(Expression.Constant(longResult)); } else if (double.TryParse(Source, out doubleResult)) { return(Expression.Constant(doubleResult)); } else if (!asContext.QuoteUnknownIdentifiers && !IsQuoted) { return(null); } Expression cons = Expression.Constant(Convert.ChangeType(Source, SourceType)); if (IsNegated) { cons = Expression.Negate(cons); } if (IsNotted) { cons = Expression.Not(cons); } return(cons); } return(null); } var xParam = Expression.Parameter(elementType, "x"); if (targetField.FieldType == typeof(string) || targetField.FieldType == typeof(bool)) { return(Expression.MakeMemberAccess(xParam, targetField)); } else if (targetField.FieldType == typeof(long) || targetField.FieldType == typeof(double) || targetField.FieldType == typeof(int) || targetField.FieldType == typeof(float) || targetField.FieldType == typeof(DateTime)) { Expression memberAccessExpr = Expression.MakeMemberAccess(xParam, targetField); //if (IsNegated) // memberAccessExpr = Expression.Negate(memberAccessExpr); return(memberAccessExpr); } else if (ReduceExpressionGeneration.IsCollectionType(targetField.FieldType)) { return(Expression.MakeMemberAccess(xParam, targetField)); } else { var res = Expression.MakeMemberAccess(xParam, targetField); return(res); //throw new NotImplementedException("Unsupported field Type: " + targetField.FieldType.Name); } } else { var elementType = Root.ElementType; var xParam = Expression.Parameter(elementType, "x"); var asDim = (param.Left ?? param.Right) as DimensionExpression; var functionCall = ReduceExpressionGeneration.MakeFunctionCallExpression(asDim, elementType, xParam); return(functionCall); //throw new NotImplementedException("Not supported functions in where logic"); } }