Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Metadata / Edm / Provider / EdmProviderManifest.cs / 1305376 / EdmProviderManifest.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System.Data.Common;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading;
namespace System.Data.Metadata.Edm
{
internal class EdmProviderManifest : DbProviderManifest
{
///
/// The ConcurrencyMode Facet Name
///
internal const string ConcurrencyModeFacetName = "ConcurrencyMode";
///
/// The StoreGeneratedPattern Facet Name
///
internal const string StoreGeneratedPatternFacetName = "StoreGeneratedPattern";
private Dictionary> _facetDescriptions;
private System.Collections.ObjectModel.ReadOnlyCollection _primitiveTypes;
private System.Collections.ObjectModel.ReadOnlyCollection _functions;
private static EdmProviderManifest _instance = new EdmProviderManifest();
private System.Collections.ObjectModel.ReadOnlyCollection[] _promotionTypes;
static TypeUsage[] _canonicalModelTypes;
internal const byte MaximumDecimalPrecision = Byte.MaxValue;
internal const byte MaximumDateTimePrecision = Byte.MaxValue;
///
/// A private constructor to prevent other places from instantiating this class
///
private EdmProviderManifest()
{
}
///
/// Gets the EDM provider manifest singleton instance
///
internal static EdmProviderManifest Instance
{
get
{
return _instance;
}
}
///
/// Returns the namespace used by this provider manifest
///
public override string NamespaceName
{
get { return EdmConstants.EdmNamespace; }
}
///
/// Store version hint
///
internal string Token
{
// we shouldn't throw exception on properties
get { return String.Empty; }
}
///
/// Returns the list of all the canonical functions
///
///
public override System.Collections.ObjectModel.ReadOnlyCollection GetStoreFunctions()
{
InitializeCanonicalFunctions();
return _functions;
}
///
/// Returns all the FacetDescriptions for a particular type
///
/// the type to return FacetDescriptions for.
/// The FacetDescriptions for the type given.
public override System.Collections.ObjectModel.ReadOnlyCollection 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 collection = null;
if (_facetDescriptions.TryGetValue(type as PrimitiveType, out collection))
{
return collection;
}
return Helper.EmptyFacetDescriptionEnumerable;
}
///
/// Returns a primitive type from this manifest having the specified primitive type kind
///
/// The value specifying the kind of primitive type to return
/// A primitive type having the given primitive type kind
public PrimitiveType GetPrimitiveType(PrimitiveTypeKind primitiveTypeKind)
{
InitializePrimitiveTypes();
return _primitiveTypes[(int)primitiveTypeKind];
}
///
/// Boostrapping all the primitive types for the EDM Provider Manifest
///
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();
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));
// Set all primitive types to be readonly
foreach (PrimitiveType primitiveType in primitiveTypes)
{
primitiveType.ProviderManifest = this;
primitiveType.SetReadOnly();
}
System.Collections.ObjectModel.ReadOnlyCollection readOnlyTypes = new System.Collections.ObjectModel.ReadOnlyCollection(primitiveTypes);
// Set the result to _primitiveTypes at the end
Interlocked.CompareExchange>(ref _primitiveTypes, readOnlyTypes, null);
}
///
/// Initialize all the primitive type with the given primitive type kind and name
///
/// The primitive type to initialize
/// Type of the primitive type which is getting initialized
/// name of the built in type
/// the CLR Type of that maps to the EDM PrimitiveType
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");
}
///
/// Boostrapping all the facet descriptions for the EDM Provider Manifest
///
private void InitializeFacetDescriptions()
{
if (_facetDescriptions != null)
{
return;
}
// Ensure the primitive types are there
InitializePrimitiveTypes();
// Create the dictionary of facet descriptions
Dictionary> facetDescriptions = new Dictionary>();
// 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));
// Set the result to _facetDescriptions at the end
Interlocked.CompareExchange>>(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;
}
default:
return null;
}
}
///
/// Boostrapping all the canonical functions for the EDM Provider Manifest
///
private void InitializeCanonicalFunctions()
{
if (_functions != null)
{
return;
}
List functions = new List();
// Ensure primitive types are available
InitializePrimitiveTypes();
// Initialize all the various parameter types. We do not want to create new instance of parameter types
// again and again for perf reasons
TypeUsage[] parameterTypeUsages = new TypeUsage[EdmConstants.NumPrimitiveTypes];
Func CreateFirstParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateSecondParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateThirdParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateFourthParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateFifthParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateSixthParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateSeventhParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateReturnParameter = ptk => new FunctionParameter(EdmConstants.ReturnType, parameterTypeUsages[(int)ptk], ParameterMode.ReturnValue);
Func CreateFirstParametersCollectionType = ptk => new FunctionParameter("collection", TypeUsage.Create(parameterTypeUsages[(int)ptk].EdmType.GetCollectionType()), ParameterMode.In);
for (int i = 0; i < EdmConstants.NumPrimitiveTypes; i++)
{
parameterTypeUsages[i] = TypeUsage.Create(_primitiveTypes[i]);
}
#region Aggregate Functions
// function overloads for Max, Min and Sum
string[] functionNames = { "Max", "Min" };
PrimitiveTypeKind[] parameterTypes = { 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
};
foreach (string functionName in functionNames)
{
foreach (PrimitiveTypeKind kind in parameterTypes)
{
EdmFunction function = CreateAggregateCannonicalFunction( functionName,
CreateReturnParameter(kind),
CreateFirstParametersCollectionType(kind));
functions.Add(function);
}
}
string[] functionNames1 = { "Avg", "Sum" };
PrimitiveTypeKind[] aggregateParameterTypes = { PrimitiveTypeKind.Decimal,
PrimitiveTypeKind.Double,
PrimitiveTypeKind.Int32,
PrimitiveTypeKind.Int64 };
foreach (string functionName in functionNames1)
{
foreach (PrimitiveTypeKind kind in aggregateParameterTypes)
{
EdmFunction function = CreateAggregateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParametersCollectionType(kind));
functions.Add(function);
}
}
// STDEV, STDEVP, VAR, VARP
string[] statisticalFunctionNames = {"StDev", "StDevP", "Var", "VarP"};
PrimitiveTypeKind[] statisticalFunctionParameterTypes = { PrimitiveTypeKind.Decimal,
PrimitiveTypeKind.Double,
PrimitiveTypeKind.Int32,
PrimitiveTypeKind.Int64};
foreach (string functionName in statisticalFunctionNames)
{
foreach (PrimitiveTypeKind kind in statisticalFunctionParameterTypes)
{
EdmFunction function = CreateAggregateCannonicalFunction(functionName,
CreateReturnParameter(PrimitiveTypeKind.Double),
CreateFirstParametersCollectionType(kind));
functions.Add(function);
}
}
// Count and Big Count must be supported for all edm types
for (int kindIndex = 0; kindIndex < EdmConstants.NumPrimitiveTypes; kindIndex++)
{
PrimitiveTypeKind kind = (PrimitiveTypeKind)kindIndex;
EdmFunction function = CreateAggregateCannonicalFunction("Count",
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParametersCollectionType(kind));
functions.Add(function);
}
for (int kindIndex = 0; kindIndex < EdmConstants.NumPrimitiveTypes; kindIndex++)
{
PrimitiveTypeKind kind = (PrimitiveTypeKind)kindIndex;
EdmFunction function = CreateAggregateCannonicalFunction("BigCount",
CreateReturnParameter(PrimitiveTypeKind.Int64),
CreateFirstParametersCollectionType(kind));
functions.Add(function);
}
#endregion
#region String Functions
functions.Add(CreateCannonicalFunction("Trim",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
functions.Add(CreateCannonicalFunction("RTrim",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
functions.Add(CreateCannonicalFunction("LTrim",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
functions.Add(CreateCannonicalFunction("Concat",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "string1"),
CreateSecondParameter(PrimitiveTypeKind.String, "string2")));
functions.Add(CreateCannonicalFunction("Length",
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
// Substring, Left, Right overloads
PrimitiveTypeKind[] subStringParameterTypes = { PrimitiveTypeKind.Byte,
PrimitiveTypeKind.Int16,
PrimitiveTypeKind.Int32,
PrimitiveTypeKind.Int64,
PrimitiveTypeKind.SByte };
foreach (PrimitiveTypeKind kind in subStringParameterTypes)
{
functions.Add(CreateCannonicalFunction("Substring",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument"),
CreateSecondParameter(kind, "start"),
CreateThirdParameter(kind, "length")));
}
foreach (PrimitiveTypeKind kind in subStringParameterTypes)
{
functions.Add(CreateCannonicalFunction("Left",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument"),
CreateSecondParameter(kind, "length")));
}
foreach (PrimitiveTypeKind kind in subStringParameterTypes)
{
functions.Add(CreateCannonicalFunction("Right",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument"),
CreateSecondParameter(kind, "length")));
}
functions.Add(CreateCannonicalFunction("Replace",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument"),
CreateSecondParameter(PrimitiveTypeKind.String, "toReplace"),
CreateThirdParameter(PrimitiveTypeKind.String, "replacement")));
functions.Add(CreateCannonicalFunction("IndexOf",
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(PrimitiveTypeKind.String, "searchString"),
CreateSecondParameter(PrimitiveTypeKind.String, "stringToFind")));
functions.Add(CreateCannonicalFunction("ToUpper",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
functions.Add(CreateCannonicalFunction("ToLower",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
functions.Add(CreateCannonicalFunction("Reverse",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
functions.Add(CreateCannonicalFunction("Contains",
CreateReturnParameter(PrimitiveTypeKind.Boolean),
CreateFirstParameter(PrimitiveTypeKind.String, "searchedString"),
CreateSecondParameter(PrimitiveTypeKind.String, "searchedForString")));
functions.Add(CreateCannonicalFunction("StartsWith",
CreateReturnParameter(PrimitiveTypeKind.Boolean),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument"),
CreateSecondParameter(PrimitiveTypeKind.String, "prefix")));
functions.Add(CreateCannonicalFunction("EndsWith",
CreateReturnParameter(PrimitiveTypeKind.Boolean),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument"),
CreateSecondParameter(PrimitiveTypeKind.String, "suffix")));
#endregion // String Functions
#region DateTime Functions
string[] dateTimeFunctions = { "Year", "Month", "Day", "DayOfYear" };
PrimitiveTypeKind[] dateTimeParameterTypes = { PrimitiveTypeKind.DateTimeOffset,
PrimitiveTypeKind.DateTime,
};
foreach (string dateTimeFunction in dateTimeFunctions)
{
foreach (PrimitiveTypeKind kind in dateTimeParameterTypes)
{
functions.Add(CreateCannonicalFunction(dateTimeFunction,
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(kind, "dateValue")));
}
}
string[] timeFunctions = { "Hour", "Minute", "Second", "Millisecond" };
PrimitiveTypeKind[] timeParameterTypes = { PrimitiveTypeKind.DateTimeOffset,
PrimitiveTypeKind.DateTime,
PrimitiveTypeKind.Time,
};
foreach (string timeFunction in timeFunctions)
{
foreach (PrimitiveTypeKind kind in timeParameterTypes)
{
functions.Add(CreateCannonicalFunction(timeFunction,
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(kind, "timeValue")));
}
}
EdmFunction dateFunction = CreateCannonicalFunction("CurrentDateTime",
CreateReturnParameter(PrimitiveTypeKind.DateTime));
functions.Add(dateFunction);
EdmFunction dateTimeOffsetFunction = CreateCannonicalFunction("CurrentDateTimeOffset",
CreateReturnParameter(PrimitiveTypeKind.DateTimeOffset));
functions.Add(dateTimeOffsetFunction);
functions.Add(CreateCannonicalFunction("GetTotalOffsetMinutes",
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(PrimitiveTypeKind.DateTimeOffset, "dateTimeOffsetArgument")));
dateFunction = CreateCannonicalFunction("CurrentUtcDateTime",
CreateReturnParameter(PrimitiveTypeKind.DateTime));
functions.Add(dateFunction);
//TruncateTime
foreach (PrimitiveTypeKind kind in dateTimeParameterTypes)
{
functions.Add(CreateCannonicalFunction("TruncateTime",
CreateReturnParameter(kind),
CreateFirstParameter(kind, "dateValue")));
}
//DateTime constructor
functions.Add(CreateCannonicalFunction("CreateDateTime",
CreateReturnParameter(PrimitiveTypeKind.DateTime),
CreateFirstParameter(PrimitiveTypeKind.Int32, "year"),
CreateSecondParameter(PrimitiveTypeKind.Int32, "month"),
CreateThirdParameter(PrimitiveTypeKind.Int32, "day"),
CreateFourthParameter(PrimitiveTypeKind.Int32, "hour"),
CreateFifthParameter(PrimitiveTypeKind.Int32, "minute"),
CreateSixthParameter(PrimitiveTypeKind.Double, "second")));
//DateTimeOffset constructor
functions.Add(CreateCannonicalFunction("CreateDateTimeOffset",
CreateReturnParameter(PrimitiveTypeKind.DateTimeOffset),
CreateFirstParameter(PrimitiveTypeKind.Int32, "year"),
CreateSecondParameter(PrimitiveTypeKind.Int32, "month"),
CreateThirdParameter(PrimitiveTypeKind.Int32, "day"),
CreateFourthParameter(PrimitiveTypeKind.Int32, "hour"),
CreateFifthParameter(PrimitiveTypeKind.Int32, "minute"),
CreateSixthParameter(PrimitiveTypeKind.Double, "second"),
CreateSeventhParameter(PrimitiveTypeKind.Int32, "timeZoneOffset")));
//Time constructor
functions.Add(CreateCannonicalFunction("CreateTime",
CreateReturnParameter(PrimitiveTypeKind.Time),
CreateFirstParameter(PrimitiveTypeKind.Int32, "hour"),
CreateSecondParameter(PrimitiveTypeKind.Int32, "minute"),
CreateThirdParameter(PrimitiveTypeKind.Double, "second")));
//Date and time addition functions
string[] dateAddFunctionsNames = new string[] { "AddYears", "AddMonths", "AddDays" };
foreach (string functionName in dateAddFunctionsNames)
{
foreach (PrimitiveTypeKind kind in dateTimeParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParameter(kind, "dateValue"),
CreateSecondParameter(PrimitiveTypeKind.Int32, "addValue")));
}
}
string[] timeAddFunctionsNames = new string[] { "AddHours", "AddMinutes", "AddSeconds", "AddMilliseconds", "AddMicroseconds", "AddNanoseconds" };
foreach (string functionName in timeAddFunctionsNames)
{
foreach (PrimitiveTypeKind kind in timeParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParameter(kind, "timeValue"),
CreateSecondParameter(PrimitiveTypeKind.Int32, "addValue")));
}
}
// Date and time diff functions
string[] dateDiffFunctionsNames = new string[] { "DiffYears", "DiffMonths", "DiffDays" };
foreach (string functionName in dateDiffFunctionsNames)
{
foreach (PrimitiveTypeKind kind in dateTimeParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(kind, "dateValue1"),
CreateSecondParameter(kind, "dateValue2")));
}
}
string[] timeDiffFunctionsNames = new string[] { "DiffHours", "DiffMinutes", "DiffSeconds", "DiffMilliseconds", "DiffMicroseconds", "DiffNanoseconds" };
foreach (string functionName in timeDiffFunctionsNames)
{
foreach (PrimitiveTypeKind kind in timeParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(kind, "timeValue1"),
CreateSecondParameter(kind, "timeValue2")));
}
}
#endregion // DateTime Functions
#region Math Functions
// Overloads for ROUND, FLOOR, CEILING functions
string[] approximationFunctions1 = { "Round", "Floor", "Ceiling" };
PrimitiveTypeKind[] approximationFunctions1ParameterTypes = { PrimitiveTypeKind.Single,
PrimitiveTypeKind.Double,
PrimitiveTypeKind.Decimal };
foreach (string functionName in approximationFunctions1)
{
foreach (PrimitiveTypeKind kind in approximationFunctions1ParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParameter(kind, "value")));
}
}
// Overloads for ROUND, TRUNCATE
string[] approximationFunctions2 = { "Round", "Truncate" };
PrimitiveTypeKind[] approximationFunctions2ParameterTypes = { PrimitiveTypeKind.Double,
PrimitiveTypeKind.Decimal };
foreach (string functionName in approximationFunctions2)
{
foreach (PrimitiveTypeKind kind in approximationFunctions2ParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParameter(kind, "value"),
CreateSecondParameter(PrimitiveTypeKind.Int32, "digits")));
}
}
// Overloads for ABS functions
PrimitiveTypeKind[] absParameterTypes = { PrimitiveTypeKind.Decimal,
PrimitiveTypeKind.Double,
PrimitiveTypeKind.Int16,
PrimitiveTypeKind.Int32,
PrimitiveTypeKind.Int64,
PrimitiveTypeKind.Byte,
PrimitiveTypeKind.Single };
foreach (PrimitiveTypeKind kind in absParameterTypes)
{
functions.Add(CreateCannonicalFunction("Abs",
CreateReturnParameter(kind),
CreateFirstParameter(kind, "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.Add(CreateCannonicalFunction("Power",
CreateReturnParameter(kind1),
CreateFirstParameter(kind1, "baseArgument"),
CreateSecondParameter(kind2, "exponent")));
}
}
#endregion // Math Functions
#region Bitwise Functions
string[] bitwiseFunctions = { "BitwiseAnd", "BitwiseOr", "BitwiseXor" };
// Overloads for BitwiseAND, BitwiseNOT, BitwiseOR, BitwiseXOR functions
PrimitiveTypeKind[] bitwiseFunctionOverloads = { PrimitiveTypeKind.Int16,
PrimitiveTypeKind.Int32,
PrimitiveTypeKind.Int64,
PrimitiveTypeKind.Byte };
foreach (string functionName in bitwiseFunctions)
{
foreach (PrimitiveTypeKind kind in bitwiseFunctionOverloads)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParameter(kind, "value1"),
CreateSecondParameter(kind, "value2")));
}
}
foreach (PrimitiveTypeKind kind in bitwiseFunctionOverloads)
{
functions.Add(CreateCannonicalFunction("BitwiseNot",
CreateReturnParameter(kind),
CreateFirstParameter(kind, "value")));
}
#endregion
#region Misc Functions
functions.Add(CreateCannonicalFunction("NewGuid",
CreateReturnParameter(PrimitiveTypeKind.Guid)));
#endregion // Misc Functions
//Set all the functions to readonly
foreach (EdmFunction function in functions)
{
function.SetReadOnly();
}
System.Collections.ObjectModel.ReadOnlyCollection readOnlyFunctions = new System.Collections.ObjectModel.ReadOnlyCollection(functions);
Interlocked.CompareExchange>(ref _functions, readOnlyFunctions, null);
}
private static EdmFunction CreateAggregateCannonicalFunction(string name, FunctionParameter returnParameter, FunctionParameter parameter)
{
Debug.Assert(name != null && returnParameter != null && parameter != null, "did you choose the wrong overload");
EdmFunction function = new EdmFunction( name,
EdmConstants.EdmNamespace,
DataSpace.CSpace,
new EdmFunctionPayload
{
IsAggregate = true,
IsBuiltIn = true,
ReturnParameter = returnParameter,
Parameters = new FunctionParameter[1] { parameter },
});
return function;
}
private static EdmFunction CreateCannonicalFunction(string name, FunctionParameter returnParameter, params FunctionParameter [] parameters)
{
Debug.Assert(name != null && returnParameter != null && parameters != null, "did you choose the wrong overload");
EdmFunction function = new EdmFunction(name,
EdmConstants.EdmNamespace,
DataSpace.CSpace,
new EdmFunctionPayload
{
IsBuiltIn = true,
ReturnParameter = returnParameter,
Parameters = parameters,
});
return function;
}
#region Edm Provider Specific Functionality
///
/// Returns the list of super-types for the given primitiveType
///
///
///
internal System.Collections.ObjectModel.ReadOnlyCollection GetPromotionTypes(PrimitiveType primitiveType)
{
InitializePromotableTypes();
return _promotionTypes[(int)primitiveType.PrimitiveTypeKind];
}
///
/// Initializes Promotion Type relation
///
private void InitializePromotableTypes()
{
if (null != _promotionTypes)
{
return;
}
System.Collections.ObjectModel.ReadOnlyCollection[] promotionTypes = new System.Collections.ObjectModel.ReadOnlyCollection[EdmConstants.NumPrimitiveTypes];
for (int i = 0; i < EdmConstants.NumPrimitiveTypes; i++)
{
promotionTypes[i] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] { _primitiveTypes[i] });
}
//
// PrimitiveTypeKind.Byte
//
promotionTypes[(int)PrimitiveTypeKind.Byte] = new System.Collections.ObjectModel.ReadOnlyCollection(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(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(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(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(new PrimitiveType[] {
_primitiveTypes[(int)PrimitiveTypeKind.Single],
_primitiveTypes[(int)PrimitiveTypeKind.Double]
});
Interlocked.CompareExchange[]>(ref _promotionTypes,
promotionTypes,
null);
}
internal TypeUsage GetCanonicalModelTypeUsage(PrimitiveTypeKind primitiveTypeKind)
{
if (null == _canonicalModelTypes)
{
InitializeCanonicalModelTypes();
}
return _canonicalModelTypes[(int)primitiveTypeKind];
}
///
/// Initializes Canonical Model Types
///
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(ref _canonicalModelTypes, canonicalTypes, null);
}
#endregion
#region DbProviderManifest Interface
///
/// Returns all the primitive types supported by the provider manifest
///
/// A collection of primitive types
public override System.Collections.ObjectModel.ReadOnlyCollection 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;
}
}
///
/// Providers should override this to return information specific to their provider.
///
/// This method should never return null.
///
/// The name of the information to be retrieved.
/// An XmlReader at the begining of the information requested.
protected override System.Xml.XmlReader GetDbInformation(string informationType)
{
throw new NotImplementedException();
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System.Data.Common;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading;
namespace System.Data.Metadata.Edm
{
internal class EdmProviderManifest : DbProviderManifest
{
///
/// The ConcurrencyMode Facet Name
///
internal const string ConcurrencyModeFacetName = "ConcurrencyMode";
///
/// The StoreGeneratedPattern Facet Name
///
internal const string StoreGeneratedPatternFacetName = "StoreGeneratedPattern";
private Dictionary> _facetDescriptions;
private System.Collections.ObjectModel.ReadOnlyCollection _primitiveTypes;
private System.Collections.ObjectModel.ReadOnlyCollection _functions;
private static EdmProviderManifest _instance = new EdmProviderManifest();
private System.Collections.ObjectModel.ReadOnlyCollection[] _promotionTypes;
static TypeUsage[] _canonicalModelTypes;
internal const byte MaximumDecimalPrecision = Byte.MaxValue;
internal const byte MaximumDateTimePrecision = Byte.MaxValue;
///
/// A private constructor to prevent other places from instantiating this class
///
private EdmProviderManifest()
{
}
///
/// Gets the EDM provider manifest singleton instance
///
internal static EdmProviderManifest Instance
{
get
{
return _instance;
}
}
///
/// Returns the namespace used by this provider manifest
///
public override string NamespaceName
{
get { return EdmConstants.EdmNamespace; }
}
///
/// Store version hint
///
internal string Token
{
// we shouldn't throw exception on properties
get { return String.Empty; }
}
///
/// Returns the list of all the canonical functions
///
///
public override System.Collections.ObjectModel.ReadOnlyCollection GetStoreFunctions()
{
InitializeCanonicalFunctions();
return _functions;
}
///
/// Returns all the FacetDescriptions for a particular type
///
/// the type to return FacetDescriptions for.
/// The FacetDescriptions for the type given.
public override System.Collections.ObjectModel.ReadOnlyCollection 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 collection = null;
if (_facetDescriptions.TryGetValue(type as PrimitiveType, out collection))
{
return collection;
}
return Helper.EmptyFacetDescriptionEnumerable;
}
///
/// Returns a primitive type from this manifest having the specified primitive type kind
///
/// The value specifying the kind of primitive type to return
/// A primitive type having the given primitive type kind
public PrimitiveType GetPrimitiveType(PrimitiveTypeKind primitiveTypeKind)
{
InitializePrimitiveTypes();
return _primitiveTypes[(int)primitiveTypeKind];
}
///
/// Boostrapping all the primitive types for the EDM Provider Manifest
///
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();
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));
// Set all primitive types to be readonly
foreach (PrimitiveType primitiveType in primitiveTypes)
{
primitiveType.ProviderManifest = this;
primitiveType.SetReadOnly();
}
System.Collections.ObjectModel.ReadOnlyCollection readOnlyTypes = new System.Collections.ObjectModel.ReadOnlyCollection(primitiveTypes);
// Set the result to _primitiveTypes at the end
Interlocked.CompareExchange>(ref _primitiveTypes, readOnlyTypes, null);
}
///
/// Initialize all the primitive type with the given primitive type kind and name
///
/// The primitive type to initialize
/// Type of the primitive type which is getting initialized
/// name of the built in type
/// the CLR Type of that maps to the EDM PrimitiveType
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");
}
///
/// Boostrapping all the facet descriptions for the EDM Provider Manifest
///
private void InitializeFacetDescriptions()
{
if (_facetDescriptions != null)
{
return;
}
// Ensure the primitive types are there
InitializePrimitiveTypes();
// Create the dictionary of facet descriptions
Dictionary> facetDescriptions = new Dictionary>();
// 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));
// Set the result to _facetDescriptions at the end
Interlocked.CompareExchange>>(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;
}
default:
return null;
}
}
///
/// Boostrapping all the canonical functions for the EDM Provider Manifest
///
private void InitializeCanonicalFunctions()
{
if (_functions != null)
{
return;
}
List functions = new List();
// Ensure primitive types are available
InitializePrimitiveTypes();
// Initialize all the various parameter types. We do not want to create new instance of parameter types
// again and again for perf reasons
TypeUsage[] parameterTypeUsages = new TypeUsage[EdmConstants.NumPrimitiveTypes];
Func CreateFirstParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateSecondParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateThirdParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateFourthParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateFifthParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateSixthParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateSeventhParameter = (ptk, name) => new FunctionParameter(name, parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateReturnParameter = ptk => new FunctionParameter(EdmConstants.ReturnType, parameterTypeUsages[(int)ptk], ParameterMode.ReturnValue);
Func CreateFirstParametersCollectionType = ptk => new FunctionParameter("collection", TypeUsage.Create(parameterTypeUsages[(int)ptk].EdmType.GetCollectionType()), ParameterMode.In);
for (int i = 0; i < EdmConstants.NumPrimitiveTypes; i++)
{
parameterTypeUsages[i] = TypeUsage.Create(_primitiveTypes[i]);
}
#region Aggregate Functions
// function overloads for Max, Min and Sum
string[] functionNames = { "Max", "Min" };
PrimitiveTypeKind[] parameterTypes = { 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
};
foreach (string functionName in functionNames)
{
foreach (PrimitiveTypeKind kind in parameterTypes)
{
EdmFunction function = CreateAggregateCannonicalFunction( functionName,
CreateReturnParameter(kind),
CreateFirstParametersCollectionType(kind));
functions.Add(function);
}
}
string[] functionNames1 = { "Avg", "Sum" };
PrimitiveTypeKind[] aggregateParameterTypes = { PrimitiveTypeKind.Decimal,
PrimitiveTypeKind.Double,
PrimitiveTypeKind.Int32,
PrimitiveTypeKind.Int64 };
foreach (string functionName in functionNames1)
{
foreach (PrimitiveTypeKind kind in aggregateParameterTypes)
{
EdmFunction function = CreateAggregateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParametersCollectionType(kind));
functions.Add(function);
}
}
// STDEV, STDEVP, VAR, VARP
string[] statisticalFunctionNames = {"StDev", "StDevP", "Var", "VarP"};
PrimitiveTypeKind[] statisticalFunctionParameterTypes = { PrimitiveTypeKind.Decimal,
PrimitiveTypeKind.Double,
PrimitiveTypeKind.Int32,
PrimitiveTypeKind.Int64};
foreach (string functionName in statisticalFunctionNames)
{
foreach (PrimitiveTypeKind kind in statisticalFunctionParameterTypes)
{
EdmFunction function = CreateAggregateCannonicalFunction(functionName,
CreateReturnParameter(PrimitiveTypeKind.Double),
CreateFirstParametersCollectionType(kind));
functions.Add(function);
}
}
// Count and Big Count must be supported for all edm types
for (int kindIndex = 0; kindIndex < EdmConstants.NumPrimitiveTypes; kindIndex++)
{
PrimitiveTypeKind kind = (PrimitiveTypeKind)kindIndex;
EdmFunction function = CreateAggregateCannonicalFunction("Count",
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParametersCollectionType(kind));
functions.Add(function);
}
for (int kindIndex = 0; kindIndex < EdmConstants.NumPrimitiveTypes; kindIndex++)
{
PrimitiveTypeKind kind = (PrimitiveTypeKind)kindIndex;
EdmFunction function = CreateAggregateCannonicalFunction("BigCount",
CreateReturnParameter(PrimitiveTypeKind.Int64),
CreateFirstParametersCollectionType(kind));
functions.Add(function);
}
#endregion
#region String Functions
functions.Add(CreateCannonicalFunction("Trim",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
functions.Add(CreateCannonicalFunction("RTrim",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
functions.Add(CreateCannonicalFunction("LTrim",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
functions.Add(CreateCannonicalFunction("Concat",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "string1"),
CreateSecondParameter(PrimitiveTypeKind.String, "string2")));
functions.Add(CreateCannonicalFunction("Length",
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
// Substring, Left, Right overloads
PrimitiveTypeKind[] subStringParameterTypes = { PrimitiveTypeKind.Byte,
PrimitiveTypeKind.Int16,
PrimitiveTypeKind.Int32,
PrimitiveTypeKind.Int64,
PrimitiveTypeKind.SByte };
foreach (PrimitiveTypeKind kind in subStringParameterTypes)
{
functions.Add(CreateCannonicalFunction("Substring",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument"),
CreateSecondParameter(kind, "start"),
CreateThirdParameter(kind, "length")));
}
foreach (PrimitiveTypeKind kind in subStringParameterTypes)
{
functions.Add(CreateCannonicalFunction("Left",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument"),
CreateSecondParameter(kind, "length")));
}
foreach (PrimitiveTypeKind kind in subStringParameterTypes)
{
functions.Add(CreateCannonicalFunction("Right",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument"),
CreateSecondParameter(kind, "length")));
}
functions.Add(CreateCannonicalFunction("Replace",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument"),
CreateSecondParameter(PrimitiveTypeKind.String, "toReplace"),
CreateThirdParameter(PrimitiveTypeKind.String, "replacement")));
functions.Add(CreateCannonicalFunction("IndexOf",
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(PrimitiveTypeKind.String, "searchString"),
CreateSecondParameter(PrimitiveTypeKind.String, "stringToFind")));
functions.Add(CreateCannonicalFunction("ToUpper",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
functions.Add(CreateCannonicalFunction("ToLower",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
functions.Add(CreateCannonicalFunction("Reverse",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument")));
functions.Add(CreateCannonicalFunction("Contains",
CreateReturnParameter(PrimitiveTypeKind.Boolean),
CreateFirstParameter(PrimitiveTypeKind.String, "searchedString"),
CreateSecondParameter(PrimitiveTypeKind.String, "searchedForString")));
functions.Add(CreateCannonicalFunction("StartsWith",
CreateReturnParameter(PrimitiveTypeKind.Boolean),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument"),
CreateSecondParameter(PrimitiveTypeKind.String, "prefix")));
functions.Add(CreateCannonicalFunction("EndsWith",
CreateReturnParameter(PrimitiveTypeKind.Boolean),
CreateFirstParameter(PrimitiveTypeKind.String, "stringArgument"),
CreateSecondParameter(PrimitiveTypeKind.String, "suffix")));
#endregion // String Functions
#region DateTime Functions
string[] dateTimeFunctions = { "Year", "Month", "Day", "DayOfYear" };
PrimitiveTypeKind[] dateTimeParameterTypes = { PrimitiveTypeKind.DateTimeOffset,
PrimitiveTypeKind.DateTime,
};
foreach (string dateTimeFunction in dateTimeFunctions)
{
foreach (PrimitiveTypeKind kind in dateTimeParameterTypes)
{
functions.Add(CreateCannonicalFunction(dateTimeFunction,
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(kind, "dateValue")));
}
}
string[] timeFunctions = { "Hour", "Minute", "Second", "Millisecond" };
PrimitiveTypeKind[] timeParameterTypes = { PrimitiveTypeKind.DateTimeOffset,
PrimitiveTypeKind.DateTime,
PrimitiveTypeKind.Time,
};
foreach (string timeFunction in timeFunctions)
{
foreach (PrimitiveTypeKind kind in timeParameterTypes)
{
functions.Add(CreateCannonicalFunction(timeFunction,
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(kind, "timeValue")));
}
}
EdmFunction dateFunction = CreateCannonicalFunction("CurrentDateTime",
CreateReturnParameter(PrimitiveTypeKind.DateTime));
functions.Add(dateFunction);
EdmFunction dateTimeOffsetFunction = CreateCannonicalFunction("CurrentDateTimeOffset",
CreateReturnParameter(PrimitiveTypeKind.DateTimeOffset));
functions.Add(dateTimeOffsetFunction);
functions.Add(CreateCannonicalFunction("GetTotalOffsetMinutes",
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(PrimitiveTypeKind.DateTimeOffset, "dateTimeOffsetArgument")));
dateFunction = CreateCannonicalFunction("CurrentUtcDateTime",
CreateReturnParameter(PrimitiveTypeKind.DateTime));
functions.Add(dateFunction);
//TruncateTime
foreach (PrimitiveTypeKind kind in dateTimeParameterTypes)
{
functions.Add(CreateCannonicalFunction("TruncateTime",
CreateReturnParameter(kind),
CreateFirstParameter(kind, "dateValue")));
}
//DateTime constructor
functions.Add(CreateCannonicalFunction("CreateDateTime",
CreateReturnParameter(PrimitiveTypeKind.DateTime),
CreateFirstParameter(PrimitiveTypeKind.Int32, "year"),
CreateSecondParameter(PrimitiveTypeKind.Int32, "month"),
CreateThirdParameter(PrimitiveTypeKind.Int32, "day"),
CreateFourthParameter(PrimitiveTypeKind.Int32, "hour"),
CreateFifthParameter(PrimitiveTypeKind.Int32, "minute"),
CreateSixthParameter(PrimitiveTypeKind.Double, "second")));
//DateTimeOffset constructor
functions.Add(CreateCannonicalFunction("CreateDateTimeOffset",
CreateReturnParameter(PrimitiveTypeKind.DateTimeOffset),
CreateFirstParameter(PrimitiveTypeKind.Int32, "year"),
CreateSecondParameter(PrimitiveTypeKind.Int32, "month"),
CreateThirdParameter(PrimitiveTypeKind.Int32, "day"),
CreateFourthParameter(PrimitiveTypeKind.Int32, "hour"),
CreateFifthParameter(PrimitiveTypeKind.Int32, "minute"),
CreateSixthParameter(PrimitiveTypeKind.Double, "second"),
CreateSeventhParameter(PrimitiveTypeKind.Int32, "timeZoneOffset")));
//Time constructor
functions.Add(CreateCannonicalFunction("CreateTime",
CreateReturnParameter(PrimitiveTypeKind.Time),
CreateFirstParameter(PrimitiveTypeKind.Int32, "hour"),
CreateSecondParameter(PrimitiveTypeKind.Int32, "minute"),
CreateThirdParameter(PrimitiveTypeKind.Double, "second")));
//Date and time addition functions
string[] dateAddFunctionsNames = new string[] { "AddYears", "AddMonths", "AddDays" };
foreach (string functionName in dateAddFunctionsNames)
{
foreach (PrimitiveTypeKind kind in dateTimeParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParameter(kind, "dateValue"),
CreateSecondParameter(PrimitiveTypeKind.Int32, "addValue")));
}
}
string[] timeAddFunctionsNames = new string[] { "AddHours", "AddMinutes", "AddSeconds", "AddMilliseconds", "AddMicroseconds", "AddNanoseconds" };
foreach (string functionName in timeAddFunctionsNames)
{
foreach (PrimitiveTypeKind kind in timeParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParameter(kind, "timeValue"),
CreateSecondParameter(PrimitiveTypeKind.Int32, "addValue")));
}
}
// Date and time diff functions
string[] dateDiffFunctionsNames = new string[] { "DiffYears", "DiffMonths", "DiffDays" };
foreach (string functionName in dateDiffFunctionsNames)
{
foreach (PrimitiveTypeKind kind in dateTimeParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(kind, "dateValue1"),
CreateSecondParameter(kind, "dateValue2")));
}
}
string[] timeDiffFunctionsNames = new string[] { "DiffHours", "DiffMinutes", "DiffSeconds", "DiffMilliseconds", "DiffMicroseconds", "DiffNanoseconds" };
foreach (string functionName in timeDiffFunctionsNames)
{
foreach (PrimitiveTypeKind kind in timeParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(kind, "timeValue1"),
CreateSecondParameter(kind, "timeValue2")));
}
}
#endregion // DateTime Functions
#region Math Functions
// Overloads for ROUND, FLOOR, CEILING functions
string[] approximationFunctions1 = { "Round", "Floor", "Ceiling" };
PrimitiveTypeKind[] approximationFunctions1ParameterTypes = { PrimitiveTypeKind.Single,
PrimitiveTypeKind.Double,
PrimitiveTypeKind.Decimal };
foreach (string functionName in approximationFunctions1)
{
foreach (PrimitiveTypeKind kind in approximationFunctions1ParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParameter(kind, "value")));
}
}
// Overloads for ROUND, TRUNCATE
string[] approximationFunctions2 = { "Round", "Truncate" };
PrimitiveTypeKind[] approximationFunctions2ParameterTypes = { PrimitiveTypeKind.Double,
PrimitiveTypeKind.Decimal };
foreach (string functionName in approximationFunctions2)
{
foreach (PrimitiveTypeKind kind in approximationFunctions2ParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParameter(kind, "value"),
CreateSecondParameter(PrimitiveTypeKind.Int32, "digits")));
}
}
// Overloads for ABS functions
PrimitiveTypeKind[] absParameterTypes = { PrimitiveTypeKind.Decimal,
PrimitiveTypeKind.Double,
PrimitiveTypeKind.Int16,
PrimitiveTypeKind.Int32,
PrimitiveTypeKind.Int64,
PrimitiveTypeKind.Byte,
PrimitiveTypeKind.Single };
foreach (PrimitiveTypeKind kind in absParameterTypes)
{
functions.Add(CreateCannonicalFunction("Abs",
CreateReturnParameter(kind),
CreateFirstParameter(kind, "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.Add(CreateCannonicalFunction("Power",
CreateReturnParameter(kind1),
CreateFirstParameter(kind1, "baseArgument"),
CreateSecondParameter(kind2, "exponent")));
}
}
#endregion // Math Functions
#region Bitwise Functions
string[] bitwiseFunctions = { "BitwiseAnd", "BitwiseOr", "BitwiseXor" };
// Overloads for BitwiseAND, BitwiseNOT, BitwiseOR, BitwiseXOR functions
PrimitiveTypeKind[] bitwiseFunctionOverloads = { PrimitiveTypeKind.Int16,
PrimitiveTypeKind.Int32,
PrimitiveTypeKind.Int64,
PrimitiveTypeKind.Byte };
foreach (string functionName in bitwiseFunctions)
{
foreach (PrimitiveTypeKind kind in bitwiseFunctionOverloads)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParameter(kind, "value1"),
CreateSecondParameter(kind, "value2")));
}
}
foreach (PrimitiveTypeKind kind in bitwiseFunctionOverloads)
{
functions.Add(CreateCannonicalFunction("BitwiseNot",
CreateReturnParameter(kind),
CreateFirstParameter(kind, "value")));
}
#endregion
#region Misc Functions
functions.Add(CreateCannonicalFunction("NewGuid",
CreateReturnParameter(PrimitiveTypeKind.Guid)));
#endregion // Misc Functions
//Set all the functions to readonly
foreach (EdmFunction function in functions)
{
function.SetReadOnly();
}
System.Collections.ObjectModel.ReadOnlyCollection readOnlyFunctions = new System.Collections.ObjectModel.ReadOnlyCollection(functions);
Interlocked.CompareExchange>(ref _functions, readOnlyFunctions, null);
}
private static EdmFunction CreateAggregateCannonicalFunction(string name, FunctionParameter returnParameter, FunctionParameter parameter)
{
Debug.Assert(name != null && returnParameter != null && parameter != null, "did you choose the wrong overload");
EdmFunction function = new EdmFunction( name,
EdmConstants.EdmNamespace,
DataSpace.CSpace,
new EdmFunctionPayload
{
IsAggregate = true,
IsBuiltIn = true,
ReturnParameter = returnParameter,
Parameters = new FunctionParameter[1] { parameter },
});
return function;
}
private static EdmFunction CreateCannonicalFunction(string name, FunctionParameter returnParameter, params FunctionParameter [] parameters)
{
Debug.Assert(name != null && returnParameter != null && parameters != null, "did you choose the wrong overload");
EdmFunction function = new EdmFunction(name,
EdmConstants.EdmNamespace,
DataSpace.CSpace,
new EdmFunctionPayload
{
IsBuiltIn = true,
ReturnParameter = returnParameter,
Parameters = parameters,
});
return function;
}
#region Edm Provider Specific Functionality
///
/// Returns the list of super-types for the given primitiveType
///
///
///
internal System.Collections.ObjectModel.ReadOnlyCollection GetPromotionTypes(PrimitiveType primitiveType)
{
InitializePromotableTypes();
return _promotionTypes[(int)primitiveType.PrimitiveTypeKind];
}
///
/// Initializes Promotion Type relation
///
private void InitializePromotableTypes()
{
if (null != _promotionTypes)
{
return;
}
System.Collections.ObjectModel.ReadOnlyCollection[] promotionTypes = new System.Collections.ObjectModel.ReadOnlyCollection[EdmConstants.NumPrimitiveTypes];
for (int i = 0; i < EdmConstants.NumPrimitiveTypes; i++)
{
promotionTypes[i] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] { _primitiveTypes[i] });
}
//
// PrimitiveTypeKind.Byte
//
promotionTypes[(int)PrimitiveTypeKind.Byte] = new System.Collections.ObjectModel.ReadOnlyCollection(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(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(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(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(new PrimitiveType[] {
_primitiveTypes[(int)PrimitiveTypeKind.Single],
_primitiveTypes[(int)PrimitiveTypeKind.Double]
});
Interlocked.CompareExchange[]>(ref _promotionTypes,
promotionTypes,
null);
}
internal TypeUsage GetCanonicalModelTypeUsage(PrimitiveTypeKind primitiveTypeKind)
{
if (null == _canonicalModelTypes)
{
InitializeCanonicalModelTypes();
}
return _canonicalModelTypes[(int)primitiveTypeKind];
}
///
/// Initializes Canonical Model Types
///
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(ref _canonicalModelTypes, canonicalTypes, null);
}
#endregion
#region DbProviderManifest Interface
///
/// Returns all the primitive types supported by the provider manifest
///
/// A collection of primitive types
public override System.Collections.ObjectModel.ReadOnlyCollection 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;
}
}
///
/// Providers should override this to return information specific to their provider.
///
/// This method should never return null.
///
/// The name of the information to be retrieved.
/// An XmlReader at the begining of the information requested.
protected override System.Xml.XmlReader GetDbInformation(string informationType)
{
throw new NotImplementedException();
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RemotingServices.cs
- HtmlContainerControl.cs
- CodeExporter.cs
- PingOptions.cs
- xml.cs
- ToolBarButton.cs
- BoundField.cs
- HttpServerUtilityBase.cs
- SourceElementsCollection.cs
- PipelineModuleStepContainer.cs
- LayoutEditorPart.cs
- SQLCharsStorage.cs
- WindowsListViewItemCheckBox.cs
- HttpModuleCollection.cs
- Page.cs
- PackagePart.cs
- M3DUtil.cs
- XPathNode.cs
- BroadcastEventHelper.cs
- RtfToken.cs
- OdbcHandle.cs
- EndEvent.cs
- ObjectConverter.cs
- SqlUserDefinedAggregateAttribute.cs
- GroupLabel.cs
- SynchronizingStream.cs
- XmlNodeList.cs
- MetabaseSettings.cs
- SafeLibraryHandle.cs
- ToolStripLocationCancelEventArgs.cs
- RootCodeDomSerializer.cs
- QuotedStringFormatReader.cs
- Dynamic.cs
- SchemaElement.cs
- SoapReflectionImporter.cs
- RayHitTestParameters.cs
- FlowLayout.cs
- SimpleFieldTemplateUserControl.cs
- VariantWrapper.cs
- DockPattern.cs
- DesigntimeLicenseContext.cs
- ListParagraph.cs
- LateBoundBitmapDecoder.cs
- ServicesExceptionNotHandledEventArgs.cs
- SubstitutionResponseElement.cs
- TemplateXamlParser.cs
- DelayedRegex.cs
- TextViewElement.cs
- AuthorizationRule.cs
- SafeUserTokenHandle.cs
- ItemCollection.cs
- BaseCollection.cs
- PartialCachingAttribute.cs
- DataGridViewCellCollection.cs
- ClientApiGenerator.cs
- OverrideMode.cs
- FastPropertyAccessor.cs
- PageRequestManager.cs
- WebContext.cs
- PrivateFontCollection.cs
- ConnectionConsumerAttribute.cs
- ListViewCancelEventArgs.cs
- TextTreeTextNode.cs
- SiteMapDataSourceView.cs
- ModelPropertyCollectionImpl.cs
- MediaEntryAttribute.cs
- StringUtil.cs
- _CacheStreams.cs
- RegexMatchCollection.cs
- SubMenuStyleCollection.cs
- RawStylusActions.cs
- CustomError.cs
- SetterTriggerConditionValueConverter.cs
- KeyValuePair.cs
- ToolStrip.cs
- HtmlElementEventArgs.cs
- ScriptingJsonSerializationSection.cs
- BinaryParser.cs
- DirectoryObjectSecurity.cs
- SqlVisitor.cs
- Triangle.cs
- AssociatedControlConverter.cs
- PrinterResolution.cs
- ApplicationServiceHelper.cs
- Overlapped.cs
- DocumentCollection.cs
- SmtpReplyReaderFactory.cs
- TrustManager.cs
- ListControl.cs
- NullReferenceException.cs
- UIElement.cs
- SynchronousChannelMergeEnumerator.cs
- CacheEntry.cs
- DataSourceCacheDurationConverter.cs
- CrossAppDomainChannel.cs
- EmptyCollection.cs
- SystemUdpStatistics.cs
- CatalogPart.cs
- ComPlusTraceRecord.cs
- Stacktrace.cs