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