/// <summary>
        ///     create greater than or equal expression ( operator ">=" or "=ge=" )
        /// </summary>
        /// <param name="parameter"></param>
        /// <param name="context"></param>
        /// <param name="jsonNamingPolicy"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static Expression <Func <T, bool> > GetGeExpression <T>(ParameterExpression parameter,
                                                                       RSqlQueryParser.ComparisonContext context,
                                                                       JsonNamingPolicy jsonNamingPolicy = null)
        {
            var expressionValue = GetSelector <T>(parameter, context, jsonNamingPolicy);

            if (!RSqlQueryGetValueHelper.IsLowerOrGreaterComparisonType(expressionValue.Property.PropertyType))
            {
                throw new ComparisonInvalidComparatorSelectionException(context);
            }

            var value = GetUniqueValue <T>(parameter, expressionValue, context, jsonNamingPolicy);

            var expression = value is ExpressionValue valueExp1
                ? valueExp1.Expression
                : Expression.Constant(value, expressionValue.Property.PropertyType);

            if (value is ExpressionValue valueExp2 &&
                valueExp2.Property.PropertyType != expressionValue.Property.PropertyType)
            {
                throw new ComparisonInvalidMatchTypeException(context);
            }

            return(Expression.Lambda <Func <T, bool> >(Expression.GreaterThanOrEqual(
                                                           expressionValue.Expression,
                                                           expression), parameter));
        }
        /// <summary>
        /// extract the selector
        /// </summary>
        /// <param name="parameter"></param>
        /// <param name="context"></param>
        /// <param name="jsonNamingPolicy"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        private static ExpressionValue GetSelector <T>(ParameterExpression parameter,
                                                       RSqlQueryParser.ComparisonContext context,
                                                       JsonNamingPolicy jsonNamingPolicy)
        {
            var result = ExpressionValue.Parse <T>(parameter, context.selector().GetText(), jsonNamingPolicy);

            return(result ?? throw new ComparisonUnknownSelectorException(context));
        }
        /// <summary>
        ///     create not in expression ( operator "=out=" )
        /// </summary>
        /// <returns></returns>
        public static Expression <Func <T, bool> > GetOutExpression <T>(ParameterExpression parameter,
                                                                        RSqlQueryParser.ComparisonContext context,
                                                                        JsonNamingPolicy namingStrategy = null)
        {
            var expression = GetInExpression <T>(parameter, context, namingStrategy);
            var body       = Expression.Not(expression.Body);

            return(Expression.Lambda <Func <T, bool> >(body, parameter));
        }
示例#4
0
        public static object GetTemporalValue <T>(ParameterExpression parameter, ExpressionValue expressionValue,
                                                  RSqlQueryParser.ComparisonContext context,
                                                  JsonNamingPolicy jsonNamingPolicy = null)
        {
            if (IsDateTimeOffset(expressionValue.Property.PropertyType))
            {
                return(GetDateTimeOffset <T>(parameter, context.arguments().value()[0], jsonNamingPolicy));
            }

            return(GetDateTime <T>(parameter, context.arguments().value()[0], jsonNamingPolicy));
        }
示例#5
0
        public static object GetAlphabeticValue <T>(ParameterExpression parameter, ExpressionValue expressionValue,
                                                    RSqlQueryParser.ComparisonContext context,
                                                    JsonNamingPolicy jsonNamingPolicy = null)
        {
            if (IsChar(expressionValue.Property.PropertyType))
            {
                return(GetChar <T>(parameter, context.arguments().value()[0], jsonNamingPolicy));
            }

            return(GetString <T>(parameter, context.arguments().value()[0], jsonNamingPolicy));
        }
        /// <summary>
        /// extract the unique value
        /// </summary>
        /// <param name="parameter"></param>
        /// <param name="expressionValue"></param>
        /// <param name="context"></param>
        /// <param name="jsonNamingPolicy"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        /// <exception cref="ComparisonNotEnoughArgumentException"></exception>
        /// <exception cref="ComparisonTooManyArgumentException"></exception>
        private static object GetUniqueValue <T>(ParameterExpression parameter, ExpressionValue expressionValue,
                                                 RSqlQueryParser.ComparisonContext context,
                                                 JsonNamingPolicy jsonNamingPolicy = null)
        {
            var value = context.arguments().value();

            if (value.Length > 1)
            {
                throw new ComparisonTooManyArgumentException(context);
            }

            return(RSqlQueryGetValueHelper.GetValue <T>(parameter, expressionValue, context, jsonNamingPolicy));
        }
        /// <summary>
        ///     create in expression ( operator "=in=" )
        /// </summary>
        /// <returns></returns>
        public static Expression <Func <T, bool> > GetInExpression <T>(ParameterExpression parameter,
                                                                       RSqlQueryParser.ComparisonContext context,
                                                                       JsonNamingPolicy jsonNamingPolicy = null)
        {
            var expressionValue    = GetSelector <T>(parameter, context, jsonNamingPolicy);
            var values             = GetMultipleValue(expressionValue, context);
            var methodContainsInfo =
                QueryReflectionHelper.GetOrRegistryContainsMethodInfo(expressionValue.Property.PropertyType);

            return(Expression.Lambda <Func <T, bool> >(
                       Expression.Call(Expression.Constant(methodContainsInfo.Convert(values)),
                                       methodContainsInfo.ContainsMethod,
                                       expressionValue.Expression), parameter));
        }
示例#8
0
        /// <summary>
        ///     visit a comparison expression
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override Expression <Func <T, bool> > VisitComparison(RSqlQueryParser.ComparisonContext context)
        {
            var comparator = context.comparator().GetText().ToLowerInvariant();

            switch (comparator)
            {
            case "=is-null=":
            case "=nil=":
                return(RSqlQueryExpressionHelper.GetIsNullExpression <T>(_parameter, context, _jsonNamingPolicy));

            case "==":
            case "=eq=":
                return(RSqlQueryExpressionHelper.GetEqExpression <T>(_parameter, context, _jsonNamingPolicy));

            case "!=":
            case "=neq=":
                return(RSqlQueryExpressionHelper.GetNeqExpression <T>(_parameter, context, _jsonNamingPolicy));

            case "<":
            case "=lt=":
                return(RSqlQueryExpressionHelper.GetLtExpression <T>(_parameter, context, _jsonNamingPolicy));

            case "<=":
            case "=le=":
                return(RSqlQueryExpressionHelper.GetLeExpression <T>(_parameter, context, _jsonNamingPolicy));

            case ">":
            case "=gt=":
                return(RSqlQueryExpressionHelper.GetGtExpression <T>(_parameter, context, _jsonNamingPolicy));

            case ">=":
            case "=ge=":
                return(RSqlQueryExpressionHelper.GetGeExpression <T>(_parameter, context, _jsonNamingPolicy));

            case "=in=":
                return(RSqlQueryExpressionHelper.GetInExpression <T>(_parameter, context, _jsonNamingPolicy));

            case "=out=":
                return(RSqlQueryExpressionHelper.GetOutExpression <T>(_parameter, context, _jsonNamingPolicy));

            default:
                throw new ComparisonUnknownComparatorException(context);
            }
        }
        /// <summary>
        ///     create equal expression ( operator "==" or "=eq=" )
        /// </summary>
        /// <param name="parameter"></param>
        /// <param name="context"></param>
        /// <param name="jsonNamingPolicy"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static Expression <Func <T, bool> > GetEqExpression <T>(ParameterExpression parameter,
                                                                       RSqlQueryParser.ComparisonContext context,
                                                                       JsonNamingPolicy jsonNamingPolicy = null)
        {
            var expressionValue = GetSelector <T>(parameter, context, jsonNamingPolicy);

            if (!RSqlQueryGetValueHelper.IsEqualComparisonType(expressionValue.Property.PropertyType))
            {
                throw new ComparisonInvalidComparatorSelectionException(context);
            }

            var value      = GetUniqueValue <T>(parameter, expressionValue, context, jsonNamingPolicy);
            var expression = value is ExpressionValue valueExp1
                ? valueExp1.Expression
                : Expression.Constant(value, expressionValue.Property.PropertyType);

            if (value is ExpressionValue valueExp2 &&
                valueExp2.Property.PropertyType != expressionValue.Property.PropertyType)
            {
                throw new ComparisonInvalidMatchTypeException(context);
            }

            if (expressionValue.Property.PropertyType != typeof(string) || value is ExpressionValue)
            {
                return(Expression.Lambda <Func <T, bool> >(Expression.Equal(
                                                               expressionValue.Expression, expression
                                                               ), parameter));
            }

            var v = ((string)value).Replace(@"\*", MaskLk);

            if (v.IndexOf('*') != -1)
            {
                return(GetLkExpression <T>(parameter, context, jsonNamingPolicy));
            }

            value = v.Replace(MaskLk, "*");

            return(Expression.Lambda <Func <T, bool> >(Expression.Equal(
                                                           expressionValue.Expression,
                                                           Expression.Constant(value, expressionValue.Property.PropertyType)), parameter));
        }
        /// <summary>
        ///     create like expression
        /// </summary>
        /// <returns></returns>
        private static Expression <Func <T, bool> > GetLkExpression <T>(ParameterExpression parameter,
                                                                        RSqlQueryParser.ComparisonContext context,
                                                                        JsonNamingPolicy jsonNamingPolicy = null)
        {
            var expressionValue = GetSelector <T>(parameter, context, jsonNamingPolicy);
            var values          = RSqlQueryGetValueHelper.GetValues(expressionValue.Property.PropertyType, context.arguments());

            if (values.Count > 1)
            {
                throw new ComparisonTooManyArgumentException(context);
            }

            var criteria = Convert.ToString(values[0]) ?? string.Empty;
            var maskStar = "{" + Guid.NewGuid() + "}";

            criteria = criteria.Replace(@"\*", maskStar);
            MethodInfo method;

            if (!criteria.Contains('*'))
            {
                criteria += '*';
            }

            if (criteria.StartsWith("*", StringComparison.Ordinal) && criteria.EndsWith("*", StringComparison.Ordinal))
            {
                method = QueryReflectionHelper.MethodStringContains;
            }
            else if (criteria.StartsWith("*", StringComparison.Ordinal))
            {
                method = QueryReflectionHelper.MethodStringEndsWith;
            }
            else
            {
                method = QueryReflectionHelper.MethodStringStartsWith;
            }

            criteria = criteria.Replace("*", "").Replace(maskStar, "*");
            return(Expression.Lambda <Func <T, bool> >(Expression.Call(expressionValue.Expression,
                                                                       method,
                                                                       Expression.Constant(criteria, expressionValue.Property.PropertyType)), parameter));
        }
示例#11
0
        public static object GetValue <T>(ParameterExpression parameter, ExpressionValue expressionValue,
                                          RSqlQueryParser.ComparisonContext context,
                                          JsonNamingPolicy jsonNamingPolicy = null)
        {
            CheckParameters(parameter, expressionValue, context);

            if (IsNumeric(expressionValue.Property.PropertyType))
            {
                return(GetNumericValue <T>(parameter, expressionValue, context, jsonNamingPolicy));
            }

            if (IsTemporal(expressionValue.Property.PropertyType))
            {
                return(GetTemporalValue <T>(parameter, expressionValue, context, jsonNamingPolicy));
            }

            if (IsAlphabetic(expressionValue.Property.PropertyType))
            {
                return(GetAlphabeticValue <T>(parameter, expressionValue, context, jsonNamingPolicy));
            }

            if (IsBool(expressionValue.Property.PropertyType))
            {
                return(GetBoolean <T>(parameter, context.arguments().value()[0], jsonNamingPolicy));
            }

            if (IsEnum(expressionValue.Property.PropertyType))
            {
                return(GetEnum <T>(parameter, context.arguments().value()[0],
                                   expressionValue.Property.PropertyType, jsonNamingPolicy));
            }

            if (IsGuid(expressionValue.Property.PropertyType))
            {
                return(GetGuid <T>(parameter, context.arguments().value()[0], jsonNamingPolicy));
            }

            return(null);
        }
        /// <summary>
        ///     create is null expression ( operator "=is-null=" or "=nil=" )
        /// </summary>
        /// <param name="parameter"></param>
        /// <param name="context"></param>
        /// <param name="jsonNamingPolicy"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static Expression <Func <T, bool> > GetIsNullExpression <T>(ParameterExpression parameter,
                                                                           RSqlQueryParser.ComparisonContext context,
                                                                           JsonNamingPolicy jsonNamingPolicy = null)
        {
            var expressionValue = GetSelector <T>(parameter, context, jsonNamingPolicy);

            if (!RSqlQueryGetValueHelper.IsNullableComparisonType(expressionValue.Property.PropertyType))
            {
                throw new ComparisonInvalidComparatorSelectionException(context);
            }

            var values = RSqlQueryGetValueHelper.GetValues(typeof(bool), context.arguments());

            if (!values.Any())
            {
                throw new ComparisonNotEnoughArgumentException(context);
            }

            if (values.Count > 1)
            {
                throw new ComparisonTooManyArgumentException(context);
            }

            var result = Expression.Lambda <Func <T, bool> >(Expression.Equal(
                                                                 expressionValue.Expression,
                                                                 Expression.Constant(null, typeof(object))), parameter);

            if ((bool)values[0])
            {
                return(result);
            }

            var body = Expression.Not(result.Body);

            result = Expression.Lambda <Func <T, bool> >(body, parameter);
            return(result);
        }
示例#13
0
        public static object GetNumericValue <T>(ParameterExpression parameter, ExpressionValue expressionValue,
                                                 RSqlQueryParser.ComparisonContext context,
                                                 JsonNamingPolicy jsonNamingPolicy = null)
        {
            if (IsShort(expressionValue.Property.PropertyType))
            {
                return(GetShort <T>(parameter, context.arguments().value()[0], jsonNamingPolicy));
            }

            if (IsLong(expressionValue.Property.PropertyType))
            {
                return(GetLong <T>(parameter, context.arguments().value()[0], jsonNamingPolicy));
            }

            if (IsFloat(expressionValue.Property.PropertyType))
            {
                return(GetFloat <T>(parameter, context.arguments().value()[0], jsonNamingPolicy));
            }

            if (IsDouble(expressionValue.Property.PropertyType))
            {
                return(GetDouble <T>(parameter, context.arguments().value()[0], jsonNamingPolicy));
            }

            if (IsDecimal(expressionValue.Property.PropertyType))
            {
                return(GetDecimal <T>(parameter, context.arguments().value()[0], jsonNamingPolicy));
            }

            if (IsByte(expressionValue.Property.PropertyType))
            {
                return(GetByte <T>(parameter, context.arguments().value()[0], jsonNamingPolicy));
            }

            return(GetInt <T>(parameter, context.arguments().value()[0], jsonNamingPolicy));
        }
示例#14
0
 /// <summary>
 /// Exit a parse tree produced by <see cref="RSqlQueryParser.comparison"/>.
 /// <para>The default implementation does nothing.</para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 public virtual void ExitComparison([NotNull] RSqlQueryParser.ComparisonContext context)
 {
 }
 /// <summary>
 /// extract the multi value
 /// </summary>
 /// <param name="expressionValue"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 /// <exception cref="ComparisonNotEnoughArgumentException"></exception>
 private static List <object> GetMultipleValue(ExpressionValue expressionValue,
                                               RSqlQueryParser.ComparisonContext context)
 {
     return(RSqlQueryGetValueHelper.GetValues(expressionValue.Property.PropertyType, context.arguments()));
 }
示例#16
0
 public ComparisonTooManyArgumentException(RSqlQueryParser.ComparisonContext origin,
                                           Exception innerException = null) : base(origin, $"Too many arguments : {origin?.selector()?.GetText()}",
                                                                                   innerException)
 {
 }
示例#17
0
        private static void CheckParameters(ParameterExpression parameter, ExpressionValue expressionValue, RSqlQueryParser.ComparisonContext context)
        {
            if (parameter == null)
            {
                throw new ArgumentNullException(nameof(parameter));
            }

            if (expressionValue == null)
            {
                throw new ArgumentNullException(nameof(expressionValue));
            }

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
        }
 public ComparisonInvalidComparatorSelectionException(RSqlQueryParser.ComparisonContext origin,
                                                      Exception innerException = null) : base(origin,
                                                                                              $"Invalid selector : {origin?.selector()?.GetText()}", innerException)
 {
 }
 public ComparisonInvalidMatchTypeException(RSqlQueryParser.ComparisonContext origin,
                                            Exception innerException = null) : base(origin,
                                                                                    $"Invalid comparison match type : {origin?.selector()?.GetText()} and {origin?.arguments()?.GetText()}",
                                                                                    innerException)
 {
 }
示例#20
0
 public ComparisonUnknownComparatorException(RSqlQueryParser.ComparisonContext origin,
                                             Exception innerException = null) : base(origin,
                                                                                     $"Unknown comparator : {origin?.comparator()?.GetText()}", innerException)
 {
 }
 public ComparisonNotEnoughArgumentException(RSqlQueryParser.ComparisonContext origin,
                                             Exception innerException = null) : base(origin,
                                                                                     $"Not enough argument : {origin?.selector()?.GetText()}", innerException)
 {
 }
示例#22
0
 /// <summary>
 /// Visit a parse tree produced by <see cref="RSqlQueryParser.comparison"/>.
 /// <para>
 /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>
 /// on <paramref name="context"/>.
 /// </para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 /// <return>The visitor result.</return>
 public virtual Result VisitComparison([NotNull] RSqlQueryParser.ComparisonContext context)
 {
     return(VisitChildren(context));
 }
 public ComparisonUnknownSelectorException(RSqlQueryParser.ComparisonContext origin,
                                           Exception innerException = null) : base(origin,
                                                                                   $"Unknown selector : '{origin?.selector()?.GetText()}'", innerException)
 {
 }