Example #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;
 }
        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;
        }
Example #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;
        }
Example #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;
        }
Example #5
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;
 }
Example #6
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;
		}
Example #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;
		}
Example #8
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;
		}
Example #9
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(")");
        }
Example #10
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))");
 }
Example #11
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);
 }
Example #12
0
 private static void MatchStringToUpper(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     queryBuilder.Append("UPPER(");
     visitExpression(methodCall.Object);
     queryBuilder.Append(")");
 }
Example #13
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 ");
 }
Example #14
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 ");
 }
Example #15
0
        /*
        private static void GetDate(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            visitExpression(memberCall.Expression);
            queryBuilder.AppendFormat("::date");
        }

        private static void GetTimeOfDay(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            visitExpression(memberCall.Expression);
            queryBuilder.AppendFormat("::time");
        }

        private static void Format(
            MemberExpression memberCall,
            StringBuilder queryBuilder,
            Action<Expression> visitExpression,
            string part)
        {
            queryBuilder.AppendFormat("extract({0} from ", part);
            visitExpression(memberCall.Expression);
            queryBuilder.AppendFormat(")::int");
        }

        private static void GetDayOfWeek(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            Format(memberCall, queryBuilder, visitExpression, "dow");
        }

        private static void GetDayOfYear(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            Format(memberCall, queryBuilder, visitExpression, "doy");
        }

        private static void GetYear(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            Format(memberCall, queryBuilder, visitExpression, "y");
        }

        private static void GetMonth(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            Format(memberCall, queryBuilder, visitExpression, "mon");
        }

        private static void GetDay(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            Format(memberCall, queryBuilder, visitExpression, "d");
        }

        private static void GetHour(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            Format(memberCall, queryBuilder, visitExpression, "h");
        }

        private static void GetMinute(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            Format(memberCall, queryBuilder, visitExpression, "m");
        }

        private static void GetSecond(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            Format(memberCall, queryBuilder, visitExpression, "s");
        }

        private static void GetMillisecond(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            Format(memberCall, queryBuilder, visitExpression, "ms");
            queryBuilder.Append("%1000");
        }

        private static void GetTimeSpanDays(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            GetTimeSpanTotalDays(memberCall, queryBuilder, visitExpression);
            queryBuilder.AppendFormat("::int");
        }

        private static void GetTimeSpanTotalDays(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            queryBuilder.Append("extract(day from ");
            visitExpression(memberCall.Expression);
            queryBuilder.AppendFormat(")");
        }

        private static void GetTimeSpanTotalHours(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            queryBuilder.Append("extract(day from ");
            visitExpression(memberCall.Expression);
            queryBuilder.AppendFormat(")::int * 24 + extract(hour from ");
            visitExpression(memberCall.Expression);
            queryBuilder.AppendFormat(")");
        }
        */
        private static void CurrentTimestamp(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
        {
            queryBuilder.Append("CURRENT_TIMESTAMP");
        }
Example #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(")");
 }
Example #17
0
		private static void SubstringFromTo(MethodCallExpression methodCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
		{
			queryBuilder.Append("SUBSTR(");
			visitExpression(methodCall.Object);
			queryBuilder.Append(",");
			var ce = methodCall.Arguments[0] as ConstantExpression;
			if (ce != null && ce.Type == typeof(int))
				queryBuilder.Append(1 + (int)ce.Value);
			else
			{
				queryBuilder.Append("1 + ");
				visitExpression(methodCall.Arguments[0]);
			}
			queryBuilder.Append(",");
			visitExpression(methodCall.Arguments[1]);
			queryBuilder.Append(")");
		}
Example #18
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;
 }
Example #19
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("))");
 }
Example #20
0
 private static void CurrentDate(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     queryBuilder.Append("CURRENT_DATE");
 }
		private SubqueryGeneratorQueryModelVisitor(QueryParts parentQuery, bool canQueryInMemory, Expression selector, string contextName, QueryContext context)
		{
			QueryParts = new SubqueryParts(parentQuery, canQueryInMemory, selector, contextName, context);
		}
		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);
		}
Example #24
0
		public SubqueryParts(QueryParts parentQuery, Expression selector, string contextName, QueryContext context)
			: this(parentQuery, false, selector, contextName, context) { }
Example #25
0
 private static void GetStringLength(MemberExpression memberCall, StringBuilder queryBuilder, Action<Expression> visitExpression, QueryContext context)
 {
     queryBuilder.Append("length(");
     visitExpression(memberCall.Expression);
     queryBuilder.Append(")");
 }