/// <include file='../../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetSqlValue/*' /> public virtual object GetSqlValue(int ordinal) { EnsureSubclassOverride(); SmiMetaData metaData = GetSmiMetaData(ordinal); return(ValueUtilsSmi.GetSqlValue200(_eventSink, _recordBuffer, ordinal, metaData)); }
/// <include file='..\..\..\..\..\..\..\..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetValue/*' /> public virtual Object GetValue(int ordinal) { EnsureSubclassOverride(); SmiMetaData metaData = GetSmiMetaData(ordinal); if (SmiVersion >= SmiContextFactory.KatmaiVersion) { return(ValueUtilsSmi.GetValue200( _eventSink, _recordBuffer, ordinal, metaData, _recordContext )); } else { return(ValueUtilsSmi.GetValue( _eventSink, (ITypedGettersV3)_recordBuffer, ordinal, metaData, _recordContext )); } }
private static void GetNullOutputParameterSmi(SmiMetaData metaData, SqlBuffer targetBuffer, ref object result) { if (SqlDbType.Udt == metaData.SqlDbType) { result = NullUdtInstance(metaData); } else { SqlBuffer.StorageType stype = SqlDbTypeToStorageType(metaData.SqlDbType); if (SqlBuffer.StorageType.Empty == stype) { result = DBNull.Value; } else if (SqlBuffer.StorageType.SqlBinary == stype) { // special case SqlBinary, 'cause tds parser never sets SqlBuffer to null, just to empty! targetBuffer.SqlBinary = SqlBinary.Null; } else if (SqlBuffer.StorageType.SqlGuid == stype) { targetBuffer.SqlGuid = SqlGuid.Null; } else { targetBuffer.SetToNullOfType(stype); } } }
internal void SetInt64(long value) { if (SqlDbType.Variant == this._metaData.SqlDbType) { if (this._variantType == null) { this._stateObj.Parser.WriteSqlVariantHeader(10, 0x7f, 0, this._stateObj); this._stateObj.Parser.WriteLong(value, this._stateObj); } else { this._stateObj.Parser.WriteSqlVariantHeader(10, 60, 0, this._stateObj); this._stateObj.Parser.WriteInt((int)(value >> 0x20), this._stateObj); this._stateObj.Parser.WriteInt((int)value, this._stateObj); this._variantType = null; } } else { this._stateObj.Parser.WriteByte((byte)this._metaData.MaxLength, this._stateObj); if (SqlDbType.SmallMoney == this._metaData.SqlDbType) { this._stateObj.Parser.WriteInt((int)value, this._stateObj); } else if (SqlDbType.Money == this._metaData.SqlDbType) { this._stateObj.Parser.WriteInt((int)(value >> 0x20), this._stateObj); this._stateObj.Parser.WriteInt((int)value, this._stateObj); } else { this._stateObj.Parser.WriteLong(value, this._stateObj); } } }
internal static bool IsGetterAccessValid(SmiMetaData metaData, SmiXetterTypeCode xetterType) { // Make sure no-one adds a new xetter type without updating this file! Debug.Assert(SmiXetterTypeCode.XetBoolean <= xetterType && SmiXetterTypeCode.XetDateTimeOffset >= xetterType); return(__isGetterAccessValid[(int)metaData.SqlDbType, (int)xetterType]); }
// valid for DateTimeOffset internal void SetDateTimeOffset(DateTimeOffset value) { Debug.Assert( SmiXetterAccessMap.IsSetterAccessValid(_metaData, SmiXetterTypeCode.XetDateTimeOffset)); byte scale; byte length; if (SqlDbType.Variant == _metaData.SqlDbType) { // VSTFDevDiv #885208 - DateTimeOffset throws ArgumentException for when passing DateTimeOffset value to a sql_variant TVP // using a SqlDataRecord or SqlDataReader SmiMetaData dateTimeOffsetMetaData = SmiMetaData.DefaultDateTimeOffset; scale = MetaType.MetaDateTimeOffset.Scale; length = (byte)dateTimeOffsetMetaData.MaxLength; _stateObj.Parser.WriteSqlVariantHeader(13, TdsEnums.SQLDATETIMEOFFSET, 1, _stateObj); _stateObj.WriteByte(scale); //propbytes: scale } else { scale = _metaData.Scale; length = (byte)_metaData.MaxLength; _stateObj.WriteByte(length); } DateTime utcDateTime = value.UtcDateTime; Int64 time = utcDateTime.TimeOfDay.Ticks / TdsEnums.TICKS_FROM_SCALE[scale]; int days = utcDateTime.Subtract(DateTime.MinValue).Days; Int16 offset = (Int16)value.Offset.TotalMinutes; _stateObj.WriteByteArray(BitConverter.GetBytes(time), length - 5, 0); // time _stateObj.WriteByteArray(BitConverter.GetBytes(days), 3, 0); // date _stateObj.WriteByte((byte)(offset & 0xff)); // offset byte 1 _stateObj.WriteByte((byte)((offset >> 8) & 0xff)); // offset byte 2 }
// Does this type use PLP format values? internal static bool IsPlpFormat(SmiMetaData metaData) { return(metaData.MaxLength == SmiMetaData.UnlimitedMaxLengthIndicator || metaData.SqlDbType == SqlDbType.Image || metaData.SqlDbType == SqlDbType.NText || metaData.SqlDbType == SqlDbType.Text || metaData.SqlDbType == SqlDbType.Udt); }
internal TdsValueSetter(TdsParserStateObject stateObj, SmiMetaData md) { this._stateObj = stateObj; this._metaData = md; this._isPlp = MetaDataUtilsSmi.IsPlpFormat(md); this._plpUnknownSent = false; this._encoder = null; }
internal TdsRecordBufferSetter(TdsParserStateObject stateObj, SmiMetaData md) { this._fieldSetters = new TdsValueSetter[md.FieldMetaData.Count]; for (int i = 0; i < md.FieldMetaData.Count; i++) { this._fieldSetters[i] = new TdsValueSetter(stateObj, md.FieldMetaData[i]); } this._stateObj = stateObj; this._metaData = md; }
private object GetSqlValueFrameworkSpecific(int ordinal) { SmiMetaData metaData = GetSmiMetaData(ordinal); if (SmiVersion >= SmiContextFactory.Sql2008Version) { return(ValueUtilsSmi.GetSqlValue200(_eventSink, _recordBuffer, ordinal, metaData, _recordContext)); } return(ValueUtilsSmi.GetSqlValue(_eventSink, _recordBuffer, ordinal, metaData, _recordContext)); }
/// <include file='../../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetSqlValue/*' /> public virtual object GetSqlValue(int ordinal) { SmiMetaData metaData = GetSmiMetaData(ordinal); if (SmiVersion >= SmiContextFactory.KatmaiVersion) { return(ValueUtilsSmi.GetSqlValue200(_eventSink, _recordBuffer, ordinal, metaData, _recordContext)); } return(ValueUtilsSmi.GetSqlValue(_eventSink, _recordBuffer, ordinal, metaData, _recordContext)); }
public virtual void SetVariantMetaData(SmiEventSink sink, int ordinal, SmiMetaData metaData) { // ******** OBSOLETING from SMI -- this should have been removed from ITypedSettersV3 // Intended to be removed prior to RTM. Sub-classes need not implement // Implement body with throw because there are only a couple of ways to get to this code: // 1) Client is calling this method even though the server negotiated for V3+ and dropped support for V2-. // 2) Server didn't implement V2- on some interface and negotiated V2-. throw Microsoft.Data.Common.ADP.InternalError(Microsoft.Data.Common.ADP.InternalErrorCode.UnimplementedSMIMethod); }
// valid for DateTime, SmallDateTime, Date, DateTime2 internal void SetDateTime(DateTime value) { Debug.Assert( SmiXetterAccessMap.IsSetterAccessValid(_metaData, SmiXetterTypeCode.XetDateTime)); if (SqlDbType.Variant == _metaData.SqlDbType) { if ((_variantType != null) && (_variantType.SqlDbType == SqlDbType.DateTime2)) { _stateObj.Parser.WriteSqlVariantDateTime2(value, _stateObj); } else if ((_variantType != null) && (_variantType.SqlDbType == SqlDbType.Date)) { _stateObj.Parser.WriteSqlVariantDate(value, _stateObj); } else { TdsDateTime dt = MetaType.FromDateTime(value, 8); _stateObj.Parser.WriteSqlVariantHeader(10, TdsEnums.SQLDATETIME, 0, _stateObj); _stateObj.Parser.WriteInt(dt.days, _stateObj); _stateObj.Parser.WriteInt(dt.time, _stateObj); } // Clean the variant metadata to prevent sharing it with next row. // As a reminder, SetVariantType raises an assert if _variantType is not clean _variantType = null; } else { _stateObj.WriteByte((byte)_metaData.MaxLength); if (SqlDbType.SmallDateTime == _metaData.SqlDbType) { TdsDateTime dt = MetaType.FromDateTime(value, (byte)_metaData.MaxLength); Debug.Assert(0 <= dt.days && dt.days <= ushort.MaxValue, "Invalid DateTime '" + value + "' for SmallDateTime"); _stateObj.Parser.WriteShort(dt.days, _stateObj); _stateObj.Parser.WriteShort(dt.time, _stateObj); } else if (SqlDbType.DateTime == _metaData.SqlDbType) { TdsDateTime dt = MetaType.FromDateTime(value, (byte)_metaData.MaxLength); _stateObj.Parser.WriteInt(dt.days, _stateObj); _stateObj.Parser.WriteInt(dt.time, _stateObj); } else { // date and datetime2 int days = value.Subtract(DateTime.MinValue).Days; if (SqlDbType.DateTime2 == _metaData.SqlDbType) { long time = value.TimeOfDay.Ticks / TdsEnums.TICKS_FROM_SCALE[_metaData.Scale]; _stateObj.WriteByteArray(BitConverter.GetBytes(time), (int)_metaData.MaxLength - 3, 0); } _stateObj.WriteByteArray(BitConverter.GetBytes(days), 3, 0); } } }
public override object GetSqlValue(int ordinal) { this.EnsureCanGetCol("GetSqlValue", ordinal); SmiMetaData metaData = this._currentMetaData[ordinal]; if (this._currentConnection.IsKatmaiOrNewer) { return(ValueUtilsSmi.GetSqlValue200(this._readerEventSink, (SmiTypedGetterSetter)this._currentColumnValuesV3, ordinal, metaData, this._currentConnection.InternalContext)); } return(ValueUtilsSmi.GetSqlValue(this._readerEventSink, this._currentColumnValuesV3, ordinal, metaData, this._currentConnection.InternalContext)); }
// compare SmiMetaData to SqlMetaData and determine if they are compatible. internal static bool IsCompatible(SmiMetaData firstMd, SqlMetaData secondMd) { return(firstMd.SqlDbType == secondMd.SqlDbType && firstMd.MaxLength == secondMd.MaxLength && firstMd.Precision == secondMd.Precision && firstMd.Scale == secondMd.Scale && firstMd.CompareOptions == secondMd.CompareOptions && firstMd.LocaleId == secondMd.LocaleId && firstMd.SqlDbType != SqlDbType.Structured && // SqlMetaData doesn't support Structured types !firstMd.IsMultiValued); // SqlMetaData doesn't have a "multivalued" option }
private int _currentOffset; // for chunking, verify that caller is using correct offsets #endif #endregion #region Exposed Construct/factory methods internal TdsValueSetter(TdsParserStateObject stateObj, SmiMetaData md) { _stateObj = stateObj; _metaData = md; _isPlp = MetaDataUtilsSmi.IsPlpFormat(md); _plpUnknownSent = false; _encoder = null; #if DEBUG _currentOffset = 0; #endif }
// UDTs and null variants come back via return value, all else is via targetBuffer. // implements SqlClient 1.1-compatible output parameter semantics internal static object GetOutputParameterV200Smi( SmiEventSink_Default sink, // event sink for errors SmiTypedGetterSetter getters, // getters interface to grab value from int ordinal, // parameter within getters SmiMetaData metaData, // Getter's type for this ordinal SmiContext context, // used to obtain scratch streams SqlBuffer targetBuffer // destination ) { object result = null; // Workaround for UDT hack in non-Smi code paths. if (IsDBNull_Unchecked(sink, getters, ordinal)) { GetNullOutputParameterSmi(metaData, targetBuffer, ref result); } else { switch (metaData.SqlDbType) { // new types go here case SqlDbType.Variant: // Handle variants specifically for v200, since they could contain v200 types // For variants, recur using the current value's sqldbtype metaData = getters.GetVariantType(sink, ordinal); sink.ProcessMessagesAndThrow(); Debug.Assert(SqlDbType.Variant != metaData.SqlDbType, "Variant-within-variant not supposed to be possible!"); GetOutputParameterV200Smi(sink, getters, ordinal, metaData, context, targetBuffer); break; case SqlDbType.Date: targetBuffer.SetToDate(GetDateTime_Unchecked(sink, getters, ordinal)); break; case SqlDbType.DateTime2: targetBuffer.SetToDateTime2(GetDateTime_Unchecked(sink, getters, ordinal), metaData.Scale); break; case SqlDbType.Time: targetBuffer.SetToTime(GetTimeSpan_Unchecked(sink, getters, ordinal), metaData.Scale); break; case SqlDbType.DateTimeOffset: targetBuffer.SetToDateTimeOffset(GetDateTimeOffset_Unchecked(sink, getters, ordinal), metaData.Scale); break; default: result = GetOutputParameterV3Smi(sink, getters, ordinal, metaData, context, targetBuffer); break; } } return(result); }
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetString/*' /> public virtual string GetString(int ordinal) { SmiMetaData colMeta = GetSmiMetaData(ordinal); if (_usesStringStorageForXml && colMeta.SqlDbType == SqlDbType.Xml) { return(ValueUtilsSmi.GetString(_eventSink, _recordBuffer, ordinal, s_maxNVarCharForXml)); } else { return(ValueUtilsSmi.GetString(_eventSink, _recordBuffer, ordinal, colMeta)); } }
internal SmiSettersStream(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData) { Debug.Assert(null != sink); Debug.Assert(null != setters); Debug.Assert(0 <= ordinal); Debug.Assert(null != metaData); _sink = sink; _setters = setters; _ordinal = ordinal; _lengthWritten = 0; _metaData = metaData; }
internal SmiGettersStream(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData) { Debug.Assert(null != sink); Debug.Assert(null != getters); Debug.Assert(0 <= ordinal); Debug.Assert(null != metaData); _sink = sink; _getters = getters; _ordinal = ordinal; _readPosition = 0; _metaData = metaData; }
private int _currentField; // validate that caller sets columns in correct order. #endif #endregion #region Exposed Construct and control methods/properties internal TdsRecordBufferSetter(TdsParserStateObject stateObj, SmiMetaData md) { Debug.Assert(SqlDbType.Structured == md.SqlDbType, "Unsupported SqlDbType: " + md.SqlDbType); _fieldSetters = new TdsValueSetter[md.FieldMetaData.Count]; for (int i = 0; i < md.FieldMetaData.Count; i++) { _fieldSetters[i] = new TdsValueSetter(stateObj, md.FieldMetaData[i]); } _stateObj = stateObj; _metaData = md; #if DEBUG _currentField = ReadyForToken; #endif }
internal void SetVariantType(SmiMetaData value) { Debug.Assert(null == _variantType, "Variant type can only be set once"); Debug.Assert(value != null && (value.SqlDbType == SqlDbType.Money || value.SqlDbType == SqlDbType.NVarChar || value.SqlDbType == SqlDbType.Date || value.SqlDbType == SqlDbType.DateTime || value.SqlDbType == SqlDbType.DateTime2 || value.SqlDbType == SqlDbType.DateTimeOffset || value.SqlDbType == SqlDbType.SmallDateTime ), "Invalid variant type"); _variantType = value; }
/// <include file='../../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetString/*' /> public virtual string GetString(int ordinal) { EnsureSubclassOverride(); SmiMetaData colMeta = GetSmiMetaData(ordinal); if (_usesStringStorageForXml && SqlDbType.Xml == colMeta.SqlDbType) { return(ValueUtilsSmi.GetString(_eventSink, _recordBuffer, ordinal, s_maxNVarCharForXml)); } else { return(ValueUtilsSmi.GetString(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal))); } }
// valid for SqlDbType.BigInt, SqlDbType.Money, SqlDbType.SmallMoney internal void SetInt64(long value) { Debug.Assert( SmiXetterAccessMap.IsSetterAccessValid(_metaData, SmiXetterTypeCode.XetInt64)); if (SqlDbType.Variant == _metaData.SqlDbType) { if (null == _variantType) { _stateObj.Parser.WriteSqlVariantHeader(10, TdsEnums.SQLINT8, 0, _stateObj); _stateObj.Parser.WriteLong(value, _stateObj); } else { Debug.Assert(SqlDbType.Money == _variantType.SqlDbType, "Invalid variant type"); _stateObj.Parser.WriteSqlVariantHeader(10, TdsEnums.SQLMONEY, 0, _stateObj); _stateObj.Parser.WriteInt((int)(value >> 0x20), _stateObj); _stateObj.Parser.WriteInt((int)value, _stateObj); _variantType = null; } } else { _stateObj.WriteByte((byte)_metaData.MaxLength); if (SqlDbType.SmallMoney == _metaData.SqlDbType) { _stateObj.Parser.WriteInt((int)value, _stateObj); } else if (SqlDbType.Money == _metaData.SqlDbType) { _stateObj.Parser.WriteInt((int)(value >> 0x20), _stateObj); _stateObj.Parser.WriteInt((int)value, _stateObj); } else { _stateObj.Parser.WriteLong(value, _stateObj); } } }
internal TdsParameterSetter(TdsParserStateObject stateObj, SmiMetaData md) { _target = new TdsRecordBufferSetter(stateObj, md); }
// Map SmiMetaData from a schema table. // DEVNOTE: Since we're using SchemaTable, we can assume that we aren't directly using a SqlDataReader // so we don't support the Sql-specific stuff, like collation. internal static SmiExtendedMetaData SmiMetaDataFromSchemaTableRow(DataRow schemaRow) { string colName = ""; object temp = schemaRow[SchemaTableColumn.ColumnName]; if (DBNull.Value != temp) { colName = (string)temp; } // Determine correct SqlDbType. temp = schemaRow[SchemaTableColumn.DataType]; if (DBNull.Value == temp) { throw SQL.NullSchemaTableDataTypeNotSupported(colName); } Type colType = (Type)temp; SqlDbType colDbType = InferSqlDbTypeFromType_2008(colType); if (InvalidSqlDbType == colDbType) { // Unknown through standard mapping, use VarBinary for columns that are Object typed, otherwise error if (typeof(object) == colType) { colDbType = SqlDbType.VarBinary; } else { throw SQL.UnsupportedColumnTypeForSqlProvider(colName, colType.ToString()); } } // Determine metadata modifier values per type (maxlength, precision, scale, etc) long maxLength = 0; byte precision = 0; byte scale = 0; switch (colDbType) { case SqlDbType.BigInt: case SqlDbType.Bit: case SqlDbType.DateTime: case SqlDbType.Float: case SqlDbType.Image: case SqlDbType.Int: case SqlDbType.Money: case SqlDbType.NText: case SqlDbType.Real: case SqlDbType.UniqueIdentifier: case SqlDbType.SmallDateTime: case SqlDbType.SmallInt: case SqlDbType.SmallMoney: case SqlDbType.Text: case SqlDbType.Timestamp: case SqlDbType.TinyInt: case SqlDbType.Variant: case SqlDbType.Xml: case SqlDbType.Date: // These types require no metadata modifies break; case SqlDbType.Binary: case SqlDbType.VarBinary: // These types need a binary max length temp = schemaRow[SchemaTableColumn.ColumnSize]; if (DBNull.Value == temp) { // source isn't specifying a size, so assume the worst if (SqlDbType.Binary == colDbType) { maxLength = SmiMetaData.MaxBinaryLength; } else { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } } else { // We (should) have a valid maxlength, so use it. maxLength = Convert.ToInt64(temp, null); // Max length must be 0 to MaxBinaryLength or it can be UnlimitedMAX if type is varbinary. // If it's greater than MaxBinaryLength, just promote it to UnlimitedMAX, if possible. if (maxLength > SmiMetaData.MaxBinaryLength) { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } if ((maxLength < 0 && (maxLength != SmiMetaData.UnlimitedMaxLengthIndicator || SqlDbType.Binary == colDbType))) { throw SQL.InvalidColumnMaxLength(colName, maxLength); } } break; case SqlDbType.Char: case SqlDbType.VarChar: // These types need an ANSI max length temp = schemaRow[SchemaTableColumn.ColumnSize]; if (DBNull.Value == temp) { // source isn't specifying a size, so assume the worst if (SqlDbType.Char == colDbType) { maxLength = SmiMetaData.MaxANSICharacters; } else { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } } else { // We (should) have a valid maxlength, so use it. maxLength = Convert.ToInt64(temp, null); // Max length must be 0 to MaxANSICharacters or it can be UnlimitedMAX if type is varbinary. // If it's greater than MaxANSICharacters, just promote it to UnlimitedMAX, if possible. if (maxLength > SmiMetaData.MaxANSICharacters) { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } if ((maxLength < 0 && (maxLength != SmiMetaData.UnlimitedMaxLengthIndicator || SqlDbType.Char == colDbType))) { throw SQL.InvalidColumnMaxLength(colName, maxLength); } } break; case SqlDbType.NChar: case SqlDbType.NVarChar: // These types need a unicode max length temp = schemaRow[SchemaTableColumn.ColumnSize]; if (DBNull.Value == temp) { // source isn't specifying a size, so assume the worst if (SqlDbType.NChar == colDbType) { maxLength = SmiMetaData.MaxUnicodeCharacters; } else { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } } else { // We (should) have a valid maxlength, so use it. maxLength = Convert.ToInt64(temp, null); // Max length must be 0 to MaxUnicodeCharacters or it can be UnlimitedMAX if type is varbinary. // If it's greater than MaxUnicodeCharacters, just promote it to UnlimitedMAX, if possible. if (maxLength > SmiMetaData.MaxUnicodeCharacters) { maxLength = SmiMetaData.UnlimitedMaxLengthIndicator; } if ((maxLength < 0 && (maxLength != SmiMetaData.UnlimitedMaxLengthIndicator || SqlDbType.NChar == colDbType))) { throw SQL.InvalidColumnMaxLength(colName, maxLength); } } break; case SqlDbType.Decimal: // Decimal requires precision and scale temp = schemaRow[SchemaTableColumn.NumericPrecision]; if (DBNull.Value == temp) { precision = SmiMetaData.DefaultDecimal.Precision; } else { precision = Convert.ToByte(temp, null); } temp = schemaRow[SchemaTableColumn.NumericScale]; if (DBNull.Value == temp) { scale = SmiMetaData.DefaultDecimal.Scale; } else { scale = Convert.ToByte(temp, null); } if (precision < SmiMetaData.MinPrecision || precision > SqlDecimal.MaxPrecision || scale < SmiMetaData.MinScale || scale > SqlDecimal.MaxScale || scale > precision) { throw SQL.InvalidColumnPrecScale(); } break; case SqlDbType.Time: case SqlDbType.DateTime2: case SqlDbType.DateTimeOffset: // requires scale temp = schemaRow[SchemaTableColumn.NumericScale]; if (DBNull.Value == temp) { scale = SmiMetaData.DefaultTime.Scale; } else { scale = Convert.ToByte(temp, null); } if (scale > SmiMetaData.MaxTimeScale) { throw SQL.InvalidColumnPrecScale(); } else if (scale < 0) { scale = SmiMetaData.DefaultTime.Scale; } break; case SqlDbType.Udt: case SqlDbType.Structured: default: // These types are not supported from SchemaTable throw SQL.UnsupportedColumnTypeForSqlProvider(colName, colType.ToString()); } return(new SmiExtendedMetaData( colDbType, maxLength, precision, scale, System.Globalization.CultureInfo.CurrentCulture.LCID, SmiMetaData.GetDefaultForType(colDbType).CompareOptions, null, false, // no support for multi-valued columns in a TVP yet null, // no support for structured columns yet null, // no support for structured columns yet colName, null, null, null)); }
private bool _isMetaSet; // flag to indicate whether we have set the variant metadata internal SqlRecordBuffer(SmiMetaData metaData) { _isNull = true; }
// valid for character types: Char, VarChar, Text, NChar, NVarChar, NText internal void SetString(string value, int offset, int length) { Debug.Assert( SmiXetterAccessMap.IsSetterAccessValid(_metaData, SmiXetterTypeCode.XetString)); // ANSI types must convert to byte[] because that's the tool we have. if (MetaDataUtilsSmi.IsAnsiType(_metaData.SqlDbType)) { byte[] bytes; // Optimize for common case of writing entire string if (offset == 0 && value.Length <= length) { bytes = _stateObj.Parser._defaultEncoding.GetBytes(value); } else { char[] chars = value.ToCharArray(offset, length); bytes = _stateObj.Parser._defaultEncoding.GetBytes(chars); } SetBytes(0, bytes, 0, bytes.Length); SetBytesLength(bytes.Length); } else if (SqlDbType.Variant == _metaData.SqlDbType) { Debug.Assert(null != _variantType && SqlDbType.NVarChar == _variantType.SqlDbType, "Invalid variant type"); SqlCollation collation = new SqlCollation(); collation.LCID = checked ((int)_variantType.LocaleId); collation.SqlCompareOptions = _variantType.CompareOptions; if (length * ADP.CharSize > TdsEnums.TYPE_SIZE_LIMIT) { // send as varchar for length greater than 4000 byte[] bytes; // Optimize for common case of writing entire string if (offset == 0 && value.Length <= length) { bytes = _stateObj.Parser._defaultEncoding.GetBytes(value); } else { bytes = _stateObj.Parser._defaultEncoding.GetBytes(value.ToCharArray(offset, length)); } _stateObj.Parser.WriteSqlVariantHeader(9 + bytes.Length, TdsEnums.SQLBIGVARCHAR, 7, _stateObj); _stateObj.Parser.WriteUnsignedInt(collation.info, _stateObj); // propbytes: collation.Info _stateObj.WriteByte(collation.sortId); // propbytes: collation.SortId _stateObj.Parser.WriteShort(bytes.Length, _stateObj); // propbyte: varlen _stateObj.WriteByteArray(bytes, bytes.Length, 0); } else { _stateObj.Parser.WriteSqlVariantHeader(9 + length * ADP.CharSize, TdsEnums.SQLNVARCHAR, 7, _stateObj); _stateObj.Parser.WriteUnsignedInt(collation.info, _stateObj); // propbytes: collation.Info _stateObj.WriteByte(collation.sortId); // propbytes: collation.SortId _stateObj.Parser.WriteShort(length * ADP.CharSize, _stateObj); // propbyte: varlen _stateObj.Parser.WriteString(value, length, offset, _stateObj); } _variantType = null; } else if (_isPlp) { // Send the string as a complete PLP chunk. _stateObj.Parser.WriteLong(length * ADP.CharSize, _stateObj); // PLP total length _stateObj.Parser.WriteInt(length * ADP.CharSize, _stateObj); // Chunk length _stateObj.Parser.WriteString(value, length, offset, _stateObj); // Data if (length != 0) { _stateObj.Parser.WriteInt(TdsEnums.SQL_PLP_CHUNK_TERMINATOR, _stateObj); // Terminator } } else { _stateObj.Parser.WriteShort(length * ADP.CharSize, _stateObj); _stateObj.Parser.WriteString(value, length, offset, _stateObj); } }
// valid for SqlDbType.Variant public override void SetVariantMetaData(SmiEventSink sink, int ordinal, SmiMetaData metaData) { CheckWritingToColumn(ordinal); _fieldSetters[ordinal].SetVariantType(metaData); }
public override void SetVariantMetaData(SmiEventSink sink, int ordinal, SmiMetaData metaData) { this._fieldSetters[ordinal].SetVariantType(metaData); }