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(); }
// 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); }
// 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("metadata"); } _columnMetaData = new SqlMetaData[metaData.Length]; _columnSmiMetaData = new SmiExtendedMetaData[metaData.Length]; ulong smiVersion = SmiVersion; for (int i = 0; i < _columnSmiMetaData.Length; i++) { if (null == metaData[i]) { throw ADP.ArgumentNull("metadata[" + i + "]"); } _columnMetaData[i] = metaData[i]; _columnSmiMetaData[i] = MetaDataUtilsSmi.SqlMetaDataToSmiExtendedMetaData(_columnMetaData[i]); if (!MetaDataUtilsSmi.IsValidForSmiVersion(_columnSmiMetaData[i], smiVersion)) { throw ADP.VersionDoesNotSupportDataType(_columnSmiMetaData[i].TypeName); } } _eventSink = new SmiEventSink_Default(); if (InOutOfProcHelper.InProc) { _recordContext = SmiContextFactory.Instance.GetCurrentContext(); _recordBuffer = _recordContext.CreateRecordBuffer(_columnSmiMetaData, _eventSink); _usesStringStorageForXml = false; } else { _recordContext = null; _recordBuffer = new MemoryRecordBuffer(_columnSmiMetaData); _usesStringStorageForXml = true; } _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); }
// 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); }