//--------------------------------------------------------------------- // // Portions of this file copyright (c) Microsoft Corporation // and are released under the Microsoft Pulic License. See // http://archive.msdn.microsoft.com/EFSampleProvider/Project/License.aspx // or License.txt for details. // All rights reserved. // //--------------------------------------------------------------------- #if USE_ENTITY_FRAMEWORK_6 namespace System.Data.SQLite.EF6 #else namespace System.Data.SQLite.Linq #endif { using System; using System.Data; using System.Collections.Generic; using System.Diagnostics; #if USE_ENTITY_FRAMEWORK_6 using System.Data.Entity.Core.Metadata.Edm; #else using System.Data.Metadata.Edm; #endif /// /// A set of static helpers for type metadata /// static class MetadataHelpers { #region Type Helpers /// /// Cast the EdmType of the given type usage to the given TEdmType /// /// /// /// internal static TEdmType GetEdmType(TypeUsage typeUsage) where TEdmType : EdmType { return (TEdmType)typeUsage.EdmType; } /// /// Gets the TypeUsage of the elment if the given type is a collection type /// /// /// internal static TypeUsage GetElementTypeUsage(TypeUsage type) { if (MetadataHelpers.IsCollectionType(type)) { return ((CollectionType)type.EdmType).TypeUsage; } return null; } /// /// Retrieves the properties of in the EdmType underlying the input type usage, /// if that EdmType is a structured type (EntityType, RowType). /// /// /// internal static IList GetProperties(TypeUsage typeUsage) { return MetadataHelpers.GetProperties(typeUsage.EdmType); } /// /// Retrieves the properties of the given EdmType, if it is /// a structured type (EntityType, RowType). /// /// /// internal static IList GetProperties(EdmType edmType) { switch (edmType.BuiltInTypeKind) { case BuiltInTypeKind.ComplexType: return ((ComplexType)edmType).Properties; case BuiltInTypeKind.EntityType: return ((EntityType)edmType).Properties; case BuiltInTypeKind.RowType: return ((RowType)edmType).Properties; default: return new List(); } } /// /// Is the given type usage over a collection type /// /// /// internal static bool IsCollectionType(TypeUsage typeUsage) { return MetadataHelpers.IsCollectionType(typeUsage.EdmType); } /// /// Is the given type a collection type /// /// /// internal static bool IsCollectionType(EdmType type) { return (BuiltInTypeKind.CollectionType == type.BuiltInTypeKind); } /// /// Is the given type usage over a primitive type /// /// /// internal static bool IsPrimitiveType(TypeUsage type) { return MetadataHelpers.IsPrimitiveType(type.EdmType); } /// /// Is the given type a primitive type /// /// /// internal static bool IsPrimitiveType(EdmType type) { return (BuiltInTypeKind.PrimitiveType == type.BuiltInTypeKind); } /// /// Is the given type usage over a row type /// /// /// internal static bool IsRowType(TypeUsage type) { return MetadataHelpers.IsRowType(type.EdmType); } /// /// Is the given type a row type /// /// /// internal static bool IsRowType(EdmType type) { return (BuiltInTypeKind.RowType == type.BuiltInTypeKind); } /// /// Gets the type of the given type usage if it is a primitive type /// /// /// /// internal static bool TryGetPrimitiveTypeKind(TypeUsage type, out PrimitiveTypeKind typeKind) { if (type != null && type.EdmType != null && type.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType) { typeKind = ((PrimitiveType)type.EdmType).PrimitiveTypeKind; return true; } typeKind = default(PrimitiveTypeKind); return false; } internal static PrimitiveTypeKind GetPrimitiveTypeKind(TypeUsage type) { PrimitiveTypeKind returnValue; if (!MetadataHelpers.TryGetPrimitiveTypeKind(type, out returnValue)) { Debug.Assert(false, "Cannot create parameter of non-primitive type"); throw new NotSupportedException("Cannot create parameter of non-primitive type"); } return returnValue; } /// /// Gets the value for the metadata property with the given name /// /// /// /// /// internal static T TryGetValueForMetadataProperty(MetadataItem item, string propertyName) { MetadataProperty property; if (!item.MetadataProperties.TryGetValue(propertyName, true, out property)) { return default(T); } return (T)property.Value; } internal static bool IsPrimitiveType(TypeUsage type, PrimitiveTypeKind primitiveType) { PrimitiveTypeKind typeKind; if (TryGetPrimitiveTypeKind(type, out typeKind)) { return (typeKind == primitiveType); } return false; } internal static DbType GetDbType(PrimitiveTypeKind primitiveType) { switch (primitiveType) { case PrimitiveTypeKind.Binary: return DbType.Binary; case PrimitiveTypeKind.Boolean: return DbType.Boolean; case PrimitiveTypeKind.Byte: return DbType.Byte; case PrimitiveTypeKind.DateTime: return DbType.DateTime; case PrimitiveTypeKind.Decimal: return DbType.Decimal; case PrimitiveTypeKind.Double: return DbType.Double; case PrimitiveTypeKind.Single: return DbType.Single; case PrimitiveTypeKind.Guid: return DbType.Guid; case PrimitiveTypeKind.Int16: return DbType.Int16; case PrimitiveTypeKind.Int32: return DbType.Int32; case PrimitiveTypeKind.Int64: return DbType.Int64; //case PrimitiveTypeKind.Money: return DbType.Decimal; case PrimitiveTypeKind.SByte: return DbType.SByte; case PrimitiveTypeKind.String: return DbType.String; //case PrimitiveTypeKind.UInt16: return DbType.UInt16; //case PrimitiveTypeKind.UInt32: return DbType.UInt32; //case PrimitiveTypeKind.UInt64: return DbType.UInt64; //case PrimitiveTypeKind.Xml: return DbType.Xml; default: Debug.Fail("unknown PrimitiveTypeKind" + primitiveType.ToString()); throw new InvalidOperationException(string.Format("Unknown PrimitiveTypeKind {0}", primitiveType)); } } #endregion #region Facet Support internal static readonly int UnicodeStringMaxMaxLength = Int32.MaxValue; internal static readonly int AsciiStringMaxMaxLength = Int32.MaxValue; internal static readonly int BinaryMaxMaxLength = Int32.MaxValue; #region Facet Names /// /// Name of the MaxLength Facet /// public static readonly string MaxLengthFacetName = "MaxLength"; /// /// Name of the Unicode Facet /// public static readonly string UnicodeFacetName = "Unicode"; /// /// Name of the FixedLength Facet /// public static readonly string FixedLengthFacetName = "FixedLength"; /// /// Name of the PreserveSeconds Facet /// public static readonly string PreserveSecondsFacetName = "PreserveSeconds"; /// /// Name of the Precision Facet /// public static readonly string PrecisionFacetName = "Precision"; /// /// Name of the Scale Facet /// public static readonly string ScaleFacetName = "Scale"; /// /// Name of the DefaultValue Facet /// public static readonly string DefaultValueFacetName = "DefaultValue"; /// /// Name of the Nullable Facet /// internal const string NullableFacetName = "Nullable"; #endregion #region Facet Retreival Helpers /// /// Get the value specified on the given type usage for the given facet name. /// If the faces does not have a value specifid or that value is null returns /// the default value for that facet. /// /// /// /// /// /// internal static T GetFacetValueOrDefault(TypeUsage type, string facetName, T defaultValue) { //Get the value for the facet, if any Facet facet; if (type.Facets.TryGetValue(facetName, false, out facet) && facet.Value != null && !facet.IsUnbounded) { return (T)facet.Value; } else { return defaultValue; } } internal static bool IsFacetValueConstant(TypeUsage type, string facetName) { return MetadataHelpers.GetFacet(((PrimitiveType)type.EdmType).FacetDescriptions, facetName).IsConstant; } private static FacetDescription GetFacet(IEnumerable facetCollection, string facetName) { foreach (FacetDescription facetDescription in facetCollection) { if (facetDescription.FacetName == facetName) { return facetDescription; } } return null; } /// /// Given a facet name and an EdmType, tries to get that facet's description. /// /// /// /// /// internal static bool TryGetTypeFacetDescriptionByName(EdmType edmType, string facetName, out FacetDescription facetDescription) { facetDescription = null; if (MetadataHelpers.IsPrimitiveType(edmType)) { PrimitiveType primitiveType = (PrimitiveType)edmType; foreach (FacetDescription fd in primitiveType.FacetDescriptions) { if (facetName.Equals(fd.FacetName, StringComparison.OrdinalIgnoreCase)) { facetDescription = fd; return true; } } } return false; } internal static bool IsNullable(TypeUsage type) { Facet nullableFacet; if (type.Facets.TryGetValue(NullableFacetName, false, out nullableFacet)) { return (bool)nullableFacet.Value; } return false; } internal static bool TryGetMaxLength(TypeUsage type, out int maxLength) { if (!IsPrimitiveType(type, PrimitiveTypeKind.String) && !IsPrimitiveType(type, PrimitiveTypeKind.Binary)) { maxLength = 0; return false; } // Binary and String FixedLength facets share the same name return TryGetIntFacetValue(type, MaxLengthFacetName, out maxLength); } internal static bool TryGetIntFacetValue(TypeUsage type, string facetName, out int intValue) { intValue = 0; Facet intFacet; if (type.Facets.TryGetValue(facetName, false, out intFacet) && intFacet.Value != null && !intFacet.IsUnbounded) { intValue = (int)intFacet.Value; return true; } return false; } internal static bool TryGetIsFixedLength(TypeUsage type, out bool isFixedLength) { if (!IsPrimitiveType(type, PrimitiveTypeKind.String) && !IsPrimitiveType(type, PrimitiveTypeKind.Binary)) { isFixedLength = false; return false; } // Binary and String MaxLength facets share the same name return TryGetBooleanFacetValue(type, FixedLengthFacetName, out isFixedLength); } internal static bool TryGetBooleanFacetValue(TypeUsage type, string facetName, out bool boolValue) { boolValue = false; Facet boolFacet; if (type.Facets.TryGetValue(facetName, false, out boolFacet) && boolFacet.Value != null) { boolValue = (bool)boolFacet.Value; return true; } return false; } internal static bool TryGetIsUnicode(TypeUsage type, out bool isUnicode) { if (!IsPrimitiveType(type, PrimitiveTypeKind.String)) { isUnicode = false; return false; } return TryGetBooleanFacetValue(type, UnicodeFacetName, out isUnicode); } #endregion #endregion internal static bool IsCanonicalFunction(EdmFunction function) { return (function.NamespaceName == "Edm"); } internal static bool IsStoreFunction(EdmFunction function) { return !IsCanonicalFunction(function); } // Returns ParameterDirection corresponding to given ParameterMode internal static ParameterDirection ParameterModeToParameterDirection(ParameterMode mode) { switch (mode) { case ParameterMode.In: return ParameterDirection.Input; case ParameterMode.InOut: return ParameterDirection.InputOutput; case ParameterMode.Out: return ParameterDirection.Output; case ParameterMode.ReturnValue: return ParameterDirection.ReturnValue; default: Debug.Fail("unrecognized mode " + mode.ToString()); return default(ParameterDirection); } } } }