Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Data.Entity / System / Data / Metadata / Edm / Provider / ClrProviderManifest.cs
blob126408018f4495bd2f0393d3eb9b39188d5428c4
1 //---------------------------------------------------------------------
2 // <copyright file="ClrProviderManifest.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 // </copyright>
5 //
6 // @owner Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
10 using System.Collections.Generic;
11 using System.Data.Common;
12 using System.Diagnostics;
13 using System.Collections.ObjectModel;
14 using System.Data.Spatial;
15 using System.Threading;
16 using System.Linq;
18 namespace System.Data.Metadata.Edm
20 internal class ClrProviderManifest : DbProviderManifest
22 private const int s_PrimitiveTypeCount = 17;
23 private System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType> _primitiveTypes;
24 private static ClrProviderManifest _instance = new ClrProviderManifest();
26 /// <summary>
27 /// A private constructor to prevent other places from instantiating this class
28 /// </summary>
29 private ClrProviderManifest()
33 /// <summary>
34 /// Gets the EDM provider manifest singleton instance
35 /// </summary>
36 internal static ClrProviderManifest Instance
38 get
40 return _instance;
44 /// <summary>
45 /// Returns the namespace used by this provider manifest
46 /// </summary>
47 public override string NamespaceName
49 get { return EdmConstants.ClrPrimitiveTypeNamespace; }
52 /// <summary>
53 /// Returns the primitive type corresponding to the given CLR type
54 /// </summary>
55 /// <param name="clrType">The CLR type for which the PrimitiveType object is retrieved</param>
56 /// <param name="primitiveType">The retrieved primitive type</param>
57 /// <returns>True if a primitive type is returned</returns>
58 internal bool TryGetPrimitiveType(Type clrType, out PrimitiveType primitiveType)
60 primitiveType = null;
61 PrimitiveTypeKind resolvedTypeKind;
62 if (TryGetPrimitiveTypeKind(clrType, out resolvedTypeKind))
64 InitializePrimitiveTypes();
65 primitiveType = _primitiveTypes[(int)resolvedTypeKind];
66 return true;
69 return false;
72 /// <summary>
73 /// Returns the <see cref="PrimitiveTypeKind"/> corresponding to the given CLR type
74 /// </summary>
75 /// <param name="clrType">The CLR type for which the PrimitiveTypeKind value should be resolved</param>
76 /// <param name="primitiveType">The PrimitiveTypeKind value to which the CLR type resolves, if any.</param>
77 /// <returns>True if the CLR type represents a primitive (EDM) type; otherwise false.</returns>
78 internal bool TryGetPrimitiveTypeKind(Type clrType, out PrimitiveTypeKind resolvedPrimitiveTypeKind)
80 PrimitiveTypeKind? primitiveTypeKind = null;
81 if (!clrType.IsEnum) // Enums return the TypeCode of their underlying type
83 // As an optimization, short-circuit when the provided type has a known type code.
84 switch (Type.GetTypeCode(clrType))
86 // PrimitiveTypeKind.Binary = byte[] = TypeCode.Object
87 case TypeCode.Boolean:
88 primitiveTypeKind = PrimitiveTypeKind.Boolean;
89 break;
90 case TypeCode.Byte:
91 primitiveTypeKind = PrimitiveTypeKind.Byte;
92 break;
93 case TypeCode.DateTime:
94 primitiveTypeKind = PrimitiveTypeKind.DateTime;
95 break;
96 // PrimitiveTypeKind.DateTimeOffset = System.DateTimeOffset = TypeCode.Object
97 case TypeCode.Decimal:
98 primitiveTypeKind = PrimitiveTypeKind.Decimal;
99 break;
100 case TypeCode.Double:
101 primitiveTypeKind = PrimitiveTypeKind.Double;
102 break;
103 // PrimitiveTypeKind.Geography = System.Data.Spatial.DbGeometry (or subtype) = TypeCode.Object
104 // PrimitiveTypeKind.Geometry = System.Data.Spatial.DbGeometry (or subtype) = TypeCode.Object
105 // PrimitiveTypeKind.Guid = System.Guid = TypeCode.Object
106 case TypeCode.Int16:
107 primitiveTypeKind = PrimitiveTypeKind.Int16;
108 break;
109 case TypeCode.Int32:
110 primitiveTypeKind = PrimitiveTypeKind.Int32;
111 break;
112 case TypeCode.Int64:
113 primitiveTypeKind = PrimitiveTypeKind.Int64;
114 break;
115 case TypeCode.SByte:
116 primitiveTypeKind = PrimitiveTypeKind.SByte;
117 break;
118 case TypeCode.Single:
119 primitiveTypeKind = PrimitiveTypeKind.Single;
120 break;
121 case TypeCode.String:
122 primitiveTypeKind = PrimitiveTypeKind.String;
123 break;
124 // PrimitiveTypeKind.Time = System.TimeSpan = TypeCode.Object
125 case TypeCode.Object:
127 if (typeof(byte[]) == clrType)
129 primitiveTypeKind = PrimitiveTypeKind.Binary;
131 else if (typeof(DateTimeOffset) == clrType)
133 primitiveTypeKind = PrimitiveTypeKind.DateTimeOffset;
135 // DbGeography/Geometry are abstract so subtypes must be allowed
136 else if (typeof(System.Data.Spatial.DbGeography).IsAssignableFrom(clrType))
138 primitiveTypeKind = PrimitiveTypeKind.Geography;
140 else if (typeof(System.Data.Spatial.DbGeometry).IsAssignableFrom(clrType))
142 primitiveTypeKind = PrimitiveTypeKind.Geometry;
144 else if (typeof(Guid) == clrType)
146 primitiveTypeKind = PrimitiveTypeKind.Guid;
148 else if (typeof(TimeSpan) == clrType)
150 primitiveTypeKind = PrimitiveTypeKind.Time;
152 break;
157 if (primitiveTypeKind.HasValue)
159 resolvedPrimitiveTypeKind = primitiveTypeKind.Value;
160 return true;
162 else
164 resolvedPrimitiveTypeKind = default(PrimitiveTypeKind);
165 return false;
169 /// <summary>
170 /// Returns all the functions in this provider manifest
171 /// </summary>
172 /// <returns>A collection of functions</returns>
173 public override System.Collections.ObjectModel.ReadOnlyCollection<EdmFunction> GetStoreFunctions()
175 return Helper.EmptyEdmFunctionReadOnlyCollection;
178 /// <summary>
179 /// Returns all the FacetDescriptions for a particular type
180 /// </summary>
181 /// <param name="type">the type to return FacetDescriptions for.</param>
182 /// <returns>The FacetDescriptions for the type given.</returns>
183 public override System.Collections.ObjectModel.ReadOnlyCollection<FacetDescription> GetFacetDescriptions(EdmType type)
185 if (Helper.IsPrimitiveType(type) && ((PrimitiveType)type).DataSpace == DataSpace.OSpace)
187 // we don't have our own facets, just defer to the edm primitive type facets
188 PrimitiveType basePrimitive = (PrimitiveType)type.BaseType;
189 return basePrimitive.ProviderManifest.GetFacetDescriptions(basePrimitive);
192 return Helper.EmptyFacetDescriptionEnumerable;
195 /// <summary>
196 /// Initializes all the primitive types
197 /// </summary>
198 private void InitializePrimitiveTypes()
200 if (_primitiveTypes != null)
202 return;
205 PrimitiveType[] primitiveTypes = new PrimitiveType[s_PrimitiveTypeCount];
206 primitiveTypes[(int)PrimitiveTypeKind.Binary] = CreatePrimitiveType(typeof(Byte[]), PrimitiveTypeKind.Binary);
207 primitiveTypes[(int)PrimitiveTypeKind.Boolean] = CreatePrimitiveType(typeof(Boolean), PrimitiveTypeKind.Boolean);
208 primitiveTypes[(int)PrimitiveTypeKind.Byte] = CreatePrimitiveType(typeof(Byte), PrimitiveTypeKind.Byte);
209 primitiveTypes[(int)PrimitiveTypeKind.DateTime] = CreatePrimitiveType(typeof(DateTime), PrimitiveTypeKind.DateTime);
210 primitiveTypes[(int)PrimitiveTypeKind.Time] = CreatePrimitiveType(typeof(TimeSpan), PrimitiveTypeKind.Time);
211 primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset] = CreatePrimitiveType(typeof(DateTimeOffset), PrimitiveTypeKind.DateTimeOffset);
212 primitiveTypes[(int)PrimitiveTypeKind.Decimal] = CreatePrimitiveType(typeof(Decimal), PrimitiveTypeKind.Decimal);
213 primitiveTypes[(int)PrimitiveTypeKind.Double] = CreatePrimitiveType(typeof(Double), PrimitiveTypeKind.Double);
214 primitiveTypes[(int)PrimitiveTypeKind.Geography] = CreatePrimitiveType(typeof(DbGeography), PrimitiveTypeKind.Geography);
215 primitiveTypes[(int)PrimitiveTypeKind.Geometry] = CreatePrimitiveType(typeof(DbGeometry), PrimitiveTypeKind.Geometry);
216 primitiveTypes[(int)PrimitiveTypeKind.Guid] = CreatePrimitiveType(typeof(Guid), PrimitiveTypeKind.Guid);
217 primitiveTypes[(int)PrimitiveTypeKind.Int16] = CreatePrimitiveType(typeof(Int16), PrimitiveTypeKind.Int16);
218 primitiveTypes[(int)PrimitiveTypeKind.Int32] = CreatePrimitiveType(typeof(Int32), PrimitiveTypeKind.Int32);
219 primitiveTypes[(int)PrimitiveTypeKind.Int64] = CreatePrimitiveType(typeof(Int64), PrimitiveTypeKind.Int64);
220 primitiveTypes[(int)PrimitiveTypeKind.SByte] = CreatePrimitiveType(typeof(SByte), PrimitiveTypeKind.SByte);
221 primitiveTypes[(int)PrimitiveTypeKind.Single] = CreatePrimitiveType(typeof(Single), PrimitiveTypeKind.Single);
222 primitiveTypes[(int)PrimitiveTypeKind.String] = CreatePrimitiveType(typeof(String), PrimitiveTypeKind.String);
224 System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType> readOnlyTypes = new System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>(primitiveTypes);
226 // Set the result to _primitiveTypes at the end
227 Interlocked.CompareExchange<System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>>(ref _primitiveTypes, readOnlyTypes, null);
230 /// <summary>
231 /// Initialize the primitive type with the given
232 /// </summary>
233 /// <param name="clrType">The CLR type of this type</param>
234 /// <param name="primitiveTypeKind">The primitive type kind of the primitive type</param>
235 private PrimitiveType CreatePrimitiveType(Type clrType, PrimitiveTypeKind primitiveTypeKind)
237 // Figures out the base type
238 PrimitiveType baseType = MetadataItem.EdmProviderManifest.GetPrimitiveType(primitiveTypeKind);
239 PrimitiveType primitiveType = new PrimitiveType(clrType, baseType, this);
240 primitiveType.SetReadOnly();
241 return primitiveType;
245 public override System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType> GetStoreTypes()
247 InitializePrimitiveTypes();
248 return this._primitiveTypes;
251 public override TypeUsage GetEdmType(TypeUsage storeType)
253 throw new NotImplementedException();
256 public override TypeUsage GetStoreType(TypeUsage edmType)
258 throw new NotImplementedException();
261 /// <summary>
262 /// Providers should override this to return information specific to their provider.
263 ///
264 /// This method should never return null.
265 /// </summary>
266 /// <param name="informationType">The name of the information to be retrieved.</param>
267 /// <returns>An XmlReader at the begining of the information requested.</returns>
268 protected override System.Xml.XmlReader GetDbInformation(string informationType)
270 throw new NotImplementedException();