924 lines
55 KiB
C#
924 lines
55 KiB
C#
//---------------------------------------------------------------------
|
|
// <copyright file="EdmProviderManifest.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//
|
|
// @owner [....]
|
|
// @backupOwner [....]
|
|
//---------------------------------------------------------------------
|
|
|
|
using System.Collections.Generic;
|
|
using System.Data.Common;
|
|
using System.Data.Spatial;
|
|
using System.Diagnostics;
|
|
using System.Threading;
|
|
|
|
namespace System.Data.Metadata.Edm
|
|
{
|
|
internal class EdmProviderManifest : DbProviderManifest
|
|
{
|
|
/// <summary>
|
|
/// The ConcurrencyMode Facet Name
|
|
/// </summary>
|
|
internal const string ConcurrencyModeFacetName = "ConcurrencyMode";
|
|
/// <summary>
|
|
/// The StoreGeneratedPattern Facet Name
|
|
/// </summary>
|
|
internal const string StoreGeneratedPatternFacetName = "StoreGeneratedPattern";
|
|
private Dictionary<PrimitiveType, System.Collections.ObjectModel.ReadOnlyCollection<FacetDescription>> _facetDescriptions;
|
|
private System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType> _primitiveTypes;
|
|
private System.Collections.ObjectModel.ReadOnlyCollection<EdmFunction> _functions;
|
|
private static EdmProviderManifest _instance = new EdmProviderManifest();
|
|
private System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>[] _promotionTypes;
|
|
static TypeUsage[] _canonicalModelTypes;
|
|
|
|
internal const byte MaximumDecimalPrecision = Byte.MaxValue;
|
|
internal const byte MaximumDateTimePrecision = Byte.MaxValue;
|
|
|
|
/// <summary>
|
|
/// A private constructor to prevent other places from instantiating this class
|
|
/// </summary>
|
|
private EdmProviderManifest()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the EDM provider manifest singleton instance
|
|
/// </summary>
|
|
internal static EdmProviderManifest Instance
|
|
{
|
|
get
|
|
{
|
|
return _instance;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the namespace used by this provider manifest
|
|
/// </summary>
|
|
public override string NamespaceName
|
|
{
|
|
get { return EdmConstants.EdmNamespace; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Store version hint
|
|
/// </summary>
|
|
internal string Token
|
|
{
|
|
// we shouldn't throw exception on properties
|
|
get { return String.Empty; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the list of all the canonical functions
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override System.Collections.ObjectModel.ReadOnlyCollection<EdmFunction> GetStoreFunctions()
|
|
{
|
|
InitializeCanonicalFunctions();
|
|
return _functions;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns all the FacetDescriptions for a particular type
|
|
/// </summary>
|
|
/// <param name="type">the type to return FacetDescriptions for.</param>
|
|
/// <returns>The FacetDescriptions for the type given.</returns>
|
|
public override System.Collections.ObjectModel.ReadOnlyCollection<FacetDescription> GetFacetDescriptions(EdmType type)
|
|
{
|
|
Debug.Assert(type is PrimitiveType, "EdmProviderManifest.GetFacetDescriptions(): Argument is not a PrimitiveType");
|
|
|
|
InitializeFacetDescriptions();
|
|
|
|
// Some types may not have facets, so just try to get them, if there aren't any, just return an empty list
|
|
System.Collections.ObjectModel.ReadOnlyCollection<FacetDescription> collection = null;
|
|
if (_facetDescriptions.TryGetValue(type as PrimitiveType, out collection))
|
|
{
|
|
return collection;
|
|
}
|
|
return Helper.EmptyFacetDescriptionEnumerable;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a primitive type from this manifest having the specified primitive type kind
|
|
/// </summary>
|
|
/// <param name="primitiveTypeKind">The value specifying the kind of primitive type to return</param>
|
|
/// <returns>A primitive type having the given primitive type kind</returns>
|
|
public PrimitiveType GetPrimitiveType(PrimitiveTypeKind primitiveTypeKind)
|
|
{
|
|
InitializePrimitiveTypes();
|
|
return _primitiveTypes[(int)primitiveTypeKind];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Boostrapping all the primitive types for the EDM Provider Manifest
|
|
/// </summary>
|
|
private void InitializePrimitiveTypes()
|
|
{
|
|
if (_primitiveTypes != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
PrimitiveType[] primitiveTypes = new PrimitiveType[EdmConstants.NumPrimitiveTypes];
|
|
primitiveTypes[(int)PrimitiveTypeKind.Binary] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.Boolean] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.Byte] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.DateTime] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.Decimal] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.Double] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.Single] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.Guid] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.Int16] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.Int32] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.Int64] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.SByte] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.String] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.Time] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.Geometry] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeometryPoint] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeometryLineString] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeometryPolygon] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeometryMultiPoint] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeometryMultiLineString] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeometryMultiPolygon] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeometryCollection] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.Geography] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeographyPoint] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeographyLineString] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeographyPolygon] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeographyMultiPoint] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeographyMultiLineString] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeographyMultiPolygon] = new PrimitiveType();
|
|
primitiveTypes[(int)PrimitiveTypeKind.GeographyCollection] = new PrimitiveType();
|
|
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Binary], PrimitiveTypeKind.Binary, EdmConstants.Binary, typeof(Byte[]));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Boolean], PrimitiveTypeKind.Boolean, EdmConstants.Boolean, typeof(Boolean));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Byte], PrimitiveTypeKind.Byte, EdmConstants.Byte, typeof(Byte));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.DateTime], PrimitiveTypeKind.DateTime, EdmConstants.DateTime, typeof(DateTime));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Decimal], PrimitiveTypeKind.Decimal, EdmConstants.Decimal, typeof(Decimal));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Double], PrimitiveTypeKind.Double, EdmConstants.Double, typeof(Double));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Single], PrimitiveTypeKind.Single, EdmConstants.Single, typeof(Single));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Guid], PrimitiveTypeKind.Guid, EdmConstants.Guid, typeof(Guid));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Int16], PrimitiveTypeKind.Int16, EdmConstants.Int16, typeof(Int16));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Int32], PrimitiveTypeKind.Int32, EdmConstants.Int32, typeof(Int32));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Int64], PrimitiveTypeKind.Int64, EdmConstants.Int64, typeof(Int64));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.SByte], PrimitiveTypeKind.SByte, EdmConstants.SByte, typeof(SByte));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.String], PrimitiveTypeKind.String, EdmConstants.String, typeof(String));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Time], PrimitiveTypeKind.Time, EdmConstants.Time, typeof(TimeSpan));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset], PrimitiveTypeKind.DateTimeOffset, EdmConstants.DateTimeOffset, typeof(DateTimeOffset));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Geography], PrimitiveTypeKind.Geography, EdmConstants.Geography, typeof(DbGeography));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeographyPoint], PrimitiveTypeKind.GeographyPoint, EdmConstants.GeographyPoint, typeof(DbGeography));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeographyLineString], PrimitiveTypeKind.GeographyLineString, EdmConstants.GeographyLineString, typeof(DbGeography));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeographyPolygon], PrimitiveTypeKind.GeographyPolygon, EdmConstants.GeographyPolygon, typeof(DbGeography));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeographyMultiPoint], PrimitiveTypeKind.GeographyMultiPoint, EdmConstants.GeographyMultiPoint, typeof(DbGeography));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeographyMultiLineString], PrimitiveTypeKind.GeographyMultiLineString, EdmConstants.GeographyMultiLineString, typeof(DbGeography));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeographyMultiPolygon], PrimitiveTypeKind.GeographyMultiPolygon, EdmConstants.GeographyMultiPolygon, typeof(DbGeography));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeographyCollection], PrimitiveTypeKind.GeographyCollection, EdmConstants.GeographyCollection, typeof(DbGeography));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Geometry], PrimitiveTypeKind.Geometry, EdmConstants.Geometry, typeof(DbGeometry));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeometryPoint], PrimitiveTypeKind.GeometryPoint, EdmConstants.GeometryPoint, typeof(DbGeometry));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeometryLineString], PrimitiveTypeKind.GeometryLineString, EdmConstants.GeometryLineString, typeof(DbGeometry));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeometryPolygon], PrimitiveTypeKind.GeometryPolygon, EdmConstants.GeometryPolygon, typeof(DbGeometry));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeometryMultiPoint], PrimitiveTypeKind.GeometryMultiPoint, EdmConstants.GeometryMultiPoint, typeof(DbGeometry));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeometryMultiLineString], PrimitiveTypeKind.GeometryMultiLineString, EdmConstants.GeometryMultiLineString, typeof(DbGeometry));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeometryMultiPolygon], PrimitiveTypeKind.GeometryMultiPolygon, EdmConstants.GeometryMultiPolygon, typeof(DbGeometry));
|
|
InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.GeometryCollection], PrimitiveTypeKind.GeometryCollection, EdmConstants.GeometryCollection, typeof(DbGeometry));
|
|
|
|
// Set all primitive types to be readonly
|
|
foreach (PrimitiveType primitiveType in primitiveTypes)
|
|
{
|
|
primitiveType.ProviderManifest = this;
|
|
primitiveType.SetReadOnly();
|
|
}
|
|
|
|
System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType> readOnlyTypes = new System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>(primitiveTypes);
|
|
|
|
// Set the result to _primitiveTypes at the end
|
|
Interlocked.CompareExchange<System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>>(ref _primitiveTypes, readOnlyTypes, null);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initialize all the primitive type with the given primitive type kind and name
|
|
/// </summary>
|
|
/// <param name="primitiveType">The primitive type to initialize</param>
|
|
/// <param name="primitiveTypeKind">Type of the primitive type which is getting initialized</param>
|
|
/// <param name="name">name of the built in type</param>
|
|
/// <param name="clrType">the CLR Type of that maps to the EDM PrimitiveType</param>
|
|
private void InitializePrimitiveType(PrimitiveType primitiveType,
|
|
PrimitiveTypeKind primitiveTypeKind,
|
|
string name,
|
|
Type clrType)
|
|
{
|
|
// Only null types are not abstract and they are sealed, all others are abstract and unsealed
|
|
EdmType.Initialize(primitiveType, name,
|
|
EdmConstants.EdmNamespace,
|
|
DataSpace.CSpace,
|
|
true /* isabstract */,
|
|
null /* baseType */);
|
|
PrimitiveType.Initialize(primitiveType,
|
|
primitiveTypeKind,
|
|
true, // isDefault
|
|
this);
|
|
Debug.Assert(clrType == primitiveType.ClrEquivalentType, "ClrEquivalentType mismatch");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Boostrapping all the facet descriptions for the EDM Provider Manifest
|
|
/// </summary>
|
|
private void InitializeFacetDescriptions()
|
|
{
|
|
if (_facetDescriptions != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Ensure the primitive types are there
|
|
InitializePrimitiveTypes();
|
|
|
|
// Create the dictionary of facet descriptions
|
|
Dictionary<PrimitiveType, System.Collections.ObjectModel.ReadOnlyCollection<FacetDescription>> facetDescriptions = new Dictionary<PrimitiveType, System.Collections.ObjectModel.ReadOnlyCollection<FacetDescription>>();
|
|
|
|
// String facets
|
|
FacetDescription[] list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.String);
|
|
PrimitiveType applicableType = _primitiveTypes[(int)PrimitiveTypeKind.String];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
// Binary facets
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.Binary);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.Binary];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
// DateTime facets
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.DateTime);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.DateTime];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
// Time facets
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.Time);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.Time];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
// DateTimeOffset facets
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.DateTimeOffset);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
|
|
// Decimal facets
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.Decimal);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.Decimal];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
// Spatial facets
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.Geography);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.Geography];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeographyPoint);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeographyPoint];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeographyLineString);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeographyLineString];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeographyPolygon);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeographyPolygon];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeographyMultiPoint);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeographyMultiPoint];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeographyMultiLineString);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeographyMultiLineString];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeographyMultiPolygon);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeographyMultiPolygon];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeographyCollection);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeographyCollection];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.Geometry);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.Geometry];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeometryPoint);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeometryPoint];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeometryLineString);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeometryLineString];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeometryPolygon);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeometryPolygon];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeometryMultiPoint);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeometryMultiPoint];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeometryMultiLineString);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeometryMultiLineString];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeometryMultiPolygon);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeometryMultiPolygon];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.GeometryCollection);
|
|
applicableType = _primitiveTypes[(int)PrimitiveTypeKind.GeometryCollection];
|
|
facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
|
|
|
|
// Set the result to _facetDescriptions at the end
|
|
Interlocked.CompareExchange<Dictionary<PrimitiveType, System.Collections.ObjectModel.ReadOnlyCollection<FacetDescription>>>(ref _facetDescriptions,
|
|
facetDescriptions,
|
|
null);
|
|
}
|
|
|
|
internal static FacetDescription[] GetInitialFacetDescriptions(PrimitiveTypeKind primitiveTypeKind)
|
|
{
|
|
FacetDescription[] list;
|
|
|
|
switch (primitiveTypeKind)
|
|
{
|
|
case PrimitiveTypeKind.String:
|
|
{
|
|
list = new FacetDescription[3];
|
|
|
|
list[0] = (new FacetDescription(DbProviderManifest.MaxLengthFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Int32),
|
|
0,
|
|
Int32.MaxValue,
|
|
null));
|
|
list[1] = (new FacetDescription(DbProviderManifest.UnicodeFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Boolean),
|
|
null,
|
|
null,
|
|
null));
|
|
list[2] = (new FacetDescription(DbProviderManifest.FixedLengthFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Boolean),
|
|
null,
|
|
null,
|
|
null));
|
|
|
|
return list;
|
|
}
|
|
|
|
case PrimitiveTypeKind.Binary:
|
|
{
|
|
list = new FacetDescription[2];
|
|
|
|
list[0] = (new FacetDescription(DbProviderManifest.MaxLengthFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Int32),
|
|
0,
|
|
Int32.MaxValue,
|
|
null));
|
|
list[1] = (new FacetDescription(DbProviderManifest.FixedLengthFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Boolean),
|
|
null,
|
|
null,
|
|
null));
|
|
return list;
|
|
}
|
|
|
|
case PrimitiveTypeKind.DateTime:
|
|
{
|
|
list = new FacetDescription[1];
|
|
|
|
list[0] = (new FacetDescription(DbProviderManifest.PrecisionFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte),
|
|
0, EdmProviderManifest.MaximumDateTimePrecision, null));
|
|
|
|
return list;
|
|
}
|
|
case PrimitiveTypeKind.Time:
|
|
{
|
|
list = new FacetDescription[1];
|
|
|
|
list[0] = (new FacetDescription(DbProviderManifest.PrecisionFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte),
|
|
0, EdmProviderManifest.MaximumDateTimePrecision, TypeUsage.DefaultDateTimePrecisionFacetValue));
|
|
|
|
return list;
|
|
}
|
|
case PrimitiveTypeKind.DateTimeOffset:
|
|
{
|
|
list = new FacetDescription[1];
|
|
list[0] = (new FacetDescription(DbProviderManifest.PrecisionFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte),
|
|
0, EdmProviderManifest.MaximumDateTimePrecision, TypeUsage.DefaultDateTimePrecisionFacetValue));
|
|
|
|
return list;
|
|
}
|
|
case PrimitiveTypeKind.Decimal:
|
|
{
|
|
list = new FacetDescription[2];
|
|
|
|
list[0] = (new FacetDescription(DbProviderManifest.PrecisionFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte),
|
|
1,
|
|
EdmProviderManifest.MaximumDecimalPrecision,
|
|
null));
|
|
list[1] = (new FacetDescription(DbProviderManifest.ScaleFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte),
|
|
0,
|
|
EdmProviderManifest.MaximumDecimalPrecision,
|
|
null));
|
|
return list;
|
|
}
|
|
case PrimitiveTypeKind.Geometry:
|
|
case PrimitiveTypeKind.GeometryPoint:
|
|
case PrimitiveTypeKind.GeometryLineString:
|
|
case PrimitiveTypeKind.GeometryPolygon:
|
|
case PrimitiveTypeKind.GeometryMultiPoint:
|
|
case PrimitiveTypeKind.GeometryMultiLineString:
|
|
case PrimitiveTypeKind.GeometryMultiPolygon:
|
|
case PrimitiveTypeKind.GeometryCollection:
|
|
{
|
|
list = new FacetDescription[2];
|
|
|
|
list[0] = (new FacetDescription(DbProviderManifest.SridFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Int32),
|
|
0,
|
|
Int32.MaxValue,
|
|
DbGeometry.DefaultCoordinateSystemId));
|
|
list[1] = (new FacetDescription(DbProviderManifest.IsStrictFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Boolean),
|
|
null,
|
|
null,
|
|
true));
|
|
return list;
|
|
}
|
|
case PrimitiveTypeKind.Geography:
|
|
case PrimitiveTypeKind.GeographyPoint:
|
|
case PrimitiveTypeKind.GeographyLineString:
|
|
case PrimitiveTypeKind.GeographyPolygon:
|
|
case PrimitiveTypeKind.GeographyMultiPoint:
|
|
case PrimitiveTypeKind.GeographyMultiLineString:
|
|
case PrimitiveTypeKind.GeographyMultiPolygon:
|
|
case PrimitiveTypeKind.GeographyCollection:
|
|
{
|
|
list = new FacetDescription[2];
|
|
|
|
list[0] = (new FacetDescription(DbProviderManifest.SridFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Int32),
|
|
0,
|
|
Int32.MaxValue,
|
|
DbGeography.DefaultCoordinateSystemId));
|
|
list[1] = (new FacetDescription(DbProviderManifest.IsStrictFacetName,
|
|
MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Boolean),
|
|
null,
|
|
null,
|
|
true));
|
|
return list;
|
|
}
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Boostrapping all the canonical functions for the EDM Provider Manifest
|
|
/// </summary>
|
|
private void InitializeCanonicalFunctions()
|
|
{
|
|
if (_functions != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Ensure primitive types are available
|
|
InitializePrimitiveTypes();
|
|
|
|
EdmProviderManifestFunctionBuilder functions = new EdmProviderManifestFunctionBuilder(_primitiveTypes);
|
|
PrimitiveTypeKind[] parameterTypes;
|
|
|
|
#region Aggregate Functions
|
|
|
|
// Max, Min
|
|
parameterTypes = new[] { PrimitiveTypeKind.Byte,
|
|
PrimitiveTypeKind.DateTime,
|
|
PrimitiveTypeKind.Decimal,
|
|
PrimitiveTypeKind.Double,
|
|
PrimitiveTypeKind.Int16,
|
|
PrimitiveTypeKind.Int32,
|
|
PrimitiveTypeKind.Int64,
|
|
PrimitiveTypeKind.SByte,
|
|
PrimitiveTypeKind.Single,
|
|
PrimitiveTypeKind.String,
|
|
PrimitiveTypeKind.Binary,
|
|
PrimitiveTypeKind.Time,
|
|
PrimitiveTypeKind.DateTimeOffset };
|
|
|
|
functions.ForTypes(parameterTypes, type => functions.AddAggregate("Max", type));
|
|
functions.ForTypes(parameterTypes, type => functions.AddAggregate("Min", type));
|
|
|
|
// Avg, Sum
|
|
parameterTypes = new[] { PrimitiveTypeKind.Decimal,
|
|
PrimitiveTypeKind.Double,
|
|
PrimitiveTypeKind.Int32,
|
|
PrimitiveTypeKind.Int64 };
|
|
|
|
functions.ForTypes(parameterTypes, type => functions.AddAggregate("Avg", type));
|
|
functions.ForTypes(parameterTypes, type => functions.AddAggregate("Sum", type));
|
|
|
|
// STDEV, STDEVP, VAR, VARP
|
|
parameterTypes = new[] { PrimitiveTypeKind.Decimal,
|
|
PrimitiveTypeKind.Double,
|
|
PrimitiveTypeKind.Int32,
|
|
PrimitiveTypeKind.Int64};
|
|
|
|
functions.ForTypes(parameterTypes, type => functions.AddAggregate(PrimitiveTypeKind.Double, "StDev", type));
|
|
functions.ForTypes(parameterTypes, type => functions.AddAggregate(PrimitiveTypeKind.Double, "StDevP", type));
|
|
functions.ForTypes(parameterTypes, type => functions.AddAggregate(PrimitiveTypeKind.Double, "Var", type));
|
|
functions.ForTypes(parameterTypes, type => functions.AddAggregate(PrimitiveTypeKind.Double, "VarP", type));
|
|
|
|
// Count and Big Count must be supported for all edm types, except the strong spatial types.
|
|
functions.ForAllBasePrimitiveTypes(type => functions.AddAggregate(PrimitiveTypeKind.Int32, "Count", type));
|
|
functions.ForAllBasePrimitiveTypes(type => functions.AddAggregate(PrimitiveTypeKind.Int64, "BigCount", type));
|
|
|
|
#endregion
|
|
|
|
#region String Functions
|
|
|
|
functions.AddFunction(PrimitiveTypeKind.String, "Trim", PrimitiveTypeKind.String, "stringArgument");
|
|
functions.AddFunction(PrimitiveTypeKind.String, "RTrim", PrimitiveTypeKind.String, "stringArgument");
|
|
functions.AddFunction(PrimitiveTypeKind.String, "LTrim", PrimitiveTypeKind.String, "stringArgument");
|
|
functions.AddFunction(PrimitiveTypeKind.String, "Concat", PrimitiveTypeKind.String, "string1", PrimitiveTypeKind.String, "string2");
|
|
functions.AddFunction(PrimitiveTypeKind.Int32, "Length", PrimitiveTypeKind.String, "stringArgument");
|
|
|
|
// Substring, Left, Right overloads
|
|
parameterTypes = new[] { PrimitiveTypeKind.Byte,
|
|
PrimitiveTypeKind.Int16,
|
|
PrimitiveTypeKind.Int32,
|
|
PrimitiveTypeKind.Int64,
|
|
PrimitiveTypeKind.SByte };
|
|
|
|
functions.ForTypes(parameterTypes, type => functions.AddFunction(PrimitiveTypeKind.String, "Substring", PrimitiveTypeKind.String, "stringArgument", type, "start", type, "length"));
|
|
functions.ForTypes(parameterTypes, type => functions.AddFunction(PrimitiveTypeKind.String, "Left", PrimitiveTypeKind.String, "stringArgument", type, "length"));
|
|
functions.ForTypes(parameterTypes, type => functions.AddFunction(PrimitiveTypeKind.String, "Right", PrimitiveTypeKind.String, "stringArgument", type, "length"));
|
|
|
|
functions.AddFunction(PrimitiveTypeKind.String, "Replace", PrimitiveTypeKind.String, "stringArgument", PrimitiveTypeKind.String, "toReplace", PrimitiveTypeKind.String, "replacement");
|
|
functions.AddFunction(PrimitiveTypeKind.Int32, "IndexOf", PrimitiveTypeKind.String, "searchString", PrimitiveTypeKind.String, "stringToFind");
|
|
functions.AddFunction(PrimitiveTypeKind.String, "ToUpper", PrimitiveTypeKind.String, "stringArgument");
|
|
functions.AddFunction(PrimitiveTypeKind.String, "ToLower", PrimitiveTypeKind.String, "stringArgument");
|
|
functions.AddFunction(PrimitiveTypeKind.String, "Reverse", PrimitiveTypeKind.String, "stringArgument");
|
|
functions.AddFunction(PrimitiveTypeKind.Boolean, "Contains", PrimitiveTypeKind.String, "searchedString", PrimitiveTypeKind.String, "searchedForString");
|
|
functions.AddFunction(PrimitiveTypeKind.Boolean, "StartsWith", PrimitiveTypeKind.String, "stringArgument", PrimitiveTypeKind.String, "prefix");
|
|
functions.AddFunction(PrimitiveTypeKind.Boolean, "EndsWith", PrimitiveTypeKind.String, "stringArgument", PrimitiveTypeKind.String, "suffix");
|
|
|
|
#endregion
|
|
|
|
#region DateTime Functions
|
|
|
|
PrimitiveTypeKind[] dateTimeParameterTypes = { PrimitiveTypeKind.DateTimeOffset,
|
|
PrimitiveTypeKind.DateTime };
|
|
functions.ForTypes(dateTimeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "Year", type, "dateValue"));
|
|
functions.ForTypes(dateTimeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "Month", type, "dateValue"));
|
|
functions.ForTypes(dateTimeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "Day", type, "dateValue"));
|
|
functions.ForTypes(dateTimeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "DayOfYear", type, "dateValue"));
|
|
|
|
PrimitiveTypeKind[] timeParameterTypes = { PrimitiveTypeKind.DateTimeOffset,
|
|
PrimitiveTypeKind.DateTime,
|
|
PrimitiveTypeKind.Time };
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "Hour", type, "timeValue"));
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "Minute", type, "timeValue"));
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "Second", type, "timeValue"));
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "Millisecond", type, "timeValue"));
|
|
|
|
functions.AddFunction(PrimitiveTypeKind.DateTime, "CurrentDateTime");
|
|
functions.AddFunction(PrimitiveTypeKind.DateTimeOffset, "CurrentDateTimeOffset");
|
|
functions.AddFunction(PrimitiveTypeKind.Int32, "GetTotalOffsetMinutes", PrimitiveTypeKind.DateTimeOffset, "dateTimeOffsetArgument");
|
|
functions.AddFunction(PrimitiveTypeKind.DateTime, "CurrentUtcDateTime");
|
|
|
|
//TruncateTime
|
|
functions.ForTypes(dateTimeParameterTypes, type => functions.AddFunction(type, "TruncateTime", type, "dateValue"));
|
|
|
|
//DateTime constructor
|
|
functions.AddFunction(PrimitiveTypeKind.DateTime, "CreateDateTime", PrimitiveTypeKind.Int32, "year",
|
|
PrimitiveTypeKind.Int32, "month",
|
|
PrimitiveTypeKind.Int32, "day",
|
|
PrimitiveTypeKind.Int32, "hour",
|
|
PrimitiveTypeKind.Int32, "minute",
|
|
PrimitiveTypeKind.Double, "second");
|
|
|
|
|
|
//DateTimeOffset constructor
|
|
functions.AddFunction(PrimitiveTypeKind.DateTimeOffset, "CreateDateTimeOffset", PrimitiveTypeKind.Int32, "year",
|
|
PrimitiveTypeKind.Int32, "month",
|
|
PrimitiveTypeKind.Int32, "day",
|
|
PrimitiveTypeKind.Int32, "hour",
|
|
PrimitiveTypeKind.Int32, "minute",
|
|
PrimitiveTypeKind.Double, "second",
|
|
PrimitiveTypeKind.Int32, "timeZoneOffset");
|
|
|
|
//Time constructor
|
|
functions.AddFunction(PrimitiveTypeKind.Time, "CreateTime", PrimitiveTypeKind.Int32, "hour", PrimitiveTypeKind.Int32, "minute", PrimitiveTypeKind.Double, "second");
|
|
|
|
//Date and time addition functions
|
|
functions.ForTypes(dateTimeParameterTypes, type => functions.AddFunction(type, "AddYears", type, "dateValue", PrimitiveTypeKind.Int32, "addValue"));
|
|
functions.ForTypes(dateTimeParameterTypes, type => functions.AddFunction(type, "AddMonths", type, "dateValue", PrimitiveTypeKind.Int32, "addValue"));
|
|
functions.ForTypes(dateTimeParameterTypes, type => functions.AddFunction(type, "AddDays", type, "dateValue", PrimitiveTypeKind.Int32, "addValue"));
|
|
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(type, "AddHours", type, "timeValue", PrimitiveTypeKind.Int32, "addValue"));
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(type, "AddMinutes", type, "timeValue", PrimitiveTypeKind.Int32, "addValue"));
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(type, "AddSeconds", type, "timeValue", PrimitiveTypeKind.Int32, "addValue"));
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(type, "AddMilliseconds", type, "timeValue", PrimitiveTypeKind.Int32, "addValue"));
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(type, "AddMicroseconds", type, "timeValue", PrimitiveTypeKind.Int32, "addValue"));
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(type, "AddNanoseconds", type, "timeValue", PrimitiveTypeKind.Int32, "addValue"));
|
|
|
|
// Date and time diff functions
|
|
functions.ForTypes(dateTimeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "DiffYears", type, "dateValue1", type, "dateValue2"));
|
|
functions.ForTypes(dateTimeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "DiffMonths", type, "dateValue1", type, "dateValue2"));
|
|
functions.ForTypes(dateTimeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "DiffDays", type, "dateValue1", type, "dateValue2"));
|
|
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "DiffHours", type, "timeValue1", type, "timeValue2"));
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "DiffMinutes", type, "timeValue1", type, "timeValue2"));
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "DiffSeconds", type, "timeValue1", type, "timeValue2"));
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "DiffMilliseconds", type, "timeValue1", type, "timeValue2"));
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "DiffMicroseconds", type, "timeValue1", type, "timeValue2"));
|
|
functions.ForTypes(timeParameterTypes, type => functions.AddFunction(PrimitiveTypeKind.Int32, "DiffNanoseconds", type, "timeValue1", type, "timeValue2"));
|
|
|
|
#endregion // DateTime Functions
|
|
|
|
#region Math Functions
|
|
|
|
// Overloads for ROUND, FLOOR, CEILING functions
|
|
parameterTypes = new[] { PrimitiveTypeKind.Single,
|
|
PrimitiveTypeKind.Double,
|
|
PrimitiveTypeKind.Decimal };
|
|
functions.ForTypes(parameterTypes, type => functions.AddFunction(type, "Round", type, "value"));
|
|
functions.ForTypes(parameterTypes, type => functions.AddFunction(type, "Floor", type, "value"));
|
|
functions.ForTypes(parameterTypes, type => functions.AddFunction(type, "Ceiling", type, "value"));
|
|
|
|
// Overloads for ROUND, TRUNCATE
|
|
parameterTypes = new [] { PrimitiveTypeKind.Double,
|
|
PrimitiveTypeKind.Decimal };
|
|
functions.ForTypes(parameterTypes, type => functions.AddFunction(type, "Round", type, "value", PrimitiveTypeKind.Int32, "digits"));
|
|
functions.ForTypes(parameterTypes, type => functions.AddFunction(type, "Truncate", type, "value", PrimitiveTypeKind.Int32, "digits"));
|
|
|
|
// Overloads for ABS functions
|
|
parameterTypes = new[] { PrimitiveTypeKind.Decimal,
|
|
PrimitiveTypeKind.Double,
|
|
PrimitiveTypeKind.Int16,
|
|
PrimitiveTypeKind.Int32,
|
|
PrimitiveTypeKind.Int64,
|
|
PrimitiveTypeKind.Byte,
|
|
PrimitiveTypeKind.Single };
|
|
functions.ForTypes(parameterTypes, type => functions.AddFunction(type, "Abs", type, "value"));
|
|
|
|
// Overloads for POWER functions
|
|
PrimitiveTypeKind[] powerFirstParameterTypes = { PrimitiveTypeKind.Decimal,
|
|
PrimitiveTypeKind.Double,
|
|
PrimitiveTypeKind.Int32,
|
|
PrimitiveTypeKind.Int64};
|
|
|
|
PrimitiveTypeKind[] powerSecondParameterTypes = { PrimitiveTypeKind.Decimal,
|
|
PrimitiveTypeKind.Double,
|
|
PrimitiveTypeKind.Int64 };
|
|
|
|
foreach (PrimitiveTypeKind kind1 in powerFirstParameterTypes)
|
|
{
|
|
foreach (PrimitiveTypeKind kind2 in powerSecondParameterTypes)
|
|
{
|
|
functions.AddFunction(kind1, "Power", kind1, "baseArgument", kind2, "exponent");
|
|
}
|
|
}
|
|
|
|
#endregion // Math Functions
|
|
|
|
#region Bitwise Functions
|
|
|
|
// Overloads for BitwiseAND, BitwiseNOT, BitwiseOR, BitwiseXOR functions
|
|
parameterTypes = new[] { PrimitiveTypeKind.Int16,
|
|
PrimitiveTypeKind.Int32,
|
|
PrimitiveTypeKind.Int64,
|
|
PrimitiveTypeKind.Byte };
|
|
|
|
functions.ForTypes(parameterTypes, type => functions.AddFunction(type, "BitwiseAnd", type, "value1", type, "value2"));
|
|
functions.ForTypes(parameterTypes, type => functions.AddFunction(type, "BitwiseOr", type, "value1", type, "value2"));
|
|
functions.ForTypes(parameterTypes, type => functions.AddFunction(type, "BitwiseXor", type, "value1", type, "value2"));
|
|
functions.ForTypes(parameterTypes, type => functions.AddFunction(type, "BitwiseNot", type, "value"));
|
|
|
|
#endregion
|
|
|
|
#region Misc Functions
|
|
|
|
functions.AddFunction(PrimitiveTypeKind.Guid, "NewGuid");
|
|
|
|
#endregion // Misc Functions
|
|
|
|
#region Spatial Functions
|
|
|
|
EdmProviderManifestSpatialFunctions.AddFunctions(functions);
|
|
|
|
#endregion
|
|
|
|
System.Collections.ObjectModel.ReadOnlyCollection<EdmFunction> readOnlyFunctions = functions.ToFunctionCollection();
|
|
|
|
Interlocked.CompareExchange<System.Collections.ObjectModel.ReadOnlyCollection<EdmFunction>>(ref _functions, readOnlyFunctions, null);
|
|
}
|
|
|
|
#region Edm Provider Specific Functionality
|
|
/// <summary>
|
|
/// Returns the list of super-types for the given primitiveType
|
|
/// </summary>
|
|
/// <param name="primitiveType"></param>
|
|
/// <returns></returns>
|
|
internal System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType> GetPromotionTypes(PrimitiveType primitiveType)
|
|
{
|
|
InitializePromotableTypes();
|
|
|
|
return _promotionTypes[(int)primitiveType.PrimitiveTypeKind];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes Promotion Type relation
|
|
/// </summary>
|
|
private void InitializePromotableTypes()
|
|
{
|
|
if (null != _promotionTypes)
|
|
{
|
|
return;
|
|
}
|
|
|
|
System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>[] promotionTypes = new System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>[EdmConstants.NumPrimitiveTypes];
|
|
|
|
for (int i = 0; i < EdmConstants.NumPrimitiveTypes; i++)
|
|
{
|
|
promotionTypes[i] = new System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>(new PrimitiveType[] { _primitiveTypes[i] });
|
|
}
|
|
|
|
//
|
|
// PrimitiveTypeKind.Byte
|
|
//
|
|
promotionTypes[(int)PrimitiveTypeKind.Byte] = new System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>(new PrimitiveType[] {
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Byte],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Int16],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Int32],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Int64],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Decimal],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Single],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Double]
|
|
});
|
|
|
|
//
|
|
// PrimitiveTypeKind.Int16
|
|
//
|
|
promotionTypes[(int)PrimitiveTypeKind.Int16] = new System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>(new PrimitiveType[] {
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Int16],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Int32],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Int64],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Decimal],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Single],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Double]
|
|
});
|
|
|
|
//
|
|
// PrimitiveTypeKind.Int32
|
|
//
|
|
promotionTypes[(int)PrimitiveTypeKind.Int32] = new System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>(new PrimitiveType[] {
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Int32],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Int64],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Decimal],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Single],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Double]
|
|
});
|
|
|
|
//
|
|
// PrimitiveTypeKind.Int64
|
|
//
|
|
promotionTypes[(int)PrimitiveTypeKind.Int64] = new System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>(new PrimitiveType[] {
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Int64],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Decimal],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Single],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Double]
|
|
});
|
|
|
|
//
|
|
// PrimitiveTypeKind.Single
|
|
//
|
|
promotionTypes[(int)PrimitiveTypeKind.Single] = new System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>(new PrimitiveType[] {
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Single],
|
|
_primitiveTypes[(int)PrimitiveTypeKind.Double]
|
|
});
|
|
|
|
InitializeSpatialPromotionGroup(
|
|
promotionTypes,
|
|
new PrimitiveTypeKind[] {
|
|
PrimitiveTypeKind.GeographyPoint, PrimitiveTypeKind.GeographyLineString, PrimitiveTypeKind.GeographyPolygon,
|
|
PrimitiveTypeKind.GeographyMultiPoint, PrimitiveTypeKind.GeographyMultiLineString, PrimitiveTypeKind.GeographyMultiPolygon,
|
|
PrimitiveTypeKind.GeographyCollection},
|
|
PrimitiveTypeKind.Geography);
|
|
|
|
InitializeSpatialPromotionGroup(
|
|
promotionTypes,
|
|
new PrimitiveTypeKind[] {
|
|
PrimitiveTypeKind.GeometryPoint, PrimitiveTypeKind.GeometryLineString, PrimitiveTypeKind.GeometryPolygon,
|
|
PrimitiveTypeKind.GeometryMultiPoint, PrimitiveTypeKind.GeometryMultiLineString, PrimitiveTypeKind.GeometryMultiPolygon,
|
|
PrimitiveTypeKind.GeometryCollection},
|
|
PrimitiveTypeKind.Geometry);
|
|
|
|
Interlocked.CompareExchange<System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>[]>(ref _promotionTypes,
|
|
promotionTypes,
|
|
null);
|
|
}
|
|
|
|
private void InitializeSpatialPromotionGroup(System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>[] promotionTypes, PrimitiveTypeKind[] promotableKinds, PrimitiveTypeKind baseKind)
|
|
{
|
|
foreach (PrimitiveTypeKind promotableKind in promotableKinds)
|
|
{
|
|
promotionTypes[(int)promotableKind] = new System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType>(new PrimitiveType[] {
|
|
_primitiveTypes[(int)promotableKind],
|
|
_primitiveTypes[(int)baseKind]
|
|
});
|
|
}
|
|
}
|
|
|
|
internal TypeUsage GetCanonicalModelTypeUsage(PrimitiveTypeKind primitiveTypeKind)
|
|
{
|
|
if (null == _canonicalModelTypes)
|
|
{
|
|
InitializeCanonicalModelTypes();
|
|
}
|
|
return _canonicalModelTypes[(int)primitiveTypeKind];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes Canonical Model Types
|
|
/// </summary>
|
|
private void InitializeCanonicalModelTypes()
|
|
{
|
|
InitializePrimitiveTypes();
|
|
|
|
TypeUsage[] canonicalTypes = new TypeUsage[EdmConstants.NumPrimitiveTypes];
|
|
for (int primitiveTypeIndex = 0; primitiveTypeIndex < EdmConstants.NumPrimitiveTypes; primitiveTypeIndex++)
|
|
{
|
|
PrimitiveType primitiveType = _primitiveTypes[primitiveTypeIndex];
|
|
TypeUsage typeUsage = TypeUsage.CreateDefaultTypeUsage(primitiveType);
|
|
Debug.Assert(null != typeUsage, "TypeUsage must not be null");
|
|
canonicalTypes[primitiveTypeIndex] = typeUsage;
|
|
}
|
|
|
|
Interlocked.CompareExchange<TypeUsage[]>(ref _canonicalModelTypes, canonicalTypes, null);
|
|
}
|
|
#endregion
|
|
|
|
#region DbProviderManifest Interface
|
|
/// <summary>
|
|
/// Returns all the primitive types supported by the provider manifest
|
|
/// </summary>
|
|
/// <returns>A collection of primitive types</returns>
|
|
public override System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType> GetStoreTypes()
|
|
{
|
|
InitializePrimitiveTypes();
|
|
return _primitiveTypes;
|
|
}
|
|
|
|
public override TypeUsage GetEdmType(TypeUsage storeType)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override TypeUsage GetStoreType(TypeUsage edmType)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
internal TypeUsage ForgetScalarConstraints(TypeUsage type)
|
|
{
|
|
PrimitiveType primitiveType = type.EdmType as PrimitiveType;
|
|
Debug.Assert(primitiveType != null, "type argument must be primitive in order to use this function");
|
|
if (primitiveType != null)
|
|
{
|
|
return GetCanonicalModelTypeUsage(primitiveType.PrimitiveTypeKind);
|
|
}
|
|
else
|
|
{
|
|
return type;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Providers should override this to return information specific to their provider.
|
|
///
|
|
/// This method should never return null.
|
|
/// </summary>
|
|
/// <param name="informationType">The name of the information to be retrieved.</param>
|
|
/// <returns>An XmlReader at the begining of the information requested.</returns>
|
|
protected override System.Xml.XmlReader GetDbInformation(string informationType)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
}
|