1 //------------------------------------------------------------------------------
2 // <copyright file="MemoryRecordBuffer.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 // <owner current="true" primary="false">Microsoft</owner>
8 //------------------------------------------------------------------------------
10 namespace Microsoft.SqlServer.Server {
13 using System.Data.SqlTypes;
14 using System.Diagnostics;
16 // Class for implementing a record object used in out-of-proc scenarios.
17 internal sealed class MemoryRecordBuffer : SmiRecordBuffer {
19 private SqlRecordBuffer[] _buffer;
21 internal MemoryRecordBuffer(SmiMetaData[] metaData) {
22 Debug.Assert(null != metaData, "invalid attempt to instantiate MemoryRecordBuffer with null SmiMetaData[]");
24 _buffer = new SqlRecordBuffer[metaData.Length];
26 for (int i = 0; i < _buffer.Length; ++i) {
27 _buffer[i] = new SqlRecordBuffer(metaData[i]);
33 // valid for all types
34 public override bool IsDBNull(SmiEventSink sink, int ordinal) {
35 return _buffer[ordinal].IsNull;
38 // Check what type current sql_variant value is
39 // valid for SqlDbType.Variant
40 public override SmiMetaData GetVariantType(SmiEventSink sink, int ordinal) {
41 return _buffer[ordinal].VariantType;
44 // valid for SqlDbType.Bit
45 public override Boolean GetBoolean(SmiEventSink sink, int ordinal) {
46 return _buffer[ordinal].Boolean;
49 // valid for SqlDbType.TinyInt
50 public override Byte GetByte(SmiEventSink sink, int ordinal) {
51 return _buffer[ordinal].Byte;
54 // valid for SqlDbTypes: Binary, VarBinary, Image, Udt, Xml, Char, VarChar, Text, NChar, NVarChar, NText
55 // (Character type support needed for ExecuteXmlReader handling)
56 public override Int64 GetBytesLength(SmiEventSink sink, int ordinal) {
57 return _buffer[ordinal].BytesLength;
59 public override int GetBytes(SmiEventSink sink, int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length) {
60 return _buffer[ordinal].GetBytes(fieldOffset, buffer, bufferOffset, length);
63 // valid for character types: Char, VarChar, Text, NChar, NVarChar, NText
64 public override Int64 GetCharsLength(SmiEventSink sink, int ordinal) {
65 return _buffer[ordinal].CharsLength;
67 public override int GetChars(SmiEventSink sink, int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length) {
68 return _buffer[ordinal].GetChars(fieldOffset, buffer, bufferOffset, length);
70 public override String GetString(SmiEventSink sink, int ordinal) {
71 return _buffer[ordinal].String;
74 // valid for SqlDbType.SmallInt
75 public override Int16 GetInt16(SmiEventSink sink, int ordinal) {
76 return _buffer[ordinal].Int16;
79 // valid for SqlDbType.Int
80 public override Int32 GetInt32(SmiEventSink sink, int ordinal) {
81 return _buffer[ordinal].Int32;
84 // valid for SqlDbType.BigInt, SqlDbType.Money, SqlDbType.SmallMoney
85 public override Int64 GetInt64(SmiEventSink sink, int ordinal) {
86 return _buffer[ordinal].Int64;
89 // valid for SqlDbType.Real
90 public override Single GetSingle(SmiEventSink sink, int ordinal) {
91 return _buffer[ordinal].Single;
94 // valid for SqlDbType.Float
95 public override Double GetDouble(SmiEventSink sink, int ordinal) {
96 return _buffer[ordinal].Double;
99 // valid for SqlDbType.Numeric (uses SqlDecimal since Decimal cannot hold full range)
100 public override SqlDecimal GetSqlDecimal(SmiEventSink sink, int ordinal) {
101 return _buffer[ordinal].SqlDecimal;
104 // valid for DateTime, SmallDateTime, Date, and DateTime2
105 public override DateTime GetDateTime(SmiEventSink sink, int ordinal) {
106 return _buffer[ordinal].DateTime;
109 // valid for UniqueIdentifier
110 public override Guid GetGuid(SmiEventSink sink, int ordinal) {
111 return _buffer[ordinal].Guid;
114 // valid for SqlDbType.Time
115 public override TimeSpan GetTimeSpan(SmiEventSink sink, int ordinal) {
116 return _buffer[ordinal].TimeSpan;
119 // valid for DateTimeOffset
120 public override DateTimeOffset GetDateTimeOffset(SmiEventSink sink, int ordinal) {
121 return _buffer[ordinal].DateTimeOffset;
127 // valid for all types
128 public override void SetDBNull(SmiEventSink sink, int ordinal) {
129 _buffer[ordinal].SetNull();
132 // valid for SqlDbType.Bit
133 public override void SetBoolean(SmiEventSink sink, int ordinal, Boolean value) {
134 _buffer[ordinal].Boolean = value;
137 // valid for SqlDbType.TinyInt
138 public override void SetByte(SmiEventSink sink, int ordinal, Byte value) {
139 _buffer[ordinal].Byte = value;
142 // Semantics for SetBytes are to modify existing value, not overwrite
143 // Use in combination with SetLength to ensure overwriting when necessary
144 // valid for SqlDbTypes: Binary, VarBinary, Image, Udt, Xml
145 // (VarBinary assumed for variants)
146 public override int SetBytes(SmiEventSink sink, int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length) {
147 return _buffer[ordinal].SetBytes(fieldOffset, buffer, bufferOffset, length);
149 public override void SetBytesLength(SmiEventSink sink, int ordinal, long length) {
150 _buffer[ordinal].BytesLength = length;
153 // Semantics for SetChars are to modify existing value, not overwrite
154 // Use in combination with SetLength to ensure overwriting when necessary
155 // valid for character types: Char, VarChar, Text, NChar, NVarChar, NText
156 // (NVarChar and global clr collation assumed for variants)
157 public override int SetChars(SmiEventSink sink, int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length) {
158 return _buffer[ordinal].SetChars(fieldOffset, buffer, bufferOffset, length);
160 public override void SetCharsLength(SmiEventSink sink, int ordinal, long length) {
161 _buffer[ordinal].CharsLength = length;
164 // valid for character types: Char, VarChar, Text, NChar, NVarChar, NText
165 public override void SetString(SmiEventSink sink, int ordinal, string value, int offset, int length) {
166 Debug.Assert(offset == 0 && length <= value.Length, "Invalid string length or offset"); // for sqlvariant, length could be less than value.Length
168 _buffer[ordinal].String = value.Substring(offset, length); // Perf test shows that Substring method has already optimized the case where length = value.Length
171 // valid for SqlDbType.SmallInt
172 public override void SetInt16(SmiEventSink sink, int ordinal, Int16 value) {
173 _buffer[ordinal].Int16 = value;
176 // valid for SqlDbType.Int
177 public override void SetInt32(SmiEventSink sink, int ordinal, Int32 value) {
178 _buffer[ordinal].Int32 = value;
181 // valid for SqlDbType.BigInt, SqlDbType.Money, SqlDbType.SmallMoney
182 public override void SetInt64(SmiEventSink sink, int ordinal, Int64 value) {
183 _buffer[ordinal].Int64 = value;
186 // valid for SqlDbType.Real
187 public override void SetSingle(SmiEventSink sink, int ordinal, Single value) {
188 _buffer[ordinal].Single = value;
191 // valid for SqlDbType.Float
192 public override void SetDouble(SmiEventSink sink, int ordinal, Double value) {
193 _buffer[ordinal].Double = value;
196 // valid for SqlDbType.Numeric (uses SqlDecimal since Decimal cannot hold full range)
197 public override void SetSqlDecimal(SmiEventSink sink, int ordinal, SqlDecimal value) {
198 _buffer[ordinal].SqlDecimal = value;
201 // valid for DateTime, SmallDateTime, Date, and DateTime2
202 public override void SetDateTime(SmiEventSink sink, int ordinal, DateTime value) {
203 _buffer[ordinal].DateTime = value;
206 // valid for UniqueIdentifier
207 public override void SetGuid(SmiEventSink sink, int ordinal, Guid value) {
208 _buffer[ordinal].Guid = value;
212 public override void SetTimeSpan(SmiEventSink sink, int ordinal, TimeSpan value) {
213 _buffer[ordinal].TimeSpan = value;
217 public override void SetDateTimeOffset(SmiEventSink sink, int ordinal, DateTimeOffset value) {
218 _buffer[ordinal].DateTimeOffset = value;
221 // valid for SqlDbType.Variant
222 public override void SetVariantMetaData(SmiEventSink sink, int ordinal, SmiMetaData metaData) {
223 _buffer[ordinal].VariantType = metaData;