Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Metadata / Edm / Provider / EdmProviderManifest.cs / 2 / 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;
// The maximum allowed precision for decimal type in edm is 29 since clr decimal can handle upto 29 precision only
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 cononical 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();
// 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 => new FunctionParameter("arg1", parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateSecondParameter = ptk => new FunctionParameter("arg2", parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateThirdParameter = ptk => new FunctionParameter("arg3", parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateReturnParameter = ptk => new FunctionParameter(EdmConstants.ReturnType, parameterTypeUsages[(int)ptk], ParameterMode.ReturnValue);
Func CreateFirstParametersCollectionType = ptk => new FunctionParameter("arg1", 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
{
string stDevFunctioName = "StDev";
PrimitiveTypeKind[] stDevParameterTypes = { PrimitiveTypeKind.Decimal,
PrimitiveTypeKind.Double,
PrimitiveTypeKind.Int32,
PrimitiveTypeKind.Int64};
foreach (PrimitiveTypeKind kind in stDevParameterTypes)
{
EdmFunction function = CreateAggregateCannonicalFunction( stDevFunctioName,
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)));
functions.Add(CreateCannonicalFunction("RTrim",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("LTrim",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("Concat",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String),
CreateSecondParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("Length",
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(PrimitiveTypeKind.String)));
// Substring, Left, Right overloads and also for DateAdd function
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),
CreateSecondParameter(kind),
CreateThirdParameter(kind)));
}
foreach (PrimitiveTypeKind kind in subStringParameterTypes)
{
functions.Add(CreateCannonicalFunction("Left",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String),
CreateSecondParameter(kind)));
}
foreach (PrimitiveTypeKind kind in subStringParameterTypes)
{
functions.Add(CreateCannonicalFunction("Right",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String),
CreateSecondParameter(kind)));
}
functions.Add(CreateCannonicalFunction("Replace",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String),
CreateSecondParameter(PrimitiveTypeKind.String),
CreateThirdParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("IndexOf",
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(PrimitiveTypeKind.String),
CreateSecondParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("ToUpper",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("ToLower",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("Reverse",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String)));
#endregion // String Functions
#region DateTime Functions
string[] dateTimeFunctions = { "Year", "Month", "Day" };
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)));
}
}
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)));
}
}
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)));
dateFunction = CreateCannonicalFunction("CurrentUtcDateTime",
CreateReturnParameter(PrimitiveTypeKind.DateTime));
functions.Add(dateFunction);
#endregion // DateTime Functions
#region Math Functions
string[] mathFunctions = { "Round", "Floor", "Ceiling" };
// Overloads for ROUND, FLOOR, CEILING functions
PrimitiveTypeKind[] roundParameterTypes = { PrimitiveTypeKind.Single,
PrimitiveTypeKind.Double,
PrimitiveTypeKind.Decimal };
foreach (string functionName in mathFunctions)
{
foreach (PrimitiveTypeKind kind in roundParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParameter(kind)));
}
}
// 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)));
}
#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),
CreateSecondParameter(kind)));
}
}
foreach (PrimitiveTypeKind kind in bitwiseFunctionOverloads)
{
functions.Add(CreateCannonicalFunction("BitwiseNot",
CreateReturnParameter(kind),
CreateFirstParameter(kind)));
}
#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.CanonicalFunctionNamespace,
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.CanonicalFunctionNamespace,
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.Decimal
//
promotionTypes[(int)PrimitiveTypeKind.Decimal] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
_primitiveTypes[(int)PrimitiveTypeKind.Decimal]
});
//
// PrimitiveTypeKind.Single
//
promotionTypes[(int)PrimitiveTypeKind.Single] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
_primitiveTypes[(int)PrimitiveTypeKind.Double]
});
//
// PrimitiveTypeKind.DateTime
//
promotionTypes[(int)PrimitiveTypeKind.DateTime] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
_primitiveTypes[(int)PrimitiveTypeKind.DateTime]
});
//
// PrimitiveTypeKind.Time
//
promotionTypes[(int)PrimitiveTypeKind.Time] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
_primitiveTypes[(int)PrimitiveTypeKind.Time]
});
//
// PrimitiveTypeKind.DateTimeOffset
//
promotionTypes[(int)PrimitiveTypeKind.DateTimeOffset] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
_primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset]
});
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()
{
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;
// The maximum allowed precision for decimal type in edm is 29 since clr decimal can handle upto 29 precision only
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 cononical 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();
// 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 => new FunctionParameter("arg1", parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateSecondParameter = ptk => new FunctionParameter("arg2", parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateThirdParameter = ptk => new FunctionParameter("arg3", parameterTypeUsages[(int)ptk], ParameterMode.In);
Func CreateReturnParameter = ptk => new FunctionParameter(EdmConstants.ReturnType, parameterTypeUsages[(int)ptk], ParameterMode.ReturnValue);
Func CreateFirstParametersCollectionType = ptk => new FunctionParameter("arg1", 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
{
string stDevFunctioName = "StDev";
PrimitiveTypeKind[] stDevParameterTypes = { PrimitiveTypeKind.Decimal,
PrimitiveTypeKind.Double,
PrimitiveTypeKind.Int32,
PrimitiveTypeKind.Int64};
foreach (PrimitiveTypeKind kind in stDevParameterTypes)
{
EdmFunction function = CreateAggregateCannonicalFunction( stDevFunctioName,
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)));
functions.Add(CreateCannonicalFunction("RTrim",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("LTrim",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("Concat",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String),
CreateSecondParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("Length",
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(PrimitiveTypeKind.String)));
// Substring, Left, Right overloads and also for DateAdd function
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),
CreateSecondParameter(kind),
CreateThirdParameter(kind)));
}
foreach (PrimitiveTypeKind kind in subStringParameterTypes)
{
functions.Add(CreateCannonicalFunction("Left",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String),
CreateSecondParameter(kind)));
}
foreach (PrimitiveTypeKind kind in subStringParameterTypes)
{
functions.Add(CreateCannonicalFunction("Right",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String),
CreateSecondParameter(kind)));
}
functions.Add(CreateCannonicalFunction("Replace",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String),
CreateSecondParameter(PrimitiveTypeKind.String),
CreateThirdParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("IndexOf",
CreateReturnParameter(PrimitiveTypeKind.Int32),
CreateFirstParameter(PrimitiveTypeKind.String),
CreateSecondParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("ToUpper",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("ToLower",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String)));
functions.Add(CreateCannonicalFunction("Reverse",
CreateReturnParameter(PrimitiveTypeKind.String),
CreateFirstParameter(PrimitiveTypeKind.String)));
#endregion // String Functions
#region DateTime Functions
string[] dateTimeFunctions = { "Year", "Month", "Day" };
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)));
}
}
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)));
}
}
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)));
dateFunction = CreateCannonicalFunction("CurrentUtcDateTime",
CreateReturnParameter(PrimitiveTypeKind.DateTime));
functions.Add(dateFunction);
#endregion // DateTime Functions
#region Math Functions
string[] mathFunctions = { "Round", "Floor", "Ceiling" };
// Overloads for ROUND, FLOOR, CEILING functions
PrimitiveTypeKind[] roundParameterTypes = { PrimitiveTypeKind.Single,
PrimitiveTypeKind.Double,
PrimitiveTypeKind.Decimal };
foreach (string functionName in mathFunctions)
{
foreach (PrimitiveTypeKind kind in roundParameterTypes)
{
functions.Add(CreateCannonicalFunction(functionName,
CreateReturnParameter(kind),
CreateFirstParameter(kind)));
}
}
// 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)));
}
#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),
CreateSecondParameter(kind)));
}
}
foreach (PrimitiveTypeKind kind in bitwiseFunctionOverloads)
{
functions.Add(CreateCannonicalFunction("BitwiseNot",
CreateReturnParameter(kind),
CreateFirstParameter(kind)));
}
#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.CanonicalFunctionNamespace,
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.CanonicalFunctionNamespace,
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.Decimal
//
promotionTypes[(int)PrimitiveTypeKind.Decimal] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
_primitiveTypes[(int)PrimitiveTypeKind.Decimal]
});
//
// PrimitiveTypeKind.Single
//
promotionTypes[(int)PrimitiveTypeKind.Single] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
_primitiveTypes[(int)PrimitiveTypeKind.Double]
});
//
// PrimitiveTypeKind.DateTime
//
promotionTypes[(int)PrimitiveTypeKind.DateTime] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
_primitiveTypes[(int)PrimitiveTypeKind.DateTime]
});
//
// PrimitiveTypeKind.Time
//
promotionTypes[(int)PrimitiveTypeKind.Time] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
_primitiveTypes[(int)PrimitiveTypeKind.Time]
});
//
// PrimitiveTypeKind.DateTimeOffset
//
promotionTypes[(int)PrimitiveTypeKind.DateTimeOffset] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
_primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset]
});
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()
{
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
- PropertyFilterAttribute.cs
- ComplexTypeEmitter.cs
- XamlSerializerUtil.cs
- MetadataSource.cs
- ToolStripDropDown.cs
- DbConnectionFactory.cs
- CopyAction.cs
- XmlUnspecifiedAttribute.cs
- VoiceObjectToken.cs
- CheckBoxFlatAdapter.cs
- LayoutSettings.cs
- SimpleBitVector32.cs
- GridViewRowCollection.cs
- Exception.cs
- RawStylusInputCustomDataList.cs
- CompiledQueryCacheKey.cs
- BuiltInExpr.cs
- SpoolingTask.cs
- SqlConnectionHelper.cs
- CellConstant.cs
- EntityClassGenerator.cs
- FormsAuthenticationCredentials.cs
- LicenseProviderAttribute.cs
- securestring.cs
- DescendantQuery.cs
- RowToParametersTransformer.cs
- SoapReflectionImporter.cs
- ConfigurationElementProperty.cs
- InvalidPropValue.cs
- Control.cs
- LinqDataSourceEditData.cs
- SignedPkcs7.cs
- TextSelection.cs
- BatchWriter.cs
- CodeTypeReferenceExpression.cs
- DetailsViewPageEventArgs.cs
- PropertyIDSet.cs
- RepeaterItemCollection.cs
- Compress.cs
- ControlPaint.cs
- Ipv6Element.cs
- BaseInfoTable.cs
- XMLSyntaxException.cs
- FillBehavior.cs
- IpcServerChannel.cs
- TemplateParser.cs
- DataBoundControlDesigner.cs
- WorkerRequest.cs
- Config.cs
- HandleTable.cs
- StrokeFIndices.cs
- AccessDataSource.cs
- ThaiBuddhistCalendar.cs
- RemoteEndpointMessageProperty.cs
- ErrorFormatter.cs
- TakeOrSkipQueryOperator.cs
- WebHeaderCollection.cs
- QueryContinueDragEvent.cs
- GetImportedCardRequest.cs
- ObjectItemAttributeAssemblyLoader.cs
- DesignerTextBoxAdapter.cs
- StructuralObject.cs
- RegexCapture.cs
- CultureInfo.cs
- XmlWrappingReader.cs
- CopyAttributesAction.cs
- X509ClientCertificateAuthentication.cs
- TreeNodeBinding.cs
- XPathParser.cs
- ViewManager.cs
- ToolStripOverflowButton.cs
- ToolStripActionList.cs
- GenericAuthenticationEventArgs.cs
- MouseGestureConverter.cs
- WebPartVerbsEventArgs.cs
- SqlNotificationRequest.cs
- RegularExpressionValidator.cs
- ToolStripComboBox.cs
- Transform.cs
- UpdatePanelTrigger.cs
- SpellerInterop.cs
- PointAnimationClockResource.cs
- sqlpipe.cs
- SqlProcedureAttribute.cs
- TreeViewTemplateSelector.cs
- CodeDirectiveCollection.cs
- SynchronizationContext.cs
- PolyLineSegment.cs
- Repeater.cs
- CircleEase.cs
- CompatibleComparer.cs
- DeflateEmulationStream.cs
- ClientScriptManager.cs
- Image.cs
- GcSettings.cs
- SQLDateTime.cs
- ClosableStream.cs
- ListBindingHelper.cs
- PermissionRequestEvidence.cs
- SqlWebEventProvider.cs