PageRenderTime 89ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/referencesource/System.Data.Entity/System/Data/Mapping/ViewGeneration/Structures/Constant.cs

https://github.com/pruiz/mono
C# | 345 lines | 243 code | 51 blank | 51 comment | 11 complexity | 7f4e1965a7ae57f6ea002471a49c832a MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. //---------------------------------------------------------------------
  2. // <copyright file="Constant.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. //
  6. // @owner Microsoft
  7. // @backupOwner Microsoft
  8. //---------------------------------------------------------------------
  9. namespace System.Data.Mapping.ViewGeneration.Structures
  10. {
  11. using System.Collections.Generic;
  12. using System.Data.Common.CommandTrees;
  13. using System.Data.Common.CommandTrees.ExpressionBuilder;
  14. using System.Data.Common.Utils;
  15. using System.Data.Mapping.ViewGeneration.CqlGeneration;
  16. using System.Data.Metadata.Edm;
  17. using System.Diagnostics;
  18. using System.Text;
  19. /// <summary>
  20. /// This class denotes a constant that can be stored in multiconstants or projected in fields.
  21. /// </summary>
  22. internal abstract class Constant : InternalBase
  23. {
  24. #region Fields
  25. internal static readonly IEqualityComparer<Constant> EqualityComparer = new CellConstantComparer();
  26. internal static readonly Constant Null = NullConstant.Instance;
  27. internal static readonly Constant NotNull = new NegatedConstant( new Constant[] { NullConstant.Instance });
  28. internal static readonly Constant Undefined = UndefinedConstant.Instance;
  29. /// <summary>
  30. /// Represents scalar constants within a finite set that are not specified explicitly in the domain.
  31. /// Currently only used as a Sentinel node to prevent expression optimization
  32. /// </summary>
  33. internal static readonly Constant AllOtherConstants = AllOtherConstantsConstant.Instance;
  34. #endregion
  35. #region Methods
  36. internal abstract bool IsNull();
  37. internal abstract bool IsNotNull();
  38. internal abstract bool IsUndefined();
  39. /// <summary>
  40. /// Returns true if this constant contains not null.
  41. /// Implemented in <see cref="NegatedConstant"/> class, all other implementations return false.
  42. /// </summary>
  43. internal abstract bool HasNotNull();
  44. /// <summary>
  45. /// Generates eSQL for the constant expression.
  46. /// </summary>
  47. /// <param name="outputMember">The member to which this constant is directed</param>
  48. internal abstract StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias);
  49. /// <summary>
  50. /// Generates CQT for the constant expression.
  51. /// </summary>
  52. /// <param name="row">The input row.</param>
  53. /// <param name="outputMember">The member to which this constant is directed</param>
  54. internal abstract DbExpression AsCqt(DbExpression row, MemberPath outputMember);
  55. public override bool Equals(object obj)
  56. {
  57. Constant cellConst = obj as Constant;
  58. if (cellConst == null)
  59. {
  60. return false;
  61. }
  62. else
  63. {
  64. return IsEqualTo(cellConst);
  65. }
  66. }
  67. public override int GetHashCode()
  68. {
  69. return base.GetHashCode();
  70. }
  71. protected abstract bool IsEqualTo(Constant right);
  72. internal abstract string ToUserString();
  73. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  74. internal static void ConstantsToUserString(StringBuilder builder, Set<Constant> constants)
  75. {
  76. bool isFirst = true;
  77. foreach (Constant constant in constants)
  78. {
  79. if (isFirst == false)
  80. {
  81. builder.Append(System.Data.Entity.Strings.ViewGen_CommaBlank);
  82. }
  83. isFirst = false;
  84. string constrStr = constant.ToUserString();
  85. builder.Append(constrStr);
  86. }
  87. }
  88. #endregion
  89. #region Comparer class
  90. private class CellConstantComparer : IEqualityComparer<Constant>
  91. {
  92. public bool Equals(Constant left, Constant right)
  93. {
  94. // Quick check with references
  95. if (object.ReferenceEquals(left, right))
  96. {
  97. // Gets the Null and Undefined case as well
  98. return true;
  99. }
  100. // One of them is non-null at least. So if the other one is
  101. // null, we cannot be equal
  102. if (left == null || right == null)
  103. {
  104. return false;
  105. }
  106. // Both are non-null at this point
  107. return left.IsEqualTo(right);
  108. }
  109. public int GetHashCode(Constant key)
  110. {
  111. EntityUtil.CheckArgumentNull(key, "key");
  112. return key.GetHashCode();
  113. }
  114. }
  115. #endregion
  116. #region Special constant classes (NullConstant, UndefinedConstant, AllOtherConstants)
  117. private sealed class NullConstant : Constant
  118. {
  119. internal static readonly Constant Instance = new NullConstant();
  120. private NullConstant() { }
  121. #region Methods
  122. internal override bool IsNull()
  123. {
  124. return true;
  125. }
  126. internal override bool IsNotNull()
  127. {
  128. return false;
  129. }
  130. internal override bool IsUndefined()
  131. {
  132. return false;
  133. }
  134. internal override bool HasNotNull()
  135. {
  136. return false;
  137. }
  138. internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias)
  139. {
  140. Debug.Assert(outputMember.LeafEdmMember != null, "Constant can't correspond to an empty member path.");
  141. EdmType constType = Helper.GetModelTypeUsage(outputMember.LeafEdmMember).EdmType;
  142. builder.Append("CAST(NULL AS ");
  143. CqlWriter.AppendEscapedTypeName(builder, constType);
  144. builder.Append(')');
  145. return builder;
  146. }
  147. internal override DbExpression AsCqt(DbExpression row, MemberPath outputMember)
  148. {
  149. Debug.Assert(outputMember.LeafEdmMember != null, "Constant can't correspond to an empty path.");
  150. EdmType constType = Helper.GetModelTypeUsage(outputMember.LeafEdmMember).EdmType;
  151. return TypeUsage.Create(constType).Null();
  152. }
  153. public override int GetHashCode()
  154. {
  155. return 0;
  156. }
  157. protected override bool IsEqualTo(Constant right)
  158. {
  159. Debug.Assert(Object.ReferenceEquals(this, Instance), "this must be == Instance for NullConstant");
  160. return Object.ReferenceEquals(this, right);
  161. }
  162. internal override string ToUserString()
  163. {
  164. return System.Data.Entity.Strings.ViewGen_Null;
  165. }
  166. internal override void ToCompactString(StringBuilder builder)
  167. {
  168. builder.Append("NULL");
  169. }
  170. #endregion
  171. }
  172. private sealed class UndefinedConstant : Constant
  173. {
  174. internal static readonly Constant Instance = new UndefinedConstant();
  175. private UndefinedConstant() { }
  176. #region Methods
  177. internal override bool IsNull()
  178. {
  179. return false;
  180. }
  181. internal override bool IsNotNull()
  182. {
  183. return false;
  184. }
  185. internal override bool IsUndefined()
  186. {
  187. return true;
  188. }
  189. internal override bool HasNotNull()
  190. {
  191. return false;
  192. }
  193. /// <summary>
  194. /// Not supported in this class.
  195. /// </summary>
  196. internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias)
  197. {
  198. Debug.Fail("Should not be called.");
  199. return null; // To keep the compiler happy
  200. }
  201. /// <summary>
  202. /// Not supported in this class.
  203. /// </summary>
  204. internal override DbExpression AsCqt(DbExpression row, MemberPath outputMember)
  205. {
  206. Debug.Fail("Should not be called.");
  207. return null; // To keep the compiler happy
  208. }
  209. public override int GetHashCode()
  210. {
  211. return 0;
  212. }
  213. protected override bool IsEqualTo(Constant right)
  214. {
  215. Debug.Assert(Object.ReferenceEquals(this, Instance), "this must be == Instance for NullConstant");
  216. return Object.ReferenceEquals(this, right);
  217. }
  218. /// <summary>
  219. /// Not supported in this class.
  220. /// </summary>
  221. internal override string ToUserString()
  222. {
  223. Debug.Fail("We should not emit a message about Undefined constants to the user.");
  224. return null;
  225. }
  226. internal override void ToCompactString(StringBuilder builder)
  227. {
  228. builder.Append("?");
  229. }
  230. #endregion
  231. }
  232. private sealed class AllOtherConstantsConstant : Constant
  233. {
  234. internal static readonly Constant Instance = new AllOtherConstantsConstant();
  235. private AllOtherConstantsConstant() { }
  236. #region Methods
  237. internal override bool IsNull()
  238. {
  239. return false;
  240. }
  241. internal override bool IsNotNull()
  242. {
  243. return false;
  244. }
  245. internal override bool IsUndefined()
  246. {
  247. return false;
  248. }
  249. internal override bool HasNotNull()
  250. {
  251. return false;
  252. }
  253. /// <summary>
  254. /// Not supported in this class.
  255. /// </summary>
  256. internal override StringBuilder AsEsql(StringBuilder builder, MemberPath outputMember, string blockAlias)
  257. {
  258. Debug.Fail("Should not be called.");
  259. return null; // To keep the compiler happy
  260. }
  261. /// <summary>
  262. /// Not supported in this class.
  263. /// </summary>
  264. internal override DbExpression AsCqt(DbExpression row, MemberPath outputMember)
  265. {
  266. Debug.Fail("Should not be called.");
  267. return null; // To keep the compiler happy
  268. }
  269. public override int GetHashCode()
  270. {
  271. return 0;
  272. }
  273. protected override bool IsEqualTo(Constant right)
  274. {
  275. Debug.Assert(Object.ReferenceEquals(this, Instance), "this must be == Instance for NullConstant");
  276. return Object.ReferenceEquals(this, right);
  277. }
  278. /// <summary>
  279. /// Not supported in this class.
  280. /// </summary>
  281. internal override string ToUserString()
  282. {
  283. Debug.Fail("We should not emit a message about Undefined constants to the user.");
  284. return null;
  285. }
  286. internal override void ToCompactString(StringBuilder builder)
  287. {
  288. builder.Append("AllOtherConstants");
  289. }
  290. #endregion
  291. }
  292. #endregion
  293. }
  294. }