/// <summary> /// Called when an <see cref="DbExpression" /> of an otherwise unrecognized type is encountered. /// </summary> /// <param name="expression"> The expression </param> /// <exception cref="ArgumentNullException"> /// <paramref name="expression" /> /// is null /// </exception> /// <exception cref="NotSupportedException"> /// Always thrown if this method is called, since it indicates that /// <paramref name="expression" /> /// is of an unsupported type /// </exception> public override void Visit(DbExpression expression) { // #433613: PreSharp warning 56506: Parameter 'expression' to this public method must be validated: A null-dereference can occur here. Check.NotNull(expression, "expression"); throw ADP1.NotSupported(); // EntityRes.GetString(EntityRes.Cqt_General_UnsupportedExpression, expression.GetType().FullName)); }
// <summary> // Chooses the appropriate SqlDbType for the given string type. // </summary> private static SqlDbType GetStringDbType(TypeUsage type) { Debug.Assert( type.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType && PrimitiveTypeKind.String == ((PrimitiveType)type.EdmType).PrimitiveTypeKind, "only valid for string type"); SqlDbType dbType; if (type.EdmType.Name.ToUpperInvariant() == "XML") { // vamshikb: throw as SQLCE doesn't support XML datatype. throw ADP1.NotSupported(EntityRes.GetString(EntityRes.ProviderDoesNotSupportType, "XML")); } else { // Specific type depends on whether the string is a unicode string and whether it is a fixed length string. // By default, assume widest type (unicode) and most common type (variable length) bool unicode, fixedLength, isMaxLength = false; int maxLength; if (!TypeHelpers.TryGetIsFixedLength(type, out fixedLength)) { fixedLength = false; } if (!TypeHelpers.TryGetIsUnicode(type, out unicode)) { unicode = true; } if (!TypeHelpers.TryGetMaxLength(type, out maxLength)) { isMaxLength = true; } Debug.Assert(unicode, "SQLCE supports unicode strings only."); // vamshikb: SQLCE supports unicode datatypes only. // Include logic related to the unicode datatypes alone. (unicode == true) if (fixedLength) { dbType = SqlDbType.NChar; } else { dbType = isMaxLength ? SqlDbType.NText : SqlDbType.NVarChar; } } return(dbType); }
public override TypeUsage GetStoreType(TypeUsage edmType) { Check.NotNull(edmType, "edmType"); Debug.Assert(edmType.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType); var primitiveType = edmType.EdmType as PrimitiveType; if (primitiveType == null) { throw ADP1.Argument(EntityRes.GetString(EntityRes.ProviderDoesNotSupportType, edmType.EdmType)); } var facets = edmType.Facets; switch (primitiveType.PrimitiveTypeKind) { case PrimitiveTypeKind.Boolean: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["bit"])); case PrimitiveTypeKind.Byte: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["tinyint"])); case PrimitiveTypeKind.Int16: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["smallint"])); case PrimitiveTypeKind.Int32: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int"])); case PrimitiveTypeKind.Int64: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["bigint"])); case PrimitiveTypeKind.Guid: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["uniqueidentifier"])); case PrimitiveTypeKind.Double: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["float"])); case PrimitiveTypeKind.Single: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["real"])); case PrimitiveTypeKind.Decimal: // decimal, numeric, money { byte precision; if (!TypeHelpers.TryGetPrecision(edmType, out precision)) { precision = 18; } byte scale; if (!TypeHelpers.TryGetScale(edmType, out scale)) { scale = 0; } var tu = TypeUsage.CreateDecimalTypeUsage(StoreTypeNameToStorePrimitiveType["decimal"], precision, scale); return(tu); } case PrimitiveTypeKind.Binary: // binary, varbinary, image, timestamp, rowversion { var isFixedLength = null != facets[ProviderManifest.FixedLengthFacetName].Value && (bool)facets[ProviderManifest.FixedLengthFacetName].Value; var f = facets[ProviderManifest.MaxLengthFacetName]; var isMaxLength = Helper.IsUnboundedFacetValue(f) || null == f.Value || (int)f.Value > binaryMaxSize; var maxLength = !isMaxLength ? (int)f.Value : Int32.MinValue; TypeUsage tu; if (isFixedLength) { tu = TypeUsage.CreateBinaryTypeUsage( StoreTypeNameToStorePrimitiveType["binary"], true, (isMaxLength ? binaryMaxSize : maxLength)); } else { if (null == f.Value) { tu = TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["varbinary"], false, binaryMaxSize); } else if (Helper.IsUnboundedFacetValue(f) || edmType.EdmType.Name == "image") { tu = TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["image"], false); } else if ((int)f.Value > binaryMaxSize) { throw ADP1.ColumnGreaterThanMaxLengthNotSupported(edmType.EdmType.Name, binaryMaxSize); } else { tu = TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["varbinary"], false, maxLength); } } return(tu); } case PrimitiveTypeKind.String: //char, nchar, varchar, nvarchar, ntext, text, xml { var isFixedLength = null != facets[ProviderManifest.FixedLengthFacetName].Value && (bool)facets[ProviderManifest.FixedLengthFacetName].Value; var f = facets[ProviderManifest.MaxLengthFacetName]; // maxlen is true if facet value is unbounded, the value is bigger than the limited string sizes *or* the facet // value is null. this is needed since functions still have maxlength facet value as null var isMaxLength = Helper.IsUnboundedFacetValue(f) || null == f.Value || (int)f.Value > (nvarcharMaxSize); var maxLength = !isMaxLength ? (int)f.Value : Int32.MinValue; TypeUsage tu; if (isFixedLength) { tu = TypeUsage.CreateStringTypeUsage( StoreTypeNameToStorePrimitiveType["nchar"], true, true, (isMaxLength ? nvarcharMaxSize : maxLength)); } else { if (null == f.Value) { // if it is unknown, fallback to nvarchar[4000] instead of ntext since it has limited store semantics tu = TypeUsage.CreateStringTypeUsage( StoreTypeNameToStorePrimitiveType["nvarchar"], true, false, nvarcharMaxSize); } else if (Helper.IsUnboundedFacetValue(f) || edmType.EdmType.Name == "ntext") { tu = TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["ntext"], true, false); } else if ((int)f.Value > nvarcharMaxSize) { throw ADP1.ColumnGreaterThanMaxLengthNotSupported(edmType.EdmType.Name, nvarcharMaxSize); } else { tu = TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["nvarchar"], true, false, maxLength); } } return(tu); } case PrimitiveTypeKind.DateTime: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["datetime"])); default: throw ADP1.NotSupported( EntityRes.GetString( EntityRes.NoStoreTypeForEdmType, TypeHelpers.GetIdentity(edmType), primitiveType.PrimitiveTypeKind)); } }
public override TypeUsage GetEdmType(TypeUsage storeType) { Check.NotNull(storeType, "storeType"); var storeTypeName = storeType.EdmType.Name.ToLowerInvariant(); if (!base.StoreTypeNameToEdmPrimitiveType.ContainsKey(storeTypeName)) { throw ADP1.Argument(EntityRes.GetString(EntityRes.ProviderDoesNotSupportType, storeTypeName)); } var edmPrimitiveType = base.StoreTypeNameToEdmPrimitiveType[storeTypeName]; var maxLength = 0; var isFixedLen = false; var isUnbounded = true; PrimitiveTypeKind newPrimitiveTypeKind; switch (storeTypeName) { // for some types we just go with simple type usage with no facets case "tinyint": case "smallint": case "bigint": case "bit": case "uniqueidentifier": case "int": return(TypeUsage.CreateDefaultTypeUsage(edmPrimitiveType)); case "nvarchar": newPrimitiveTypeKind = PrimitiveTypeKind.String; isUnbounded = !TypeHelpers.TryGetMaxLength(storeType, out maxLength); isFixedLen = false; break; case "nchar": newPrimitiveTypeKind = PrimitiveTypeKind.String; isUnbounded = !TypeHelpers.TryGetMaxLength(storeType, out maxLength); isFixedLen = true; break; case "ntext": newPrimitiveTypeKind = PrimitiveTypeKind.String; isUnbounded = true; isFixedLen = false; break; case "binary": newPrimitiveTypeKind = PrimitiveTypeKind.Binary; isUnbounded = !TypeHelpers.TryGetMaxLength(storeType, out maxLength); isFixedLen = true; break; case "varbinary": newPrimitiveTypeKind = PrimitiveTypeKind.Binary; isUnbounded = !TypeHelpers.TryGetMaxLength(storeType, out maxLength); isFixedLen = false; break; case "image": newPrimitiveTypeKind = PrimitiveTypeKind.Binary; isUnbounded = true; isFixedLen = false; break; case "timestamp": case "rowversion": return(TypeUsage.CreateBinaryTypeUsage(edmPrimitiveType, true, 8)); case "float": case "real": return(TypeUsage.CreateDefaultTypeUsage(edmPrimitiveType)); case "decimal": case "numeric": { byte precision; byte scale; if (TypeHelpers.TryGetPrecision(storeType, out precision) && TypeHelpers.TryGetScale(storeType, out scale)) { return(TypeUsage.CreateDecimalTypeUsage(edmPrimitiveType, precision, scale)); } else { return(TypeUsage.CreateDecimalTypeUsage(edmPrimitiveType)); } } case "money": return(TypeUsage.CreateDecimalTypeUsage(edmPrimitiveType, 19, 4)); case "datetime": return(TypeUsage.CreateDateTimeTypeUsage(edmPrimitiveType, null)); default: throw ADP1.NotSupported(EntityRes.GetString(EntityRes.ProviderDoesNotSupportType, storeTypeName)); } Debug.Assert( newPrimitiveTypeKind == PrimitiveTypeKind.String || newPrimitiveTypeKind == PrimitiveTypeKind.Binary, "at this point only string and binary types should be present"); switch (newPrimitiveTypeKind) { case PrimitiveTypeKind.String: if (!isUnbounded) { return(TypeUsage.CreateStringTypeUsage(edmPrimitiveType, /*isUnicode*/ true, isFixedLen, maxLength)); } else { return(TypeUsage.CreateStringTypeUsage(edmPrimitiveType, /*isUnicode*/ true, isFixedLen)); } case PrimitiveTypeKind.Binary: if (!isUnbounded) { return(TypeUsage.CreateBinaryTypeUsage(edmPrimitiveType, isFixedLen, maxLength)); } else { return(TypeUsage.CreateBinaryTypeUsage(edmPrimitiveType, isFixedLen)); } default: throw ADP1.NotSupported(EntityRes.GetString(EntityRes.ProviderDoesNotSupportType, storeTypeName)); } }
// <summary> // Determines SqlDbType for the given primitive type. Extracts facet // information as well. // </summary> private static SqlDbType GetSqlDbType(TypeUsage type, out int?size, out byte?precision, out byte?scale) { // only supported for primitive type var primitiveTypeKind = TypeSemantics.GetPrimitiveTypeKind(type); size = default(int?); precision = default(byte?); scale = default(byte?); // CONSIDER(CMeek):: add logic for Xml here switch (primitiveTypeKind) { case PrimitiveTypeKind.Binary: // for output parameters, ensure there is space... size = GetParameterSize(type); return(GetBinaryDbType(type)); case PrimitiveTypeKind.Boolean: return(SqlDbType.Bit); case PrimitiveTypeKind.Byte: return(SqlDbType.TinyInt); case PrimitiveTypeKind.Time: throw ADP1.NotSupported(EntityRes.GetString(EntityRes.ProviderDoesNotSupportType, "Time")); case PrimitiveTypeKind.DateTimeOffset: throw ADP1.NotSupported(EntityRes.GetString(EntityRes.ProviderDoesNotSupportType, "DateTimeOffset")); case PrimitiveTypeKind.DateTime: return(SqlDbType.DateTime); case PrimitiveTypeKind.Decimal: precision = GetParameterPrecision(type, null); scale = GetScale(type); return(SqlDbType.Decimal); case PrimitiveTypeKind.Double: return(SqlDbType.Float); case PrimitiveTypeKind.Guid: return(SqlDbType.UniqueIdentifier); case PrimitiveTypeKind.Int16: return(SqlDbType.SmallInt); case PrimitiveTypeKind.Int32: return(SqlDbType.Int); case PrimitiveTypeKind.Int64: return(SqlDbType.BigInt); case PrimitiveTypeKind.SByte: return(SqlDbType.SmallInt); case PrimitiveTypeKind.Single: return(SqlDbType.Real); case PrimitiveTypeKind.String: size = GetParameterSize(type); return(GetStringDbType(type)); default: Debug.Fail("unknown PrimitiveTypeKind " + primitiveTypeKind); return(SqlDbType.Variant); } }
private DbCommand CreateCommand(DbProviderManifest providerManifest, DbCommandTree commandTree) { // DEVNOTE/CAUTION: This method could be called either from Remote or Local Provider. // Ensure that the code works well with the both provider types. // The methods called from the below code also need to be capable // of handling both provider types. // // NOTE: Remote Provider is loaded at runtime, if available. // This is done to remove hard dependency on Remote Provider and // it might not be present in all scenarios. All Remote Provider // type checks need to be done using RemoteProviderHelper class. // Check.NotNull(providerManifest, "providerManifest"); Check.NotNull(commandTree, "commandTree"); if (commandTree is DbFunctionCommandTree) { throw ADP1.NotSupported(EntityRes.GetString(EntityRes.StoredProceduresNotSupported)); } var command = _isLocalProvider ? new SqlCeMultiCommand() : (DbCommand)RemoteProviderHelper.CreateRemoteProviderType(RemoteProvider.SqlCeCommand); command.Connection = null; // don't hold on to the connection when we're going to cache this forever; List <DbParameter> parameters; CommandType commandType; var commandTexts = SqlGenerator.GenerateSql(commandTree, out parameters, out commandType, _isLocalProvider); if (_isLocalProvider) { Debug.Assert(command is SqlCeMultiCommand, "SqlCeMultiCommand expected"); // Set the multiple command texts for the command object ((SqlCeMultiCommand)command).CommandTexts = commandTexts; } else { // Set the command text for the RDP case. Debug.Assert(commandTexts.Length == 1, "BatchQueries are not supported in designer scenarios"); command.CommandText = commandTexts[0]; } command.CommandType = commandType; // Now make sure we populate the command's parameters from the CQT's parameters: // foreach (var queryParameter in commandTree.Parameters) { DbParameter parameter; const bool ignoreMaxLengthFacet = false; parameter = CreateSqlCeParameter( queryParameter.Key, queryParameter.Value, DBNull.Value, ignoreMaxLengthFacet, _isLocalProvider); command.Parameters.Add(parameter); } // Now add parameters added as part of SQL gen (note: this feature is only safe for DML SQL gen which // does not support user parameters, where there is no risk of name collision) // if (null != parameters && 0 < parameters.Count) { if (!(commandTree is DbDeleteCommandTree || commandTree is DbInsertCommandTree || commandTree is DbUpdateCommandTree)) { throw ADP1.InternalError(ADP1.InternalErrorCode.SqlGenParametersNotPermitted); } foreach (var parameter in parameters) { command.Parameters.Add(parameter); } } return(command); }