123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433 |
- using Ant.Core;
- using Ant.DbExpressions;
- using Ant.ORM;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- namespace Ant.Oracle
- {
- partial class SqlGenerator : DbExpressionVisitor<DbExpression>
- {
- static Dictionary<string, Action<DbMethodCallExpression, SqlGenerator>> InitMethodHandlers()
- {
- var methodHandlers = new Dictionary<string, Action<DbMethodCallExpression, SqlGenerator>>();
- methodHandlers.Add("Trim", Method_Trim);
- methodHandlers.Add("TrimStart", Method_TrimStart);
- methodHandlers.Add("TrimEnd", Method_TrimEnd);
- methodHandlers.Add("StartsWith", Method_StartsWith);
- methodHandlers.Add("EndsWith", Method_EndsWith);
- methodHandlers.Add("ToUpper", Method_String_ToUpper);
- methodHandlers.Add("ToLower", Method_String_ToLower);
- methodHandlers.Add("Substring", Method_String_Substring);
- methodHandlers.Add("IsNullOrEmpty", Method_String_IsNullOrEmpty);
- methodHandlers.Add("Contains", Method_Contains);
- methodHandlers.Add("Count", Method_Count);
- methodHandlers.Add("LongCount", Method_LongCount);
- methodHandlers.Add("Sum", Method_Sum);
- methodHandlers.Add("Max", Method_Max);
- methodHandlers.Add("Min", Method_Min);
- methodHandlers.Add("Average", Method_Average);
- methodHandlers.Add("AddYears", Method_DateTime_AddYears);
- methodHandlers.Add("AddMonths", Method_DateTime_AddMonths);
- methodHandlers.Add("AddDays", Method_DateTime_AddDays);
- methodHandlers.Add("AddHours", Method_DateTime_AddHours);
- methodHandlers.Add("AddMinutes", Method_DateTime_AddMinutes);
- methodHandlers.Add("AddSeconds", Method_DateTime_AddSeconds);
- methodHandlers.Add("AddMilliseconds", Method_DateTime_AddMilliseconds);
- methodHandlers.Add("Parse", Method_Parse);
- methodHandlers.Add("NewGuid", Method_Guid_NewGuid);
- methodHandlers.Add("DiffYears", Method_DbFunctions_DiffYears);
- methodHandlers.Add("DiffMonths", Method_DbFunctions_DiffMonths);
- methodHandlers.Add("DiffDays", Method_DbFunctions_DiffDays);
- methodHandlers.Add("DiffHours", Method_DbFunctions_DiffHours);
- methodHandlers.Add("DiffMinutes", Method_DbFunctions_DiffMinutes);
- methodHandlers.Add("DiffSeconds", Method_DbFunctions_DiffSeconds);
- methodHandlers.Add("DiffMilliseconds", Method_DbFunctions_DiffMilliseconds);
- methodHandlers.Add("DiffMicroseconds", Method_DbFunctions_DiffMicroseconds);
- var ret = Utils.Clone(methodHandlers);
- return ret;
- }
- static void Method_Trim(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_String_Trim);
- generator._sqlBuilder.Append("TRIM(");
- exp.Object.Accept(generator);
- generator._sqlBuilder.Append(")");
- }
- static void Method_TrimStart(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_String_TrimStart);
- EnsureTrimCharArgumentIsSpaces(exp.Arguments[0]);
- generator._sqlBuilder.Append("LTRIM(");
- exp.Object.Accept(generator);
- generator._sqlBuilder.Append(")");
- }
- static void Method_TrimEnd(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_String_TrimEnd);
- EnsureTrimCharArgumentIsSpaces(exp.Arguments[0]);
- generator._sqlBuilder.Append("RTRIM(");
- exp.Object.Accept(generator);
- generator._sqlBuilder.Append(")");
- }
- static void Method_StartsWith(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_String_StartsWith);
- exp.Object.Accept(generator);
- generator._sqlBuilder.Append(" LIKE ");
- exp.Arguments.First().Accept(generator);
- generator._sqlBuilder.Append(" || '%'");
- }
- static void Method_EndsWith(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_String_EndsWith);
- exp.Object.Accept(generator);
- generator._sqlBuilder.Append(" LIKE '%' || ");
- exp.Arguments.First().Accept(generator);
- }
- static void Method_String_Contains(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_String_Contains);
- exp.Object.Accept(generator);
- generator._sqlBuilder.Append(" LIKE '%' || ");
- exp.Arguments.First().Accept(generator);
- generator._sqlBuilder.Append(" || '%'");
- }
- static void Method_String_ToUpper(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_String_ToUpper);
- generator._sqlBuilder.Append("UPPER(");
- exp.Object.Accept(generator);
- generator._sqlBuilder.Append(")");
- }
- static void Method_String_ToLower(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_String_ToLower);
- generator._sqlBuilder.Append("LOWER(");
- exp.Object.Accept(generator);
- generator._sqlBuilder.Append(")");
- }
- static void Method_String_Substring(DbMethodCallExpression exp, SqlGenerator generator)
- {
- generator._sqlBuilder.Append("SUBSTR(");
- exp.Object.Accept(generator);
- generator._sqlBuilder.Append(",");
- exp.Arguments[0].Accept(generator);
- generator._sqlBuilder.Append(" + 1");
- generator._sqlBuilder.Append(",");
- if (exp.Method == UtilConstants.MethodInfo_String_Substring_Int32)
- {
- var string_LengthExp = DbExpression.MemberAccess(UtilConstants.PropertyInfo_String_Length, exp.Object);
- string_LengthExp.Accept(generator);
- }
- else if (exp.Method == UtilConstants.MethodInfo_String_Substring_Int32_Int32)
- {
- exp.Arguments[1].Accept(generator);
- }
- else
- throw UtilExceptions.NotSupportedMethod(exp.Method);
- generator._sqlBuilder.Append(")");
- }
- static void Method_String_IsNullOrEmpty(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_String_IsNullOrEmpty);
- DbExpression e = exp.Arguments.First();
- DbEqualExpression equalNullExpression = DbExpression.Equal(e, DbExpression.Constant(null, UtilConstants.TypeOfString));
- DbEqualExpression equalEmptyExpression = DbExpression.Equal(e, DbExpression.Constant(string.Empty));
- DbOrElseExpression orElseExpression = DbExpression.OrElse(equalNullExpression, equalEmptyExpression);
- DbCaseWhenExpression.WhenThenExpressionPair whenThenPair = new DbCaseWhenExpression.WhenThenExpressionPair(orElseExpression, DbConstantExpression.One);
- List<DbCaseWhenExpression.WhenThenExpressionPair> whenThenExps = new List<DbCaseWhenExpression.WhenThenExpressionPair>(1);
- whenThenExps.Add(whenThenPair);
- DbCaseWhenExpression caseWhenExpression = DbExpression.CaseWhen(whenThenExps, DbConstantExpression.Zero, UtilConstants.TypeOfBoolean);
- var eqExp = DbExpression.Equal(caseWhenExpression, DbConstantExpression.One);
- eqExp.Accept(generator);
- }
- static void Method_Contains(DbMethodCallExpression exp, SqlGenerator generator)
- {
- MethodInfo method = exp.Method;
- if (method.DeclaringType == UtilConstants.TypeOfString)
- {
- Method_String_Contains(exp, generator);
- return;
- }
- List<DbExpression> exps = new List<DbExpression>();
- IEnumerable values = null;
- DbExpression arg = null;
- var declaringType = method.DeclaringType;
- if (typeof(IList).IsAssignableFrom(declaringType) || (declaringType.IsGenericType && typeof(ICollection<>).MakeGenericType(declaringType.GetGenericArguments()).IsAssignableFrom(declaringType)))
- {
- DbMemberExpression memberExp = exp.Object as DbMemberExpression;
- if (memberExp == null || !memberExp.CanEvaluate())
- throw new NotSupportedException(exp.ToString());
- values = DbExpressionExtensions.GetExpressionValue(memberExp) as IEnumerable; //Enumerable
- arg = exp.Arguments.First();
- goto constructInState;
- }
- if (method.IsStatic && declaringType == typeof(Enumerable) && exp.Arguments.Count == 2)
- {
- DbMemberExpression memberExp = exp.Arguments.First() as DbMemberExpression;
- if (memberExp == null || !memberExp.CanEvaluate())
- throw new NotSupportedException(exp.ToString());
- values = DbExpressionExtensions.GetExpressionValue(memberExp) as IEnumerable;
- arg = exp.Arguments.Skip(1).First();
- goto constructInState;
- }
- throw UtilExceptions.NotSupportedMethod(exp.Method);
- constructInState:
- foreach (object value in values)
- {
- if (value == null)
- exps.Add(DbExpression.Constant(null, arg.Type));
- else
- exps.Add(DbExpression.Parameter(value));
- }
- In(generator, exps, arg);
- }
- static void In(SqlGenerator generator, List<DbExpression> elementExps, DbExpression arg)
- {
- if (elementExps.Count == 0)
- {
- generator._sqlBuilder.Append("1=0");
- return;
- }
- arg.Accept(generator);
- generator._sqlBuilder.Append(" IN (");
- var first = true;
- foreach (DbExpression ele in elementExps)
- {
- if (first)
- first = false;
- else
- generator._sqlBuilder.Append(",");
- ele.Accept(generator);
- }
- generator._sqlBuilder.Append(")");
- return;
- }
- static void Method_Count(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethodDeclaringType(exp, typeof(AggregateFunctions));
- Aggregate_Count(generator);
- }
- static void Method_LongCount(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethodDeclaringType(exp, typeof(AggregateFunctions));
- Aggregate_LongCount(generator);
- }
- static void Method_Sum(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethodDeclaringType(exp, typeof(AggregateFunctions));
- Aggregate_Sum(generator, exp.Arguments.First(), exp.Method.ReturnType);
- }
- static void Method_Max(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethodDeclaringType(exp, typeof(AggregateFunctions));
- Aggregate_Max(generator, exp.Arguments.First(), exp.Method.ReturnType);
- }
- static void Method_Min(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethodDeclaringType(exp, typeof(AggregateFunctions));
- Aggregate_Min(generator, exp.Arguments.First(), exp.Method.ReturnType);
- }
- static void Method_Average(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethodDeclaringType(exp, typeof(AggregateFunctions));
- Aggregate_Average(generator, exp.Arguments.First(), exp.Method.ReturnType);
- }
- static void Method_DateTime_AddYears(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethodDeclaringType(exp, UtilConstants.TypeOfDateTime);
- /* add_months(systimestamp,12 * 2) */
- generator._sqlBuilder.Append("ADD_MONTHS(");
- exp.Object.Accept(generator);
- generator._sqlBuilder.Append(",12 * ");
- exp.Arguments[0].Accept(generator);
- generator._sqlBuilder.Append(")");
- }
- static void Method_DateTime_AddMonths(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethodDeclaringType(exp, UtilConstants.TypeOfDateTime);
- /* add_months(systimestamp,2) */
- generator._sqlBuilder.Append("ADD_MONTHS(");
- exp.Object.Accept(generator);
- generator._sqlBuilder.Append(",");
- exp.Arguments[0].Accept(generator);
- generator._sqlBuilder.Append(")");
- }
- static void Method_DateTime_AddDays(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethodDeclaringType(exp, UtilConstants.TypeOfDateTime);
- /* (systimestamp + 3) */
- generator._sqlBuilder.Append("(");
- exp.Object.Accept(generator);
- generator._sqlBuilder.Append(" + ");
- exp.Arguments[0].Accept(generator);
- generator._sqlBuilder.Append(")");
- }
- static void Method_DateTime_AddHours(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethodDeclaringType(exp, UtilConstants.TypeOfDateTime);
- DbFunction_DATEADD(generator, "HOUR", exp);
- }
- static void Method_DateTime_AddMinutes(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethodDeclaringType(exp, UtilConstants.TypeOfDateTime);
- DbFunction_DATEADD(generator, "MINUTE", exp);
- }
- static void Method_DateTime_AddSeconds(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethodDeclaringType(exp, UtilConstants.TypeOfDateTime);
- DbFunction_DATEADD(generator, "SECOND", exp);
- }
- static void Method_DateTime_AddMilliseconds(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethodDeclaringType(exp, UtilConstants.TypeOfDateTime);
- throw UtilExceptions.NotSupportedMethod(exp.Method);
- }
- static void Method_Parse(DbMethodCallExpression exp, SqlGenerator generator)
- {
- if (exp.Arguments.Count != 1)
- throw UtilExceptions.NotSupportedMethod(exp.Method);
- DbExpression arg = exp.Arguments[0];
- if (arg.Type != UtilConstants.TypeOfString)
- throw UtilExceptions.NotSupportedMethod(exp.Method);
- Type retType = exp.Method.ReturnType;
- EnsureMethodDeclaringType(exp, retType);
- DbExpression e = DbExpression.Convert(arg, retType);
- if (retType == UtilConstants.TypeOfBoolean)
- {
- e.Accept(generator);
- generator._sqlBuilder.Append(" = ");
- DbConstantExpression.True.Accept(generator);
- }
- else
- e.Accept(generator);
- }
- static void Method_Guid_NewGuid(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_Guid_NewGuid);
- throw UtilExceptions.NotSupportedMethod(exp.Method);
- //返回的是一个长度为 16 的 byte[]
- generator._sqlBuilder.Append("SYS_GUID()");
- }
- static void Method_DbFunctions_DiffYears(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_DbFunctions_DiffYears);
- throw UtilExceptions.NotSupportedMethod(exp.Method);
- }
- static void Method_DbFunctions_DiffMonths(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_DbFunctions_DiffMonths);
- throw UtilExceptions.NotSupportedMethod(exp.Method);
- }
- static void Method_DbFunctions_DiffDays(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_DbFunctions_DiffDays);
- throw new NotSupportedException(AppendNotSupportedDbFunctionsMsg(exp.Method, "TotalDays"));
- }
- static void Method_DbFunctions_DiffHours(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_DbFunctions_DiffHours);
- throw new NotSupportedException(AppendNotSupportedDbFunctionsMsg(exp.Method, "TotalHours"));
- }
- static void Method_DbFunctions_DiffMinutes(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_DbFunctions_DiffMinutes);
- throw new NotSupportedException(AppendNotSupportedDbFunctionsMsg(exp.Method, "TotalMinutes"));
- }
- static void Method_DbFunctions_DiffSeconds(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_DbFunctions_DiffSeconds);
- throw new NotSupportedException(AppendNotSupportedDbFunctionsMsg(exp.Method, "TotalSeconds"));
- }
- static void Method_DbFunctions_DiffMilliseconds(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_DbFunctions_DiffMilliseconds);
- throw new NotSupportedException(AppendNotSupportedDbFunctionsMsg(exp.Method, "TotalMilliseconds"));
- }
- static void Method_DbFunctions_DiffMicroseconds(DbMethodCallExpression exp, SqlGenerator generator)
- {
- EnsureMethod(exp, UtilConstants.MethodInfo_DbFunctions_DiffMicroseconds);
- throw UtilExceptions.NotSupportedMethod(exp.Method);
- }
- static string AppendNotSupportedDbFunctionsMsg(MethodInfo method, string insteadProperty)
- {
- return string.Format("'{0}' is not supported.Instead of using '{1}.{2}'.", Utils.ToMethodString(method), Utils.ToMethodString(UtilConstants.MethodInfo_DateTime_Subtract_DateTime), insteadProperty);
- }
- }
- }
|