**** Merged from MCS ****
[mono-project.git] / mcs / class / System.Data / System.Data.SqlClient / SqlDataReader.cs
blob5e1c293e87b4cc2406bc9030926d70977a840129
1 //
2 // System.Data.SqlClient.SqlDataReader.cs
3 //
4 // Author:
5 // Rodrigo Moya (rodrigo@ximian.com)
6 // Daniel Morgan (danmorg@sc.rr.com)
7 // Tim Coleman (tim@timcoleman.com)
8 //
9 // (C) Ximian, Inc 2002
10 // (C) Daniel Morgan 2002
11 // Copyright (C) Tim Coleman, 2002
15 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
17 // Permission is hereby granted, free of charge, to any person obtaining
18 // a copy of this software and associated documentation files (the
19 // "Software"), to deal in the Software without restriction, including
20 // without limitation the rights to use, copy, modify, merge, publish,
21 // distribute, sublicense, and/or sell copies of the Software, and to
22 // permit persons to whom the Software is furnished to do so, subject to
23 // the following conditions:
24 //
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
27 //
28 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 using Mono.Data.Tds.Protocol;
38 using System;
39 using System.Collections;
40 using System.ComponentModel;
41 using System.Data;
42 using System.Data.Common;
43 using System.Data.SqlTypes;
45 namespace System.Data.SqlClient {
46 public sealed class SqlDataReader : MarshalByRefObject, IEnumerable, IDataReader, IDisposable, IDataRecord
48 #region Fields
50 SqlCommand command;
51 ArrayList dataTypeNames;
52 bool disposed = false;
53 int fieldCount;
54 bool isClosed;
55 bool isSelect;
56 bool moreResults;
57 int resultsRead;
58 int rowsRead;
59 DataTable schemaTable;
60 bool hasRows;
61 bool haveRead;
62 bool readResult;
63 bool readResultUsed;
65 #endregion // Fields
67 #region Constructors
69 internal SqlDataReader (SqlCommand command)
71 readResult = false;
72 haveRead = false;
73 readResultUsed = false;
74 this.command = command;
75 schemaTable = ConstructSchemaTable ();
76 resultsRead = 0;
77 fieldCount = 0;
78 isClosed = false;
79 isSelect = (command.CommandText.Trim ().ToUpper ().StartsWith ("SELECT"));
80 command.Tds.RecordsAffected = 0;
81 NextResult ();
84 #endregion // Constructors
86 #region Properties
88 public int Depth {
89 get { return 0; }
92 public int FieldCount {
93 get { return fieldCount; }
96 public bool IsClosed {
97 get { return isClosed; }
100 public object this [int i] {
101 get { return GetValue (i); }
104 public object this [string name] {
105 get { return GetValue (GetOrdinal (name)); }
108 public int RecordsAffected {
109 get {
110 if (isSelect)
111 return -1;
112 else
113 return command.Tds.RecordsAffected;
117 public bool HasRows {
118 get {
119 if (haveRead)
120 return readResult;
122 haveRead = true;
123 readResult = ReadRecord ();
124 return readResult;
128 #endregion // Properties
130 #region Methods
132 public void Close ()
134 // skip to end & read output parameters.
135 while (NextResult ())
137 isClosed = true;
138 command.Connection.DataReader = null;
139 command.CloseDataReader (moreResults);
142 private static DataTable ConstructSchemaTable ()
144 Type booleanType = Type.GetType ("System.Boolean");
145 Type stringType = Type.GetType ("System.String");
146 Type intType = Type.GetType ("System.Int32");
147 Type typeType = Type.GetType ("System.Type");
148 Type shortType = Type.GetType ("System.Int16");
150 DataTable schemaTable = new DataTable ("SchemaTable");
151 schemaTable.Columns.Add ("ColumnName", stringType);
152 schemaTable.Columns.Add ("ColumnOrdinal", intType);
153 schemaTable.Columns.Add ("ColumnSize", intType);
154 schemaTable.Columns.Add ("NumericPrecision", shortType);
155 schemaTable.Columns.Add ("NumericScale", shortType);
156 schemaTable.Columns.Add ("IsUnique", booleanType);
157 schemaTable.Columns.Add ("IsKey", booleanType);
158 schemaTable.Columns.Add ("BaseServerName", stringType);
159 schemaTable.Columns.Add ("BaseCatalogName", stringType);
160 schemaTable.Columns.Add ("BaseColumnName", stringType);
161 schemaTable.Columns.Add ("BaseSchemaName", stringType);
162 schemaTable.Columns.Add ("BaseTableName", stringType);
163 schemaTable.Columns.Add ("DataType", typeType);
164 schemaTable.Columns.Add ("AllowDBNull", booleanType);
165 schemaTable.Columns.Add ("ProviderType", intType);
166 schemaTable.Columns.Add ("IsAliased", booleanType);
167 schemaTable.Columns.Add ("IsExpression", booleanType);
168 schemaTable.Columns.Add ("IsIdentity", booleanType);
169 schemaTable.Columns.Add ("IsAutoIncrement", booleanType);
170 schemaTable.Columns.Add ("IsRowVersion", booleanType);
171 schemaTable.Columns.Add ("IsHidden", booleanType);
172 schemaTable.Columns.Add ("IsLong", booleanType);
173 schemaTable.Columns.Add ("IsReadOnly", booleanType);
175 return schemaTable;
178 private void Dispose (bool disposing)
180 if (!disposed) {
181 if (disposing) {
182 schemaTable.Dispose ();
183 Close ();
184 command = null;
186 disposed = true;
190 public bool GetBoolean (int i)
192 object value = GetValue (i);
193 if (!(value is bool)) {
194 if (value is DBNull) throw new SqlNullValueException ();
195 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
197 return (bool) value;
200 public byte GetByte (int i)
202 object value = GetValue (i);
203 if (!(value is byte)) {
204 if (value is DBNull) throw new SqlNullValueException ();
205 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
207 return (byte) value;
210 public long GetBytes (int i, long dataIndex, byte[] buffer, int bufferIndex, int length)
212 object value = GetValue (i);
213 if (!(value is byte [])) {
214 if (value is DBNull) throw new SqlNullValueException ();
215 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
218 if ( buffer == null ) {
219 // Return length of data
220 return ((byte []) value).Length;
222 else {
223 // Copy data into buffer
224 Array.Copy ((byte []) value, (int) dataIndex, buffer, bufferIndex, length);
225 return ((byte []) value).Length - dataIndex;
229 [EditorBrowsableAttribute (EditorBrowsableState.Never)]
230 public char GetChar (int i)
232 object value = GetValue (i);
233 if (!(value is char)) {
234 if (value is DBNull) throw new SqlNullValueException ();
235 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
237 return (char) value;
240 public long GetChars (int i, long dataIndex, char[] buffer, int bufferIndex, int length)
242 object value = GetValue (i);
243 char [] valueBuffer;
245 if (value is char[])
246 valueBuffer = (char[])value;
247 else if (value is string)
248 valueBuffer = ((string)value).ToCharArray();
249 else {
250 if (value is DBNull) throw new SqlNullValueException ();
251 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
254 if ( buffer == null ) {
255 // Return length of data
256 return valueBuffer.Length;
258 else {
259 // Copy data into buffer
260 Array.Copy (valueBuffer, (int) dataIndex, buffer, bufferIndex, length);
261 return valueBuffer.Length - dataIndex;
265 [EditorBrowsableAttribute (EditorBrowsableState.Never)]
266 public IDataReader GetData (int i)
268 return ( (IDataReader) this [i]);
271 public string GetDataTypeName (int i)
273 return (string) dataTypeNames [i];
276 public DateTime GetDateTime (int i)
278 object value = GetValue (i);
279 if (!(value is DateTime)) {
280 if (value is DBNull) throw new SqlNullValueException ();
281 else throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
283 return (DateTime) value;
286 public decimal GetDecimal (int i)
288 object value = GetValue (i);
289 if (!(value is decimal)) {
290 if (value is DBNull) throw new SqlNullValueException ();
291 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
293 return (decimal) value;
296 public double GetDouble (int i)
298 object value = GetValue (i);
299 if (!(value is double)) {
300 if (value is DBNull) throw new SqlNullValueException ();
301 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
303 return (double) value;
306 public Type GetFieldType (int i)
308 return (Type) schemaTable.Rows[i]["DataType"];
311 public float GetFloat (int i)
313 object value = GetValue (i);
314 if (!(value is float)) {
315 if (value is DBNull) throw new SqlNullValueException ();
316 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
318 return (float) value;
321 public Guid GetGuid (int i)
323 object value = GetValue (i);
324 if (!(value is Guid)) {
325 if (value is DBNull) throw new SqlNullValueException ();
326 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
328 return (Guid) value;
331 public short GetInt16 (int i)
333 object value = GetValue (i);
334 if (!(value is short)) {
335 if (value is DBNull) throw new SqlNullValueException ();
336 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
338 return (short) value;
341 public int GetInt32 (int i)
343 object value = GetValue (i);
344 if (!(value is int)) {
345 if (value is DBNull) throw new SqlNullValueException ();
346 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
348 return (int) value;
351 public long GetInt64 (int i)
353 object value = GetValue (i);
354 if (!(value is long)) {
355 if (value is DBNull) throw new SqlNullValueException ();
356 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
358 return (long) value;
361 public string GetName (int i)
363 return (string) schemaTable.Rows[i]["ColumnName"];
366 public int GetOrdinal (string name)
368 foreach (DataRow schemaRow in schemaTable.Rows)
369 if (((string) schemaRow ["ColumnName"]).Equals (name))
370 return (int) schemaRow ["ColumnOrdinal"];
371 foreach (DataRow schemaRow in schemaTable.Rows)
372 if (String.Compare (((string) schemaRow ["ColumnName"]), name, true) == 0)
373 return (int) schemaRow ["ColumnOrdinal"];
374 throw new IndexOutOfRangeException ();
377 public DataTable GetSchemaTable ()
379 if (schemaTable.Rows != null && schemaTable.Rows.Count > 0)
380 return schemaTable;
382 if (!moreResults)
383 return null;
385 fieldCount = 0;
387 dataTypeNames = new ArrayList ();
389 foreach (TdsDataColumn schema in command.Tds.Columns) {
390 DataRow row = schemaTable.NewRow ();
392 row ["ColumnName"] = GetSchemaValue (schema, "ColumnName");
393 row ["ColumnSize"] = GetSchemaValue (schema, "ColumnSize");
394 row ["ColumnOrdinal"] = GetSchemaValue (schema, "ColumnOrdinal");
395 row ["NumericPrecision"] = GetSchemaValue (schema, "NumericPrecision");
396 row ["NumericScale"] = GetSchemaValue (schema, "NumericScale");
397 row ["IsUnique"] = GetSchemaValue (schema, "IsUnique");
398 row ["IsKey"] = GetSchemaValue (schema, "IsKey");
399 row ["BaseServerName"] = GetSchemaValue (schema, "BaseServerName");
400 row ["BaseCatalogName"] = GetSchemaValue (schema, "BaseCatalogName");
401 row ["BaseColumnName"] = GetSchemaValue (schema, "BaseColumnName");
402 row ["BaseSchemaName"] = GetSchemaValue (schema, "BaseSchemaName");
403 row ["BaseTableName"] = GetSchemaValue (schema, "BaseTableName");
404 row ["AllowDBNull"] = GetSchemaValue (schema, "AllowDBNull");
405 row ["IsAliased"] = GetSchemaValue (schema, "IsAliased");
406 row ["IsExpression"] = GetSchemaValue (schema, "IsExpression");
407 row ["IsIdentity"] = GetSchemaValue (schema, "IsIdentity");
408 row ["IsAutoIncrement"] = GetSchemaValue (schema, "IsAutoIncrement");
409 row ["IsRowVersion"] = GetSchemaValue (schema, "IsRowVersion");
410 row ["IsHidden"] = GetSchemaValue (schema, "IsHidden");
411 row ["IsReadOnly"] = GetSchemaValue (schema, "IsReadOnly");
413 // We don't always get the base column name.
414 if (row ["BaseColumnName"] == DBNull.Value)
415 row ["BaseColumnName"] = row ["ColumnName"];
417 switch ((TdsColumnType) schema ["ColumnType"]) {
418 case TdsColumnType.Int1:
419 case TdsColumnType.Int2:
420 case TdsColumnType.Int4:
421 case TdsColumnType.IntN:
422 switch ((int) schema ["ColumnSize"]) {
423 case 1:
424 dataTypeNames.Add ("tinyint");
425 row ["ProviderType"] = (int) SqlDbType.TinyInt;
426 row ["DataType"] = typeof (byte);
427 row ["IsLong"] = false;
428 break;
429 case 2:
430 dataTypeNames.Add ("smallint");
431 row ["ProviderType"] = (int) SqlDbType.SmallInt;
432 row ["DataType"] = typeof (short);
433 row ["IsLong"] = false;
434 break;
435 case 4:
436 dataTypeNames.Add ("int");
437 row ["ProviderType"] = (int) SqlDbType.Int;
438 row ["DataType"] = typeof (int);
439 row ["IsLong"] = false;
440 break;
441 case 8:
442 dataTypeNames.Add ("bigint");
443 row ["ProviderType"] = (int) SqlDbType.BigInt;
444 row ["DataType"] = typeof (long);
445 row ["IsLong"] = false;
446 break;
448 break;
449 case TdsColumnType.Real:
450 case TdsColumnType.Float8:
451 case TdsColumnType.FloatN:
452 switch ((int) schema ["ColumnSize"]) {
453 case 4:
454 dataTypeNames.Add ("real");
455 row ["ProviderType"] = (int) SqlDbType.Real;
456 row ["DataType"] = typeof (float);
457 row ["IsLong"] = false;
458 break;
459 case 8:
460 dataTypeNames.Add ("float");
461 row ["ProviderType"] = (int) SqlDbType.Float;
462 row ["DataType"] = typeof (double);
463 row ["IsLong"] = false;
464 break;
466 break;
467 case TdsColumnType.Image :
468 dataTypeNames.Add ("image");
469 row ["ProviderType"] = (int) SqlDbType.Image;
470 row ["DataType"] = typeof (byte[]);
471 row ["IsLong"] = true;
472 break;
473 case TdsColumnType.Text :
474 dataTypeNames.Add ("text");
475 row ["ProviderType"] = (int) SqlDbType.Text;
476 row ["DataType"] = typeof (string);
477 row ["IsLong"] = true;
478 break;
479 case TdsColumnType.UniqueIdentifier :
480 dataTypeNames.Add ("uniqueidentifier");
481 row ["ProviderType"] = (int) SqlDbType.UniqueIdentifier;
482 row ["DataType"] = typeof (Guid);
483 row ["IsLong"] = false;
484 break;
485 case TdsColumnType.VarBinary :
486 case TdsColumnType.BigVarBinary :
487 dataTypeNames.Add ("varbinary");
488 row ["ProviderType"] = (int) SqlDbType.VarBinary;
489 row ["DataType"] = typeof (byte[]);
490 row ["IsLong"] = true;
491 break;
492 case TdsColumnType.VarChar :
493 case TdsColumnType.BigVarChar :
494 dataTypeNames.Add ("varchar");
495 row ["ProviderType"] = (int) SqlDbType.VarChar;
496 row ["DataType"] = typeof (string);
497 row ["IsLong"] = false;
498 break;
499 case TdsColumnType.Binary :
500 case TdsColumnType.BigBinary :
501 dataTypeNames.Add ("binary");
502 row ["ProviderType"] = (int) SqlDbType.Binary;
503 row ["DataType"] = typeof (byte[]);
504 row ["IsLong"] = true;
505 break;
506 case TdsColumnType.Char :
507 case TdsColumnType.BigChar :
508 dataTypeNames.Add ("char");
509 row ["ProviderType"] = (int) SqlDbType.Char;
510 row ["DataType"] = typeof (string);
511 row ["IsLong"] = false;
512 break;
513 case TdsColumnType.Bit :
514 case TdsColumnType.BitN :
515 dataTypeNames.Add ("bit");
516 row ["ProviderType"] = (int) SqlDbType.Bit;
517 row ["DataType"] = typeof (bool);
518 row ["IsLong"] = false;
519 break;
520 case TdsColumnType.DateTime4 :
521 case TdsColumnType.DateTime :
522 case TdsColumnType.DateTimeN :
523 dataTypeNames.Add ("datetime");
524 row ["ProviderType"] = (int) SqlDbType.DateTime;
525 row ["DataType"] = typeof (DateTime);
526 row ["IsLong"] = false;
527 break;
528 case TdsColumnType.Money :
529 case TdsColumnType.MoneyN :
530 case TdsColumnType.Money4 :
531 dataTypeNames.Add ("money");
532 row ["ProviderType"] = (int) SqlDbType.Money;
533 row ["DataType"] = typeof (decimal);
534 row ["IsLong"] = false;
535 break;
536 case TdsColumnType.NText :
537 dataTypeNames.Add ("ntext");
538 row ["ProviderType"] = (int) SqlDbType.NText;
539 row ["DataType"] = typeof (string);
540 row ["IsLong"] = true;
541 break;
542 case TdsColumnType.NVarChar :
543 dataTypeNames.Add ("nvarchar");
544 row ["ProviderType"] = (int) SqlDbType.NVarChar;
545 row ["DataType"] = typeof (string);
546 row ["IsLong"] = false;
547 break;
548 case TdsColumnType.Decimal :
549 case TdsColumnType.Numeric :
550 dataTypeNames.Add ("decimal");
551 row ["ProviderType"] = (int) SqlDbType.Decimal;
552 row ["DataType"] = typeof (decimal);
553 row ["IsLong"] = false;
554 break;
555 case TdsColumnType.NChar :
556 dataTypeNames.Add ("nchar");
557 row ["ProviderType"] = (int) SqlDbType.NChar;
558 row ["DataType"] = typeof (string);
559 row ["IsLong"] = false;
560 break;
561 case TdsColumnType.SmallMoney :
562 dataTypeNames.Add ("smallmoney");
563 row ["ProviderType"] = (int) SqlDbType.SmallMoney;
564 row ["DataType"] = typeof (decimal);
565 row ["IsLong"] = false;
566 break;
567 default :
568 dataTypeNames.Add ("variant");
569 row ["ProviderType"] = (int) SqlDbType.Variant;
570 row ["DataType"] = typeof (object);
571 row ["IsLong"] = false;
572 break;
575 schemaTable.Rows.Add (row);
577 fieldCount += 1;
579 return schemaTable;
582 private static object GetSchemaValue (TdsDataColumn schema, object key)
584 if (schema.ContainsKey (key) && schema [key] != null)
585 return schema [key];
586 return DBNull.Value;
589 public SqlBinary GetSqlBinary (int i)
591 throw new NotImplementedException ();
594 public SqlBoolean GetSqlBoolean (int i)
596 object value = GetSqlValue (i);
597 if (!(value is SqlBoolean))
598 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
599 return (SqlBoolean) value;
602 public SqlByte GetSqlByte (int i)
604 object value = GetSqlValue (i);
605 if (!(value is SqlByte))
606 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
607 return (SqlByte) value;
610 public SqlDateTime GetSqlDateTime (int i)
612 object value = GetSqlValue (i);
613 if (!(value is SqlDateTime))
614 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
615 return (SqlDateTime) value;
618 public SqlDecimal GetSqlDecimal (int i)
620 object value = GetSqlValue (i);
621 if (!(value is SqlDecimal))
622 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
623 return (SqlDecimal) value;
626 public SqlDouble GetSqlDouble (int i)
628 object value = GetSqlValue (i);
629 if (!(value is SqlDouble))
630 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
631 return (SqlDouble) value;
634 public SqlGuid GetSqlGuid (int i)
636 object value = GetSqlValue (i);
637 if (!(value is SqlGuid))
638 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
639 return (SqlGuid) value;
642 public SqlInt16 GetSqlInt16 (int i)
644 object value = GetSqlValue (i);
645 if (!(value is SqlInt16))
646 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
647 return (SqlInt16) value;
650 public SqlInt32 GetSqlInt32 (int i)
652 object value = GetSqlValue (i);
653 if (!(value is SqlInt32))
654 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
655 return (SqlInt32) value;
658 public SqlInt64 GetSqlInt64 (int i)
660 object value = GetSqlValue (i);
661 if (!(value is SqlInt64))
662 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
663 return (SqlInt64) value;
666 public SqlMoney GetSqlMoney (int i)
668 object value = GetSqlValue (i);
669 if (!(value is SqlMoney))
670 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
671 return (SqlMoney) value;
674 public SqlSingle GetSqlSingle (int i)
676 object value = GetSqlValue (i);
677 if (!(value is SqlSingle))
678 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
679 return (SqlSingle) value;
682 public SqlString GetSqlString (int i)
684 object value = GetSqlValue (i);
685 if (!(value is SqlString))
686 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
687 return (SqlString) value;
690 public object GetSqlValue (int i)
692 SqlDbType type = (SqlDbType) (schemaTable.Rows [i]["ProviderType"]);
693 object value = GetValue (i);
695 switch (type) {
696 case SqlDbType.BigInt:
697 if (value == DBNull.Value)
698 return SqlInt64.Null;
699 return (SqlInt64) ((long) value);
700 case SqlDbType.Binary:
701 case SqlDbType.Image:
702 case SqlDbType.VarBinary:
703 case SqlDbType.Timestamp:
704 if (value == DBNull.Value)
705 return SqlBinary.Null;
706 return (SqlBinary) ((byte[]) value);
707 case SqlDbType.Bit:
708 if (value == DBNull.Value)
709 return SqlBoolean.Null;
710 return (SqlBoolean) ((bool) value);
711 case SqlDbType.Char:
712 case SqlDbType.NChar:
713 case SqlDbType.NText:
714 case SqlDbType.NVarChar:
715 case SqlDbType.Text:
716 case SqlDbType.VarChar:
717 if (value == DBNull.Value)
718 return SqlString.Null;
719 return (SqlString) ((string) value);
720 case SqlDbType.DateTime:
721 case SqlDbType.SmallDateTime:
722 if (value == DBNull.Value)
723 return SqlDateTime.Null;
724 return (SqlDateTime) ((DateTime) value);
725 case SqlDbType.Decimal:
726 if (value == DBNull.Value)
727 return SqlDecimal.Null;
728 if (value is TdsBigDecimal)
729 return SqlDecimal.FromTdsBigDecimal ((TdsBigDecimal) value);
730 return (SqlDecimal) ((decimal) value);
731 case SqlDbType.Float:
732 if (value == DBNull.Value)
733 return SqlDouble.Null;
734 return (SqlDouble) ((double) value);
735 case SqlDbType.Int:
736 if (value == DBNull.Value)
737 return SqlInt32.Null;
738 return (SqlInt32) ((int) value);
739 case SqlDbType.Money:
740 case SqlDbType.SmallMoney:
741 if (value == DBNull.Value)
742 return SqlMoney.Null;
743 return (SqlMoney) ((decimal) value);
744 case SqlDbType.Real:
745 if (value == DBNull.Value)
746 return SqlSingle.Null;
747 return (SqlSingle) ((float) value);
748 case SqlDbType.UniqueIdentifier:
749 if (value == DBNull.Value)
750 return SqlGuid.Null;
751 return (SqlGuid) ((Guid) value);
752 case SqlDbType.SmallInt:
753 if (value == DBNull.Value)
754 return SqlInt16.Null;
755 return (SqlInt16) ((short) value);
756 case SqlDbType.TinyInt:
757 if (value == DBNull.Value)
758 return SqlByte.Null;
759 return (SqlByte) ((byte) value);
762 throw new InvalidOperationException ("The type of this column is unknown.");
765 public int GetSqlValues (object[] values)
767 int count = 0;
768 int columnCount = schemaTable.Rows.Count;
769 int arrayCount = values.Length;
771 if (arrayCount > columnCount)
772 count = columnCount;
773 else
774 count = arrayCount;
776 for (int i = 0; i < count; i += 1)
777 values [i] = GetSqlValue (i);
779 return count;
782 public string GetString (int i)
784 object value = GetValue (i);
785 if (!(value is string)) {
786 if (value is DBNull) throw new SqlNullValueException ();
787 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
789 return (string) value;
792 public object GetValue (int i)
794 return command.Tds.ColumnValues [i];
797 public int GetValues (object[] values)
799 int len = values.Length;
800 int bigDecimalIndex = command.Tds.ColumnValues.BigDecimalIndex;
802 // If a four-byte decimal is stored, then we can't convert to
803 // a native type. Throw an OverflowException.
804 if (bigDecimalIndex >= 0 && bigDecimalIndex < len)
805 throw new OverflowException ();
807 command.Tds.ColumnValues.CopyTo (0, values, 0, len);
808 return (len > FieldCount ? len : FieldCount);
811 void IDisposable.Dispose ()
813 Dispose (true);
814 GC.SuppressFinalize (this);
817 IEnumerator IEnumerable.GetEnumerator ()
819 return new DbEnumerator (this);
822 public bool IsDBNull (int i)
824 return GetValue (i) == DBNull.Value;
827 public bool NextResult ()
829 if ((command.CommandBehavior & CommandBehavior.SingleResult) != 0 && resultsRead > 0)
830 return false;
832 schemaTable.Rows.Clear ();
834 moreResults = command.Tds.NextResult ();
835 if (!moreResults)
836 command.GetOutputParameters ();
838 GetSchemaTable ();
840 rowsRead = 0;
841 resultsRead += 1;
842 return moreResults;
845 public bool Read ()
847 if ((command.CommandBehavior & CommandBehavior.SingleRow) != 0 && rowsRead > 0)
848 return false;
849 if ((command.CommandBehavior & CommandBehavior.SchemaOnly) != 0)
850 return false;
851 if (!moreResults)
852 return false;
854 if ((haveRead) && (!readResultUsed))
856 readResultUsed = true;
857 return true;
861 return (ReadRecord ());
865 internal bool ReadRecord ()
868 bool result = command.Tds.NextRow ();
870 rowsRead += 1;
872 return result;
877 #endregion // Methods