public static void DeleteMetaInfo(int objId, MetaType type) { SQLDataAccess.ExecuteNonQuery("DELETE FROM [SEO].[MetaInfo] WHERE ObjId=@objId and Type=@type", CommandType.Text, new SqlParameter("@objId", objId), new SqlParameter("@type", type.ToString())); }
// For MAX types, this method can only write everything in one big chunk. If multiple // chunk writes needed, please use WritePlpBytes/WritePlpChars private Task WriteUnterminatedValue(object value, MetaType type, byte scale, int actualLength, int encodingByteSize, int offset, TdsParserStateObject stateObj, int paramSize, bool isDataFeed) { Debug.Assert((null != value) && (DBNull.Value != value), "unexpected missing or empty object"); // parameters are always sent over as BIG or N types switch (type.NullableType) { case TdsEnums.SQLFLTN: if (type.FixedLength == 4) WriteFloat((Single)value, stateObj); else { Debug.Assert(type.FixedLength == 8, "Invalid length for SqlDouble type!"); WriteDouble((Double)value, stateObj); } break; case TdsEnums.SQLBIGBINARY: case TdsEnums.SQLBIGVARBINARY: case TdsEnums.SQLIMAGE: case TdsEnums.SQLUDT: { // An array should be in the object Debug.Assert(isDataFeed || value is byte[], "Value should be an array of bytes"); Debug.Assert(!isDataFeed || value is StreamDataFeed, "Value should be a stream"); if (isDataFeed) { Debug.Assert(type.IsPlp, "Stream assigned to non-PLP was not converted!"); return NullIfCompletedWriteTask(WriteStreamFeed((StreamDataFeed)value, stateObj, paramSize)); } else { if (type.IsPlp) { WriteInt(actualLength, stateObj); // chunk length } return stateObj.WriteByteArray((byte[])value, actualLength, offset, canAccumulate: false); } } case TdsEnums.SQLUNIQUEID: { System.Guid guid = (System.Guid)value; byte[] b = guid.ToByteArray(); Debug.Assert((actualLength == b.Length) && (actualLength == 16), "Invalid length for guid type in com+ object"); stateObj.WriteByteArray(b, actualLength, 0); break; } case TdsEnums.SQLBITN: { Debug.Assert(type.FixedLength == 1, "Invalid length for SqlBoolean type"); if ((bool)value == true) stateObj.WriteByte(1); else stateObj.WriteByte(0); break; } case TdsEnums.SQLINTN: if (type.FixedLength == 1) stateObj.WriteByte((byte)value); else if (type.FixedLength == 2) WriteShort((Int16)value, stateObj); else if (type.FixedLength == 4) WriteInt((Int32)value, stateObj); else { Debug.Assert(type.FixedLength == 8, "invalid length for SqlIntN type: " + type.FixedLength.ToString(CultureInfo.InvariantCulture)); WriteLong((Int64)value, stateObj); } break; case TdsEnums.SQLBIGCHAR: case TdsEnums.SQLBIGVARCHAR: case TdsEnums.SQLTEXT: { Debug.Assert(!isDataFeed || (value is TextDataFeed || value is XmlDataFeed), "Value must be a TextReader or XmlReader"); Debug.Assert(isDataFeed || (value is string || value is byte[]), "Value is a byte array or string"); if (isDataFeed) { Debug.Assert(type.IsPlp, "Stream assigned to non-PLP was not converted!"); TextDataFeed tdf = value as TextDataFeed; if (tdf == null) { return NullIfCompletedWriteTask(WriteXmlFeed((XmlDataFeed)value, stateObj, needBom: true, encoding: _defaultEncoding, size: paramSize)); } else { return NullIfCompletedWriteTask(WriteTextFeed(tdf, _defaultEncoding, false, stateObj, paramSize)); } } else { if (type.IsPlp) { WriteInt(encodingByteSize, stateObj); // chunk length } if (value is byte[]) { // If LazyMat non-filled blob, send cookie rather than value return stateObj.WriteByteArray((byte[])value, actualLength, 0, canAccumulate: false); } else { return WriteEncodingChar((string)value, actualLength, offset, _defaultEncoding, stateObj, canAccumulate: false); } } } case TdsEnums.SQLNCHAR: case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: case TdsEnums.SQLXMLTYPE: { Debug.Assert(!isDataFeed || (value is TextDataFeed || value is XmlDataFeed), "Value must be a TextReader or XmlReader"); Debug.Assert(isDataFeed || (value is string || value is byte[]), "Value is a byte array or string"); if (isDataFeed) { Debug.Assert(type.IsPlp, "Stream assigned to non-PLP was not converted!"); TextDataFeed tdf = value as TextDataFeed; if (tdf == null) { return NullIfCompletedWriteTask(WriteXmlFeed((XmlDataFeed)value, stateObj, IsBOMNeeded(type, value), Encoding.Unicode, paramSize)); } else { return NullIfCompletedWriteTask(WriteTextFeed(tdf, null, IsBOMNeeded(type, value), stateObj, paramSize)); } } else { if (type.IsPlp) { if (IsBOMNeeded(type, value)) { WriteInt(actualLength + 2, stateObj); // chunk length WriteShort(TdsEnums.XMLUNICODEBOM, stateObj); } else { WriteInt(actualLength, stateObj); // chunk length } } if (value is byte[]) { // If LazyMat non-filled blob, send cookie rather than value return stateObj.WriteByteArray((byte[])value, actualLength, 0, canAccumulate: false); } else { // convert to cchars instead of cbytes actualLength >>= 1; return WriteString((string)value, actualLength, offset, stateObj, canAccumulate: false); } } } case TdsEnums.SQLNUMERICN: Debug.Assert(type.FixedLength <= 17, "Decimal length cannot be greater than 17 bytes"); WriteDecimal((Decimal)value, stateObj); break; case TdsEnums.SQLDATETIMN: Debug.Assert(type.FixedLength <= 0xff, "Invalid Fixed Length"); TdsDateTime dt = MetaType.FromDateTime((DateTime)value, (byte)type.FixedLength); if (type.FixedLength == 4) { if (0 > dt.days || dt.days > UInt16.MaxValue) throw SQL.SmallDateTimeOverflow(MetaType.ToDateTime(dt.days, dt.time, 4).ToString(CultureInfo.InvariantCulture)); WriteShort(dt.days, stateObj); WriteShort(dt.time, stateObj); } else { WriteInt(dt.days, stateObj); WriteInt(dt.time, stateObj); } break; case TdsEnums.SQLMONEYN: { WriteCurrency((Decimal)value, type.FixedLength, stateObj); break; } case TdsEnums.SQLDATE: { WriteDate((DateTime)value, stateObj); break; } case TdsEnums.SQLTIME: if (scale > TdsEnums.DEFAULT_VARTIME_SCALE) { throw SQL.TimeScaleValueOutOfRange(scale); } WriteTime((TimeSpan)value, scale, actualLength, stateObj); break; case TdsEnums.SQLDATETIME2: if (scale > TdsEnums.DEFAULT_VARTIME_SCALE) { throw SQL.TimeScaleValueOutOfRange(scale); } WriteDateTime2((DateTime)value, scale, actualLength, stateObj); break; case TdsEnums.SQLDATETIMEOFFSET: WriteDateTimeOffset((DateTimeOffset)value, scale, actualLength, stateObj); break; default: Debug.Assert(false, "Unknown TdsType!" + type.NullableType.ToString("x2", (IFormatProvider)null)); break; } // switch // return point for accumualated writes, note: non-accumulated writes returned from their case statements return null; // Debug.WriteLine("value: " + value.ToString(CultureInfo.InvariantCulture)); }
// For MAX types, this method can only write everything in one big chunk. If multiple // chunk writes needed, please use WritePlpBytes/WritePlpChars private Task WriteUnterminatedSqlValue(object value, MetaType type, int actualLength, int codePageByteSize, int offset, TdsParserStateObject stateObj) { Debug.Assert(((type.NullableType == TdsEnums.SQLXMLTYPE) || (value is INullable && !((INullable)value).IsNull)), "unexpected null SqlType!"); // parameters are always sent over as BIG or N types switch (type.NullableType) { case TdsEnums.SQLFLTN: if (type.FixedLength == 4) WriteFloat(((SqlSingle)value).Value, stateObj); else { Debug.Assert(type.FixedLength == 8, "Invalid length for SqlDouble type!"); WriteDouble(((SqlDouble)value).Value, stateObj); } break; case TdsEnums.SQLBIGBINARY: case TdsEnums.SQLBIGVARBINARY: case TdsEnums.SQLIMAGE: { if (type.IsPlp) { WriteInt(actualLength, stateObj); // chunk length } if (value is SqlBinary) { return stateObj.WriteByteArray(((SqlBinary)value).Value, actualLength, offset, canAccumulate: false); } else { Debug.Assert(value is SqlBytes); return stateObj.WriteByteArray(((SqlBytes)value).Value, actualLength, offset, canAccumulate: false); } } case TdsEnums.SQLUNIQUEID: { byte[] b = ((SqlGuid)value).ToByteArray(); Debug.Assert((actualLength == b.Length) && (actualLength == 16), "Invalid length for guid type in com+ object"); stateObj.WriteByteArray(b, actualLength, 0); break; } case TdsEnums.SQLBITN: { Debug.Assert(type.FixedLength == 1, "Invalid length for SqlBoolean type"); if (((SqlBoolean)value).Value == true) stateObj.WriteByte(1); else stateObj.WriteByte(0); break; } case TdsEnums.SQLINTN: if (type.FixedLength == 1) stateObj.WriteByte(((SqlByte)value).Value); else if (type.FixedLength == 2) WriteShort(((SqlInt16)value).Value, stateObj); else if (type.FixedLength == 4) WriteInt(((SqlInt32)value).Value, stateObj); else { Debug.Assert(type.FixedLength == 8, "invalid length for SqlIntN type: " + type.FixedLength.ToString(CultureInfo.InvariantCulture)); WriteLong(((SqlInt64)value).Value, stateObj); } break; case TdsEnums.SQLBIGCHAR: case TdsEnums.SQLBIGVARCHAR: case TdsEnums.SQLTEXT: if (type.IsPlp) { WriteInt(codePageByteSize, stateObj); // chunk length } if (value is SqlChars) { String sch = new String(((SqlChars)value).Value); return WriteEncodingChar(sch, actualLength, offset, _defaultEncoding, stateObj, canAccumulate: false); } else { Debug.Assert(value is SqlString); return WriteEncodingChar(((SqlString)value).Value, actualLength, offset, _defaultEncoding, stateObj, canAccumulate: false); } case TdsEnums.SQLNCHAR: case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: case TdsEnums.SQLXMLTYPE: if (type.IsPlp) { if (IsBOMNeeded(type, value)) { WriteInt(actualLength + 2, stateObj); // chunk length WriteShort(TdsEnums.XMLUNICODEBOM, stateObj); } else { WriteInt(actualLength, stateObj); // chunk length } } // convert to cchars instead of cbytes // Xml type is already converted to string through GetCoercedValue if (actualLength != 0) actualLength >>= 1; if (value is SqlChars) { return WriteCharArray(((SqlChars)value).Value, actualLength, offset, stateObj, canAccumulate: false); } else { Debug.Assert(value is SqlString); return WriteString(((SqlString)value).Value, actualLength, offset, stateObj, canAccumulate: false); } case TdsEnums.SQLNUMERICN: Debug.Assert(type.FixedLength <= 17, "Decimal length cannot be greater than 17 bytes"); WriteSqlDecimal((SqlDecimal)value, stateObj); break; case TdsEnums.SQLDATETIMN: SqlDateTime dt = (SqlDateTime)value; if (type.FixedLength == 4) { if (0 > dt.DayTicks || dt.DayTicks > UInt16.MaxValue) throw SQL.SmallDateTimeOverflow(dt.ToString()); WriteShort(dt.DayTicks, stateObj); WriteShort(dt.TimeTicks / SqlDateTime.SQLTicksPerMinute, stateObj); } else { WriteInt(dt.DayTicks, stateObj); WriteInt(dt.TimeTicks, stateObj); } break; case TdsEnums.SQLMONEYN: { WriteSqlMoney((SqlMoney)value, type.FixedLength, stateObj); break; } case TdsEnums.SQLUDT: throw ADP.DbTypeNotSupported(SqlDbType.Udt.ToString()); default: Debug.Assert(false, "Unknown TdsType!" + type.NullableType.ToString("x2", (IFormatProvider)null)); break; } // switch // return point for accumualated writes, note: non-accumulated writes returned from their case statements return null; }
private Task GetTerminationTask(Task unterminatedWriteTask, object value, MetaType type, int actualLength, TdsParserStateObject stateObj, bool isDataFeed) { if (type.IsPlp && ((actualLength > 0) || isDataFeed)) { if (unterminatedWriteTask == null) { WriteInt(0, stateObj); return null; } else { return AsyncHelper.CreateContinuationTask<int, TdsParserStateObject>(unterminatedWriteTask, WriteInt, 0, stateObj, connectionToDoom: _connHandler); } } else { return unterminatedWriteTask; } }
private bool IsNull(MetaType mt, ulong length) { // null bin and char types have a length of -1 to represent null if (mt.IsPlp) { return (TdsEnums.SQL_PLP_NULL == length); } // HOTFIX #50000415: for image/text, 0xFFFF is the length, not representing null if ((TdsEnums.VARNULL == length) && !mt.IsLong) { return true; } // other types have a length of 0 to represent null // long and non-PLP types will always return false because these types are either char or binary // this is expected since for long and non-plp types isnull is checked based on textptr field and not the length return ((TdsEnums.FIXEDNULL == length) && !mt.IsCharType && !mt.IsBinType); }
internal static Exception BulkLoadCannotConvertValue(Type sourcetype, MetaType metatype, Exception e) { return ADP.InvalidOperation(Res.GetString("SQL_BulkLoadCannotConvertValue", new object[] { sourcetype.Name, metatype.TypeName }), e); }
internal static MetaType GetMaxMetaTypeFromMetaType(MetaType mt) { System.Data.SqlDbType sqlDbType = mt.SqlDbType; if (sqlDbType <= System.Data.SqlDbType.NVarChar) { switch (sqlDbType) { case System.Data.SqlDbType.Binary: goto Label_004F; case System.Data.SqlDbType.Bit: return mt; case System.Data.SqlDbType.Char: goto Label_0055; case System.Data.SqlDbType.NChar: case System.Data.SqlDbType.NVarChar: return MetaMaxNVarChar; case System.Data.SqlDbType.NText: return mt; } return mt; } switch (sqlDbType) { case System.Data.SqlDbType.VarBinary: break; case System.Data.SqlDbType.VarChar: goto Label_0055; case System.Data.SqlDbType.Udt: return MetaMaxUdt; default: return mt; } Label_004F: return MetaMaxVarBinary; Label_0055: return MetaMaxVarChar; }
public void ResetSqlDbType() { if (null != _metaType) { PropertyTypeChanging(); _metaType = null; } }
// func will change type to that with a 4 byte length if the type has a two // byte length and a parameter length > than that expressable in 2 bytes internal MetaType ValidateTypeLengths(bool yukonOrNewer) { MetaType mt = InternalMetaType; // MDAC if ((SqlDbType.Udt != mt.SqlDbType) && (false == mt.IsFixed) && (false == mt.IsLong)) { // if type has 2 byte length long actualSizeInBytes = this.GetActualSize(); long sizeInCharacters = this.Size; // long maxSizeInBytes = 0; if ((mt.IsNCharType) && (yukonOrNewer)) maxSizeInBytes = ((sizeInCharacters * sizeof(char)) > actualSizeInBytes) ? sizeInCharacters * sizeof(char) : actualSizeInBytes; else { // Notes: // Elevation from (n)(var)char (4001+) to (n)text succeeds without failure only with Yukon and greater. // it fails in sql server 2000 maxSizeInBytes = (sizeInCharacters > actualSizeInBytes) ? sizeInCharacters : actualSizeInBytes; } if ((maxSizeInBytes > TdsEnums.TYPE_SIZE_LIMIT) || (_coercedValueIsDataFeed) || (sizeInCharacters == -1) || (actualSizeInBytes == -1)) { // is size > size able to be described by 2 bytes if (yukonOrNewer) { // Convert the parameter to its max type mt = MetaType.GetMaxMetaTypeFromMetaType(mt); _metaType = mt; InternalMetaType = mt; if (!mt.IsPlp) { if (mt.SqlDbType == SqlDbType.Xml) { throw ADP.InvalidMetaDataValue(); //Xml should always have IsPartialLength = true } if (mt.SqlDbType == SqlDbType.NVarChar || mt.SqlDbType == SqlDbType.VarChar || mt.SqlDbType == SqlDbType.VarBinary) { Size = (int)(SmiMetaData.UnlimitedMaxLengthIndicator); } } } else { switch (mt.SqlDbType) { // widening the SqlDbType is automatic case SqlDbType.Binary: case SqlDbType.VarBinary: mt = MetaType.GetMetaTypeFromSqlDbType (SqlDbType.Image, false); _metaType = mt; // do not use SqlDbType property which calls PropertyTypeChanging resetting coerced value InternalMetaType = mt; break; case SqlDbType.Char: case SqlDbType.VarChar: mt = MetaType.GetMetaTypeFromSqlDbType (SqlDbType.Text, false); _metaType = mt; InternalMetaType = mt; break; case SqlDbType.NChar: case SqlDbType.NVarChar: mt = MetaType.GetMetaTypeFromSqlDbType (SqlDbType.NText, false); _metaType = mt; InternalMetaType = mt; break; default: Debug.Assert(false, "Missed metatype in SqlCommand.BuildParamList()"); break; } } } } return mt; }
internal static MetaType GetMaxMetaTypeFromMetaType(MetaType mt) { // if we can't map it, we need to throw switch (mt.SqlDbType) { case SqlDbType.VarBinary: case SqlDbType.Binary: return MetaMaxVarBinary; case SqlDbType.VarChar: case SqlDbType.Char: return MetaMaxVarChar; case SqlDbType.NVarChar: case SqlDbType.NChar: return MetaMaxNVarChar; case SqlDbType.Udt: Debug.Assert(false, "UDT is not supported"); return mt; default: return mt; } }
internal MetaType ValidateTypeLengths(bool yukonOrNewer) { MetaType internalMetaType = this.InternalMetaType; if (((System.Data.SqlDbType.Udt != internalMetaType.SqlDbType) && !internalMetaType.IsFixed) && !internalMetaType.IsLong) { long actualSize = this.GetActualSize(); long size = this.Size; long num3 = 0L; if (internalMetaType.IsNCharType && yukonOrNewer) { num3 = ((size * 2L) > actualSize) ? (size * 2L) : actualSize; } else { num3 = (size > actualSize) ? size : actualSize; } if (((num3 <= 0x1f40L) && (size != -1L)) && (actualSize != -1L)) { return internalMetaType; } if (yukonOrNewer) { internalMetaType = MetaType.GetMaxMetaTypeFromMetaType(internalMetaType); this._metaType = internalMetaType; this.InternalMetaType = internalMetaType; if (!internalMetaType.IsPlp) { if (internalMetaType.SqlDbType == System.Data.SqlDbType.Xml) { throw ADP.InvalidMetaDataValue(); } if (((internalMetaType.SqlDbType != System.Data.SqlDbType.NVarChar) && (internalMetaType.SqlDbType != System.Data.SqlDbType.VarChar)) && (internalMetaType.SqlDbType != System.Data.SqlDbType.VarBinary)) { return internalMetaType; } this.Size = -1; } return internalMetaType; } switch (internalMetaType.SqlDbType) { case System.Data.SqlDbType.Binary: case System.Data.SqlDbType.VarBinary: internalMetaType = MetaType.GetMetaTypeFromSqlDbType(System.Data.SqlDbType.Image, false); this._metaType = internalMetaType; this.InternalMetaType = internalMetaType; return internalMetaType; case System.Data.SqlDbType.Bit: return internalMetaType; case System.Data.SqlDbType.Char: case System.Data.SqlDbType.VarChar: internalMetaType = MetaType.GetMetaTypeFromSqlDbType(System.Data.SqlDbType.Text, false); this._metaType = internalMetaType; this.InternalMetaType = internalMetaType; return internalMetaType; case System.Data.SqlDbType.NChar: case System.Data.SqlDbType.NVarChar: internalMetaType = MetaType.GetMetaTypeFromSqlDbType(System.Data.SqlDbType.NText, false); this._metaType = internalMetaType; this.InternalMetaType = internalMetaType; return internalMetaType; case System.Data.SqlDbType.NText: return internalMetaType; } } return internalMetaType; }
internal void Validate(int index, bool isCommandProc) { MetaType metaTypeOnly = this.GetMetaTypeOnly(); this._internalMetaType = metaTypeOnly; if ((((ADP.IsDirection(this, ParameterDirection.Output) && !ADP.IsDirection(this, ParameterDirection.ReturnValue)) && (!metaTypeOnly.IsFixed && !this.ShouldSerializeSize())) && ((this._value == null) || Convert.IsDBNull(this._value))) && (((this.SqlDbType != System.Data.SqlDbType.Timestamp) && (this.SqlDbType != System.Data.SqlDbType.Udt)) && ((this.SqlDbType != System.Data.SqlDbType.Xml) && !metaTypeOnly.IsVarTime))) { throw ADP.UninitializedParameterSize(index, metaTypeOnly.ClassType); } if ((metaTypeOnly.SqlDbType != System.Data.SqlDbType.Udt) && (this.Direction != ParameterDirection.Output)) { this.GetCoercedValue(); } if (metaTypeOnly.SqlDbType == System.Data.SqlDbType.Udt) { if (ADP.IsEmpty(this.UdtTypeName)) { throw SQL.MustSetUdtTypeNameForUdtParams(); } } else if (!ADP.IsEmpty(this.UdtTypeName)) { throw SQL.UnexpectedUdtTypeNameForNonUdtParams(); } if (metaTypeOnly.SqlDbType == System.Data.SqlDbType.Structured) { if (!isCommandProc && ADP.IsEmpty(this.TypeName)) { throw SQL.MustSetTypeNameForParam(metaTypeOnly.TypeName, this.ParameterName); } if (ParameterDirection.Input != this.Direction) { throw SQL.UnsupportedTVPOutputParameter(this.Direction, this.ParameterName); } if (DBNull.Value == this.GetCoercedValue()) { throw SQL.DBNullNotSupportedForTVPValues(this.ParameterName); } } else if (!ADP.IsEmpty(this.TypeName)) { throw SQL.UnexpectedTypeNameForNonStructParams(this.ParameterName); } }
public void ResetSqlDbType() { if (this._metaType != null) { this.PropertyTypeChanging(); this._metaType = null; } }
internal static object CoerceValue(object value, MetaType destinationType) { if ((value != null) && (DBNull.Value != value)) { Type c = value.GetType(); bool flag = true; if ((value is INullable) && ((INullable) value).IsNull) { flag = false; } if (!flag || !(typeof(object) != destinationType.ClassType)) { return value; } if (((c == destinationType.ClassType) || (c == destinationType.SqlType)) && (System.Data.SqlDbType.Xml != destinationType.SqlDbType)) { return value; } try { if (typeof(string) == destinationType.ClassType) { if (typeof(SqlXml) == c) { value = MetaType.GetStringFromXml(((SqlXml) value).CreateReader()); return value; } if (typeof(SqlString) != c) { if (typeof(XmlReader).IsAssignableFrom(c)) { value = MetaType.GetStringFromXml((XmlReader) value); return value; } if (typeof(char[]) == c) { value = new string((char[]) value); return value; } if (typeof(SqlChars) == c) { SqlChars chars = (SqlChars) value; value = new string(chars.Value); return value; } value = Convert.ChangeType(value, destinationType.ClassType, null); } return value; } if ((System.Data.DbType.Currency == destinationType.DbType) && (typeof(string) == c)) { value = decimal.Parse((string) value, NumberStyles.Currency, null); return value; } if ((typeof(SqlBytes) == c) && (typeof(byte[]) == destinationType.ClassType)) { SqlBytes bytes1 = (SqlBytes) value; return value; } if ((typeof(string) == c) && (System.Data.SqlDbType.Time == destinationType.SqlDbType)) { value = TimeSpan.Parse((string) value); return value; } if ((typeof(string) == c) && (System.Data.SqlDbType.DateTimeOffset == destinationType.SqlDbType)) { value = DateTimeOffset.Parse((string) value, null); return value; } if ((typeof(DateTime) == c) && (System.Data.SqlDbType.DateTimeOffset == destinationType.SqlDbType)) { value = new DateTimeOffset((DateTime) value); return value; } if ((0xf3 == destinationType.TDSType) && (((value is DataTable) || (value is DbDataReader)) || (value is IEnumerable<SqlDataRecord>))) { return value; } value = Convert.ChangeType(value, destinationType.ClassType, null); } catch (Exception exception) { if (!ADP.IsCatchableExceptionType(exception)) { throw; } throw ADP.ParameterConversionFailed(value, destinationType.ClassType, exception); } } return value; }
internal static Exception BulkLoadCannotConvertValue(Type sourcetype, MetaType metatype, Exception e) { return(ADP.InvalidOperation(SR.GetString(SR.SQL_BulkLoadCannotConvertValue, sourcetype.Name, metatype.TypeName), e)); }
/// <summary> /// Get SMI Metadata to write out type_info stream. /// </summary> /// <returns></returns> internal MSS.SmiParameterMetaData GetMetadataForTypeInfo() { ParameterPeekAheadValue peekAhead = null; if (_internalMetaType == null) { _internalMetaType = GetMetaTypeOnly(); } return MetaDataForSmi(out peekAhead); }
// func will change type to that with a 4 byte length if the type has a two // byte length and a parameter length > than that expressable in 2 bytes internal MetaType ValidateTypeLengths() { MetaType mt = InternalMetaType; // Since the server will automatically reject any // char, varchar, binary, varbinary, nchar, or nvarchar parameter that has a // byte sizeInCharacters > 8000 bytes, we promote the parameter to image, text, or ntext. This // allows the user to specify a parameter type using a COM+ datatype and be able to // use that parameter against a BLOB column. if ((SqlDbType.Udt != mt.SqlDbType) && (false == mt.IsFixed) && (false == mt.IsLong)) { // if type has 2 byte length long actualSizeInBytes = this.GetActualSize(); long sizeInCharacters = this.Size; // 'actualSizeInBytes' is the size of value passed; // 'sizeInCharacters' is the parameter size; // 'actualSizeInBytes' is in bytes; // 'this.Size' is in charaters; // 'sizeInCharacters' is in characters; // 'TdsEnums.TYPE_SIZE_LIMIT' is in bytes; // For Non-NCharType and for non-Yukon or greater variables, size should be maintained; // Modifed variable names from 'size' to 'sizeInCharacters', 'actualSize' to 'actualSizeInBytes', and // 'maxSize' to 'maxSizeInBytes' // The idea is to // Keeping these goals in mind - the following are the changes we are making long maxSizeInBytes = 0; if (mt.IsNCharType) maxSizeInBytes = ((sizeInCharacters * sizeof(char)) > actualSizeInBytes) ? sizeInCharacters * sizeof(char) : actualSizeInBytes; else { // Notes: // Elevation from (n)(var)char (4001+) to (n)text succeeds without failure only with Yukon and greater. // it fails in sql server 2000 maxSizeInBytes = (sizeInCharacters > actualSizeInBytes) ? sizeInCharacters : actualSizeInBytes; } if ((maxSizeInBytes > TdsEnums.TYPE_SIZE_LIMIT) || (_coercedValueIsDataFeed) || (sizeInCharacters == -1) || (actualSizeInBytes == -1)) { // is size > size able to be described by 2 bytes // Convert the parameter to its max type mt = MetaType.GetMaxMetaTypeFromMetaType(mt); _metaType = mt; InternalMetaType = mt; if (!mt.IsPlp) { if (mt.SqlDbType == SqlDbType.Xml) { throw ADP.InvalidMetaDataValue(); //Xml should always have IsPartialLength = true } if (mt.SqlDbType == SqlDbType.NVarChar || mt.SqlDbType == SqlDbType.VarChar || mt.SqlDbType == SqlDbType.VarBinary) { Size = (int)(SmiMetaData.UnlimitedMaxLengthIndicator); } } } } return mt; }
private MetaType GetVersionedMetaType(MetaType actualMetaType) { if (actualMetaType == MetaType.MetaUdt) { return MetaType.MetaVarBinary; } if (actualMetaType == MetaType.MetaXml) { return MetaType.MetaNText; } if (actualMetaType == MetaType.MetaMaxVarBinary) { return MetaType.MetaImage; } if (actualMetaType == MetaType.MetaMaxVarChar) { return MetaType.MetaText; } if (actualMetaType == MetaType.MetaMaxNVarChar) { return MetaType.MetaNText; } return actualMetaType; }
// Coerced Value is also used in SqlBulkCopy.ConvertValue(object value, _SqlMetaData metadata) internal static object CoerceValue(object value, MetaType destinationType, out bool coercedToDataFeed, out bool typeChanged, bool allowStreaming = true) { Debug.Assert(!(value is DataFeed), "Value provided should not already be a data feed"); Debug.Assert(!ADP.IsNull(value), "Value provided should not be null"); Debug.Assert(null != destinationType, "null destinationType"); coercedToDataFeed = false; typeChanged = false; Type currentType = value.GetType(); if ((typeof(object) != destinationType.ClassType) && (currentType != destinationType.ClassType) && ((currentType != destinationType.SqlType) || (SqlDbType.Xml == destinationType.SqlDbType))) { // Special case for Xml types (since we need to convert SqlXml into a string) try { // Assume that the type changed typeChanged = true; if ((typeof(string) == destinationType.ClassType)) { // For Xml data, destination Type is always string if (typeof(SqlXml) == currentType) { value = MetaType.GetStringFromXml((XmlReader)(((SqlXml)value).CreateReader())); } else if (typeof(SqlString) == currentType) { typeChanged = false; // Do nothing } else if (typeof(XmlReader).IsAssignableFrom(currentType)) { if (allowStreaming) { coercedToDataFeed = true; value = new XmlDataFeed((XmlReader)value); } else { value = MetaType.GetStringFromXml((XmlReader)value); } } else if (typeof(char[]) == currentType) { value = new string((char[])value); } else if (typeof(SqlChars) == currentType) { value = new string(((SqlChars)value).Value); } else if (value is TextReader && allowStreaming) { coercedToDataFeed = true; value = new TextDataFeed((TextReader)value); } else { value = Convert.ChangeType(value, destinationType.ClassType, (IFormatProvider)null); } } else if ((DbType.Currency == destinationType.DbType) && (typeof(string) == currentType)) { value = Decimal.Parse((string)value, NumberStyles.Currency, (IFormatProvider)null); // WebData 99376 } else if ((typeof(SqlBytes) == currentType) && (typeof(byte[]) == destinationType.ClassType)) { typeChanged = false; // Do nothing } else if ((typeof(string) == currentType) && (SqlDbType.Time == destinationType.SqlDbType)) { value = TimeSpan.Parse((string)value); } else if ((typeof(string) == currentType) && (SqlDbType.DateTimeOffset == destinationType.SqlDbType)) { value = DateTimeOffset.Parse((string)value, (IFormatProvider)null); } else if ((typeof(DateTime) == currentType) && (SqlDbType.DateTimeOffset == destinationType.SqlDbType)) { value = new DateTimeOffset((DateTime)value); } else if (TdsEnums.SQLTABLE == destinationType.TDSType && ( value is DbDataReader || value is System.Collections.Generic.IEnumerable<SqlDataRecord>)) { // no conversion for TVPs. typeChanged = false; } else if (destinationType.ClassType == typeof(byte[]) && value is Stream && allowStreaming) { coercedToDataFeed = true; value = new StreamDataFeed((Stream)value); } else { value = Convert.ChangeType(value, destinationType.ClassType, (IFormatProvider)null); } } catch (Exception e) { if (!ADP.IsCatchableExceptionType(e)) { throw; } throw ADP.ParameterConversionFailed(value, destinationType.ClassType, e); // WebData 75433 } } Debug.Assert(allowStreaming || !coercedToDataFeed, "Streaming is not allowed, but type was coerced into a data feed"); Debug.Assert(value.GetType() == currentType ^ typeChanged, "Incorrect value for typeChanged"); return value; }
internal static MetaType GetMaxMetaTypeFromMetaType(MetaType mt) { // if we can't map it, we need to throw switch (mt.SqlDbType) { case SqlDbType.VarBinary: case SqlDbType.Binary: return MetaMaxVarBinary; case SqlDbType.VarChar: case SqlDbType.Char: return MetaMaxVarChar; case SqlDbType.NVarChar: case SqlDbType.NChar: return MetaMaxNVarChar; case SqlDbType.Udt: // return MetaMaxUdt; default: return mt; } }
internal virtual void CopyFrom(SqlMetaDataPriv original) { this.type = original.type; this.tdsType = original.tdsType; this.precision = original.precision; this.scale = original.scale; this.length = original.length; this.collation = original.collation; this.codePage = original.codePage; this.encoding = original.encoding; this.isNullable = original.isNullable; this.isMultiValued = original.isMultiValued; this.udtDatabaseName = original.udtDatabaseName; this.udtSchemaName = original.udtSchemaName; this.udtTypeName = original.udtTypeName; this.udtAssemblyQualifiedName = original.udtAssemblyQualifiedName; this.udtType = original.udtType; this.xmlSchemaCollectionDatabase = original.xmlSchemaCollectionDatabase; this.xmlSchemaCollectionOwningSchema = original.xmlSchemaCollectionOwningSchema; this.xmlSchemaCollectionName = original.xmlSchemaCollectionName; this.metaType = original.metaType; // this.structuredTypeDatabaseName = original.structuredTypeDatabaseName; this.structuredTypeSchemaName = original.structuredTypeSchemaName; this.structuredTypeName = original.structuredTypeName; this.structuredFields = original.structuredFields; }
// func will change type to that with a 4 byte length if the type has a two // byte length and a parameter length > than that expressable in 2 bytes internal MetaType ValidateTypeLengths(bool yukonOrNewer) { MetaType mt = InternalMetaType; // MDAC bug #50839 + #52829 : Since the server will automatically reject any // char, varchar, binary, varbinary, nchar, or nvarchar parameter that has a // byte sizeInCharacters > 8000 bytes, we promote the parameter to image, text, or ntext. This // allows the user to specify a parameter type using a COM+ datatype and be able to // use that parameter against a BLOB column. if ((SqlDbType.Udt != mt.SqlDbType) && (false == mt.IsFixed) && (false == mt.IsLong)) { // if type has 2 byte length long actualSizeInBytes = this.GetActualSize(); long sizeInCharacters = this.Size; // Bug: VSTFDevDiv #636867 // Notes: // 'actualSizeInBytes' is the size of value passed; // 'sizeInCharacters' is the parameter size; // 'actualSizeInBytes' is in bytes; // 'this.Size' is in charaters; // 'sizeInCharacters' is in characters; // 'TdsEnums.TYPE_SIZE_LIMIT' is in bytes; // For Non-NCharType and for non-Yukon or greater variables, size should be maintained; // Reverting changes from bug VSTFDevDiv # 479739 as it caused an regression; // Modifed variable names from 'size' to 'sizeInCharacters', 'actualSize' to 'actualSizeInBytes', and // 'maxSize' to 'maxSizeInBytes' // The idea is to // 1) revert the regression from bug 479739 // 2) fix as many scenarios as possible including bug 636867 // 3) cause no additional regression from 3.5 sp1 // Keeping these goals in mind - the following are the changes we are making long maxSizeInBytes = 0; if ((mt.IsNCharType) && (yukonOrNewer)) maxSizeInBytes = ((sizeInCharacters * sizeof(char)) > actualSizeInBytes) ? sizeInCharacters * sizeof(char) : actualSizeInBytes; else { // Notes: // Elevation from (n)(var)char (4001+) to (n)text succeeds without failure only with Yukon and greater. // it fails in sql server 2000 maxSizeInBytes = (sizeInCharacters > actualSizeInBytes) ? sizeInCharacters : actualSizeInBytes; } if ((maxSizeInBytes > TdsEnums.TYPE_SIZE_LIMIT) || (_coercedValueIsDataFeed) || (sizeInCharacters == -1) || (actualSizeInBytes == -1)) { // is size > size able to be described by 2 bytes if (yukonOrNewer) { // Convert the parameter to its max type mt = MetaType.GetMaxMetaTypeFromMetaType(mt); _metaType = mt; InternalMetaType = mt; if (!mt.IsPlp) { if (mt.SqlDbType == SqlDbType.Xml) { throw ADP.InvalidMetaDataValue(); //Xml should always have IsPartialLength = true } if (mt.SqlDbType == SqlDbType.NVarChar || mt.SqlDbType == SqlDbType.VarChar || mt.SqlDbType == SqlDbType.VarBinary) { Size = (int)(SmiMetaData.UnlimitedMaxLengthIndicator); } } } else { switch (mt.SqlDbType) { // widening the SqlDbType is automatic case SqlDbType.Binary: case SqlDbType.VarBinary: mt = MetaType.GetMetaTypeFromSqlDbType (SqlDbType.Image, false); _metaType = mt; // do not use SqlDbType property which calls PropertyTypeChanging resetting coerced value InternalMetaType = mt; break; case SqlDbType.Char: case SqlDbType.VarChar: mt = MetaType.GetMetaTypeFromSqlDbType (SqlDbType.Text, false); _metaType = mt; InternalMetaType = mt; break; case SqlDbType.NChar: case SqlDbType.NVarChar: mt = MetaType.GetMetaTypeFromSqlDbType (SqlDbType.NText, false); _metaType = mt; InternalMetaType = mt; break; default: Debug.Assert(false, "Missed metatype in SqlCommand.BuildParamList()"); break; } } } } return mt; }
internal virtual void CopyFrom(SqlMetaDataPriv original) { this.type = original.type; this.tdsType = original.tdsType; this.precision = original.precision; this.scale = original.scale; this.length = original.length; this.collation = original.collation; this.codePage = original.codePage; this.encoding = original.encoding; this.isNullable = original.isNullable; this.xmlSchemaCollectionDatabase = original.xmlSchemaCollectionDatabase; this.xmlSchemaCollectionOwningSchema = original.xmlSchemaCollectionOwningSchema; this.xmlSchemaCollectionName = original.xmlSchemaCollectionName; this.metaType = original.metaType; }
// For MAX types, this method can only write everything in one big chunk. If multiple // chunk writes needed, please use WritePlpBytes/WritePlpChars private byte[] SerializeUnencryptedValue(object value, MetaType type, byte scale, int actualLength, int offset, bool isDataFeed, byte normalizationVersion, TdsParserStateObject stateObj) { Debug.Assert((null != value) && (DBNull.Value != value), "unexpected missing or empty object"); if (normalizationVersion != 0x01) { throw SQL.UnsupportedNormalizationVersion(normalizationVersion); } // parameters are always sent over as BIG or N types switch (type.NullableType) { case TdsEnums.SQLFLTN: if (type.FixedLength == 4) return SerializeFloat((Single)value); else { Debug.Assert(type.FixedLength == 8, "Invalid length for SqlDouble type!"); return SerializeDouble((Double)value); } case TdsEnums.SQLBIGBINARY: case TdsEnums.SQLBIGVARBINARY: case TdsEnums.SQLIMAGE: case TdsEnums.SQLUDT: { Debug.Assert(!isDataFeed, "We cannot seriliaze streams"); Debug.Assert(value is byte[], "Value should be an array of bytes"); byte[] b = new byte[actualLength]; Buffer.BlockCopy((byte[])value, offset, b, 0, actualLength); return b; } case TdsEnums.SQLUNIQUEID: { System.Guid guid = (System.Guid)value; byte[] b = guid.ToByteArray(); Debug.Assert((actualLength == b.Length) && (actualLength == 16), "Invalid length for guid type in com+ object"); return b; } case TdsEnums.SQLBITN: { Debug.Assert(type.FixedLength == 1, "Invalid length for SqlBoolean type"); // We normalize to allow conversion across data types. BIT is serialized into a BIGINT. return SerializeLong((bool)value == true ? 1 : 0, stateObj); } case TdsEnums.SQLINTN: if (type.FixedLength == 1) return SerializeLong((byte)value, stateObj); if (type.FixedLength == 2) return SerializeLong((Int16)value, stateObj); if (type.FixedLength == 4) return SerializeLong((Int32)value, stateObj); Debug.Assert(type.FixedLength == 8, "invalid length for SqlIntN type: " + type.FixedLength.ToString(CultureInfo.InvariantCulture)); return SerializeLong((Int64)value, stateObj); case TdsEnums.SQLBIGCHAR: case TdsEnums.SQLBIGVARCHAR: case TdsEnums.SQLTEXT: { Debug.Assert(!isDataFeed, "We cannot seriliaze streams"); Debug.Assert((value is string || value is byte[]), "Value is a byte array or string"); if (value is byte[]) { // If LazyMat non-filled blob, send cookie rather than value byte[] b = new byte[actualLength]; Buffer.BlockCopy((byte[])value, 0, b, 0, actualLength); return b; } else { return SerializeEncodingChar((string)value, actualLength, offset, _defaultEncoding); } } case TdsEnums.SQLNCHAR: case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: case TdsEnums.SQLXMLTYPE: { Debug.Assert(!isDataFeed, "We cannot seriliaze streams"); Debug.Assert((value is string || value is byte[]), "Value is a byte array or string"); if (value is byte[]) { // If LazyMat non-filled blob, send cookie rather than value byte[] b = new byte[actualLength]; Buffer.BlockCopy((byte[])value, 0, b, 0, actualLength); return b; } else { // convert to cchars instead of cbytes actualLength >>= 1; return SerializeString((string)value, actualLength, offset); } } case TdsEnums.SQLNUMERICN: Debug.Assert(type.FixedLength <= 17, "Decimal length cannot be greater than 17 bytes"); return SerializeDecimal((Decimal)value, stateObj); case TdsEnums.SQLDATETIMN: Debug.Assert(type.FixedLength <= 0xff, "Invalid Fixed Length"); TdsDateTime dt = MetaType.FromDateTime((DateTime)value, (byte)type.FixedLength); if (type.FixedLength == 4) { if (0 > dt.days || dt.days > UInt16.MaxValue) throw SQL.SmallDateTimeOverflow(MetaType.ToDateTime(dt.days, dt.time, 4).ToString(CultureInfo.InvariantCulture)); if (null == stateObj._bIntBytes) { stateObj._bIntBytes = new byte[4]; } byte[] b = stateObj._bIntBytes; int current = 0; byte[] bPart = SerializeShort(dt.days, stateObj); Buffer.BlockCopy(bPart, 0, b, current, 2); current += 2; bPart = SerializeShort(dt.time, stateObj); Buffer.BlockCopy(bPart, 0, b, current, 2); return b; } else { if (null == stateObj._bLongBytes) { stateObj._bLongBytes = new byte[8]; } byte[] b = stateObj._bLongBytes; int current = 0; byte[] bPart = SerializeInt(dt.days, stateObj); Buffer.BlockCopy(bPart, 0, b, current, 4); current += 4; bPart = SerializeInt(dt.time, stateObj); Buffer.BlockCopy(bPart, 0, b, current, 4); return b; } case TdsEnums.SQLMONEYN: { return SerializeCurrency((Decimal)value, type.FixedLength, stateObj); } case TdsEnums.SQLDATE: { return SerializeDate((DateTime)value); } case TdsEnums.SQLTIME: if (scale > TdsEnums.DEFAULT_VARTIME_SCALE) { throw SQL.TimeScaleValueOutOfRange(scale); } return SerializeTime((TimeSpan)value, scale, actualLength); case TdsEnums.SQLDATETIME2: if (scale > TdsEnums.DEFAULT_VARTIME_SCALE) { throw SQL.TimeScaleValueOutOfRange(scale); } return SerializeDateTime2((DateTime)value, scale, actualLength); case TdsEnums.SQLDATETIMEOFFSET: if (scale > TdsEnums.DEFAULT_VARTIME_SCALE) { throw SQL.TimeScaleValueOutOfRange(scale); } return SerializeDateTimeOffset((DateTimeOffset)value, scale, actualLength); default: throw SQL.UnsupportedDatatypeEncryption(type.TypeName); } // switch // Debug.WriteLine("value: " + value.ToString(CultureInfo.InvariantCulture)); }
// Returns true if BOM byte mark is needed for an XML value private bool IsBOMNeeded(MetaType type, object value) { if (type.NullableType == TdsEnums.SQLXMLTYPE) { Type currentType = value.GetType(); if (currentType == typeof(SqlString)) { if (!((SqlString)value).IsNull && ((((SqlString)value).Value).Length > 0)) { if ((((SqlString)value).Value[0] & 0xff) != 0xff) return true; } } else if ((currentType == typeof(String)) && (((String)value).Length > 0)) { if ((value != null) && (((String)value)[0] & 0xff) != 0xff) return true; } else if (currentType == typeof(SqlXml)) { if (!((SqlXml)value).IsNull) return true; } else if (currentType == typeof(XmlDataFeed)) { return true; // Values will eventually converted to unicode string here } } return false; }
// For MAX types, this method can only write everything in one big chunk. If multiple // chunk writes needed, please use WritePlpBytes/WritePlpChars private byte[] SerializeUnencryptedSqlValue(object value, MetaType type, int actualLength, int offset, byte normalizationVersion, TdsParserStateObject stateObj) { Debug.Assert(((type.NullableType == TdsEnums.SQLXMLTYPE) || (value is INullable && !((INullable)value).IsNull)), "unexpected null SqlType!"); if (normalizationVersion != 0x01) { throw SQL.UnsupportedNormalizationVersion(normalizationVersion); } // parameters are always sent over as BIG or N types switch (type.NullableType) { case TdsEnums.SQLFLTN: if (type.FixedLength == 4) return SerializeFloat(((SqlSingle)value).Value); else { Debug.Assert(type.FixedLength == 8, "Invalid length for SqlDouble type!"); return SerializeDouble(((SqlDouble)value).Value); } case TdsEnums.SQLBIGBINARY: case TdsEnums.SQLBIGVARBINARY: case TdsEnums.SQLIMAGE: { byte[] b = new byte[actualLength]; if (value is SqlBinary) { Buffer.BlockCopy(((SqlBinary)value).Value, offset, b, 0, actualLength); } else { Debug.Assert(value is SqlBytes); Buffer.BlockCopy(((SqlBytes)value).Value, offset, b, 0, actualLength); } return b; } case TdsEnums.SQLUNIQUEID: { byte[] b = ((SqlGuid)value).ToByteArray(); Debug.Assert((actualLength == b.Length) && (actualLength == 16), "Invalid length for guid type in com+ object"); return b; } case TdsEnums.SQLBITN: { Debug.Assert(type.FixedLength == 1, "Invalid length for SqlBoolean type"); // We normalize to allow conversion across data types. BIT is serialized into a BIGINT. return SerializeLong(((SqlBoolean)value).Value == true ? 1 : 0, stateObj); } case TdsEnums.SQLINTN: // We normalize to allow conversion across data types. All data types below are serialized into a BIGINT. if (type.FixedLength == 1) return SerializeLong(((SqlByte)value).Value, stateObj); if (type.FixedLength == 2) return SerializeLong(((SqlInt16)value).Value, stateObj); if (type.FixedLength == 4) return SerializeLong(((SqlInt32)value).Value, stateObj); else { Debug.Assert(type.FixedLength == 8, "invalid length for SqlIntN type: " + type.FixedLength.ToString(CultureInfo.InvariantCulture)); return SerializeLong(((SqlInt64)value).Value, stateObj); } case TdsEnums.SQLBIGCHAR: case TdsEnums.SQLBIGVARCHAR: case TdsEnums.SQLTEXT: if (value is SqlChars) { String sch = new String(((SqlChars)value).Value); return SerializeEncodingChar(sch, actualLength, offset, _defaultEncoding); } else { Debug.Assert(value is SqlString); return SerializeEncodingChar(((SqlString)value).Value, actualLength, offset, _defaultEncoding); } case TdsEnums.SQLNCHAR: case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: case TdsEnums.SQLXMLTYPE: // convert to cchars instead of cbytes // Xml type is already converted to string through GetCoercedValue if (actualLength != 0) actualLength >>= 1; if (value is SqlChars) { return SerializeCharArray(((SqlChars)value).Value, actualLength, offset); } else { Debug.Assert(value is SqlString); return SerializeString(((SqlString)value).Value, actualLength, offset); } case TdsEnums.SQLNUMERICN: Debug.Assert(type.FixedLength <= 17, "Decimal length cannot be greater than 17 bytes"); return SerializeSqlDecimal((SqlDecimal)value, stateObj); case TdsEnums.SQLDATETIMN: SqlDateTime dt = (SqlDateTime)value; if (type.FixedLength == 4) { if (0 > dt.DayTicks || dt.DayTicks > UInt16.MaxValue) throw SQL.SmallDateTimeOverflow(dt.ToString()); if (null == stateObj._bIntBytes) { stateObj._bIntBytes = new byte[4]; } byte[] b = stateObj._bIntBytes; int current = 0; byte[] bPart = SerializeShort(dt.DayTicks, stateObj); Buffer.BlockCopy(bPart, 0, b, current, 2); current += 2; bPart = SerializeShort(dt.TimeTicks / SqlDateTime.SQLTicksPerMinute, stateObj); Buffer.BlockCopy(bPart, 0, b, current, 2); return b; } else { if (null == stateObj._bLongBytes) { stateObj._bLongBytes = new byte[8]; } byte[] b = stateObj._bLongBytes; int current = 0; byte[] bPart = SerializeInt(dt.DayTicks, stateObj); Buffer.BlockCopy(bPart, 0, b, current, 4); current += 4; bPart = SerializeInt(dt.TimeTicks, stateObj); Buffer.BlockCopy(bPart, 0, b, current, 4); return b; } case TdsEnums.SQLMONEYN: { return SerializeSqlMoney((SqlMoney)value, type.FixedLength, stateObj); } default: throw SQL.UnsupportedDatatypeEncryption(type.TypeName); } // switch }
private Task WriteSqlValue(object value, MetaType type, int actualLength, int codePageByteSize, int offset, TdsParserStateObject stateObj) { return GetTerminationTask( WriteUnterminatedSqlValue(value, type, actualLength, codePageByteSize, offset, stateObj), value, type, actualLength, stateObj, false); }
private void PropertyChanging() { _internalMetaType = null; }
private Task WriteValue(object value, MetaType type, byte scale, int actualLength, int encodingByteSize, int offset, TdsParserStateObject stateObj, int paramSize, bool isDataFeed) { return GetTerminationTask(WriteUnterminatedValue(value, type, scale, actualLength, encodingByteSize, offset, stateObj, paramSize, isDataFeed), value, type, actualLength, stateObj, isDataFeed); }
internal void Validate(int index, bool isCommandProc) { MetaType metaType = GetMetaTypeOnly(); _internalMetaType = metaType; // NOTE: (General Criteria): SqlParameter does a Size Validation check and would fail if the size is 0. // This condition filters all scenarios where we view a valid size 0. if (ADP.IsDirection(this, ParameterDirection.Output) && !ADP.IsDirection(this, ParameterDirection.ReturnValue) && (!metaType.IsFixed) && !ShouldSerializeSize() && ((null == _value) || (_value == DBNull.Value)) && (SqlDbType != SqlDbType.Timestamp) && (SqlDbType != SqlDbType.Udt) && // Output parameter with size 0 throws for XML, TEXT, NTEXT, IMAGE. (SqlDbType != SqlDbType.Xml) && !metaType.IsVarTime) { throw ADP.UninitializedParameterSize(index, metaType.ClassType); } if (metaType.SqlDbType != SqlDbType.Udt && Direction != ParameterDirection.Output) { GetCoercedValue(); } // Validate structured-type-specific details. if (metaType.SqlDbType == SqlDbType.Structured) { if (!isCommandProc && ADP.IsEmpty(TypeName)) throw SQL.MustSetTypeNameForParam(metaType.TypeName, this.ParameterName); if (ParameterDirection.Input != this.Direction) { throw SQL.UnsupportedTVPOutputParameter(this.Direction, this.ParameterName); } if (DBNull.Value == GetCoercedValue()) { throw SQL.DBNullNotSupportedForTVPValues(this.ParameterName); } } else if (!ADP.IsEmpty(TypeName)) { throw SQL.UnexpectedTypeNameForNonStructParams(this.ParameterName); } }
// // we always send over nullable types for parameters so we always write the varlen fields // internal void WriteParameterVarLen(MetaType type, int size, bool isNull, TdsParserStateObject stateObj, bool unknownLength = false) { if (type.IsLong) { // text/image/SQLVariant have a 4 byte length, plp datatypes have 8 byte lengths if (isNull) { if (type.IsPlp) { WriteLong(unchecked((long)TdsEnums.SQL_PLP_NULL), stateObj); } else { WriteInt(unchecked((int)TdsEnums.VARLONGNULL), stateObj); } } else if (type.NullableType == TdsEnums.SQLXMLTYPE || unknownLength) { WriteUnsignedLong(TdsEnums.SQL_PLP_UNKNOWNLEN, stateObj); } else if (type.IsPlp) { // Non-xml plp types WriteLong((long)size, stateObj); } else { WriteInt(size, stateObj); } } else if (type.IsVarTime) { if (isNull) { stateObj.WriteByte(TdsEnums.FIXEDNULL); } else { stateObj.WriteByte((byte)size); } } else if (false == type.IsFixed) { // non-long but variable length column, must be a BIG* type: 2 byte length if (isNull) { WriteShort(TdsEnums.VARNULL, stateObj); } else { WriteShort(size, stateObj); } } else { if (isNull) { stateObj.WriteByte(TdsEnums.FIXEDNULL); } else { Debug.Assert(type.FixedLength <= 0xff, "WriteParameterVarLen: invalid one byte length!"); stateObj.WriteByte((byte)(type.FixedLength & 0xff)); // 1 byte for everything else } } }
private object ConvertValue(object value, _SqlMetaData metadata) { object obj2; if (ADP.IsNull(value)) { if (!metadata.isNullable) { throw SQL.BulkLoadBulkLoadNotAllowDBNull(metadata.column); } return(value); } MetaType metaType = metadata.metaType; try { MetaType metaTypeFromSqlDbType; SqlDecimal num2; switch (metaType.NullableType) { case 0x22: case 0x23: case 0x24: case 0x26: case 40: case 0x29: case 0x2a: case 0x2b: case 50: case 0x3a: case 0x3b: case 0x3d: case 0x3e: case 0x68: case 0x6d: case 110: case 0x6f: case 0xa5: case 0xa7: case 0xad: case 0xaf: metaTypeFromSqlDbType = MetaType.GetMetaTypeFromSqlDbType(metaType.SqlDbType, false); value = SqlParameter.CoerceValue(value, metaTypeFromSqlDbType); goto Label_0290; case 0x62: value = this.ValidateBulkCopyVariant(value); goto Label_0290; case 0x63: case 0xef: case 0xe7: { metaTypeFromSqlDbType = MetaType.GetMetaTypeFromSqlDbType(metaType.SqlDbType, false); value = SqlParameter.CoerceValue(value, metaTypeFromSqlDbType); int num3 = (value is string) ? ((string)value).Length : ((SqlString)value).Value.Length; if (num3 > (metadata.length / 2)) { throw SQL.BulkLoadStringTooLong(); } goto Label_0290; } case 0x6a: case 0x6c: metaTypeFromSqlDbType = MetaType.GetMetaTypeFromSqlDbType(metaType.SqlDbType, false); value = SqlParameter.CoerceValue(value, metaTypeFromSqlDbType); if (!(value is SqlDecimal)) { break; } num2 = (SqlDecimal)value; goto Label_017D; case 240: if (value.GetType() != typeof(byte[])) { value = this._connection.GetBytes(value); } goto Label_0290; case 0xf1: if (value is XmlReader) { value = MetaType.GetStringFromXml((XmlReader)value); } goto Label_0290; default: throw SQL.BulkLoadCannotConvertValue(value.GetType(), metadata.metaType, null); } num2 = new SqlDecimal((decimal)value); Label_017D: if (num2.Scale != metadata.scale) { num2 = TdsParser.AdjustSqlDecimalScale(num2, metadata.scale); value = num2; } if (num2.Precision > metadata.precision) { throw SQL.BulkLoadCannotConvertValue(value.GetType(), metaTypeFromSqlDbType, ADP.ParameterValueOutOfRange(num2)); } Label_0290: obj2 = value; } catch (Exception exception) { if (!ADP.IsCatchableExceptionType(exception)) { throw; } throw SQL.BulkLoadCannotConvertValue(value.GetType(), metadata.metaType, exception); } return(obj2); }