// caller is responsible for ensuring constant is on the right
        public static AstFilter Translate(
            TranslationContext context,
            Expression expression,
            Expression leftExpression,
            AstComparisonFilterOperator comparisonOperator,
            Expression rightExpression)
        {
            if (leftExpression is MethodCallExpression leftMethodCallExpression &&
                IsCompareToMethod(leftMethodCallExpression.Method))
            {
                var fieldExpression = leftMethodCallExpression.Object;
                var field           = ExpressionToFilterFieldTranslator.Translate(context, fieldExpression);

                var valueExpression = leftMethodCallExpression.Arguments[0];
                var value           = valueExpression.GetConstantValue <object>(containingExpression: expression);
                var serializedValue = SerializationHelper.SerializeValue(field.Serializer, value);

                var rightValue = rightExpression.GetConstantValue <int>(containingExpression: expression);
                if (rightValue == 0)
                {
                    return(AstFilter.Compare(field, comparisonOperator, serializedValue));
                }
            }

            throw new ExpressionNotSupportedException(expression);
        }
 public static string Render(this AstComparisonFilterOperator @operator)
 {
     return(@operator switch
     {
         AstComparisonFilterOperator.Eq => "$eq",
         AstComparisonFilterOperator.Gt => "$gt",
         AstComparisonFilterOperator.Gte => "$gte",
         AstComparisonFilterOperator.Lt => "$lt",
         AstComparisonFilterOperator.Lte => "$lte",
         AstComparisonFilterOperator.Ne => "$ne",
         _ => throw new InvalidOperationException($"Unexpected comparison filter operator: {@operator}.")
     });
Exemple #3
0
        // caller is responsible for ensuring constant is on the right
        public static AstFilter Translate(
            TranslationContext context,
            Expression expression,
            Expression leftExpression,
            AstComparisonFilterOperator comparisonOperator,
            Expression rightExpression)
        {
            if (leftExpression is BinaryExpression leftBinaryExpression &&
                leftBinaryExpression.NodeType == ExpressionType.And)
            {
                var fieldExpression = leftBinaryExpression.Left;
                var field           = ExpressionToFilterFieldTranslator.Translate(context, fieldExpression);

                var bitMaskExpression = leftBinaryExpression.Right;
                var bitMask           = bitMaskExpression.GetConstantValue <object>(containingExpression: expression);
                var serializedBitMask = SerializationHelper.SerializeValue(field.Serializer, bitMask);

                var rightValue = rightExpression.GetConstantValue <object>(containingExpression: expression);
                var zeroValue  = Activator.CreateInstance(bitMask.GetType());

                switch (comparisonOperator)
                {
                case AstComparisonFilterOperator.Eq:
                    if (rightValue.Equals(zeroValue))
                    {
                        return(AstFilter.BitsAllClear(field, serializedBitMask));
                    }
                    else if (rightValue.Equals(bitMask))
                    {
                        return(AstFilter.BitsAllSet(field, serializedBitMask));
                    }
                    break;

                case AstComparisonFilterOperator.Ne:
                    if (rightValue.Equals(zeroValue))
                    {
                        return(AstFilter.BitsAnySet(field, serializedBitMask));
                    }
                    else if (rightValue.Equals(bitMask))
                    {
                        return(AstFilter.BitsAnyClear(field, serializedBitMask));
                    }
                    break;
                }
            }

            throw new ExpressionNotSupportedException(expression);
        }
Exemple #4
0
        private static AstFilter TranslateGetCharsComparison(TranslationContext context, Expression expression, Expression leftExpression, AstComparisonFilterOperator comparisonOperator, Expression rightExpression)
        {
            var leftConvertExpression  = (UnaryExpression)leftExpression;
            var leftGetCharsExpression = (MethodCallExpression)leftConvertExpression.Operand;
            var fieldExpression        = leftGetCharsExpression.Object;

            var(field, modifiers) = TranslateField(context, expression, fieldExpression);

            var indexExpression = leftGetCharsExpression.Arguments[0];
            var index           = indexExpression.GetConstantValue <int>(containingExpression: expression);

            var comparand       = rightExpression.GetConstantValue <int>(containingExpression: expression);
            var comparandChar   = (char)comparand;
            var comparandString = new string(comparandChar, 1);

            if (comparisonOperator == AstComparisonFilterOperator.Eq || comparisonOperator == AstComparisonFilterOperator.Ne)
            {
                var pattern = comparisonOperator == AstComparisonFilterOperator.Eq ?
                              $".{{{index}}}{Regex.Escape(comparandString)}.*" :
                              $".{{{index}}}[^{EscapeCharacterSet(comparandChar)}].*";

                return(CreateRegexFilter(field, modifiers, pattern));
            }

            throw new ExpressionNotSupportedException(expression);
        }
Exemple #5
0
        // caller is responsible for ensuring constant is on the right
        public static AstFilter TranslateComparisonExpression(TranslationContext context, Expression expression, Expression leftExpression, AstComparisonFilterOperator comparisonOperator, Expression rightExpression)
        {
            if (IsGetCharsComparison(leftExpression))
            {
                return(TranslateGetCharsComparison(context, expression, leftExpression, comparisonOperator, rightExpression));
            }

            if (IsStringComparison(leftExpression))
            {
                return(TranslateStringComparison(context, expression, leftExpression, comparisonOperator, rightExpression));
            }

            if (IsStringIndexOfComparison(leftExpression))
            {
                return(TranslateStringIndexOfComparison(context, expression, leftExpression, comparisonOperator, rightExpression));
            }

            if (IsStringLengthComparison(leftExpression) || IsStringCountComparison(leftExpression))
            {
                return(TranslateStringLengthComparison(context, expression, leftExpression, comparisonOperator, rightExpression));
            }

            throw new ExpressionNotSupportedException(expression);
        }
Exemple #6
0
 // caller is responsible for ensuring constant is on the right
 public static bool TryTranslateComparisonExpression(TranslationContext context, Expression expression, Expression leftExpression, AstComparisonFilterOperator comparisonOperator, Expression rightExpression, out AstFilter filter)
 {
     try
     {
         filter = TranslateComparisonExpression(context, expression, leftExpression, comparisonOperator, rightExpression);
         return(true);
     }
     catch (ExpressionNotSupportedException)
     {
         filter = null;
         return(false);
     }
 }
        private static AstFilter TranslateComparisonToBooleanConstant(TranslationContext context, Expression expression, Expression leftExpression, AstComparisonFilterOperator comparisonOperator, bool comparand)
        {
            var filter = ExpressionToFilterTranslator.Translate(context, leftExpression);

            if (filter is AstFieldOperationFilter fieldOperationFilter &&
                fieldOperationFilter.Operation is AstComparisonFilterOperation comparisonOperation &&
                comparisonOperation.Operator == AstComparisonFilterOperator.Eq &&
                comparisonOperation.Value == true)
            {
                var field = fieldOperationFilter.Field;

                switch (comparisonOperator)
                {
                case AstComparisonFilterOperator.Eq:
                    return(AstFilter.Eq(field, comparand));

                case AstComparisonFilterOperator.Ne:
                    return(AstFilter.Ne(field, comparand));

                default:
                    throw new ExpressionNotSupportedException(expression);
                }
            }
Exemple #8
0
 public AstComparisonFilterOperation(AstComparisonFilterOperator @operator, BsonValue value)
 {
     _operator = @operator;
     _value    = Ensure.IsNotNull(value, nameof(value));
 }
Exemple #9
0
        // caller is responsible for ensuring constant is on the right
        public static bool CanTranslateComparisonExpression(Expression leftExpression, AstComparisonFilterOperator comparisonOperator, Expression rightExpression)
        {
            // (int)document.S[i] == c
            if (IsGetCharsComparison(leftExpression))
            {
                return(true);
            }

            // document.S == "abc"
            if (IsStringComparison(leftExpression))
            {
                return(true);
            }

            // document.S.IndexOf('a') == n etc...
            if (IsStringIndexOfComparison(leftExpression))
            {
                return(true);
            }
            // document.S.Length == n or document.S.Count() == n
            if (IsStringLengthComparison(leftExpression) || IsStringCountComparison(leftExpression))
            {
                return(true);
            }

            return(false);
        }
 public static AstFieldOperationFilter Compare(AstFilterField field, AstComparisonFilterOperator comparisonOperator, BsonValue value)
 {
     return(new AstFieldOperationFilter(field, new AstComparisonFilterOperation(comparisonOperator, value)));
 }