internal SqlDataRecord(SmiRecordBuffer recordBuffer, params SmiExtendedMetaData[] metaData) { Debug.Assert(null != recordBuffer, "invalid attempt to instantiate SqlDataRecord with null SmiRecordBuffer"); Debug.Assert(null != metaData, "invalid attempt to instantiate SqlDataRecord with null SmiExtendedMetaData[]"); _columnMetaData = new SqlMetaData[metaData.Length]; _columnSmiMetaData = new SmiExtendedMetaData[metaData.Length]; for (int i = 0; i < _columnSmiMetaData.Length; i++) { _columnSmiMetaData[i] = metaData[i]; _columnMetaData[i] = MetaDataUtilsSmi.SmiExtendedMetaDataToSqlMetaData(_columnSmiMetaData[i]); } _eventSink = new SmiEventSink_Default(); if (InOutOfProcHelper.InProc) { _recordContext = SmiContextFactory.Instance.GetCurrentContext(); } else { _recordContext = null; } _recordBuffer = recordBuffer; _eventSink.ProcessMessagesAndThrow(); }
internal SqlClientWrapperSmiStream(SmiEventSink_Default sink, SmiStream stream) { Debug.Assert(null != sink); Debug.Assert(null != stream); _sink = sink; _stream = stream; }
protected virtual void DispatchMessages( #if NETFRAMEWORK bool ignoreNonFatalMessages #endif ) { // virtual because we want a default implementation in the cases // where we don't have a connection to process stuff, but we want to // provide the connection the ability to fire info messages when it // hooks up. #if NETFRAMEWORK SmiEventSink_Default parent = (SmiEventSink_Default)_parent; if (null != parent) { parent.DispatchMessages(ignoreNonFatalMessages); } else #endif { SqlException errors = ProcessMessages(true #if NETFRAMEWORK , ignoreNonFatalMessages #endif ); // ignore warnings, because there's no place to send them... if (null != errors) { throw errors; } } }
// SqlDataRecord public API /// <include file='../../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/ctor/*' /> public SqlDataRecord(params SqlMetaData[] metaData) { // Initial consistency check if (null == metaData) { throw ADP.ArgumentNull(nameof(metaData)); } _columnMetaData = new SqlMetaData[metaData.Length]; _columnSmiMetaData = new SmiExtendedMetaData[metaData.Length]; for (int i = 0; i < _columnSmiMetaData.Length; i++) { if (null == metaData[i]) { throw ADP.ArgumentNull($"{nameof(metaData)}[{i}]"); } _columnMetaData[i] = metaData[i]; _columnSmiMetaData[i] = MetaDataUtilsSmi.SqlMetaDataToSmiExtendedMetaData(_columnMetaData[i]); } _eventSink = new SmiEventSink_Default(); _recordBuffer = new MemoryRecordBuffer(_columnSmiMetaData); _usesStringStorageForXml = true; _eventSink.ProcessMessagesAndThrow(); }
internal static TextReader GetTextReader(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData) { bool isDbNull = ValueUtilsSmi.IsDBNull_Unchecked(sink, getters, ordinal); // If a sql_variant, get the internal type if ((!isDbNull) && (metaData.SqlDbType == SqlDbType.Variant)) { metaData = getters.GetVariantType(sink, ordinal); } // If the SqlDbType is still variant, then it must contain null, so don't throw InvalidCast if ((metaData.SqlDbType != SqlDbType.Variant) && (!CanAccessGetterDirectly(metaData, ExtendedClrTypeCode.TextReader))) { throw ADP.InvalidCast(); } string data; if (isDbNull) { // "null" textreader data = string.Empty; } else { // Read all data data = GetString_Unchecked(sink, getters, ordinal); } // Wrap in pre-built object return(new StringReader(data)); }
internal static Stream GetStream(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, bool bypassTypeCheck = false) { bool isDbNull = ValueUtilsSmi.IsDBNull_Unchecked(sink, getters, ordinal); // If a sql_variant, get the internal type if (!bypassTypeCheck) { if ((!isDbNull) && (metaData.SqlDbType == SqlDbType.Variant)) { metaData = getters.GetVariantType(sink, ordinal); } // If the SqlDbType is still variant, then it must contain null, so don't throw InvalidCast if ((metaData.SqlDbType != SqlDbType.Variant) && (!CanAccessGetterDirectly(metaData, ExtendedClrTypeCode.Stream))) { throw ADP.InvalidCast(); } } byte[] data; if (isDbNull) { // "null" stream data = new byte[0]; } else { // Read all data data = GetByteArray_Unchecked(sink, getters, ordinal); } // Wrap data in pre-built object return(new MemoryStream(data, writable: false)); }
private SmiContextFactory() { if (InOutOfProcHelper.InProc) { Type smiLinkType = Type.GetType("Microsoft.SqlServer.Server.InProcLink, SqlAccess, PublicKeyToken=89845dcd8080cc91"); if (null == smiLinkType) { Debug.Assert(false, "could not get InProcLink type"); throw SQL.ContextUnavailableOutOfProc(); // Must not be a valid version of Sql Server. } System.Reflection.FieldInfo instanceField = GetStaticField(smiLinkType, "Instance"); if (instanceField != null) { _smiLink = (SmiLink)GetValue(instanceField); } else { Debug.Assert(false, "could not get InProcLink.Instance"); throw SQL.ContextUnavailableOutOfProc(); // Must not be a valid version of Sql Server. } System.Reflection.FieldInfo buildVersionField = GetStaticField(smiLinkType, "BuildVersion"); if (buildVersionField != null) { UInt32 buildVersion = (UInt32)GetValue(buildVersionField); _majorVersion = (byte)(buildVersion >> 24); _minorVersion = (byte)((buildVersion >> 16) & 0xff); _buildNum = (short)(buildVersion & 0xffff); _serverVersion = (String.Format((IFormatProvider)null, "{0:00}.{1:00}.{2:0000}", _majorVersion, (short)_minorVersion, _buildNum)); } else { _serverVersion = String.Empty; // default value if nothing exists. } _negotiatedSmiVersion = _smiLink.NegotiateVersion(SmiLink.InterfaceVersion); bool isSupportedVersion = false; for (int i = 0; !isSupportedVersion && i < __supportedSmiVersions.Length; i++) { if (__supportedSmiVersions[i] == _negotiatedSmiVersion) { isSupportedVersion = true; } } // Disconnect if we didn't get a supported version!! if (!isSupportedVersion) { _smiLink = null; } _eventSinkForGetCurrentContext = new SmiEventSink_Default(); } }
// 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); }
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; }
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 static SqlSequentialTextReaderSmi GetSequentialTextReader(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData) { Debug.Assert(!ValueUtilsSmi.IsDBNull_Unchecked(sink, getters, ordinal), "Should not try to get a SqlSequentialTextReaderSmi on a null column"); ThrowIfITypedGettersIsNull(sink, getters, ordinal); if (!CanAccessGetterDirectly(metaData, ExtendedClrTypeCode.TextReader)) { throw ADP.InvalidCast(); } // This will advance the column to ordinal long length = GetCharsLength_Unchecked(sink, getters, ordinal); return(new SqlSequentialTextReaderSmi(sink, getters, ordinal, length)); }
internal void CleanMessages() { SmiEventSink_Default parent = (SmiEventSink_Default)_parent; if (null != parent) { parent.CleanMessages(); } else { _errors = null; _warnings = null; } }
// calling GetTimeSpan on possibly v100 SMI internal static TimeSpan GetTimeSpan(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, bool gettersSupportKatmaiDateTime) { if (gettersSupportKatmaiDateTime) { return(GetTimeSpan(sink, (SmiTypedGetterSetter)getters, ordinal, metaData)); } ThrowIfITypedGettersIsNull(sink, getters, ordinal); object obj = GetValue(sink, getters, ordinal, metaData, null); if (null == obj) { throw ADP.InvalidCast(); } return((TimeSpan)obj); }
// SqlDataRecord public API /// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/ctor/*' /> public SqlDataRecord(params SqlMetaData[] metaData) { // Initial consistency check if (metaData == null) { throw ADP.ArgumentNull(nameof(metaData)); } _columnMetaData = new SqlMetaData[metaData.Length]; _columnSmiMetaData = new SmiExtendedMetaData[metaData.Length]; #if NETFRAMEWORK ulong smiVersion = SmiVersion; #endif for (int i = 0; i < _columnSmiMetaData.Length; i++) { if (metaData[i] == null) { throw ADP.ArgumentNull($"{nameof(metaData)}[{i}]"); } _columnMetaData[i] = metaData[i]; _columnSmiMetaData[i] = MetaDataUtilsSmi.SqlMetaDataToSmiExtendedMetaData(_columnMetaData[i]); #if NETFRAMEWORK if (!MetaDataUtilsSmi.IsValidForSmiVersion(_columnSmiMetaData[i], smiVersion)) { throw ADP.VersionDoesNotSupportDataType(_columnSmiMetaData[i].TypeName); } #endif } _eventSink = new SmiEventSink_Default(); #if NETFRAMEWORK if (InOutOfProcHelper.InProc) { _recordContext = SmiContextFactory.Instance.GetCurrentContext(); _recordBuffer = _recordContext.CreateRecordBuffer(_columnSmiMetaData, _eventSink); _usesStringStorageForXml = false; } else { _recordContext = null; _recordBuffer = new MemoryRecordBuffer(_columnSmiMetaData); _usesStringStorageForXml = true; } #else _recordBuffer = new MemoryRecordBuffer(_columnSmiMetaData); _eventSink.ProcessMessagesAndThrow(); #endif }
internal SqlDataRecord(SmiRecordBuffer recordBuffer, params SmiExtendedMetaData[] metaData) { Debug.Assert(recordBuffer != null, "invalid attempt to instantiate SqlDataRecord with null SmiRecordBuffer"); Debug.Assert(metaData != null, "invalid attempt to instantiate SqlDataRecord with null SmiExtendedMetaData[]"); _columnMetaData = new SqlMetaData[metaData.Length]; _columnSmiMetaData = new SmiExtendedMetaData[metaData.Length]; for (int i = 0; i < _columnSmiMetaData.Length; i++) { _columnSmiMetaData[i] = metaData[i]; _columnMetaData[i] = MetaDataUtilsSmi.SmiExtendedMetaDataToSqlMetaData(_columnSmiMetaData[i]); } _eventSink = new SmiEventSink_Default(); _recordBuffer = recordBuffer; _eventSink.ProcessMessagesAndThrow(); }
// spool a Stream into a scratch stream from the Smi interface and return it as a SqlStreamChars internal static SqlStreamChars CopyIntoNewSmiScratchStreamChars(Stream source, SmiEventSink_Default sink, SmiContext context) { SqlClientWrapperSmiStreamChars dest = new(sink, context.GetScratchStream(sink)); int chunkSize; if (source.CanSeek && __maxByteChunkSize > source.Length) { chunkSize = unchecked ((int)source.Length); // unchecked cast is safe due to check on line above } else { chunkSize = __maxByteChunkSize; } byte[] copyBuffer = new byte[chunkSize]; int bytesRead; while (0 != (bytesRead = source.Read(copyBuffer, 0, chunkSize))) { dest.Write(copyBuffer, 0, bytesRead); } dest.Flush(); // SQLBU 494334 // Need to re-wind scratch stream to beginning before returning dest.Seek(0, SeekOrigin.Begin); return(dest); }
internal static void FillCompatibleITypedSettersFromRecord(SmiEventSink_Default sink, ITypedSettersV3 setters, SmiMetaData[] metaData, SqlDataRecord record) { FillCompatibleITypedSettersFromRecord(sink, setters, metaData, record, null); }
// UDTs and null variants come back via return value, all else is via targetBuffer. // implements SqlClient 2.0-compatible output parameter semantics internal static object GetOutputParameterV3Smi( SmiEventSink_Default sink, // event sink for errors ITypedGettersV3 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) { case SqlDbType.BigInt: targetBuffer.Int64 = GetInt64_Unchecked(sink, getters, ordinal); break; case SqlDbType.Binary: case SqlDbType.Image: case SqlDbType.Timestamp: case SqlDbType.VarBinary: targetBuffer.SqlBinary = GetSqlBinary_Unchecked(sink, getters, ordinal); break; case SqlDbType.Bit: targetBuffer.Boolean = GetBoolean_Unchecked(sink, getters, ordinal); break; case SqlDbType.NChar: case SqlDbType.NText: case SqlDbType.NVarChar: case SqlDbType.Char: case SqlDbType.VarChar: case SqlDbType.Text: targetBuffer.SetToString(GetString_Unchecked(sink, getters, ordinal)); break; case SqlDbType.DateTime: case SqlDbType.SmallDateTime: { SqlDateTime dt = new(GetDateTime_Unchecked(sink, getters, ordinal)); targetBuffer.SetToDateTime(dt.DayTicks, dt.TimeTicks); break; } case SqlDbType.Decimal: { SqlDecimal dec = GetSqlDecimal_Unchecked(sink, getters, ordinal); targetBuffer.SetToDecimal(dec.Precision, dec.Scale, dec.IsPositive, dec.Data); break; } case SqlDbType.Float: targetBuffer.Double = GetDouble_Unchecked(sink, getters, ordinal); break; case SqlDbType.Int: targetBuffer.Int32 = GetInt32_Unchecked(sink, getters, ordinal); break; case SqlDbType.Money: case SqlDbType.SmallMoney: targetBuffer.SetToMoney(GetInt64_Unchecked(sink, getters, ordinal)); break; case SqlDbType.Real: targetBuffer.Single = GetSingle_Unchecked(sink, getters, ordinal); break; case SqlDbType.UniqueIdentifier: targetBuffer.SqlGuid = new SqlGuid(GetGuid_Unchecked(sink, getters, ordinal)); break; case SqlDbType.SmallInt: targetBuffer.Int16 = GetInt16_Unchecked(sink, getters, ordinal); break; case SqlDbType.TinyInt: targetBuffer.Byte = GetByte_Unchecked(sink, getters, ordinal); break; case SqlDbType.Variant: // 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!"); GetOutputParameterV3Smi(sink, getters, ordinal, metaData, context, targetBuffer); break; case SqlDbType.Udt: result = GetUdt_LengthChecked(sink, getters, ordinal, metaData); break; case SqlDbType.Xml: targetBuffer.SqlXml = GetSqlXml_Unchecked(sink, getters, ordinal, null); break; default: Debug.Assert(false, "Unexpected SqlDbType"); break; } } return(result); }
internal static void FillCompatibleITypedSettersFromRecord(SmiEventSink_Default sink, ITypedSettersV3 setters, SmiMetaData[] metaData, SqlDataRecord record, SmiDefaultFieldsProperty useDefaultValues) { for (int i = 0; i < metaData.Length; ++i) { if (null != useDefaultValues && useDefaultValues[i]) { continue; } if (record.IsDBNull(i)) { ValueUtilsSmi.SetDBNull_Unchecked(sink, setters, i); } else { switch (metaData[i].SqlDbType) { case SqlDbType.BigInt: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Int64)); SetInt64_Unchecked(sink, setters, i, record.GetInt64(i)); break; case SqlDbType.Binary: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes)); SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0); break; case SqlDbType.Bit: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Boolean)); SetBoolean_Unchecked(sink, setters, i, record.GetBoolean(i)); break; case SqlDbType.Char: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlChars)); SetChars_FromRecord(sink, setters, i, metaData[i], record, 0); break; case SqlDbType.DateTime: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.DateTime)); SetDateTime_Checked(sink, setters, i, metaData[i], record.GetDateTime(i)); break; case SqlDbType.Decimal: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlDecimal)); SetSqlDecimal_Unchecked(sink, setters, i, record.GetSqlDecimal(i)); break; case SqlDbType.Float: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Double)); SetDouble_Unchecked(sink, setters, i, record.GetDouble(i)); break; case SqlDbType.Image: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes)); SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0); break; case SqlDbType.Int: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Int32)); SetInt32_Unchecked(sink, setters, i, record.GetInt32(i)); break; case SqlDbType.Money: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlMoney)); SetSqlMoney_Unchecked(sink, setters, i, metaData[i], record.GetSqlMoney(i)); break; case SqlDbType.NChar: case SqlDbType.NText: case SqlDbType.NVarChar: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlChars)); SetChars_FromRecord(sink, setters, i, metaData[i], record, 0); break; case SqlDbType.Real: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Single)); SetSingle_Unchecked(sink, setters, i, record.GetFloat(i)); break; case SqlDbType.UniqueIdentifier: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Guid)); SetGuid_Unchecked(sink, setters, i, record.GetGuid(i)); break; case SqlDbType.SmallDateTime: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.DateTime)); SetDateTime_Checked(sink, setters, i, metaData[i], record.GetDateTime(i)); break; case SqlDbType.SmallInt: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Int16)); SetInt16_Unchecked(sink, setters, i, record.GetInt16(i)); break; case SqlDbType.SmallMoney: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlMoney)); SetSqlMoney_Checked(sink, setters, i, metaData[i], record.GetSqlMoney(i)); break; case SqlDbType.Text: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlChars)); SetChars_FromRecord(sink, setters, i, metaData[i], record, 0); break; case SqlDbType.Timestamp: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes)); SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0); break; case SqlDbType.TinyInt: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Byte)); SetByte_Unchecked(sink, setters, i, record.GetByte(i)); break; case SqlDbType.VarBinary: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes)); SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0); break; case SqlDbType.VarChar: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.String)); SetChars_FromRecord(sink, setters, i, metaData[i], record, 0); break; case SqlDbType.Xml: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlXml)); SetSqlXml_Unchecked(sink, setters, i, record.GetSqlXml(i)); // perf improvement? break; case SqlDbType.Variant: object o = record.GetSqlValue(i); ExtendedClrTypeCode typeCode = MetaDataUtilsSmi.DetermineExtendedTypeCode(o); SetCompatibleValue(sink, setters, i, metaData[i], o, typeCode, 0); break; case SqlDbType.Udt: Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes)); SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0); break; default: Debug.Assert(false, "unsupported DbType:" + metaData[i].SqlDbType.ToString()); throw ADP.NotSupported(); } } } }