Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data / Microsoft / SqlServer / Server / SqlDataRecord.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="SmiMetaData.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
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 // <owner current="false" primary="false">Microsoft</owner>
9 //------------------------------------------------------------------------------
10
11 namespace Microsoft.SqlServer.Server {
12
13     using System;
14     using System.Data;
15     using System.Data.Common;
16     using System.Data.ProviderBase;
17     using System.Data.Sql;
18     using System.Data.SqlTypes;
19     using System.Data.SqlClient;
20     using System.Diagnostics;
21
22     public class SqlDataRecord : IDataRecord {
23         SmiRecordBuffer         _recordBuffer;
24         SmiContext              _recordContext;
25         SmiExtendedMetaData[]   _columnSmiMetaData;
26         SmiEventSink_Default    _eventSink;
27         SqlMetaData[]           _columnMetaData;
28         FieldNameLookup         _fieldNameLookup;
29         bool                    _usesStringStorageForXml;
30
31         static readonly SmiMetaData __maxNVarCharForXml = new SmiMetaData(SqlDbType.NVarChar, SmiMetaData.UnlimitedMaxLengthIndicator,
32                                         SmiMetaData.DefaultNVarChar_NoCollation.Precision,
33                                         SmiMetaData.DefaultNVarChar_NoCollation.Scale,
34                                         SmiMetaData.DefaultNVarChar.LocaleId,
35                                         SmiMetaData.DefaultNVarChar.CompareOptions,
36                                         null);
37
38         public virtual int FieldCount {
39             get {
40                 EnsureSubclassOverride();
41                 return _columnMetaData.Length;
42             }
43         }
44
45         public virtual String GetName( int ordinal ) {
46             EnsureSubclassOverride();
47             return GetSqlMetaData(ordinal).Name;
48         }
49
50         public virtual String GetDataTypeName( int ordinal ) {
51             EnsureSubclassOverride();
52             SqlMetaData metaData = GetSqlMetaData(ordinal);
53             if ( SqlDbType.Udt == metaData.SqlDbType ) {
54                 return metaData.UdtTypeName;
55             }
56             else {
57                 return MetaType.GetMetaTypeFromSqlDbType(metaData.SqlDbType, false).TypeName;
58             }
59         }
60
61         public virtual Type GetFieldType( int ordinal ) {
62             EnsureSubclassOverride();
63             if (SqlDbType.Udt == GetSqlMetaData(ordinal).SqlDbType) {
64                 return GetSqlMetaData( ordinal ).Type;
65             }
66             else {
67                 SqlMetaData md = GetSqlMetaData(ordinal);
68                 return MetaType.GetMetaTypeFromSqlDbType(md.SqlDbType, false).ClassType;
69             }
70         }
71
72         public virtual Object GetValue(int ordinal) {
73             EnsureSubclassOverride();
74             SmiMetaData metaData = GetSmiMetaData(ordinal);
75
76             if (SmiVersion >= SmiContextFactory.KatmaiVersion) {
77                 return ValueUtilsSmi.GetValue200(
78                                 _eventSink,
79                                 _recordBuffer,
80                                 ordinal,
81                                 metaData,
82                                 _recordContext
83                                 );
84             }
85             else {
86                 return ValueUtilsSmi.GetValue(
87                                 _eventSink,
88                                 (ITypedGettersV3)_recordBuffer,
89                                 ordinal,
90                                 metaData,
91                                 _recordContext
92                                 );
93             }
94         }
95
96         public virtual int GetValues( object[] values ) {
97             EnsureSubclassOverride();
98             if (null == values) {
99                 throw ADP.ArgumentNull("values");
100             }
101
102             int copyLength = ( values.Length < FieldCount ) ? values.Length : FieldCount;
103             for(int i=0; i<copyLength; i++) {
104                 values[i] = GetValue( i );
105             }
106
107             return copyLength;
108         }
109
110         public virtual int GetOrdinal( string name ) {
111             EnsureSubclassOverride();
112             if (null == _fieldNameLookup) {
113                 string[] names = new string [ FieldCount ];
114                 for( int i=0; i < names.Length; i++ ) {
115                     names[i] = GetSqlMetaData( i ).Name;
116                 }
117
118                 _fieldNameLookup = new FieldNameLookup( names, -1 );  // 
119             }
120
121             return _fieldNameLookup.GetOrdinal( name );
122         }
123
124         public virtual object this [ int ordinal ] {
125             get {
126                 EnsureSubclassOverride();
127                 return GetValue(ordinal);
128             }
129         }
130
131         public virtual object this [ String name ] {
132             get {
133                 EnsureSubclassOverride();
134                 return GetValue(GetOrdinal(name));
135             }
136         }
137
138         public virtual bool GetBoolean(int ordinal) {
139             EnsureSubclassOverride();
140             return ValueUtilsSmi.GetBoolean(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
141         }
142
143         public virtual byte GetByte(int ordinal) {
144             EnsureSubclassOverride();
145             return ValueUtilsSmi.GetByte(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
146         }
147
148         public virtual long GetBytes(int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length) {
149             EnsureSubclassOverride();
150             return ValueUtilsSmi.GetBytes(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), fieldOffset, buffer, bufferOffset, length, true);
151         }
152
153         public virtual char GetChar(int ordinal) {
154             EnsureSubclassOverride();
155             throw ADP.NotSupported();
156         }
157
158         public virtual long GetChars(int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length) {
159             EnsureSubclassOverride();
160             return ValueUtilsSmi.GetChars(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), fieldOffset, buffer, bufferOffset, length);
161         }
162
163         public virtual Guid GetGuid(int ordinal) {
164             EnsureSubclassOverride();
165             return ValueUtilsSmi.GetGuid(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
166         }
167
168         public virtual Int16 GetInt16(int ordinal) {
169             EnsureSubclassOverride();
170             return ValueUtilsSmi.GetInt16(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
171         }
172
173         public virtual Int32 GetInt32(int ordinal) {
174             EnsureSubclassOverride();
175             return ValueUtilsSmi.GetInt32(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
176         }
177
178         public virtual Int64 GetInt64(int ordinal) {
179             EnsureSubclassOverride();
180             return ValueUtilsSmi.GetInt64(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
181         }
182
183         public virtual float GetFloat(int ordinal) {
184             EnsureSubclassOverride();
185             return ValueUtilsSmi.GetSingle(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
186         }
187
188         public virtual double GetDouble(int ordinal) {
189             EnsureSubclassOverride();
190             return ValueUtilsSmi.GetDouble(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
191         }
192
193         public virtual string GetString(int ordinal) {
194             EnsureSubclassOverride();
195             SmiMetaData colMeta = GetSmiMetaData(ordinal);
196             if (_usesStringStorageForXml && SqlDbType.Xml == colMeta.SqlDbType) {
197                 return ValueUtilsSmi.GetString(_eventSink, _recordBuffer, ordinal, __maxNVarCharForXml);
198             }
199             else {
200                 return ValueUtilsSmi.GetString(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
201             }
202         }
203
204         public virtual Decimal GetDecimal(int ordinal) {
205             EnsureSubclassOverride();
206             return ValueUtilsSmi.GetDecimal(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
207         }
208
209         public virtual DateTime GetDateTime(int ordinal) {
210             EnsureSubclassOverride();
211             return ValueUtilsSmi.GetDateTime(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
212         }
213
214         public virtual DateTimeOffset GetDateTimeOffset(int ordinal) {
215             EnsureSubclassOverride();
216             return ValueUtilsSmi.GetDateTimeOffset(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
217         }
218
219         public virtual TimeSpan GetTimeSpan(int ordinal) {
220             EnsureSubclassOverride();
221             return ValueUtilsSmi.GetTimeSpan(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
222         }
223
224         [ System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never) ] // MDAC 69508
225         IDataReader IDataRecord.GetData(int ordinal) {
226             throw ADP.NotSupported();
227         }
228
229         public virtual bool IsDBNull(int ordinal) {
230             EnsureSubclassOverride();
231             ThrowIfInvalidOrdinal(ordinal);
232             return ValueUtilsSmi.IsDBNull( _eventSink, _recordBuffer, ordinal );
233         }
234
235         //
236         //  ISqlRecord implementation
237         //
238         public virtual SqlMetaData GetSqlMetaData(int ordinal) {
239             EnsureSubclassOverride();
240             return _columnMetaData[ordinal];
241         }
242
243         public virtual Type GetSqlFieldType(int ordinal) {
244             EnsureSubclassOverride();
245             SqlMetaData md = GetSqlMetaData(ordinal);
246             return MetaType.GetMetaTypeFromSqlDbType(md.SqlDbType, false).SqlType;
247         }
248
249         public virtual object GetSqlValue(int ordinal) {
250             EnsureSubclassOverride();
251             SmiMetaData metaData = GetSmiMetaData(ordinal);
252             if (SmiVersion >= SmiContextFactory.KatmaiVersion) {
253                 return ValueUtilsSmi.GetSqlValue200(_eventSink, _recordBuffer, ordinal, metaData, _recordContext);
254             }
255             return ValueUtilsSmi.GetSqlValue( _eventSink, _recordBuffer, ordinal, metaData, _recordContext );
256         }
257
258         public virtual int GetSqlValues(object[] values) {
259             EnsureSubclassOverride();
260             if (null == values) {
261                 throw ADP.ArgumentNull("values");
262             }
263
264
265             int copyLength = (values.Length < FieldCount) ? values.Length : FieldCount;
266             for(int i=0; i<copyLength; i++) {
267                 values[i] = GetSqlValue(i);
268             }
269
270             return copyLength;
271         }
272
273         public virtual SqlBinary GetSqlBinary(int ordinal) {
274             EnsureSubclassOverride();
275             return ValueUtilsSmi.GetSqlBinary(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
276         }
277
278         public virtual SqlBytes GetSqlBytes(int ordinal) {
279             EnsureSubclassOverride();
280             return ValueUtilsSmi.GetSqlBytes(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), _recordContext);
281         }
282
283         public virtual SqlXml GetSqlXml(int ordinal) {
284             EnsureSubclassOverride();
285             return ValueUtilsSmi.GetSqlXml(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), _recordContext);
286         }
287
288         public virtual SqlBoolean GetSqlBoolean(int ordinal) {
289             EnsureSubclassOverride();
290             return ValueUtilsSmi.GetSqlBoolean(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
291         }
292
293         public virtual SqlByte GetSqlByte(int ordinal) {
294             EnsureSubclassOverride();
295             return ValueUtilsSmi.GetSqlByte(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
296         }
297
298         public virtual SqlChars GetSqlChars(int ordinal) {
299             EnsureSubclassOverride();
300             return ValueUtilsSmi.GetSqlChars(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), _recordContext);
301         }
302
303         public virtual SqlInt16 GetSqlInt16(int ordinal) {
304             EnsureSubclassOverride();
305             return ValueUtilsSmi.GetSqlInt16(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
306         }
307
308         public virtual SqlInt32 GetSqlInt32(int ordinal) {
309             EnsureSubclassOverride();
310             return ValueUtilsSmi.GetSqlInt32(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
311         }
312
313         public virtual SqlInt64 GetSqlInt64(int ordinal) {
314             EnsureSubclassOverride();
315             return ValueUtilsSmi.GetSqlInt64(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
316         }
317
318         public virtual SqlSingle GetSqlSingle(int ordinal) {
319             EnsureSubclassOverride();
320             return ValueUtilsSmi.GetSqlSingle(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
321         }
322
323         public virtual SqlDouble GetSqlDouble(int ordinal) {
324             EnsureSubclassOverride();
325             return ValueUtilsSmi.GetSqlDouble(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
326         }
327
328         public virtual SqlMoney GetSqlMoney(int ordinal) {
329             EnsureSubclassOverride();
330             return ValueUtilsSmi.GetSqlMoney(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
331         }
332
333         public virtual SqlDateTime GetSqlDateTime(int ordinal) {
334             EnsureSubclassOverride();
335             return ValueUtilsSmi.GetSqlDateTime(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
336         }
337
338         public virtual SqlDecimal GetSqlDecimal(int ordinal) {
339             EnsureSubclassOverride();
340             return ValueUtilsSmi.GetSqlDecimal(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
341         }
342
343         public virtual SqlString GetSqlString(int ordinal) {
344             EnsureSubclassOverride();
345             return ValueUtilsSmi.GetSqlString(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
346         }
347
348         public virtual SqlGuid GetSqlGuid(int ordinal) {
349             EnsureSubclassOverride();
350             return ValueUtilsSmi.GetSqlGuid(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
351         }
352
353         //
354         // ISqlUpdateableRecord Implementation
355         //
356         public virtual int SetValues( params object[] values ) {
357             EnsureSubclassOverride();
358             if (null == values) {
359                 throw ADP.ArgumentNull( "values" );
360             }
361
362             // SQLBUDT #346883 Allow values array longer than FieldCount, just ignore the extra cells.
363             int copyLength = ( values.Length > FieldCount ) ? FieldCount : values.Length;
364
365             ExtendedClrTypeCode[] typeCodes = new ExtendedClrTypeCode [copyLength];
366
367             // Verify all data values as acceptable before changing current state.
368             for (int i=0; i < copyLength; i++) {
369                 SqlMetaData metaData = GetSqlMetaData(i);
370                 typeCodes[i] = MetaDataUtilsSmi.DetermineExtendedTypeCodeForUseWithSqlDbType(
371                     metaData.SqlDbType, false /* isMultiValued */, values[i], metaData.Type, SmiVersion);
372                 if ( ExtendedClrTypeCode.Invalid == typeCodes[i] ) {
373                     throw ADP.InvalidCast();
374                 }
375             }
376
377             // Now move the data (it'll only throw if someone plays with the values array between
378             //      the validation loop and here, or if an invalid UDT was sent).
379             for( int i=0; i < copyLength; i++ ) {
380                 if (SmiVersion >= SmiContextFactory.KatmaiVersion) {
381                     ValueUtilsSmi.SetCompatibleValueV200(_eventSink, _recordBuffer, i, GetSmiMetaData(i), values[i], typeCodes[i], 0, 0, null);
382                 }
383                 else {
384                     ValueUtilsSmi.SetCompatibleValue(_eventSink, _recordBuffer, i, GetSmiMetaData(i), values[i], typeCodes[i], 0);
385                 }
386             }
387
388             return copyLength;
389         }
390
391         public virtual void SetValue( int ordinal, object value ) {
392             EnsureSubclassOverride();
393             SqlMetaData metaData = GetSqlMetaData(ordinal);
394             ExtendedClrTypeCode typeCode = MetaDataUtilsSmi.DetermineExtendedTypeCodeForUseWithSqlDbType(
395                         metaData.SqlDbType, false /* isMultiValued */, value, metaData.Type, SmiVersion);
396             if ( ExtendedClrTypeCode.Invalid == typeCode ) {
397                     throw ADP.InvalidCast();
398             }
399
400             if (SmiVersion >= SmiContextFactory.KatmaiVersion) {
401                 ValueUtilsSmi.SetCompatibleValueV200(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value, typeCode, 0, 0, null);
402             }
403             else {
404                 ValueUtilsSmi.SetCompatibleValue(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value, typeCode, 0);
405             }
406         }
407
408         public virtual void SetBoolean(int ordinal, bool value) {
409             EnsureSubclassOverride();
410             ValueUtilsSmi.SetBoolean(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
411         }
412
413         public virtual void SetByte(int ordinal, byte value) {
414             EnsureSubclassOverride();
415             ValueUtilsSmi.SetByte(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
416         }
417
418         public virtual void SetBytes(int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length) {
419             EnsureSubclassOverride();
420             ValueUtilsSmi.SetBytes(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), fieldOffset, buffer, bufferOffset, length);
421         }
422
423         public virtual void SetChar(int ordinal,  char value) {
424             EnsureSubclassOverride();
425             throw ADP.NotSupported();
426         }
427
428         public virtual void SetChars(int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length) {
429             EnsureSubclassOverride();
430             ValueUtilsSmi.SetChars(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), fieldOffset, buffer, bufferOffset, length);
431         }
432
433         public virtual void SetInt16(int ordinal,  System.Int16 value) {
434             EnsureSubclassOverride();
435             ValueUtilsSmi.SetInt16(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
436         }
437
438         public virtual void SetInt32(int ordinal, System.Int32 value) {
439             EnsureSubclassOverride();
440             ValueUtilsSmi.SetInt32(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
441         }
442
443         public virtual void SetInt64(int ordinal, System.Int64 value) {
444             EnsureSubclassOverride();
445             ValueUtilsSmi.SetInt64(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
446         }
447
448         public virtual void SetFloat(int ordinal, float value) {
449             EnsureSubclassOverride();
450             ValueUtilsSmi.SetSingle(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
451         }
452
453         public virtual void SetDouble(int ordinal,  double value) {
454             EnsureSubclassOverride();
455             ValueUtilsSmi.SetDouble(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
456         }
457
458         public virtual void SetString(int ordinal, string value) {
459             EnsureSubclassOverride();
460             ValueUtilsSmi.SetString(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
461         }
462
463         public virtual void SetDecimal(int ordinal,  Decimal value) {
464             EnsureSubclassOverride();
465             ValueUtilsSmi.SetDecimal(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
466         }
467
468         public virtual void SetDateTime(int ordinal,  DateTime value) {
469             EnsureSubclassOverride();
470             ValueUtilsSmi.SetDateTime(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
471         }
472
473         public virtual void SetTimeSpan(int ordinal, TimeSpan value) {
474             EnsureSubclassOverride();
475             ValueUtilsSmi.SetTimeSpan(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value, SmiVersion >= SmiContextFactory.KatmaiVersion);
476         }
477
478         public virtual void SetDateTimeOffset(int ordinal, DateTimeOffset value) {
479             EnsureSubclassOverride();
480             ValueUtilsSmi.SetDateTimeOffset(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value, SmiVersion >= SmiContextFactory.KatmaiVersion);
481         }
482
483         public virtual void SetDBNull(int ordinal) {
484             EnsureSubclassOverride();
485             ValueUtilsSmi.SetDBNull(_eventSink, _recordBuffer, ordinal, true);
486         }
487
488         public virtual void SetGuid(int ordinal, Guid value) {
489             EnsureSubclassOverride();
490             ValueUtilsSmi.SetGuid(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
491         }
492
493         public virtual void SetSqlBoolean(int ordinal, SqlBoolean value) {
494             EnsureSubclassOverride();
495             ValueUtilsSmi.SetSqlBoolean(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
496         }
497
498         public virtual void SetSqlByte(int ordinal, SqlByte value) {
499             EnsureSubclassOverride();
500             ValueUtilsSmi.SetSqlByte(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
501         }
502
503         public virtual void SetSqlInt16(int ordinal, SqlInt16 value) {
504             EnsureSubclassOverride();
505             ValueUtilsSmi.SetSqlInt16(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
506         }
507
508         public virtual void SetSqlInt32(int ordinal, SqlInt32 value) {
509             EnsureSubclassOverride();
510             ValueUtilsSmi.SetSqlInt32(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
511         }
512
513         public virtual void SetSqlInt64(int ordinal, SqlInt64 value) {
514             EnsureSubclassOverride();
515             ValueUtilsSmi.SetSqlInt64(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
516         }
517
518         public virtual void SetSqlSingle(int ordinal, SqlSingle value) {
519             EnsureSubclassOverride();
520             ValueUtilsSmi.SetSqlSingle(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
521         }
522
523         public virtual void SetSqlDouble(int ordinal, SqlDouble value) {
524             EnsureSubclassOverride();
525             ValueUtilsSmi.SetSqlDouble(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
526         }
527
528         public virtual void SetSqlMoney(int ordinal, SqlMoney value) {
529             EnsureSubclassOverride();
530             ValueUtilsSmi.SetSqlMoney(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
531         }
532
533         public virtual void SetSqlDateTime(int ordinal, SqlDateTime value) {
534             EnsureSubclassOverride();
535             ValueUtilsSmi.SetSqlDateTime(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
536         }
537
538         public virtual void SetSqlXml(int ordinal, SqlXml value) {
539             EnsureSubclassOverride();
540             ValueUtilsSmi.SetSqlXml(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
541         }
542
543         public virtual void SetSqlDecimal(int ordinal, SqlDecimal value) {
544             EnsureSubclassOverride();
545             ValueUtilsSmi.SetSqlDecimal(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
546         }
547
548         public virtual void SetSqlString(int ordinal, SqlString value) {
549             EnsureSubclassOverride();
550             ValueUtilsSmi.SetSqlString(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
551         }
552
553         public virtual void SetSqlBinary(int ordinal, SqlBinary value) {
554             EnsureSubclassOverride();
555             ValueUtilsSmi.SetSqlBinary(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
556         }
557
558         public virtual void SetSqlGuid(int ordinal, SqlGuid value) {
559             EnsureSubclassOverride();
560             ValueUtilsSmi.SetSqlGuid(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
561         }
562
563         public virtual void SetSqlChars(int ordinal, SqlChars value) {
564             EnsureSubclassOverride();
565             ValueUtilsSmi.SetSqlChars(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
566         }
567
568         public virtual void SetSqlBytes(int ordinal, SqlBytes value) {
569             EnsureSubclassOverride();
570             ValueUtilsSmi.SetSqlBytes(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
571         }
572
573
574         //
575         //  SqlDataRecord public API
576         //
577
578         public SqlDataRecord( params SqlMetaData[] metaData ) {
579             // Initial consistency check
580             if ( null == metaData ) {
581                 throw ADP.ArgumentNull( "metadata" );
582             }
583
584             _columnMetaData = new SqlMetaData[metaData.Length];
585             _columnSmiMetaData = new SmiExtendedMetaData[metaData.Length];
586             ulong smiVersion = SmiVersion;
587             for (int i = 0; i < _columnSmiMetaData.Length; i++) {
588                 if ( null == metaData[i] ) {
589                     throw ADP.ArgumentNull( "metadata["+i+"]" );
590                 }
591                 _columnMetaData[i] = metaData[i];
592                 _columnSmiMetaData[i] = MetaDataUtilsSmi.SqlMetaDataToSmiExtendedMetaData( _columnMetaData[i] );
593                 if (!MetaDataUtilsSmi.IsValidForSmiVersion(_columnSmiMetaData[i], smiVersion)) {
594                     throw ADP.VersionDoesNotSupportDataType(_columnSmiMetaData[i].TypeName);
595                 }
596             }
597
598             _eventSink = new SmiEventSink_Default( );
599
600             if (InOutOfProcHelper.InProc) {
601                 _recordContext = SmiContextFactory.Instance.GetCurrentContext();
602                 _recordBuffer = _recordContext.CreateRecordBuffer( _columnSmiMetaData, _eventSink );
603                 _usesStringStorageForXml = false;
604             }
605             else {
606                 _recordContext = null;
607                 _recordBuffer = new MemoryRecordBuffer(_columnSmiMetaData);
608                 _usesStringStorageForXml = true;
609             }
610             _eventSink.ProcessMessagesAndThrow();
611         }
612
613         internal SqlDataRecord( SmiRecordBuffer recordBuffer, params SmiExtendedMetaData[] metaData ) {
614             Debug.Assert(null != recordBuffer, "invalid attempt to instantiate SqlDataRecord with null SmiRecordBuffer");
615             Debug.Assert(null != metaData, "invalid attempt to instantiate SqlDataRecord with null SmiExtendedMetaData[]");
616
617             _columnMetaData = new SqlMetaData[metaData.Length];
618             _columnSmiMetaData = new SmiExtendedMetaData[metaData.Length];
619             for (int i = 0; i < _columnSmiMetaData.Length; i++) {
620                 _columnSmiMetaData[i] = metaData[i];
621                 _columnMetaData[i] = MetaDataUtilsSmi.SmiExtendedMetaDataToSqlMetaData( _columnSmiMetaData[i] );
622             }
623
624             _eventSink = new SmiEventSink_Default( );
625
626             if (InOutOfProcHelper.InProc) {
627                 _recordContext = SmiContextFactory.Instance.GetCurrentContext();
628             }
629             else {
630                 _recordContext = null;
631             }
632             _recordBuffer = recordBuffer;
633             _eventSink.ProcessMessagesAndThrow();
634         }
635
636         //
637         //  SqlDataRecord private members
638         //
639         internal SmiRecordBuffer RecordBuffer {  // used by SqlPipe
640             get {
641                 return _recordBuffer;
642             }
643         }
644
645         internal SmiContext RecordContext {
646             get {
647                 return _recordContext;
648             }
649         }
650
651         private ulong SmiVersion {
652             get {
653                 return InOutOfProcHelper.InProc ? SmiContextFactory.Instance.NegotiatedSmiVersion : SmiContextFactory.LatestVersion;
654             }
655         }
656
657         internal SqlMetaData[] InternalGetMetaData() {
658             return _columnMetaData;
659         }
660
661         internal SmiExtendedMetaData[] InternalGetSmiMetaData() {
662             return _columnSmiMetaData;
663         }
664
665         internal SmiExtendedMetaData GetSmiMetaData( int ordinal ) {
666             return _columnSmiMetaData[ordinal];
667         }
668
669         internal void ThrowIfInvalidOrdinal( int ordinal ) {
670             if ( 0 > ordinal || FieldCount <= ordinal ) {
671                 throw ADP.IndexOutOfRange( ordinal );
672             }
673         }
674         private void EnsureSubclassOverride() {
675             if (null == _recordBuffer) {
676                 throw SQL.SubclassMustOverride();
677             }
678         }
679     }
680 }
681