// 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}.") });
// 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); }
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); }
// 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); }
// 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); } }
public AstComparisonFilterOperation(AstComparisonFilterOperator @operator, BsonValue value) { _operator = @operator; _value = Ensure.IsNotNull(value, nameof(value)); }
// 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))); }