Beispiel #1
0
 public bool TryMatch(MemberExpression expression, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     MemberCallDelegate mcd;
     if (SupportedMembers.TryGetValue(expression.Member, out mcd))
     {
         mcd(expression, queryBuilder, visitExpression, context);
         return true;
     }
     return false;
 }
Beispiel #2
0
        private static bool CompareString(bool equal, MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            var count = methodCall.Arguments.Count;
            if (count != 2 && count != 3)
                return false;
            //TODO: handle Oracle incorrect handling of empty string
            var ce = methodCall.Arguments[0] as ConstantExpression;
            if (ce != null && ce.Value == null)
                return GuardForNull(equal, methodCall.Arguments[1], queryBuilder, visitExpression, context);
            ce = methodCall.Arguments[1] as ConstantExpression;
            if (ce != null && ce.Value == null)
                return GuardForNull(equal, methodCall.Arguments[0], queryBuilder, visitExpression, context);

            if (count == 2)
            {
                queryBuilder.Append("(");
                if (context.InSelect)
                    queryBuilder.Append(" CASE WHEN ");
                visitExpression(methodCall.Arguments[0]);
                if (equal)
                    queryBuilder.Append(" = ");
                else
                    queryBuilder.Append(" <> ");
                visitExpression(methodCall.Arguments[1]);
            }
            else
            {
                var cmpValue = methodCall.Arguments[2] as ConstantExpression;
                if (methodCall.Arguments[2].Type == typeof(bool) && cmpValue != null)
                {
                    queryBuilder.Append("(");
                    if (context.InSelect)
                        queryBuilder.Append(" CASE WHEN ");
                    EscapeForLike(equal, (bool)cmpValue.Value, methodCall, queryBuilder, visitExpression);
                }
                else if (methodCall.Arguments[2].Type == typeof(StringComparison))
                {
                    var cmpVal = (StringComparison)cmpValue.Value;
                    var ignoreCase = cmpVal != StringComparison.CurrentCulture
                        && cmpVal != StringComparison.InvariantCulture
                        && cmpVal != StringComparison.Ordinal;

                    queryBuilder.Append("(");
                    if (context.InSelect)
                        queryBuilder.Append(" CASE WHEN ");
                    EscapeForLike(equal, ignoreCase, methodCall, queryBuilder, visitExpression);
                }
                else return false;
            }

            if (context.InSelect)
                queryBuilder.Append(" THEN 'Y' ELSE 'N' END");
            queryBuilder.Append(")");
            return true;
        }
Beispiel #3
0
        public bool TryMatch(Expression expression, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            var mce = expression as MethodCallExpression;
            if (mce == null || !mce.Method.IsGenericMethod)
                return false;

            MethodCallDelegate mcd;
            if (SupportedMethods.TryGetValue(mce.Method.GetGenericMethodDefinition(), out mcd))
            {
                return mcd(mce, queryBuilder, visitExpression);
            }
            return false;
        }
Beispiel #4
0
        public bool TryMatch(Expression expression, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            var mce = expression as MethodCallExpression;
            if (mce == null)
                return false;

            MethodCallDelegate mcd;
            if (SupportedMethods.TryGetValue(mce.Method, out mcd))
            {
                mcd(mce, queryBuilder, visitExpression, context);
                return true;
            }
            return false;
        }
Beispiel #5
0
        public SubqueryParts(QueryParts parentQuery, bool canQueryInMemory, Expression selector, string contextName, QueryContext context)
            : base(parentQuery.Locator,
				contextName,
				parentQuery.ConverterFactory,
				parentQuery.Parameters,
				context,
				parentQuery.Simplifications,
				parentQuery.ExpressionMatchers,
				parentQuery.MemberMatchers,
				parentQuery.ProjectionMatchers)
        {
            this.CanQueryInMemory = canQueryInMemory;
            this.ParentQuery = parentQuery;
            this.Selector = selector;
        }
Beispiel #6
0
 public bool TryMatch(MemberExpression expression, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     Dictionary<Type, MemberCallDelegate> dict;
     var member = expression.Member;
     if (member.DeclaringType.IsGenericType && SupportedMembers.TryGetValue(member.Name, out dict))
     {
         MemberCallDelegate mcd;
         if (dict.TryGetValue(member.DeclaringType.GetGenericTypeDefinition(), out mcd))
         {
             mcd(expression, queryBuilder, visitExpression, context);
             return true;
         }
     }
     return false;
 }
Beispiel #7
0
        public bool TryMatch(Expression expression, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            var be = expression as BinaryExpression;
            if (be == null)
                return false;

            if (expression.NodeType == ExpressionType.Equal || expression.NodeType == ExpressionType.NotEqual)
            {
                var ceZero = be.Right as ConstantExpression ?? be.Left as ConstantExpression;
                var ceMethod = be.Left as MethodCallExpression ?? be.Right as MethodCallExpression;
                if (ceZero == null || ceMethod == null || !ceZero.Value.Equals(0) || !CompareMethods.Contains(ceMethod.Method))
                    return false;

                return CompareString(expression.NodeType == ExpressionType.Equal, ceMethod, queryBuilder, visitExpression, context);
            }
            return false;
        }
Beispiel #8
0
 //actually this is not correct because ToString uses regional settings, but let's ignore it for now
 private static void ValueToString(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     queryBuilder.Append("CAST(");
     visitExpression(methodCall.Object);
     queryBuilder.Append(" AS VARCHAR(4000))");
 }
Beispiel #9
0
 public SubqueryParts(QueryParts parentQuery, Expression selector, string contextName, QueryContext context)
     : this(parentQuery, false, selector, contextName, context)
 {
 }
Beispiel #10
0
 private static void GetLength(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     queryBuilder.Append("(SELECT COUNT(*) FROM TABLE(");
     visitExpression(memberCall.Expression);
     queryBuilder.Append("))");
 }
Beispiel #11
0
 private static bool GuardForNull(bool equal, Expression exp, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     if (context.InSelect)
     {
         queryBuilder.Append(" CASE WHEN ");
         visitExpression(exp);
         if (equal)
             queryBuilder.Append(" IS NULL THEN 'Y' ELSE 'N' END");
         else
             queryBuilder.Append(" IS NULL THEN 'N' ELSE 'Y' END");
     }
     else
     {
         visitExpression(exp);
         if (equal)
             queryBuilder.Append(" IS NULL");
         else
             queryBuilder.Append(" IS NOT NULL");
     }
     return true;
 }
 public static SubqueryParts ParseSubquery(QueryModel queryModel, QueryParts parentQuery, bool canQueryInMemory, string contextName, QueryContext context)
 {
     var visitor = new SubqueryGeneratorQueryModelVisitor(parentQuery, canQueryInMemory, queryModel.SelectClause.Selector, contextName, context);
     visitor.VisitQueryModel(queryModel);
     return visitor.QueryParts;
 }
 public static SubqueryParts ParseSubquery(QueryModel queryModel, QueryParts parentQuery, string contextName, QueryContext context)
 {
     return ParseSubquery(queryModel, parentQuery, false, contextName, context);
 }
 private SubqueryGeneratorQueryModelVisitor(QueryParts parentQuery, bool canQueryInMemory, Expression selector, string contextName, QueryContext context)
 {
     QueryParts = new SubqueryParts(parentQuery, canQueryInMemory, selector, contextName, context);
 }
Beispiel #15
0
 private static bool CheckForNull(Expression exp, StringBuilder queryBuilder, QueryContext context)
 {
     var ce = exp as ConstantExpression;
     if (ce == null || ce.Value != null)
         return false;
     if (context.InSelect)
         queryBuilder.Append("'N'");
     else
         queryBuilder.Append(" 0=1");
     return true;
 }
Beispiel #16
0
 private static void Compare(bool before, bool after, MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     bool ignoreCase = false;
     ConstantExpression ce;
     if (methodCall.Arguments.Count == 2)
     {
         ce = methodCall.Arguments[1] as ConstantExpression;
         switch ((StringComparison)ce.Value)
         {
             case StringComparison.CurrentCulture:
             case StringComparison.InvariantCulture:
             case StringComparison.Ordinal:
                 break;
             default:
                 ignoreCase = true;
                 break;
         }
     }
     if (context.InSelect)
         queryBuilder.Append(" CASE WHEN");
     else
         queryBuilder.Append("(");
     ce = methodCall.Object as ConstantExpression;
     if (ce != null)
     {
         if (ignoreCase)
             visitExpression(ConstantExpression.Constant((ce.Value as string).ToUpper(), ce.Type));
         else
             visitExpression(ce);
     }
     else
     {
         if (ignoreCase)
         {
             queryBuilder.Append(" UPPER(");
             visitExpression(methodCall.Object);
             queryBuilder.Append(")");
         }
         else
             visitExpression(methodCall.Object);
     }
     bool asLike = before || after;
     if (asLike)
         queryBuilder.Append(" LIKE ");
     else
         queryBuilder.Append(" = ");
     if (before)
         queryBuilder.Append("'%' || ");
     ce = methodCall.Arguments[0] as ConstantExpression;
     if (ce != null)
     {
         if (asLike)
         {
             var value = ce.Value as string;
             if (ignoreCase)
                 value = value.ToUpper();
             value = value.Replace(@"\", @"\\").Replace(@"_", @"\_").Replace(@"%", @"\%");
             visitExpression(ConstantExpression.Constant(value, ce.Type));
         }
         else if (ignoreCase)
             visitExpression(ConstantExpression.Constant((ce.Value as string).ToUpper(), ce.Type));
         else
             visitExpression(ce);
     }
     else
     {
         if (asLike)
         {
             if (ignoreCase)
                 queryBuilder.Append(" UPPER(");
             queryBuilder.Append("REPLACE(REPLACE(REPLACE(");
             visitExpression(methodCall.Object);
             queryBuilder.Append(@", '\','\\'), '_','\_'), '%','\%')");
             if (ignoreCase)
                 queryBuilder.Append(")");
         }
         else if (ignoreCase)
         {
             queryBuilder.Append(" UPPER(");
             visitExpression(methodCall.Object);
             queryBuilder.Append(")");
         }
         else
             visitExpression(methodCall.Object);
     }
     if (after)
         queryBuilder.Append(" || '%'");
     if (asLike)
         queryBuilder.Append(@" ESCAPE '\' ");
     if (context.InSelect)
         queryBuilder.Append(" THEN 'Y' ELSE 'N' END");
     else
         queryBuilder.Append(")");
 }
Beispiel #17
0
        /*
        private static void WithFormat(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, bool inSelect, bool inWhere)
        {
            queryBuilder.Append("format(");
            var index = queryBuilder.Length;
            visitExpression(methodCall.Arguments[0]);
            var count = methodCall.Arguments.Count - 1;
            var substr = queryBuilder.ToString(index, queryBuilder.Length - index);
            for (int i = 0; i < count; i++)
                substr = substr.Replace("{" + i + "}", "%" + (i + 1) + "$s");
            queryBuilder.Length = index;
            queryBuilder.Append(substr);
            for (int i = 0; i < count; i++)
            {
                queryBuilder.Append(",");
                visitExpression(methodCall.Arguments[i + 1]);
            }
            queryBuilder.Append(")");
        }

        private static void WithFormatArray(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, bool inSelect, bool inWhere)
        {
            queryBuilder.Append("format(");
            var index = queryBuilder.Length;
            visitExpression(methodCall.Arguments[0]);
            var args = (NewArrayExpression)methodCall.Arguments[1];
            var count = args.Expressions.Count;
            var substr = queryBuilder.ToString(index, queryBuilder.Length - index);
            for (int i = 0; i < count; i++)
                substr = substr.Replace("{" + i + "}", "%" + (i + 1) + "$s");
            queryBuilder.Length = index;
            queryBuilder.Append(substr);
            for (int i = 0; i < count; i++)
            {
                queryBuilder.Append(",");
                visitExpression(args.Expressions[i]);
            }
            queryBuilder.Append(")");
        }
        */
        private static void ReplaceString(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            queryBuilder.Append("REPLACE(");
            visitExpression(methodCall.Object);
            queryBuilder.Append(",");
            visitExpression(methodCall.Arguments[0]);
            queryBuilder.Append(",");
            visitExpression(methodCall.Arguments[1]);
            queryBuilder.Append(")");
        }
Beispiel #18
0
 private static void MatchStringToUpper(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     queryBuilder.Append("UPPER(");
     visitExpression(methodCall.Object);
     queryBuilder.Append(")");
 }
Beispiel #19
0
 private static void MatchStringStartsWith(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     if (!CheckForNull(methodCall.Arguments[0], queryBuilder, context))
         Compare(false, true, methodCall, queryBuilder, visitExpression, context);
 }
Beispiel #20
0
 private static void IsNullOrWhiteSpace(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     //TODO different from C#
     queryBuilder.Append("TRIM(");
     visitExpression(methodCall.Arguments[0]);
     queryBuilder.Append(") IS NULL ");
 }
Beispiel #21
0
 private static void IsNullOrEmpty(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     //TODO check if length is greater than 0
     visitExpression(methodCall.Arguments[0]);
     queryBuilder.Append(" IS NULL ");
 }
Beispiel #22
0
 private static void GetStringLength(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     queryBuilder.Append("length(");
     visitExpression(memberCall.Expression);
     queryBuilder.Append(")");
 }
Beispiel #23
0
 public string GetSqlExpression(Expression expression, string contextName, QueryContext context)
 {
     return(SqlGeneratorExpressionTreeVisitor.GetSqlExpression(expression, this, contextName, context));
 }