示例#1
0
        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);
            }
        }
示例#2
0
        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) };
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        //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) };
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        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);
        }
示例#9
0
        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");
            }
        }