1 //------------------------------------------------------------------------------
2 // <copyright file="SmiMetaData.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 // <owner current="false" primary="false">Microsoft</owner>
9 //------------------------------------------------------------------------------
11 namespace Microsoft.SqlServer.Server {
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;
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;
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,
38 public virtual int FieldCount {
40 EnsureSubclassOverride();
41 return _columnMetaData.Length;
45 public virtual String GetName( int ordinal ) {
46 EnsureSubclassOverride();
47 return GetSqlMetaData(ordinal).Name;
50 public virtual String GetDataTypeName( int ordinal ) {
51 EnsureSubclassOverride();
52 SqlMetaData metaData = GetSqlMetaData(ordinal);
53 if ( SqlDbType.Udt == metaData.SqlDbType ) {
54 return metaData.UdtTypeName;
57 return MetaType.GetMetaTypeFromSqlDbType(metaData.SqlDbType, false).TypeName;
61 public virtual Type GetFieldType( int ordinal ) {
62 EnsureSubclassOverride();
63 if (SqlDbType.Udt == GetSqlMetaData(ordinal).SqlDbType) {
64 return GetSqlMetaData( ordinal ).Type;
67 SqlMetaData md = GetSqlMetaData(ordinal);
68 return MetaType.GetMetaTypeFromSqlDbType(md.SqlDbType, false).ClassType;
72 public virtual Object GetValue(int ordinal) {
73 EnsureSubclassOverride();
74 SmiMetaData metaData = GetSmiMetaData(ordinal);
76 if (SmiVersion >= SmiContextFactory.KatmaiVersion) {
77 return ValueUtilsSmi.GetValue200(
86 return ValueUtilsSmi.GetValue(
88 (ITypedGettersV3)_recordBuffer,
96 public virtual int GetValues( object[] values ) {
97 EnsureSubclassOverride();
99 throw ADP.ArgumentNull("values");
102 int copyLength = ( values.Length < FieldCount ) ? values.Length : FieldCount;
103 for(int i=0; i<copyLength; i++) {
104 values[i] = GetValue( i );
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;
118 _fieldNameLookup = new FieldNameLookup( names, -1 ); //
121 return _fieldNameLookup.GetOrdinal( name );
124 public virtual object this [ int ordinal ] {
126 EnsureSubclassOverride();
127 return GetValue(ordinal);
131 public virtual object this [ String name ] {
133 EnsureSubclassOverride();
134 return GetValue(GetOrdinal(name));
138 public virtual bool GetBoolean(int ordinal) {
139 EnsureSubclassOverride();
140 return ValueUtilsSmi.GetBoolean(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
143 public virtual byte GetByte(int ordinal) {
144 EnsureSubclassOverride();
145 return ValueUtilsSmi.GetByte(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
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);
153 public virtual char GetChar(int ordinal) {
154 EnsureSubclassOverride();
155 throw ADP.NotSupported();
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);
163 public virtual Guid GetGuid(int ordinal) {
164 EnsureSubclassOverride();
165 return ValueUtilsSmi.GetGuid(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
168 public virtual Int16 GetInt16(int ordinal) {
169 EnsureSubclassOverride();
170 return ValueUtilsSmi.GetInt16(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
173 public virtual Int32 GetInt32(int ordinal) {
174 EnsureSubclassOverride();
175 return ValueUtilsSmi.GetInt32(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
178 public virtual Int64 GetInt64(int ordinal) {
179 EnsureSubclassOverride();
180 return ValueUtilsSmi.GetInt64(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
183 public virtual float GetFloat(int ordinal) {
184 EnsureSubclassOverride();
185 return ValueUtilsSmi.GetSingle(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
188 public virtual double GetDouble(int ordinal) {
189 EnsureSubclassOverride();
190 return ValueUtilsSmi.GetDouble(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
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);
200 return ValueUtilsSmi.GetString(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
204 public virtual Decimal GetDecimal(int ordinal) {
205 EnsureSubclassOverride();
206 return ValueUtilsSmi.GetDecimal(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
209 public virtual DateTime GetDateTime(int ordinal) {
210 EnsureSubclassOverride();
211 return ValueUtilsSmi.GetDateTime(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
214 public virtual DateTimeOffset GetDateTimeOffset(int ordinal) {
215 EnsureSubclassOverride();
216 return ValueUtilsSmi.GetDateTimeOffset(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
219 public virtual TimeSpan GetTimeSpan(int ordinal) {
220 EnsureSubclassOverride();
221 return ValueUtilsSmi.GetTimeSpan(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
224 [ System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never) ] // MDAC 69508
225 IDataReader IDataRecord.GetData(int ordinal) {
226 throw ADP.NotSupported();
229 public virtual bool IsDBNull(int ordinal) {
230 EnsureSubclassOverride();
231 ThrowIfInvalidOrdinal(ordinal);
232 return ValueUtilsSmi.IsDBNull( _eventSink, _recordBuffer, ordinal );
236 // ISqlRecord implementation
238 public virtual SqlMetaData GetSqlMetaData(int ordinal) {
239 EnsureSubclassOverride();
240 return _columnMetaData[ordinal];
243 public virtual Type GetSqlFieldType(int ordinal) {
244 EnsureSubclassOverride();
245 SqlMetaData md = GetSqlMetaData(ordinal);
246 return MetaType.GetMetaTypeFromSqlDbType(md.SqlDbType, false).SqlType;
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);
255 return ValueUtilsSmi.GetSqlValue( _eventSink, _recordBuffer, ordinal, metaData, _recordContext );
258 public virtual int GetSqlValues(object[] values) {
259 EnsureSubclassOverride();
260 if (null == values) {
261 throw ADP.ArgumentNull("values");
265 int copyLength = (values.Length < FieldCount) ? values.Length : FieldCount;
266 for(int i=0; i<copyLength; i++) {
267 values[i] = GetSqlValue(i);
273 public virtual SqlBinary GetSqlBinary(int ordinal) {
274 EnsureSubclassOverride();
275 return ValueUtilsSmi.GetSqlBinary(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
278 public virtual SqlBytes GetSqlBytes(int ordinal) {
279 EnsureSubclassOverride();
280 return ValueUtilsSmi.GetSqlBytes(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), _recordContext);
283 public virtual SqlXml GetSqlXml(int ordinal) {
284 EnsureSubclassOverride();
285 return ValueUtilsSmi.GetSqlXml(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), _recordContext);
288 public virtual SqlBoolean GetSqlBoolean(int ordinal) {
289 EnsureSubclassOverride();
290 return ValueUtilsSmi.GetSqlBoolean(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
293 public virtual SqlByte GetSqlByte(int ordinal) {
294 EnsureSubclassOverride();
295 return ValueUtilsSmi.GetSqlByte(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
298 public virtual SqlChars GetSqlChars(int ordinal) {
299 EnsureSubclassOverride();
300 return ValueUtilsSmi.GetSqlChars(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), _recordContext);
303 public virtual SqlInt16 GetSqlInt16(int ordinal) {
304 EnsureSubclassOverride();
305 return ValueUtilsSmi.GetSqlInt16(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
308 public virtual SqlInt32 GetSqlInt32(int ordinal) {
309 EnsureSubclassOverride();
310 return ValueUtilsSmi.GetSqlInt32(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
313 public virtual SqlInt64 GetSqlInt64(int ordinal) {
314 EnsureSubclassOverride();
315 return ValueUtilsSmi.GetSqlInt64(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
318 public virtual SqlSingle GetSqlSingle(int ordinal) {
319 EnsureSubclassOverride();
320 return ValueUtilsSmi.GetSqlSingle(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
323 public virtual SqlDouble GetSqlDouble(int ordinal) {
324 EnsureSubclassOverride();
325 return ValueUtilsSmi.GetSqlDouble(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
328 public virtual SqlMoney GetSqlMoney(int ordinal) {
329 EnsureSubclassOverride();
330 return ValueUtilsSmi.GetSqlMoney(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
333 public virtual SqlDateTime GetSqlDateTime(int ordinal) {
334 EnsureSubclassOverride();
335 return ValueUtilsSmi.GetSqlDateTime(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
338 public virtual SqlDecimal GetSqlDecimal(int ordinal) {
339 EnsureSubclassOverride();
340 return ValueUtilsSmi.GetSqlDecimal(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
343 public virtual SqlString GetSqlString(int ordinal) {
344 EnsureSubclassOverride();
345 return ValueUtilsSmi.GetSqlString(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
348 public virtual SqlGuid GetSqlGuid(int ordinal) {
349 EnsureSubclassOverride();
350 return ValueUtilsSmi.GetSqlGuid(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal));
354 // ISqlUpdateableRecord Implementation
356 public virtual int SetValues( params object[] values ) {
357 EnsureSubclassOverride();
358 if (null == values) {
359 throw ADP.ArgumentNull( "values" );
362 // SQLBUDT #346883 Allow values array longer than FieldCount, just ignore the extra cells.
363 int copyLength = ( values.Length > FieldCount ) ? FieldCount : values.Length;
365 ExtendedClrTypeCode[] typeCodes = new ExtendedClrTypeCode [copyLength];
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();
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);
384 ValueUtilsSmi.SetCompatibleValue(_eventSink, _recordBuffer, i, GetSmiMetaData(i), values[i], typeCodes[i], 0);
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();
400 if (SmiVersion >= SmiContextFactory.KatmaiVersion) {
401 ValueUtilsSmi.SetCompatibleValueV200(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value, typeCode, 0, 0, null);
404 ValueUtilsSmi.SetCompatibleValue(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value, typeCode, 0);
408 public virtual void SetBoolean(int ordinal, bool value) {
409 EnsureSubclassOverride();
410 ValueUtilsSmi.SetBoolean(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
413 public virtual void SetByte(int ordinal, byte value) {
414 EnsureSubclassOverride();
415 ValueUtilsSmi.SetByte(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
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);
423 public virtual void SetChar(int ordinal, char value) {
424 EnsureSubclassOverride();
425 throw ADP.NotSupported();
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);
433 public virtual void SetInt16(int ordinal, System.Int16 value) {
434 EnsureSubclassOverride();
435 ValueUtilsSmi.SetInt16(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
438 public virtual void SetInt32(int ordinal, System.Int32 value) {
439 EnsureSubclassOverride();
440 ValueUtilsSmi.SetInt32(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
443 public virtual void SetInt64(int ordinal, System.Int64 value) {
444 EnsureSubclassOverride();
445 ValueUtilsSmi.SetInt64(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
448 public virtual void SetFloat(int ordinal, float value) {
449 EnsureSubclassOverride();
450 ValueUtilsSmi.SetSingle(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
453 public virtual void SetDouble(int ordinal, double value) {
454 EnsureSubclassOverride();
455 ValueUtilsSmi.SetDouble(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
458 public virtual void SetString(int ordinal, string value) {
459 EnsureSubclassOverride();
460 ValueUtilsSmi.SetString(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
463 public virtual void SetDecimal(int ordinal, Decimal value) {
464 EnsureSubclassOverride();
465 ValueUtilsSmi.SetDecimal(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
468 public virtual void SetDateTime(int ordinal, DateTime value) {
469 EnsureSubclassOverride();
470 ValueUtilsSmi.SetDateTime(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
473 public virtual void SetTimeSpan(int ordinal, TimeSpan value) {
474 EnsureSubclassOverride();
475 ValueUtilsSmi.SetTimeSpan(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value, SmiVersion >= SmiContextFactory.KatmaiVersion);
478 public virtual void SetDateTimeOffset(int ordinal, DateTimeOffset value) {
479 EnsureSubclassOverride();
480 ValueUtilsSmi.SetDateTimeOffset(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value, SmiVersion >= SmiContextFactory.KatmaiVersion);
483 public virtual void SetDBNull(int ordinal) {
484 EnsureSubclassOverride();
485 ValueUtilsSmi.SetDBNull(_eventSink, _recordBuffer, ordinal, true);
488 public virtual void SetGuid(int ordinal, Guid value) {
489 EnsureSubclassOverride();
490 ValueUtilsSmi.SetGuid(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
493 public virtual void SetSqlBoolean(int ordinal, SqlBoolean value) {
494 EnsureSubclassOverride();
495 ValueUtilsSmi.SetSqlBoolean(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
498 public virtual void SetSqlByte(int ordinal, SqlByte value) {
499 EnsureSubclassOverride();
500 ValueUtilsSmi.SetSqlByte(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
503 public virtual void SetSqlInt16(int ordinal, SqlInt16 value) {
504 EnsureSubclassOverride();
505 ValueUtilsSmi.SetSqlInt16(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
508 public virtual void SetSqlInt32(int ordinal, SqlInt32 value) {
509 EnsureSubclassOverride();
510 ValueUtilsSmi.SetSqlInt32(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
513 public virtual void SetSqlInt64(int ordinal, SqlInt64 value) {
514 EnsureSubclassOverride();
515 ValueUtilsSmi.SetSqlInt64(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
518 public virtual void SetSqlSingle(int ordinal, SqlSingle value) {
519 EnsureSubclassOverride();
520 ValueUtilsSmi.SetSqlSingle(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
523 public virtual void SetSqlDouble(int ordinal, SqlDouble value) {
524 EnsureSubclassOverride();
525 ValueUtilsSmi.SetSqlDouble(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
528 public virtual void SetSqlMoney(int ordinal, SqlMoney value) {
529 EnsureSubclassOverride();
530 ValueUtilsSmi.SetSqlMoney(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
533 public virtual void SetSqlDateTime(int ordinal, SqlDateTime value) {
534 EnsureSubclassOverride();
535 ValueUtilsSmi.SetSqlDateTime(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
538 public virtual void SetSqlXml(int ordinal, SqlXml value) {
539 EnsureSubclassOverride();
540 ValueUtilsSmi.SetSqlXml(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
543 public virtual void SetSqlDecimal(int ordinal, SqlDecimal value) {
544 EnsureSubclassOverride();
545 ValueUtilsSmi.SetSqlDecimal(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
548 public virtual void SetSqlString(int ordinal, SqlString value) {
549 EnsureSubclassOverride();
550 ValueUtilsSmi.SetSqlString(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
553 public virtual void SetSqlBinary(int ordinal, SqlBinary value) {
554 EnsureSubclassOverride();
555 ValueUtilsSmi.SetSqlBinary(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
558 public virtual void SetSqlGuid(int ordinal, SqlGuid value) {
559 EnsureSubclassOverride();
560 ValueUtilsSmi.SetSqlGuid(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
563 public virtual void SetSqlChars(int ordinal, SqlChars value) {
564 EnsureSubclassOverride();
565 ValueUtilsSmi.SetSqlChars(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
568 public virtual void SetSqlBytes(int ordinal, SqlBytes value) {
569 EnsureSubclassOverride();
570 ValueUtilsSmi.SetSqlBytes(_eventSink, _recordBuffer, ordinal, GetSmiMetaData(ordinal), value);
575 // SqlDataRecord public API
578 public SqlDataRecord( params SqlMetaData[] metaData ) {
579 // Initial consistency check
580 if ( null == metaData ) {
581 throw ADP.ArgumentNull( "metadata" );
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+"]" );
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);
598 _eventSink = new SmiEventSink_Default( );
600 if (InOutOfProcHelper.InProc) {
601 _recordContext = SmiContextFactory.Instance.GetCurrentContext();
602 _recordBuffer = _recordContext.CreateRecordBuffer( _columnSmiMetaData, _eventSink );
603 _usesStringStorageForXml = false;
606 _recordContext = null;
607 _recordBuffer = new MemoryRecordBuffer(_columnSmiMetaData);
608 _usesStringStorageForXml = true;
610 _eventSink.ProcessMessagesAndThrow();
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[]");
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] );
624 _eventSink = new SmiEventSink_Default( );
626 if (InOutOfProcHelper.InProc) {
627 _recordContext = SmiContextFactory.Instance.GetCurrentContext();
630 _recordContext = null;
632 _recordBuffer = recordBuffer;
633 _eventSink.ProcessMessagesAndThrow();
637 // SqlDataRecord private members
639 internal SmiRecordBuffer RecordBuffer { // used by SqlPipe
641 return _recordBuffer;
645 internal SmiContext RecordContext {
647 return _recordContext;
651 private ulong SmiVersion {
653 return InOutOfProcHelper.InProc ? SmiContextFactory.Instance.NegotiatedSmiVersion : SmiContextFactory.LatestVersion;
657 internal SqlMetaData[] InternalGetMetaData() {
658 return _columnMetaData;
661 internal SmiExtendedMetaData[] InternalGetSmiMetaData() {
662 return _columnSmiMetaData;
665 internal SmiExtendedMetaData GetSmiMetaData( int ordinal ) {
666 return _columnSmiMetaData[ordinal];
669 internal void ThrowIfInvalidOrdinal( int ordinal ) {
670 if ( 0 > ordinal || FieldCount <= ordinal ) {
671 throw ADP.IndexOutOfRange( ordinal );
674 private void EnsureSubclassOverride() {
675 if (null == _recordBuffer) {
676 throw SQL.SubclassMustOverride();