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;
41 using System.Collections;
42 using System.ComponentModel;
44 using System.Data.Common;
45 using System.Data.SqlTypes;
47 namespace System.Data.SqlClient {
49 public class SqlDataReader : DbDataReader, IDataReader, IDisposable, IDataRecord
51 public sealed class SqlDataReader : MarshalByRefObject, IEnumerable, IDataReader, IDisposable, IDataRecord
57 ArrayList dataTypeNames;
58 bool disposed = false;
64 DataTable schemaTable;
70 int visibleFieldCount;
77 internal SqlDataReader (SqlCommand command)
81 readResultUsed = false;
82 this.command = command;
83 schemaTable = ConstructSchemaTable ();
87 command.Tds.RecordsAffected = -1;
89 visibleFieldCount = 0;
94 #endregion // Constructors
111 get { return fieldCount; }
119 get { return isClosed; }
126 object this [int i] {
127 get { return GetValue (i); }
134 object this [string name] {
135 get { return GetValue (GetOrdinal (name)); }
142 int RecordsAffected {
144 return command.Tds.RecordsAffected;
158 readResult = ReadRecord ();
163 public override int VisibleFieldCount {
164 get { return visibleFieldCount; }
167 protected SqlConnection Connection {
168 get { return command.Connection; }
171 protected bool IsCommandBehavior (CommandBehavior condition) {
172 return condition == command.CommandBehavior;
176 #endregion // Properties
188 // skip to end & read output parameters.
189 while (NextResult ())
192 command.CloseDataReader (moreResults);
195 private static DataTable ConstructSchemaTable ()
197 Type booleanType = Type.GetType ("System.Boolean");
198 Type stringType = Type.GetType ("System.String");
199 Type intType = Type.GetType ("System.Int32");
200 Type typeType = Type.GetType ("System.Type");
201 Type shortType = Type.GetType ("System.Int16");
203 DataTable schemaTable = new DataTable ("SchemaTable");
204 schemaTable.Columns.Add ("ColumnName", stringType);
205 schemaTable.Columns.Add ("ColumnOrdinal", intType);
206 schemaTable.Columns.Add ("ColumnSize", intType);
207 schemaTable.Columns.Add ("NumericPrecision", shortType);
208 schemaTable.Columns.Add ("NumericScale", shortType);
209 schemaTable.Columns.Add ("IsUnique", booleanType);
210 schemaTable.Columns.Add ("IsKey", booleanType);
211 schemaTable.Columns.Add ("BaseServerName", stringType);
212 schemaTable.Columns.Add ("BaseCatalogName", stringType);
213 schemaTable.Columns.Add ("BaseColumnName", stringType);
214 schemaTable.Columns.Add ("BaseSchemaName", stringType);
215 schemaTable.Columns.Add ("BaseTableName", stringType);
216 schemaTable.Columns.Add ("DataType", typeType);
217 schemaTable.Columns.Add ("AllowDBNull", booleanType);
218 schemaTable.Columns.Add ("ProviderType", intType);
219 schemaTable.Columns.Add ("IsAliased", booleanType);
220 schemaTable.Columns.Add ("IsExpression", booleanType);
221 schemaTable.Columns.Add ("IsIdentity", booleanType);
222 schemaTable.Columns.Add ("IsAutoIncrement", booleanType);
223 schemaTable.Columns.Add ("IsRowVersion", booleanType);
224 schemaTable.Columns.Add ("IsHidden", booleanType);
225 schemaTable.Columns.Add ("IsLong", booleanType);
226 schemaTable.Columns.Add ("IsReadOnly", booleanType);
233 void Dispose (bool disposing)
237 schemaTable.Dispose ();
249 bool GetBoolean (int i)
251 object value = GetValue (i);
252 if (!(value is bool)) {
253 if (value is DBNull) throw new SqlNullValueException ();
254 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
265 object value = GetValue (i);
266 if (!(value is byte)) {
267 if (value is DBNull) throw new SqlNullValueException ();
268 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
277 long GetBytes (int i, long dataIndex, byte[] buffer, int bufferIndex, int length)
279 if ((command.CommandBehavior & CommandBehavior.SequentialAccess) != 0) {
281 long len = ((Tds)command.Tds).GetSequentialColumnValue (i, dataIndex, buffer, bufferIndex, length);
283 throw new InvalidCastException ("Invalid attempt to GetBytes on column "
284 + "'" + command.Tds.Columns[i]["ColumnName"] +
285 "'." + "The GetBytes function"
286 + " can only be used on columns of type Text, NText, or Image");
288 } catch (TdsInternalException ex) {
289 command.Connection.Close ();
290 throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
294 object value = GetValue (i);
295 if (!(value is byte [])) {
296 if (value is DBNull) throw new SqlNullValueException ();
297 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
300 if ( buffer == null )
301 return ((byte []) value).Length; // Return length of data
303 // Copy data into buffer
304 int availLen = (int) ( ( (byte []) value).Length - dataIndex);
305 if (availLen < length)
307 Array.Copy ((byte []) value, (int) dataIndex, buffer, bufferIndex, length);
308 return length; // return actual read count
311 [EditorBrowsableAttribute (EditorBrowsableState.Never)]
318 object value = GetValue (i);
319 if (!(value is char)) {
320 if (value is DBNull) throw new SqlNullValueException ();
321 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
330 long GetChars (int i, long dataIndex, char[] buffer, int bufferIndex, int length)
332 if ((command.CommandBehavior & CommandBehavior.SequentialAccess) != 0) {
333 Encoding encoding = null;
335 TdsColumnType colType = (TdsColumnType) command.Tds.Columns[i]["ColumnType"];
337 case TdsColumnType.Text :
338 case TdsColumnType.VarChar:
339 case TdsColumnType.Char:
340 case TdsColumnType.BigVarChar:
341 encoding = Encoding.ASCII;
343 case TdsColumnType.NText :
344 case TdsColumnType.NVarChar:
345 case TdsColumnType.NChar:
346 encoding = Encoding.Unicode;
354 if (buffer == null) {
355 count = GetBytes (i,0,(byte[]) null,0,0);
360 byte[] arr = new byte [length];
361 count = GetBytes (i, dataIndex, arr, 0, length);
363 throw new InvalidCastException ("Specified cast is not valid");
365 Char[] val = encoding.GetChars (arr, 0, (int)count);
366 val.CopyTo (buffer, bufferIndex);
371 object value = GetValue (i);
374 valueBuffer = (char[])value;
375 else if (value is string)
376 valueBuffer = ((string)value).ToCharArray();
378 if (value is DBNull) throw new SqlNullValueException ();
379 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
382 if ( buffer == null ) {
383 // Return length of data
384 return valueBuffer.Length;
387 // Copy data into buffer
388 Array.Copy (valueBuffer, (int) dataIndex, buffer, bufferIndex, length);
389 return valueBuffer.Length - dataIndex;
394 [EditorBrowsableAttribute (EditorBrowsableState.Never)]
395 public new IDataReader GetData (int i)
397 return ((IDataReader) this [i]);
405 string GetDataTypeName (int i)
407 if (i < 0 || i >= dataTypeNames.Count)
408 throw new IndexOutOfRangeException ();
409 return (string) dataTypeNames [i];
416 DateTime GetDateTime (int i)
418 object value = GetValue (i);
419 if (!(value is DateTime)) {
420 if (value is DBNull) throw new SqlNullValueException ();
421 else throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
423 return (DateTime) value;
430 decimal GetDecimal (int i)
432 object value = GetValue (i);
433 if (!(value is decimal)) {
434 if (value is DBNull) throw new SqlNullValueException ();
435 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
437 return (decimal) value;
444 double GetDouble (int i)
446 object value = GetValue (i);
447 if (!(value is double)) {
448 if (value is DBNull) throw new SqlNullValueException ();
449 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
451 return (double) value;
458 Type GetFieldType (int i)
460 if (i < 0 || i >= schemaTable.Rows.Count)
461 throw new IndexOutOfRangeException ();
462 return (Type) schemaTable.Rows[i]["DataType"];
469 float GetFloat (int i)
471 object value = GetValue (i);
472 if (!(value is float)) {
473 if (value is DBNull) throw new SqlNullValueException ();
474 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
476 return (float) value;
485 object value = GetValue (i);
486 if (!(value is Guid)) {
487 if (value is DBNull) throw new SqlNullValueException ();
488 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
497 short GetInt16 (int i)
499 object value = GetValue (i);
500 if (!(value is short)) {
501 if (value is DBNull) throw new SqlNullValueException ();
502 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
504 return (short) value;
513 object value = GetValue (i);
514 if (!(value is int)) {
515 if (value is DBNull) throw new SqlNullValueException ();
516 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
525 long GetInt64 (int i)
527 object value = GetValue (i);
528 // TDS 7.0 returns bigint as decimal(19,0)
529 if (value is decimal) {
530 TdsDataColumn schema = command.Tds.Columns[i];
531 if ((byte)schema["NumericPrecision"] == 19 && (byte)schema["NumericScale"] == 0)
532 value = (long) (decimal) value;
534 if (!(value is long)) {
535 if (value is DBNull) throw new SqlNullValueException ();
536 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
545 string GetName (int i)
547 return (string) schemaTable.Rows[i]["ColumnName"];
554 int GetOrdinal (string name)
556 foreach (DataRow schemaRow in schemaTable.Rows)
557 if (((string) schemaRow ["ColumnName"]).Equals (name))
558 return (int) schemaRow ["ColumnOrdinal"];
559 foreach (DataRow schemaRow in schemaTable.Rows)
560 if (String.Compare (((string) schemaRow ["ColumnName"]), name, true) == 0)
561 return (int) schemaRow ["ColumnOrdinal"];
562 throw new IndexOutOfRangeException ();
569 DataTable GetSchemaTable ()
573 if (schemaTable.Rows != null && schemaTable.Rows.Count > 0)
581 dataTypeNames = new ArrayList ();
583 foreach (TdsDataColumn schema in command.Tds.Columns) {
584 DataRow row = schemaTable.NewRow ();
586 row ["ColumnName"] = GetSchemaValue (schema, "ColumnName");
587 row ["ColumnSize"] = GetSchemaValue (schema, "ColumnSize");
588 row ["ColumnOrdinal"] = GetSchemaValue (schema, "ColumnOrdinal");
589 row ["NumericPrecision"] = GetSchemaValue (schema, "NumericPrecision");
590 row ["NumericScale"] = GetSchemaValue (schema, "NumericScale");
591 row ["IsUnique"] = GetSchemaValue (schema, "IsUnique");
592 row ["IsKey"] = GetSchemaValue (schema, "IsKey");
593 row ["BaseServerName"] = GetSchemaValue (schema, "BaseServerName");
594 row ["BaseCatalogName"] = GetSchemaValue (schema, "BaseCatalogName");
595 row ["BaseColumnName"] = GetSchemaValue (schema, "BaseColumnName");
596 row ["BaseSchemaName"] = GetSchemaValue (schema, "BaseSchemaName");
597 row ["BaseTableName"] = GetSchemaValue (schema, "BaseTableName");
598 row ["AllowDBNull"] = GetSchemaValue (schema, "AllowDBNull");
599 row ["IsAliased"] = GetSchemaValue (schema, "IsAliased");
600 row ["IsExpression"] = GetSchemaValue (schema, "IsExpression");
601 row ["IsIdentity"] = GetSchemaValue (schema, "IsIdentity");
602 row ["IsAutoIncrement"] = GetSchemaValue (schema, "IsAutoIncrement");
603 row ["IsRowVersion"] = GetSchemaValue (schema, "IsRowVersion");
604 row ["IsHidden"] = GetSchemaValue (schema, "IsHidden");
605 row ["IsReadOnly"] = GetSchemaValue (schema, "IsReadOnly");
607 // We don't always get the base column name.
608 if (row ["BaseColumnName"] == DBNull.Value)
609 row ["BaseColumnName"] = row ["ColumnName"];
611 switch ((TdsColumnType) schema ["ColumnType"]) {
612 case TdsColumnType.Int1:
613 case TdsColumnType.Int2:
614 case TdsColumnType.Int4:
615 case TdsColumnType.IntN:
616 switch ((int) schema ["ColumnSize"]) {
618 dataTypeNames.Add ("tinyint");
619 row ["ProviderType"] = (int) SqlDbType.TinyInt;
620 row ["DataType"] = typeof (byte);
621 row ["IsLong"] = false;
624 dataTypeNames.Add ("smallint");
625 row ["ProviderType"] = (int) SqlDbType.SmallInt;
626 row ["DataType"] = typeof (short);
627 row ["IsLong"] = false;
630 dataTypeNames.Add ("int");
631 row ["ProviderType"] = (int) SqlDbType.Int;
632 row ["DataType"] = typeof (int);
633 row ["IsLong"] = false;
636 dataTypeNames.Add ("bigint");
637 row ["ProviderType"] = (int) SqlDbType.BigInt;
638 row ["DataType"] = typeof (long);
639 row ["IsLong"] = false;
643 case TdsColumnType.Real:
644 case TdsColumnType.Float8:
645 case TdsColumnType.FloatN:
646 switch ((int) schema ["ColumnSize"]) {
648 dataTypeNames.Add ("real");
649 row ["ProviderType"] = (int) SqlDbType.Real;
650 row ["DataType"] = typeof (float);
651 row ["IsLong"] = false;
654 dataTypeNames.Add ("float");
655 row ["ProviderType"] = (int) SqlDbType.Float;
656 row ["DataType"] = typeof (double);
657 row ["IsLong"] = false;
661 case TdsColumnType.Image :
662 dataTypeNames.Add ("image");
663 row ["ProviderType"] = (int) SqlDbType.Image;
664 row ["DataType"] = typeof (byte[]);
665 row ["IsLong"] = true;
667 case TdsColumnType.Text :
668 dataTypeNames.Add ("text");
669 row ["ProviderType"] = (int) SqlDbType.Text;
670 row ["DataType"] = typeof (string);
671 row ["IsLong"] = true;
673 case TdsColumnType.UniqueIdentifier :
674 dataTypeNames.Add ("uniqueidentifier");
675 row ["ProviderType"] = (int) SqlDbType.UniqueIdentifier;
676 row ["DataType"] = typeof (Guid);
677 row ["IsLong"] = false;
679 case TdsColumnType.VarBinary :
680 case TdsColumnType.BigVarBinary :
681 dataTypeNames.Add ("varbinary");
682 row ["ProviderType"] = (int) SqlDbType.VarBinary;
683 row ["DataType"] = typeof (byte[]);
684 row ["IsLong"] = true;
686 case TdsColumnType.VarChar :
687 case TdsColumnType.BigVarChar :
688 dataTypeNames.Add ("varchar");
689 row ["ProviderType"] = (int) SqlDbType.VarChar;
690 row ["DataType"] = typeof (string);
691 row ["IsLong"] = false;
693 case TdsColumnType.Binary :
694 case TdsColumnType.BigBinary :
695 dataTypeNames.Add ("binary");
696 row ["ProviderType"] = (int) SqlDbType.Binary;
697 row ["DataType"] = typeof (byte[]);
698 row ["IsLong"] = true;
700 case TdsColumnType.Char :
701 case TdsColumnType.BigChar :
702 dataTypeNames.Add ("char");
703 row ["ProviderType"] = (int) SqlDbType.Char;
704 row ["DataType"] = typeof (string);
705 row ["IsLong"] = false;
707 case TdsColumnType.Bit :
708 case TdsColumnType.BitN :
709 dataTypeNames.Add ("bit");
710 row ["ProviderType"] = (int) SqlDbType.Bit;
711 row ["DataType"] = typeof (bool);
712 row ["IsLong"] = false;
714 case TdsColumnType.DateTime4 :
715 case TdsColumnType.DateTime :
716 case TdsColumnType.DateTimeN :
717 dataTypeNames.Add ("datetime");
718 row ["ProviderType"] = (int) SqlDbType.DateTime;
719 row ["DataType"] = typeof (DateTime);
720 row ["IsLong"] = false;
722 case TdsColumnType.Money :
723 case TdsColumnType.MoneyN :
724 case TdsColumnType.Money4 :
725 dataTypeNames.Add ("money");
726 row ["ProviderType"] = (int) SqlDbType.Money;
727 row ["DataType"] = typeof (decimal);
728 row ["IsLong"] = false;
730 case TdsColumnType.NText :
731 dataTypeNames.Add ("ntext");
732 row ["ProviderType"] = (int) SqlDbType.NText;
733 row ["DataType"] = typeof (string);
734 row ["IsLong"] = true;
736 case TdsColumnType.NVarChar :
737 dataTypeNames.Add ("nvarchar");
738 row ["ProviderType"] = (int) SqlDbType.NVarChar;
739 row ["DataType"] = typeof (string);
740 row ["IsLong"] = false;
742 case TdsColumnType.Decimal :
743 case TdsColumnType.Numeric :
744 dataTypeNames.Add ("decimal");
745 row ["ProviderType"] = (int) SqlDbType.Decimal;
746 row ["DataType"] = typeof (decimal);
747 row ["IsLong"] = false;
749 case TdsColumnType.NChar :
750 dataTypeNames.Add ("nchar");
751 row ["ProviderType"] = (int) SqlDbType.NChar;
752 row ["DataType"] = typeof (string);
753 row ["IsLong"] = false;
755 case TdsColumnType.SmallMoney :
756 dataTypeNames.Add ("smallmoney");
757 row ["ProviderType"] = (int) SqlDbType.SmallMoney;
758 row ["DataType"] = typeof (decimal);
759 row ["IsLong"] = false;
762 dataTypeNames.Add ("variant");
763 row ["ProviderType"] = (int) SqlDbType.Variant;
764 row ["DataType"] = typeof (object);
765 row ["IsLong"] = false;
769 if ((bool)row ["IsHidden"] == false)
770 visibleFieldCount += 1;
773 schemaTable.Rows.Add (row);
780 private static object GetSchemaValue (TdsDataColumn schema, object key)
782 if (schema.ContainsKey (key) && schema [key] != null)
791 SqlBinary GetSqlBinary (int i)
793 object value = GetSqlValue (i);
794 if (!(value is SqlBinary))
795 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
796 return (SqlBinary) value;
803 SqlBoolean GetSqlBoolean (int i)
805 object value = GetSqlValue (i);
806 if (!(value is SqlBoolean))
807 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
808 return (SqlBoolean) value;
815 SqlByte GetSqlByte (int i)
817 object value = GetSqlValue (i);
818 if (!(value is SqlByte))
819 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
820 return (SqlByte) value;
827 SqlDateTime GetSqlDateTime (int i)
829 object value = GetSqlValue (i);
830 if (!(value is SqlDateTime))
831 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
832 return (SqlDateTime) value;
839 SqlDecimal GetSqlDecimal (int i)
841 object value = GetSqlValue (i);
842 if (!(value is SqlDecimal))
843 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
844 return (SqlDecimal) value;
851 SqlDouble GetSqlDouble (int i)
853 object value = GetSqlValue (i);
854 if (!(value is SqlDouble))
855 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
856 return (SqlDouble) value;
863 SqlGuid GetSqlGuid (int i)
865 object value = GetSqlValue (i);
866 if (!(value is SqlGuid))
867 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
868 return (SqlGuid) value;
875 SqlInt16 GetSqlInt16 (int i)
877 object value = GetSqlValue (i);
878 if (!(value is SqlInt16))
879 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
880 return (SqlInt16) value;
887 SqlInt32 GetSqlInt32 (int i)
889 object value = GetSqlValue (i);
890 if (!(value is SqlInt32))
891 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
892 return (SqlInt32) value;
899 SqlInt64 GetSqlInt64 (int i)
901 object value = GetSqlValue (i);
902 // TDS 7.0 returns bigint as decimal(19,0)
903 if (value is SqlDecimal) {
904 TdsDataColumn schema = command.Tds.Columns[i];
905 if ((byte)schema["NumericPrecision"] == 19 && (byte)schema["NumericScale"] == 0)
906 value = (SqlInt64) (SqlDecimal) value;
908 if (!(value is SqlInt64))
909 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
910 return (SqlInt64) value;
917 SqlMoney GetSqlMoney (int i)
919 object value = GetSqlValue (i);
920 if (!(value is SqlMoney))
921 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
922 return (SqlMoney) value;
929 SqlSingle GetSqlSingle (int i)
931 object value = GetSqlValue (i);
932 if (!(value is SqlSingle))
933 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
934 return (SqlSingle) value;
941 SqlString GetSqlString (int i)
943 object value = GetSqlValue (i);
944 if (!(value is SqlString))
945 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
946 return (SqlString) value;
950 public virtual SqlXml GetSqlXml (int i)
952 object value = GetSqlValue (i);
953 if (!(value is SqlXml)) {
954 if (value is DBNull) throw new SqlNullValueException ();
955 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
957 return (SqlXml) value;
965 object GetSqlValue (int i)
967 SqlDbType type = (SqlDbType) (schemaTable.Rows [i]["ProviderType"]);
968 object value = GetValue (i);
971 case SqlDbType.BigInt:
972 if (value == DBNull.Value)
973 return SqlInt64.Null;
974 return (SqlInt64) ((long) value);
975 case SqlDbType.Binary:
976 case SqlDbType.Image:
977 case SqlDbType.VarBinary:
978 case SqlDbType.Timestamp:
979 if (value == DBNull.Value)
980 return SqlBinary.Null;
981 return (SqlBinary) ((byte[]) value);
983 if (value == DBNull.Value)
984 return SqlBoolean.Null;
985 return (SqlBoolean) ((bool) value);
987 case SqlDbType.NChar:
988 case SqlDbType.NText:
989 case SqlDbType.NVarChar:
991 case SqlDbType.VarChar:
992 if (value == DBNull.Value)
993 return SqlString.Null;
994 return (SqlString) ((string) value);
995 case SqlDbType.DateTime:
996 case SqlDbType.SmallDateTime:
997 if (value == DBNull.Value)
998 return SqlDateTime.Null;
999 return (SqlDateTime) ((DateTime) value);
1000 case SqlDbType.Decimal:
1001 if (value == DBNull.Value)
1002 return SqlDecimal.Null;
1003 if (value is TdsBigDecimal)
1004 return SqlDecimal.FromTdsBigDecimal ((TdsBigDecimal) value);
1005 return (SqlDecimal) ((decimal) value);
1006 case SqlDbType.Float:
1007 if (value == DBNull.Value)
1008 return SqlDouble.Null;
1009 return (SqlDouble) ((double) value);
1011 if (value == DBNull.Value)
1012 return SqlInt32.Null;
1013 return (SqlInt32) ((int) value);
1014 case SqlDbType.Money:
1015 case SqlDbType.SmallMoney:
1016 if (value == DBNull.Value)
1017 return SqlMoney.Null;
1018 return (SqlMoney) ((decimal) value);
1019 case SqlDbType.Real:
1020 if (value == DBNull.Value)
1021 return SqlSingle.Null;
1022 return (SqlSingle) ((float) value);
1023 case SqlDbType.UniqueIdentifier:
1024 if (value == DBNull.Value)
1025 return SqlGuid.Null;
1026 return (SqlGuid) ((Guid) value);
1027 case SqlDbType.SmallInt:
1028 if (value == DBNull.Value)
1029 return SqlInt16.Null;
1030 return (SqlInt16) ((short) value);
1031 case SqlDbType.TinyInt:
1032 if (value == DBNull.Value)
1033 return SqlByte.Null;
1034 return (SqlByte) ((byte) value);
1037 if (value == DBNull.Value)
1038 return SqlByte.Null;
1039 return (SqlXml) value;
1043 throw new InvalidOperationException ("The type of this column is unknown.");
1050 int GetSqlValues (object[] values)
1053 int columnCount = schemaTable.Rows.Count;
1054 int arrayCount = values.Length;
1056 if (arrayCount > columnCount)
1057 count = columnCount;
1061 for (int i = 0; i < count; i += 1)
1062 values [i] = GetSqlValue (i);
1071 string GetString (int i)
1073 object value = GetValue (i);
1074 if (!(value is string)) {
1075 if (value is DBNull) throw new SqlNullValueException ();
1076 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
1078 return (string) value;
1085 object GetValue (int i)
1087 if (i < 0 || i >= command.Tds.Columns.Count)
1088 throw new IndexOutOfRangeException ();
1091 if ((command.CommandBehavior & CommandBehavior.SequentialAccess) != 0) {
1092 return ((Tds)command.Tds).GetSequentialColumnValue (i);
1094 } catch (TdsInternalException ex) {
1095 command.Connection.Close ();
1096 throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
1099 return command.Tds.ColumnValues [i];
1106 int GetValues (object[] values)
1108 int len = values.Length;
1109 int bigDecimalIndex = command.Tds.ColumnValues.BigDecimalIndex;
1111 // If a four-byte decimal is stored, then we can't convert to
1112 // a native type. Throw an OverflowException.
1113 if (bigDecimalIndex >= 0 && bigDecimalIndex < len)
1114 throw new OverflowException ();
1116 command.Tds.ColumnValues.CopyTo (0, values, 0,
1117 len > command.Tds.ColumnValues.Count ? command.Tds.ColumnValues.Count : len);
1118 } catch (TdsInternalException ex) {
1119 command.Connection.Close ();
1120 throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
1122 return (len < FieldCount ? len : FieldCount);
1126 void IDisposable.Dispose ()
1129 GC.SuppressFinalize (this);
1134 public override IEnumerator GetEnumerator ()
1136 IEnumerator IEnumerable.GetEnumerator ()
1139 return new DbEnumerator (this);
1146 bool IsDBNull (int i)
1148 return GetValue (i) == DBNull.Value;
1159 if ((command.CommandBehavior & CommandBehavior.SingleResult) != 0 && resultsRead > 0)
1163 moreResults = command.Tds.NextResult ();
1164 } catch (TdsInternalException ex) {
1165 command.Connection.Close ();
1166 throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
1169 command.GetOutputParameters ();
1172 schemaTable = ConstructSchemaTable ();
1189 if ((command.CommandBehavior & CommandBehavior.SingleRow) != 0 && rowsRead > 0)
1191 if ((command.CommandBehavior & CommandBehavior.SchemaOnly) != 0)
1196 if ((haveRead) && (!readResultUsed))
1198 readResultUsed = true;
1201 return (ReadRecord ());
1204 internal bool ReadRecord ()
1207 bool result = command.Tds.NextRow ();
1211 } catch (TdsInternalException ex) {
1212 command.Connection.Close ();
1213 throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
1217 void ValidateState ()
1220 throw new InvalidOperationException ("Invalid attempt to read data when reader is closed");
1225 public override Type GetProviderSpecificFieldType (int position)
1227 return (GetSqlValue (position).GetType());
1230 public override object GetProviderSpecificValue (int position)
1232 return (GetSqlValue (position));
1235 public override int GetProviderSpecificValues (object [] values)
1237 return (GetSqlValues (values));
1240 public virtual SqlBytes GetSqlBytes (int i)
1242 //object value = GetSqlValue (i);
1243 //if (!(value is SqlBinary))
1244 // throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
1245 Byte[] val = (byte[])GetValue(i);
1246 SqlBytes sb = new SqlBytes (val);
1251 #endregion // Methods