/1.0.x.x/ThirdParty/anito.NET/1.0.x.x/Anito.Data.SqlClient/Translator.cs

https://github.com/diadacs/TekSuite · C# · 274 lines · 227 code · 41 blank · 6 comment · 46 complexity · 5945af7cdda57bc0f5329d1c08a3ec93 MD5 · raw file

  1. /////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // Original Code by : Michael Dela Cuesta (michael.dcuesta@gmail.com) //
  3. // Source Code Available : http://anito.codeplex.com //
  4. // //
  5. // This source code is made available under the terms of the Microsoft Public License (MS-PL) //
  6. /////////////////////////////////////////////////////////////////////////////////////////////////////
  7. using System;
  8. using System.Linq;
  9. using System.Linq.Expressions;
  10. using System.Text;
  11. using System.Reflection;
  12. using Anito.Data;
  13. using Anito.Data.Schema;
  14. using Anito.Data.Common;
  15. namespace Anito.Data.TekSuite
  16. {
  17. public class Translator : AdoTranslatorBase
  18. {
  19. private const string SELECT = "SELECT";
  20. private const string FROM = "FROM";
  21. private const string SPACE = " ";
  22. private const string COMMA = ",";
  23. public Translator(IProvider provider)
  24. : base(provider)
  25. {
  26. }
  27. protected override Expression ProcessLambda(LambdaExpression expression)
  28. {
  29. LambdaExpression lambda = (LambdaExpression)StripQuotes(expression);
  30. ProcessExpression(lambda.Body);
  31. return expression;
  32. }
  33. protected override Expression ProcessMethodCall(MethodCallExpression expression)
  34. {
  35. if (expression.Method.DeclaringType == typeof(Queryable) && expression.Method.Name == "Where")
  36. {
  37. ProcessExpression(expression.Arguments[0]);
  38. CommandTextBuilder.Append(" AS T WHERE ");
  39. LambdaExpression lambda = (LambdaExpression)StripQuotes(expression.Arguments[1]);
  40. ProcessExpression(lambda.Body);
  41. return expression;
  42. }
  43. else if (expression.Method.DeclaringType == typeof(Queryable) && expression.Method.Name == "Single")
  44. {
  45. ProcessExpression(expression.Arguments[0]);
  46. CommandTextBuilder.Append(" AS T WHERE ");
  47. LambdaExpression lambda = (LambdaExpression)StripQuotes(expression.Arguments[1]);
  48. ProcessExpression(lambda.Body);
  49. return expression;
  50. }
  51. else if (expression.Method.DeclaringType == typeof(Queryable) && expression.Method.Name == "Select")
  52. {
  53. ProcessExpression(expression.Arguments[0]);
  54. CommandTextBuilder.Append(" AS T WHERE ");
  55. return expression;
  56. }
  57. throw new NotSupportedException(string.Format("The method '{0}' is not supported", expression.Method.Name));
  58. }
  59. protected override Expression ProcessBinary(BinaryExpression expression)
  60. {
  61. CommandTextBuilder.Append("(");
  62. ProcessExpression(expression.Left);
  63. switch (expression.NodeType)
  64. {
  65. case ExpressionType.And | ExpressionType.AndAlso:
  66. CommandTextBuilder.Append(" AND ");
  67. break;
  68. case ExpressionType.Or | ExpressionType.OrElse:
  69. CommandTextBuilder.Append(" OR ");
  70. break;
  71. case ExpressionType.Equal:
  72. CommandTextBuilder.Append(" = ");
  73. break;
  74. case ExpressionType.NotEqual:
  75. CommandTextBuilder.Append(" <> ");
  76. break;
  77. case ExpressionType.LessThan:
  78. CommandTextBuilder.Append(" < ");
  79. break;
  80. case ExpressionType.LessThanOrEqual:
  81. CommandTextBuilder.Append(" <= ");
  82. break;
  83. case ExpressionType.GreaterThan:
  84. CommandTextBuilder.Append(" > ");
  85. break;
  86. case ExpressionType.GreaterThanOrEqual:
  87. CommandTextBuilder.Append(" >= ");
  88. break;
  89. default:
  90. throw new NotSupportedException(string.Format("The binary operator '{0}' is not supported", expression.NodeType));
  91. }
  92. ProcessExpression(expression.Right);
  93. CommandTextBuilder.Append(")");
  94. return expression;
  95. }
  96. protected override Expression ProcessConstant(ConstantExpression expression)
  97. {
  98. IQueryable q = expression.Value as IQueryable;
  99. if (q != null)
  100. {
  101. StringBuilder columnBuilder = new StringBuilder();
  102. TypeTable schemaTable = Provider.GetSchema(q.ElementType);
  103. foreach (Anito.Data.Schema.TypeColumn column in schemaTable)
  104. {
  105. if (columnBuilder.Length > 0)
  106. columnBuilder.Append(COMMA + SPACE);
  107. columnBuilder.Append(column.Name);
  108. }
  109. CommandTextBuilder.Append(string.Format(
  110. "{0} {1} {2} {3}",
  111. SELECT,
  112. columnBuilder.ToString(),
  113. FROM,
  114. schemaTable.ViewSource
  115. ));
  116. }
  117. else if (expression.Value == null)
  118. {
  119. CommandTextBuilder.Append("NULL");
  120. }
  121. else
  122. {
  123. switch (Type.GetTypeCode(expression.Value.GetType()))
  124. {
  125. case TypeCode.Boolean:
  126. CommandTextBuilder.Append(((bool)expression.Value) ? 1 : 0);
  127. break;
  128. case TypeCode.String:
  129. CommandTextBuilder.Append("'");
  130. CommandTextBuilder.Append(expression.Value);
  131. CommandTextBuilder.Append("'");
  132. break;
  133. case TypeCode.Object:
  134. throw new NotSupportedException(string.Format("The constant for '{0}' is not supported", expression.Value));
  135. default:
  136. CommandTextBuilder.Append(expression.Value);
  137. break;
  138. }
  139. }
  140. return expression;
  141. }
  142. protected override Expression ProcessMemberAccess(MemberExpression expression)
  143. {
  144. if (expression.Expression != null && expression.Expression.NodeType == ExpressionType.Parameter)
  145. {
  146. Anito.Data.Schema.TypeTable schemaTable = Provider.GetSchema(expression.Member.DeclaringType);
  147. CommandTextBuilder.Append(schemaTable.GetDbColumn(expression.Member.Name));
  148. return expression;
  149. }
  150. else if (expression.Expression != null && expression.Expression.NodeType == ExpressionType.MemberAccess)
  151. {
  152. PropertyInfo propertyInfo = expression.Member as PropertyInfo;
  153. MemberExpression memberExpression = expression.Expression as MemberExpression;
  154. FieldInfo fieldInfo = memberExpression.Member as FieldInfo;
  155. ConstantExpression cExpression = memberExpression.Expression as ConstantExpression;
  156. object objectValue = fieldInfo.GetValue(cExpression.Value);
  157. object value = propertyInfo.GetValue(objectValue, null);
  158. switch (Type.GetTypeCode(value.GetType()))
  159. {
  160. case TypeCode.String | TypeCode.DateTime:
  161. CommandTextBuilder.Append(string.Format("'{0}'", value));
  162. break;
  163. default:
  164. CommandTextBuilder.Append(value);
  165. break;
  166. }
  167. return expression;
  168. }
  169. else if (expression.Expression != null && expression.Expression.NodeType == ExpressionType.Constant)
  170. {
  171. FieldInfo fieldInfo = expression.Member as FieldInfo;
  172. ConstantExpression cExpression = expression.Expression as ConstantExpression;
  173. object value = fieldInfo.GetValue(cExpression.Value);
  174. switch (Type.GetTypeCode(value.GetType()))
  175. {
  176. case TypeCode.String | TypeCode.DateTime:
  177. CommandTextBuilder.Append(string.Format("'{0}'", value));
  178. break;
  179. default:
  180. CommandTextBuilder.Append(value);
  181. break;
  182. }
  183. return expression;
  184. }
  185. else if (expression.Expression != null && expression.Expression.NodeType == ExpressionType.Call)
  186. {
  187. PropertyInfo propertyInfo = expression.Member as PropertyInfo;
  188. MethodCallExpression callExpression = expression.Expression as MethodCallExpression;
  189. MethodInfo methodInfo = callExpression.Method;
  190. object[] methodParams = new object[callExpression.Arguments.Count];
  191. for (int i = 0; i < callExpression.Arguments.Count; i++)
  192. {
  193. ConstantExpression consExpression = callExpression.Arguments[i] as ConstantExpression;
  194. methodParams[i] = consExpression.Value;
  195. }
  196. MemberExpression memberExpression = callExpression.Object as MemberExpression;
  197. FieldInfo fieldInfo = memberExpression.Member as FieldInfo;
  198. ConstantExpression cExpression = memberExpression.Expression as ConstantExpression;
  199. object objectContainer = fieldInfo.GetValue(cExpression.Value);
  200. object objectValue = methodInfo.Invoke(objectContainer, methodParams);
  201. object value = propertyInfo.GetValue(objectValue, null);
  202. switch (Type.GetTypeCode(value.GetType()))
  203. {
  204. case TypeCode.String | TypeCode.DateTime:
  205. CommandTextBuilder.Append(string.Format("'{0}'", value));
  206. break;
  207. default:
  208. CommandTextBuilder.Append(value);
  209. break;
  210. }
  211. return expression;
  212. }
  213. throw new NotSupportedException(string.Format("The member '{0}' is not supported", expression.Member.Name));
  214. }
  215. protected override Expression ProcessUnary(UnaryExpression expression)
  216. {
  217. switch (expression.NodeType)
  218. {
  219. case ExpressionType.Not:
  220. CommandTextBuilder.Append(" NOT ");
  221. ProcessExpression(expression.Operand);
  222. break;
  223. case ExpressionType.Quote:
  224. LambdaExpression lambda = (LambdaExpression) StripQuotes(expression);
  225. ProcessExpression(lambda.Body);
  226. break;
  227. default:
  228. throw new NotSupportedException(string.Format("The unary operator '{0}' is not supported", expression.NodeType));
  229. }
  230. return expression;
  231. }
  232. }
  233. }