예제 #1
0
        protected override Expression VisitBinary(BinaryExpression node)
        {
            if (_parsePhase.Get() == ParsePhase.Condition)
            {
                if (node.NodeType == ExpressionType.AndAlso)
                {
                    // It's the AND of the WHERE/IF clause
                    Visit(node.Left);

                    // Add the new condition for the right portion
                    _conditions.Add(new BinaryConditionItem());
                    Visit(node.Right);
                    return(node);
                }

                var condition = _conditions.Last();
                if (BinaryConditionItem.IsSupported(node.NodeType))
                {
                    if (node.NodeType == ExpressionType.Equal && IsBoolMember(node.Left))
                    {
                        // Handle x.prop == boolValue explicitly
                        FillBooleanCondition((MemberExpression)node.Left, condition);
                        Visit(node.Right);
                        return(node);
                    }

                    if (node.NodeType == ExpressionType.Equal && IsBoolMember(node.Right))
                    {
                        // Handle boolValue == x.prop explicitly
                        FillBooleanCondition((MemberExpression)node.Right, condition);
                        Visit(node.Left);
                        return(node);
                    }

                    Visit(DropNullableConversion(node.Left));
                    condition.SetOperator(node.NodeType);
                    Visit(DropNullableConversion(node.Right));
                    return(node);
                }

                if (!CqlUnsupTags.Contains(node.NodeType))
                {
                    condition.SetParameter(Expression.Lambda(node).Compile().DynamicInvoke());
                    return(node);
                }
            }
            else if (_parsePhase.Get() == ParsePhase.SelectBinding)
            {
                var column = _pocoData.GetColumnByMemberName(_currentBindingName.Get());
                if (column == null)
                {
                    throw new ArgumentException("Trying to select a column does it excluded in the mappings");
                }
                AddProjection(node, column);
                _selectFields.Add(column.ColumnName);
                return(node);
            }
            throw new CqlLinqNotSupportedException(node, _parsePhase.Get());
        }
예제 #2
0
 protected override Expression VisitUnary(UnaryExpression node)
 {
     if (_parsePhase.Get() == ParsePhase.Condition)
     {
         var condition = _conditions.Last();
         if (node.NodeType == ExpressionType.Not && node.Operand.NodeType == ExpressionType.MemberAccess)
         {
             // We are evaluating a boolean expression parameter, the value we are trying to match is false
             FillBooleanCondition((MemberExpression)node.Operand, condition, false);
             return(node);
         }
         if (BinaryConditionItem.IsSupported(node.NodeType))
         {
             condition.SetOperator(node.NodeType);
             Visit(DropNullableConversion(node.Operand));
         }
         else if (node.NodeType == ExpressionType.Convert)
         {
             Visit(node.Operand);
         }
         else
         {
             var val = Expression.Lambda(node).Compile().DynamicInvoke();
             condition.SetParameter(val);
         }
         return(node);
     }
     if (_parsePhase.Get() == ParsePhase.SelectBinding)
     {
         if (node.NodeType == ExpressionType.Convert && node.Type.Name == "Nullable`1")
         {
             // ReSharper disable once AssignNullToNotNullAttribute
             return(Visit(node.Operand));
         }
         var column = _pocoData.GetColumnByMemberName(_currentBindingName.Get());
         if (column != null && column.IsCounter)
         {
             var value = Expression.Lambda(node).Compile().DynamicInvoke();
             if (!(value is long || value is int))
             {
                 throw new ArgumentException("Only Int64 and Int32 values are supported as counter increment of decrement values");
             }
             _projections.Add(Tuple.Create(column, value, ExpressionType.Increment));
             _selectFields.Add(column.ColumnName);
             return(node);
         }
     }
     throw new CqlLinqNotSupportedException(node, _parsePhase.Get());
 }
예제 #3
0
        private Expression EvaluateConditionFunction(MethodCallExpression node)
        {
            var condition = _conditions.Last();

            switch (node.Method.Name)
            {
            case nameof(Enumerable.Contains):
                EvaluateContainsMethod(node);
                return(node);

            case nameof(Tuple.Create) when node.Method.DeclaringType == typeof(Tuple):
                EvaluateCompositeColumn(node);
                return(node);

            case nameof(string.StartsWith) when node.Method.DeclaringType == typeof(string):
                Visit(node.Object);
                var startsWithArgument = node.Arguments[0];
                var startString        = (string)Expression.Lambda(startsWithArgument).Compile().DynamicInvoke();
                var endString          = startString + Utf8MaxValue;
                // Create 2 conditions, ie: WHERE col1 >= startString AND col2 < endString
                var column = condition.Column;
                condition.SetOperator(ExpressionType.GreaterThanOrEqual)
                .SetParameter(startString);

                condition = new BinaryConditionItem();
                condition.SetColumn(column)
                .SetOperator(ExpressionType.LessThan)
                .SetParameter(endString);
                _conditions.Add(condition);
                return(node);

            case nameof(IComparable.CompareTo):
                // Allow comparison to zero
                condition.SetAsCompareTo();
                Visit(node.Object);
                Visit(node.Arguments[0]);
                return(node);

            case nameof(Equals):
                Visit(node.Object);
                condition.SetOperator(ExpressionType.Equal);
                Visit(node.Arguments[0]);
                return(node);

            case nameof(CqlToken.Create) when node.Method.DeclaringType == typeof(CqlToken):
            case nameof(CqlFunction.Token) when node.Method.DeclaringType == typeof(CqlFunction):
                condition.SetFunctionName("token").AllowMultipleColumns().AllowMultipleParameters();
                foreach (var argument in node.Arguments)
                {
                    Visit(argument);
                }
                return(node);

            case nameof(CqlFunction.MaxTimeUuid):
            case nameof(CqlFunction.MinTimeUuid):
                condition.SetFunctionName(node.Method.Name.ToLowerInvariant());
                Visit(node.Arguments[0]);
                return(node);
            }
            // Try to invoke to obtain the parameter value
            condition.SetParameter(Expression.Lambda(node).Compile().DynamicInvoke());
            return(node);
        }