2 // System.Data.SqlClient.SqlDataReader.cs
5 // Rodrigo Moya (rodrigo@ximian.com)
6 // Daniel Morgan (danmorg@sc.rr.com)
7 // Tim Coleman (tim@timcoleman.com)
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:
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
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;
40 using System.Collections;
41 using System.ComponentModel;
43 using System.Data.Common;
44 using System.Data.SqlTypes;
46 using System.Data.ProviderBase;
49 namespace System.Data.SqlClient {
51 public sealed class SqlDataReader : DbDataReaderBase, IEnumerable, IDataReader, IDisposable, IDataRecord
53 public sealed class SqlDataReader : MarshalByRefObject, IEnumerable, IDataReader, IDisposable, IDataRecord
59 ArrayList dataTypeNames;
60 bool disposed = false;
66 DataTable schemaTable;
76 internal SqlDataReader (SqlCommand command)
78 : base (command.CommandBehavior)
83 readResultUsed = false;
84 this.command = command;
85 schemaTable = ConstructSchemaTable ();
89 command.Tds.RecordsAffected = -1;
93 #endregion // Constructors
110 get { return fieldCount; }
118 get { return isClosed; }
125 object this [int i] {
126 get { return GetValue (i); }
133 object this [string name] {
134 get { return GetValue (GetOrdinal (name)); }
141 int RecordsAffected {
143 return command.Tds.RecordsAffected;
157 readResult = ReadRecord ();
162 #endregion // Properties
174 // skip to end & read output parameters.
175 while (NextResult ())
178 command.Connection.DataReader = null;
179 command.CloseDataReader (moreResults);
182 private static DataTable ConstructSchemaTable ()
184 Type booleanType = Type.GetType ("System.Boolean");
185 Type stringType = Type.GetType ("System.String");
186 Type intType = Type.GetType ("System.Int32");
187 Type typeType = Type.GetType ("System.Type");
188 Type shortType = Type.GetType ("System.Int16");
190 DataTable schemaTable = new DataTable ("SchemaTable");
191 schemaTable.Columns.Add ("ColumnName", stringType);
192 schemaTable.Columns.Add ("ColumnOrdinal", intType);
193 schemaTable.Columns.Add ("ColumnSize", intType);
194 schemaTable.Columns.Add ("NumericPrecision", shortType);
195 schemaTable.Columns.Add ("NumericScale", shortType);
196 schemaTable.Columns.Add ("IsUnique", booleanType);
197 schemaTable.Columns.Add ("IsKey", booleanType);
198 schemaTable.Columns.Add ("BaseServerName", stringType);
199 schemaTable.Columns.Add ("BaseCatalogName", stringType);
200 schemaTable.Columns.Add ("BaseColumnName", stringType);
201 schemaTable.Columns.Add ("BaseSchemaName", stringType);
202 schemaTable.Columns.Add ("BaseTableName", stringType);
203 schemaTable.Columns.Add ("DataType", typeType);
204 schemaTable.Columns.Add ("AllowDBNull", booleanType);
205 schemaTable.Columns.Add ("ProviderType", intType);
206 schemaTable.Columns.Add ("IsAliased", booleanType);
207 schemaTable.Columns.Add ("IsExpression", booleanType);
208 schemaTable.Columns.Add ("IsIdentity", booleanType);
209 schemaTable.Columns.Add ("IsAutoIncrement", booleanType);
210 schemaTable.Columns.Add ("IsRowVersion", booleanType);
211 schemaTable.Columns.Add ("IsHidden", booleanType);
212 schemaTable.Columns.Add ("IsLong", booleanType);
213 schemaTable.Columns.Add ("IsReadOnly", booleanType);
220 void Dispose (bool disposing)
224 schemaTable.Dispose ();
236 bool GetBoolean (int i)
238 object value = GetValue (i);
239 if (!(value is bool)) {
240 if (value is DBNull) throw new SqlNullValueException ();
241 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
252 object value = GetValue (i);
253 if (!(value is byte)) {
254 if (value is DBNull) throw new SqlNullValueException ();
255 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
264 long GetBytes (int i, long dataIndex, byte[] buffer, int bufferIndex, int length)
266 if ((command.CommandBehavior & CommandBehavior.SequentialAccess) != 0) {
267 long len = ((Tds)command.Tds).GetSequentialColumnValue (i, dataIndex, buffer, bufferIndex, length);
269 throw new InvalidCastException ("Invalid attempt to GetBytes on column "
270 + "'" + command.Tds.Columns[i]["ColumnName"] + "'." + "The GetBytes function"
271 + " can only be used on columns of type Text, NText, or Image");
275 object value = GetValue (i);
276 if (!(value is byte [])) {
277 if (value is DBNull) throw new SqlNullValueException ();
278 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
281 if ( buffer == null )
282 return ((byte []) value).Length; // Return length of data
284 // Copy data into buffer
285 int availLen = (int) ( ( (byte []) value).Length - dataIndex);
286 if (availLen < length)
288 Array.Copy ((byte []) value, (int) dataIndex, buffer, bufferIndex, length);
289 return length; // return actual read count
292 [EditorBrowsableAttribute (EditorBrowsableState.Never)]
299 object value = GetValue (i);
300 if (!(value is char)) {
301 if (value is DBNull) throw new SqlNullValueException ();
302 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
311 long GetChars (int i, long dataIndex, char[] buffer, int bufferIndex, int length)
313 if ((command.CommandBehavior & CommandBehavior.SequentialAccess) != 0) {
314 Encoding encoding = null;
316 TdsColumnType colType = (TdsColumnType) command.Tds.Columns[i]["ColumnType"];
318 case TdsColumnType.Text :
319 case TdsColumnType.VarChar:
320 case TdsColumnType.Char:
321 case TdsColumnType.BigVarChar:
322 encoding = Encoding.ASCII;
324 case TdsColumnType.NText :
325 case TdsColumnType.NVarChar:
326 case TdsColumnType.NChar:
327 encoding = Encoding.Unicode;
335 if (buffer == null) {
336 count = GetBytes (i,0,(byte[]) null,0,0);
341 byte[] arr = new byte [length];
342 count = GetBytes (i, dataIndex, arr, 0, length);
344 throw new InvalidCastException ("Specified cast is not valid");
346 Char[] val = encoding.GetChars (arr, 0, (int)count);
347 val.CopyTo (buffer, bufferIndex);
352 object value = GetValue (i);
355 valueBuffer = (char[])value;
356 else if (value is string)
357 valueBuffer = ((string)value).ToCharArray();
359 if (value is DBNull) throw new SqlNullValueException ();
360 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
363 if ( buffer == null ) {
364 // Return length of data
365 return valueBuffer.Length;
368 // Copy data into buffer
369 Array.Copy (valueBuffer, (int) dataIndex, buffer, bufferIndex, length);
370 return valueBuffer.Length - dataIndex;
374 [EditorBrowsableAttribute (EditorBrowsableState.Never)]
375 public new IDataReader GetData (int i)
377 return ((IDataReader) this [i]);
384 string GetDataTypeName (int i)
386 if (i < 0 || i >= dataTypeNames.Count)
387 throw new IndexOutOfRangeException ();
388 return (string) dataTypeNames [i];
395 DateTime GetDateTime (int i)
397 object value = GetValue (i);
398 if (!(value is DateTime)) {
399 if (value is DBNull) throw new SqlNullValueException ();
400 else throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
402 return (DateTime) value;
409 decimal GetDecimal (int i)
411 object value = GetValue (i);
412 if (!(value is decimal)) {
413 if (value is DBNull) throw new SqlNullValueException ();
414 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
416 return (decimal) value;
423 double GetDouble (int i)
425 object value = GetValue (i);
426 if (!(value is double)) {
427 if (value is DBNull) throw new SqlNullValueException ();
428 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
430 return (double) value;
437 Type GetFieldType (int i)
439 if (i < 0 || i >= schemaTable.Rows.Count)
440 throw new IndexOutOfRangeException ();
441 return (Type) schemaTable.Rows[i]["DataType"];
448 float GetFloat (int i)
450 object value = GetValue (i);
451 if (!(value is float)) {
452 if (value is DBNull) throw new SqlNullValueException ();
453 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
455 return (float) value;
464 object value = GetValue (i);
465 if (!(value is Guid)) {
466 if (value is DBNull) throw new SqlNullValueException ();
467 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
476 short GetInt16 (int i)
478 object value = GetValue (i);
479 if (!(value is short)) {
480 if (value is DBNull) throw new SqlNullValueException ();
481 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
483 return (short) value;
492 object value = GetValue (i);
493 if (!(value is int)) {
494 if (value is DBNull) throw new SqlNullValueException ();
495 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
504 long GetInt64 (int i)
506 object value = GetValue (i);
507 // TDS 7.0 returns bigint as decimal(19,0)
508 if (value is decimal) {
509 TdsDataColumn schema = command.Tds.Columns[i];
510 if ((byte)schema["NumericPrecision"] == 19 && (byte)schema["NumericScale"] == 0)
511 value = (long) (decimal) value;
513 if (!(value is long)) {
514 if (value is DBNull) throw new SqlNullValueException ();
515 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
524 string GetName (int i)
526 return (string) schemaTable.Rows[i]["ColumnName"];
533 int GetOrdinal (string name)
535 foreach (DataRow schemaRow in schemaTable.Rows)
536 if (((string) schemaRow ["ColumnName"]).Equals (name))
537 return (int) schemaRow ["ColumnOrdinal"];
538 foreach (DataRow schemaRow in schemaTable.Rows)
539 if (String.Compare (((string) schemaRow ["ColumnName"]), name, true) == 0)
540 return (int) schemaRow ["ColumnOrdinal"];
541 throw new IndexOutOfRangeException ();
548 DataTable GetSchemaTable ()
552 if (schemaTable.Rows != null && schemaTable.Rows.Count > 0)
560 dataTypeNames = new ArrayList ();
562 foreach (TdsDataColumn schema in command.Tds.Columns) {
563 DataRow row = schemaTable.NewRow ();
565 row ["ColumnName"] = GetSchemaValue (schema, "ColumnName");
566 row ["ColumnSize"] = GetSchemaValue (schema, "ColumnSize");
567 row ["ColumnOrdinal"] = GetSchemaValue (schema, "ColumnOrdinal");
568 row ["NumericPrecision"] = GetSchemaValue (schema, "NumericPrecision");
569 row ["NumericScale"] = GetSchemaValue (schema, "NumericScale");
570 row ["IsUnique"] = GetSchemaValue (schema, "IsUnique");
571 row ["IsKey"] = GetSchemaValue (schema, "IsKey");
572 row ["BaseServerName"] = GetSchemaValue (schema, "BaseServerName");
573 row ["BaseCatalogName"] = GetSchemaValue (schema, "BaseCatalogName");
574 row ["BaseColumnName"] = GetSchemaValue (schema, "BaseColumnName");
575 row ["BaseSchemaName"] = GetSchemaValue (schema, "BaseSchemaName");
576 row ["BaseTableName"] = GetSchemaValue (schema, "BaseTableName");
577 row ["AllowDBNull"] = GetSchemaValue (schema, "AllowDBNull");
578 row ["IsAliased"] = GetSchemaValue (schema, "IsAliased");
579 row ["IsExpression"] = GetSchemaValue (schema, "IsExpression");
580 row ["IsIdentity"] = GetSchemaValue (schema, "IsIdentity");
581 row ["IsAutoIncrement"] = GetSchemaValue (schema, "IsAutoIncrement");
582 row ["IsRowVersion"] = GetSchemaValue (schema, "IsRowVersion");
583 row ["IsHidden"] = GetSchemaValue (schema, "IsHidden");
584 row ["IsReadOnly"] = GetSchemaValue (schema, "IsReadOnly");
586 // We don't always get the base column name.
587 if (row ["BaseColumnName"] == DBNull.Value)
588 row ["BaseColumnName"] = row ["ColumnName"];
590 switch ((TdsColumnType) schema ["ColumnType"]) {
591 case TdsColumnType.Int1:
592 case TdsColumnType.Int2:
593 case TdsColumnType.Int4:
594 case TdsColumnType.IntN:
595 switch ((int) schema ["ColumnSize"]) {
597 dataTypeNames.Add ("tinyint");
598 row ["ProviderType"] = (int) SqlDbType.TinyInt;
599 row ["DataType"] = typeof (byte);
600 row ["IsLong"] = false;
603 dataTypeNames.Add ("smallint");
604 row ["ProviderType"] = (int) SqlDbType.SmallInt;
605 row ["DataType"] = typeof (short);
606 row ["IsLong"] = false;
609 dataTypeNames.Add ("int");
610 row ["ProviderType"] = (int) SqlDbType.Int;
611 row ["DataType"] = typeof (int);
612 row ["IsLong"] = false;
615 dataTypeNames.Add ("bigint");
616 row ["ProviderType"] = (int) SqlDbType.BigInt;
617 row ["DataType"] = typeof (long);
618 row ["IsLong"] = false;
622 case TdsColumnType.Real:
623 case TdsColumnType.Float8:
624 case TdsColumnType.FloatN:
625 switch ((int) schema ["ColumnSize"]) {
627 dataTypeNames.Add ("real");
628 row ["ProviderType"] = (int) SqlDbType.Real;
629 row ["DataType"] = typeof (float);
630 row ["IsLong"] = false;
633 dataTypeNames.Add ("float");
634 row ["ProviderType"] = (int) SqlDbType.Float;
635 row ["DataType"] = typeof (double);
636 row ["IsLong"] = false;
640 case TdsColumnType.Image :
641 dataTypeNames.Add ("image");
642 row ["ProviderType"] = (int) SqlDbType.Image;
643 row ["DataType"] = typeof (byte[]);
644 row ["IsLong"] = true;
646 case TdsColumnType.Text :
647 dataTypeNames.Add ("text");
648 row ["ProviderType"] = (int) SqlDbType.Text;
649 row ["DataType"] = typeof (string);
650 row ["IsLong"] = true;
652 case TdsColumnType.UniqueIdentifier :
653 dataTypeNames.Add ("uniqueidentifier");
654 row ["ProviderType"] = (int) SqlDbType.UniqueIdentifier;
655 row ["DataType"] = typeof (Guid);
656 row ["IsLong"] = false;
658 case TdsColumnType.VarBinary :
659 case TdsColumnType.BigVarBinary :
660 dataTypeNames.Add ("varbinary");
661 row ["ProviderType"] = (int) SqlDbType.VarBinary;
662 row ["DataType"] = typeof (byte[]);
663 row ["IsLong"] = true;
665 case TdsColumnType.VarChar :
666 case TdsColumnType.BigVarChar :
667 dataTypeNames.Add ("varchar");
668 row ["ProviderType"] = (int) SqlDbType.VarChar;
669 row ["DataType"] = typeof (string);
670 row ["IsLong"] = false;
672 case TdsColumnType.Binary :
673 case TdsColumnType.BigBinary :
674 dataTypeNames.Add ("binary");
675 row ["ProviderType"] = (int) SqlDbType.Binary;
676 row ["DataType"] = typeof (byte[]);
677 row ["IsLong"] = true;
679 case TdsColumnType.Char :
680 case TdsColumnType.BigChar :
681 dataTypeNames.Add ("char");
682 row ["ProviderType"] = (int) SqlDbType.Char;
683 row ["DataType"] = typeof (string);
684 row ["IsLong"] = false;
686 case TdsColumnType.Bit :
687 case TdsColumnType.BitN :
688 dataTypeNames.Add ("bit");
689 row ["ProviderType"] = (int) SqlDbType.Bit;
690 row ["DataType"] = typeof (bool);
691 row ["IsLong"] = false;
693 case TdsColumnType.DateTime4 :
694 case TdsColumnType.DateTime :
695 case TdsColumnType.DateTimeN :
696 dataTypeNames.Add ("datetime");
697 row ["ProviderType"] = (int) SqlDbType.DateTime;
698 row ["DataType"] = typeof (DateTime);
699 row ["IsLong"] = false;
701 case TdsColumnType.Money :
702 case TdsColumnType.MoneyN :
703 case TdsColumnType.Money4 :
704 dataTypeNames.Add ("money");
705 row ["ProviderType"] = (int) SqlDbType.Money;
706 row ["DataType"] = typeof (decimal);
707 row ["IsLong"] = false;
709 case TdsColumnType.NText :
710 dataTypeNames.Add ("ntext");
711 row ["ProviderType"] = (int) SqlDbType.NText;
712 row ["DataType"] = typeof (string);
713 row ["IsLong"] = true;
715 case TdsColumnType.NVarChar :
716 dataTypeNames.Add ("nvarchar");
717 row ["ProviderType"] = (int) SqlDbType.NVarChar;
718 row ["DataType"] = typeof (string);
719 row ["IsLong"] = false;
721 case TdsColumnType.Decimal :
722 case TdsColumnType.Numeric :
723 dataTypeNames.Add ("decimal");
724 row ["ProviderType"] = (int) SqlDbType.Decimal;
725 row ["DataType"] = typeof (decimal);
726 row ["IsLong"] = false;
728 case TdsColumnType.NChar :
729 dataTypeNames.Add ("nchar");
730 row ["ProviderType"] = (int) SqlDbType.NChar;
731 row ["DataType"] = typeof (string);
732 row ["IsLong"] = false;
734 case TdsColumnType.SmallMoney :
735 dataTypeNames.Add ("smallmoney");
736 row ["ProviderType"] = (int) SqlDbType.SmallMoney;
737 row ["DataType"] = typeof (decimal);
738 row ["IsLong"] = false;
741 dataTypeNames.Add ("variant");
742 row ["ProviderType"] = (int) SqlDbType.Variant;
743 row ["DataType"] = typeof (object);
744 row ["IsLong"] = false;
748 schemaTable.Rows.Add (row);
755 private static object GetSchemaValue (TdsDataColumn schema, object key)
757 if (schema.ContainsKey (key) && schema [key] != null)
762 public SqlBinary GetSqlBinary (int i)
764 object value = GetSqlValue (i);
765 if (!(value is SqlBinary))
766 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
767 return (SqlBinary) value;
770 public SqlBoolean GetSqlBoolean (int i)
772 object value = GetSqlValue (i);
773 if (!(value is SqlBoolean))
774 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
775 return (SqlBoolean) value;
778 public SqlByte GetSqlByte (int i)
780 object value = GetSqlValue (i);
781 if (!(value is SqlByte))
782 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
783 return (SqlByte) value;
786 public SqlDateTime GetSqlDateTime (int i)
788 object value = GetSqlValue (i);
789 if (!(value is SqlDateTime))
790 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
791 return (SqlDateTime) value;
794 public SqlDecimal GetSqlDecimal (int i)
796 object value = GetSqlValue (i);
797 if (!(value is SqlDecimal))
798 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
799 return (SqlDecimal) value;
802 public SqlDouble GetSqlDouble (int i)
804 object value = GetSqlValue (i);
805 if (!(value is SqlDouble))
806 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
807 return (SqlDouble) value;
810 public SqlGuid GetSqlGuid (int i)
812 object value = GetSqlValue (i);
813 if (!(value is SqlGuid))
814 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
815 return (SqlGuid) value;
818 public SqlInt16 GetSqlInt16 (int i)
820 object value = GetSqlValue (i);
821 if (!(value is SqlInt16))
822 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
823 return (SqlInt16) value;
826 public SqlInt32 GetSqlInt32 (int i)
828 object value = GetSqlValue (i);
829 if (!(value is SqlInt32))
830 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
831 return (SqlInt32) value;
834 public SqlInt64 GetSqlInt64 (int i)
836 object value = GetSqlValue (i);
837 // TDS 7.0 returns bigint as decimal(19,0)
838 if (value is SqlDecimal) {
839 TdsDataColumn schema = command.Tds.Columns[i];
840 if ((byte)schema["NumericPrecision"] == 19 && (byte)schema["NumericScale"] == 0)
841 value = (SqlInt64) (SqlDecimal) value;
843 if (!(value is SqlInt64))
844 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
845 return (SqlInt64) value;
848 public SqlMoney GetSqlMoney (int i)
850 object value = GetSqlValue (i);
851 if (!(value is SqlMoney))
852 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
853 return (SqlMoney) value;
856 public SqlSingle GetSqlSingle (int i)
858 object value = GetSqlValue (i);
859 if (!(value is SqlSingle))
860 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
861 return (SqlSingle) value;
864 public SqlString GetSqlString (int i)
866 object value = GetSqlValue (i);
867 if (!(value is SqlString))
868 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
869 return (SqlString) value;
872 public object GetSqlValue (int i)
874 SqlDbType type = (SqlDbType) (schemaTable.Rows [i]["ProviderType"]);
875 object value = GetValue (i);
878 case SqlDbType.BigInt:
879 if (value == DBNull.Value)
880 return SqlInt64.Null;
881 return (SqlInt64) ((long) value);
882 case SqlDbType.Binary:
883 case SqlDbType.Image:
884 case SqlDbType.VarBinary:
885 case SqlDbType.Timestamp:
886 if (value == DBNull.Value)
887 return SqlBinary.Null;
888 return (SqlBinary) ((byte[]) value);
890 if (value == DBNull.Value)
891 return SqlBoolean.Null;
892 return (SqlBoolean) ((bool) value);
894 case SqlDbType.NChar:
895 case SqlDbType.NText:
896 case SqlDbType.NVarChar:
898 case SqlDbType.VarChar:
899 if (value == DBNull.Value)
900 return SqlString.Null;
901 return (SqlString) ((string) value);
902 case SqlDbType.DateTime:
903 case SqlDbType.SmallDateTime:
904 if (value == DBNull.Value)
905 return SqlDateTime.Null;
906 return (SqlDateTime) ((DateTime) value);
907 case SqlDbType.Decimal:
908 if (value == DBNull.Value)
909 return SqlDecimal.Null;
910 if (value is TdsBigDecimal)
911 return SqlDecimal.FromTdsBigDecimal ((TdsBigDecimal) value);
912 return (SqlDecimal) ((decimal) value);
913 case SqlDbType.Float:
914 if (value == DBNull.Value)
915 return SqlDouble.Null;
916 return (SqlDouble) ((double) value);
918 if (value == DBNull.Value)
919 return SqlInt32.Null;
920 return (SqlInt32) ((int) value);
921 case SqlDbType.Money:
922 case SqlDbType.SmallMoney:
923 if (value == DBNull.Value)
924 return SqlMoney.Null;
925 return (SqlMoney) ((decimal) value);
927 if (value == DBNull.Value)
928 return SqlSingle.Null;
929 return (SqlSingle) ((float) value);
930 case SqlDbType.UniqueIdentifier:
931 if (value == DBNull.Value)
933 return (SqlGuid) ((Guid) value);
934 case SqlDbType.SmallInt:
935 if (value == DBNull.Value)
936 return SqlInt16.Null;
937 return (SqlInt16) ((short) value);
938 case SqlDbType.TinyInt:
939 if (value == DBNull.Value)
941 return (SqlByte) ((byte) value);
944 throw new InvalidOperationException ("The type of this column is unknown.");
947 public int GetSqlValues (object[] values)
950 int columnCount = schemaTable.Rows.Count;
951 int arrayCount = values.Length;
953 if (arrayCount > columnCount)
958 for (int i = 0; i < count; i += 1)
959 values [i] = GetSqlValue (i);
968 string GetString (int i)
970 object value = GetValue (i);
971 if (!(value is string)) {
972 if (value is DBNull) throw new SqlNullValueException ();
973 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
975 return (string) value;
982 object GetValue (int i)
984 if (i < 0 || i >= command.Tds.Columns.Count)
985 throw new IndexOutOfRangeException ();
987 if ((command.CommandBehavior & CommandBehavior.SequentialAccess) != 0) {
988 return ((Tds)command.Tds).GetSequentialColumnValue (i);
991 return command.Tds.ColumnValues [i];
998 int GetValues (object[] values)
1000 int len = values.Length;
1001 int bigDecimalIndex = command.Tds.ColumnValues.BigDecimalIndex;
1003 // If a four-byte decimal is stored, then we can't convert to
1004 // a native type. Throw an OverflowException.
1005 if (bigDecimalIndex >= 0 && bigDecimalIndex < len)
1006 throw new OverflowException ();
1008 command.Tds.ColumnValues.CopyTo (0, values, 0, len);
1009 return (len < FieldCount ? len : FieldCount);
1012 void IDisposable.Dispose ()
1015 GC.SuppressFinalize (this);
1018 IEnumerator IEnumerable.GetEnumerator ()
1020 return new DbEnumerator (this);
1027 bool IsDBNull (int i)
1029 return GetValue (i) == DBNull.Value;
1040 if ((command.CommandBehavior & CommandBehavior.SingleResult) != 0 && resultsRead > 0)
1043 moreResults = command.Tds.NextResult ();
1045 command.GetOutputParameters ();
1048 schemaTable = ConstructSchemaTable ();
1065 if ((command.CommandBehavior & CommandBehavior.SingleRow) != 0 && rowsRead > 0)
1067 if ((command.CommandBehavior & CommandBehavior.SchemaOnly) != 0)
1072 if ((haveRead) && (!readResultUsed))
1074 readResultUsed = true;
1079 return (ReadRecord ());
1083 internal bool ReadRecord ()
1086 bool result = command.Tds.NextRow ();
1093 void ValidateState ()
1096 throw new InvalidOperationException ("Invalid attempt to read data when reader is closed");
1101 protected override bool IsValidRow
1103 get {throw new NotImplementedException ();}
1107 public override Type GetProviderSpecificFieldType (int position)
1109 throw new NotImplementedException ();
1113 public override object GetProviderSpecificValue (int position)
1115 throw new NotImplementedException ();
1119 public override int GetProviderSpecificValues (object [] values)
1121 throw new NotImplementedException ();
1126 #endregion // Methods