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 namespace System.Data.SqlClient {
48 public class SqlDataReader : DbDataReader, IDataReader, IDisposable, IDataRecord
50 public sealed class SqlDataReader : MarshalByRefObject, IEnumerable, IDataReader, IDisposable, IDataRecord
56 ArrayList dataTypeNames;
57 bool disposed = false;
63 DataTable schemaTable;
73 internal SqlDataReader (SqlCommand command)
77 readResultUsed = false;
78 this.command = command;
79 schemaTable = ConstructSchemaTable ();
83 command.Tds.RecordsAffected = -1;
87 #endregion // Constructors
104 get { return fieldCount; }
112 get { return isClosed; }
119 object this [int i] {
120 get { return GetValue (i); }
127 object this [string name] {
128 get { return GetValue (GetOrdinal (name)); }
135 int RecordsAffected {
137 return command.Tds.RecordsAffected;
151 readResult = ReadRecord ();
156 #endregion // Properties
168 // skip to end & read output parameters.
169 while (NextResult ())
172 command.Connection.DataReader = null;
173 command.CloseDataReader (moreResults);
176 private static DataTable ConstructSchemaTable ()
178 Type booleanType = Type.GetType ("System.Boolean");
179 Type stringType = Type.GetType ("System.String");
180 Type intType = Type.GetType ("System.Int32");
181 Type typeType = Type.GetType ("System.Type");
182 Type shortType = Type.GetType ("System.Int16");
184 DataTable schemaTable = new DataTable ("SchemaTable");
185 schemaTable.Columns.Add ("ColumnName", stringType);
186 schemaTable.Columns.Add ("ColumnOrdinal", intType);
187 schemaTable.Columns.Add ("ColumnSize", intType);
188 schemaTable.Columns.Add ("NumericPrecision", shortType);
189 schemaTable.Columns.Add ("NumericScale", shortType);
190 schemaTable.Columns.Add ("IsUnique", booleanType);
191 schemaTable.Columns.Add ("IsKey", booleanType);
192 schemaTable.Columns.Add ("BaseServerName", stringType);
193 schemaTable.Columns.Add ("BaseCatalogName", stringType);
194 schemaTable.Columns.Add ("BaseColumnName", stringType);
195 schemaTable.Columns.Add ("BaseSchemaName", stringType);
196 schemaTable.Columns.Add ("BaseTableName", stringType);
197 schemaTable.Columns.Add ("DataType", typeType);
198 schemaTable.Columns.Add ("AllowDBNull", booleanType);
199 schemaTable.Columns.Add ("ProviderType", intType);
200 schemaTable.Columns.Add ("IsAliased", booleanType);
201 schemaTable.Columns.Add ("IsExpression", booleanType);
202 schemaTable.Columns.Add ("IsIdentity", booleanType);
203 schemaTable.Columns.Add ("IsAutoIncrement", booleanType);
204 schemaTable.Columns.Add ("IsRowVersion", booleanType);
205 schemaTable.Columns.Add ("IsHidden", booleanType);
206 schemaTable.Columns.Add ("IsLong", booleanType);
207 schemaTable.Columns.Add ("IsReadOnly", booleanType);
214 void Dispose (bool disposing)
218 schemaTable.Dispose ();
230 bool GetBoolean (int i)
232 object value = GetValue (i);
233 if (!(value is bool)) {
234 if (value is DBNull) throw new SqlNullValueException ();
235 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
246 object value = GetValue (i);
247 if (!(value is byte)) {
248 if (value is DBNull) throw new SqlNullValueException ();
249 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
258 long GetBytes (int i, long dataIndex, byte[] buffer, int bufferIndex, int length)
260 if ((command.CommandBehavior & CommandBehavior.SequentialAccess) != 0) {
261 long len = ((Tds)command.Tds).GetSequentialColumnValue (i, dataIndex, buffer, bufferIndex, length);
263 throw new InvalidCastException ("Invalid attempt to GetBytes on column "
264 + "'" + command.Tds.Columns[i]["ColumnName"] + "'." + "The GetBytes function"
265 + " can only be used on columns of type Text, NText, or Image");
269 object value = GetValue (i);
270 if (!(value is byte [])) {
271 if (value is DBNull) throw new SqlNullValueException ();
272 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
275 if ( buffer == null )
276 return ((byte []) value).Length; // Return length of data
278 // Copy data into buffer
279 int availLen = (int) ( ( (byte []) value).Length - dataIndex);
280 if (availLen < length)
282 Array.Copy ((byte []) value, (int) dataIndex, buffer, bufferIndex, length);
283 return length; // return actual read count
286 [EditorBrowsableAttribute (EditorBrowsableState.Never)]
293 object value = GetValue (i);
294 if (!(value is char)) {
295 if (value is DBNull) throw new SqlNullValueException ();
296 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
305 long GetChars (int i, long dataIndex, char[] buffer, int bufferIndex, int length)
307 if ((command.CommandBehavior & CommandBehavior.SequentialAccess) != 0) {
308 Encoding encoding = null;
310 TdsColumnType colType = (TdsColumnType) command.Tds.Columns[i]["ColumnType"];
312 case TdsColumnType.Text :
313 case TdsColumnType.VarChar:
314 case TdsColumnType.Char:
315 case TdsColumnType.BigVarChar:
316 encoding = Encoding.ASCII;
318 case TdsColumnType.NText :
319 case TdsColumnType.NVarChar:
320 case TdsColumnType.NChar:
321 encoding = Encoding.Unicode;
329 if (buffer == null) {
330 count = GetBytes (i,0,(byte[]) null,0,0);
335 byte[] arr = new byte [length];
336 count = GetBytes (i, dataIndex, arr, 0, length);
338 throw new InvalidCastException ("Specified cast is not valid");
340 Char[] val = encoding.GetChars (arr, 0, (int)count);
341 val.CopyTo (buffer, bufferIndex);
346 object value = GetValue (i);
349 valueBuffer = (char[])value;
350 else if (value is string)
351 valueBuffer = ((string)value).ToCharArray();
353 if (value is DBNull) throw new SqlNullValueException ();
354 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
357 if ( buffer == null ) {
358 // Return length of data
359 return valueBuffer.Length;
362 // Copy data into buffer
363 Array.Copy (valueBuffer, (int) dataIndex, buffer, bufferIndex, length);
364 return valueBuffer.Length - dataIndex;
368 [EditorBrowsableAttribute (EditorBrowsableState.Never)]
369 public new IDataReader GetData (int i)
371 return ((IDataReader) this [i]);
378 string GetDataTypeName (int i)
380 if (i < 0 || i >= dataTypeNames.Count)
381 throw new IndexOutOfRangeException ();
382 return (string) dataTypeNames [i];
389 DateTime GetDateTime (int i)
391 object value = GetValue (i);
392 if (!(value is DateTime)) {
393 if (value is DBNull) throw new SqlNullValueException ();
394 else throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
396 return (DateTime) value;
403 decimal GetDecimal (int i)
405 object value = GetValue (i);
406 if (!(value is decimal)) {
407 if (value is DBNull) throw new SqlNullValueException ();
408 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
410 return (decimal) value;
417 double GetDouble (int i)
419 object value = GetValue (i);
420 if (!(value is double)) {
421 if (value is DBNull) throw new SqlNullValueException ();
422 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
424 return (double) value;
431 Type GetFieldType (int i)
433 if (i < 0 || i >= schemaTable.Rows.Count)
434 throw new IndexOutOfRangeException ();
435 return (Type) schemaTable.Rows[i]["DataType"];
442 float GetFloat (int i)
444 object value = GetValue (i);
445 if (!(value is float)) {
446 if (value is DBNull) throw new SqlNullValueException ();
447 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
449 return (float) value;
458 object value = GetValue (i);
459 if (!(value is Guid)) {
460 if (value is DBNull) throw new SqlNullValueException ();
461 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
470 short GetInt16 (int i)
472 object value = GetValue (i);
473 if (!(value is short)) {
474 if (value is DBNull) throw new SqlNullValueException ();
475 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
477 return (short) value;
486 object value = GetValue (i);
487 if (!(value is int)) {
488 if (value is DBNull) throw new SqlNullValueException ();
489 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
498 long GetInt64 (int i)
500 object value = GetValue (i);
501 // TDS 7.0 returns bigint as decimal(19,0)
502 if (value is decimal) {
503 TdsDataColumn schema = command.Tds.Columns[i];
504 if ((byte)schema["NumericPrecision"] == 19 && (byte)schema["NumericScale"] == 0)
505 value = (long) (decimal) value;
507 if (!(value is long)) {
508 if (value is DBNull) throw new SqlNullValueException ();
509 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
518 string GetName (int i)
520 return (string) schemaTable.Rows[i]["ColumnName"];
527 int GetOrdinal (string name)
529 foreach (DataRow schemaRow in schemaTable.Rows)
530 if (((string) schemaRow ["ColumnName"]).Equals (name))
531 return (int) schemaRow ["ColumnOrdinal"];
532 foreach (DataRow schemaRow in schemaTable.Rows)
533 if (String.Compare (((string) schemaRow ["ColumnName"]), name, true) == 0)
534 return (int) schemaRow ["ColumnOrdinal"];
535 throw new IndexOutOfRangeException ();
542 DataTable GetSchemaTable ()
546 if (schemaTable.Rows != null && schemaTable.Rows.Count > 0)
554 dataTypeNames = new ArrayList ();
556 foreach (TdsDataColumn schema in command.Tds.Columns) {
557 DataRow row = schemaTable.NewRow ();
559 row ["ColumnName"] = GetSchemaValue (schema, "ColumnName");
560 row ["ColumnSize"] = GetSchemaValue (schema, "ColumnSize");
561 row ["ColumnOrdinal"] = GetSchemaValue (schema, "ColumnOrdinal");
562 row ["NumericPrecision"] = GetSchemaValue (schema, "NumericPrecision");
563 row ["NumericScale"] = GetSchemaValue (schema, "NumericScale");
564 row ["IsUnique"] = GetSchemaValue (schema, "IsUnique");
565 row ["IsKey"] = GetSchemaValue (schema, "IsKey");
566 row ["BaseServerName"] = GetSchemaValue (schema, "BaseServerName");
567 row ["BaseCatalogName"] = GetSchemaValue (schema, "BaseCatalogName");
568 row ["BaseColumnName"] = GetSchemaValue (schema, "BaseColumnName");
569 row ["BaseSchemaName"] = GetSchemaValue (schema, "BaseSchemaName");
570 row ["BaseTableName"] = GetSchemaValue (schema, "BaseTableName");
571 row ["AllowDBNull"] = GetSchemaValue (schema, "AllowDBNull");
572 row ["IsAliased"] = GetSchemaValue (schema, "IsAliased");
573 row ["IsExpression"] = GetSchemaValue (schema, "IsExpression");
574 row ["IsIdentity"] = GetSchemaValue (schema, "IsIdentity");
575 row ["IsAutoIncrement"] = GetSchemaValue (schema, "IsAutoIncrement");
576 row ["IsRowVersion"] = GetSchemaValue (schema, "IsRowVersion");
577 row ["IsHidden"] = GetSchemaValue (schema, "IsHidden");
578 row ["IsReadOnly"] = GetSchemaValue (schema, "IsReadOnly");
580 // We don't always get the base column name.
581 if (row ["BaseColumnName"] == DBNull.Value)
582 row ["BaseColumnName"] = row ["ColumnName"];
584 switch ((TdsColumnType) schema ["ColumnType"]) {
585 case TdsColumnType.Int1:
586 case TdsColumnType.Int2:
587 case TdsColumnType.Int4:
588 case TdsColumnType.IntN:
589 switch ((int) schema ["ColumnSize"]) {
591 dataTypeNames.Add ("tinyint");
592 row ["ProviderType"] = (int) SqlDbType.TinyInt;
593 row ["DataType"] = typeof (byte);
594 row ["IsLong"] = false;
597 dataTypeNames.Add ("smallint");
598 row ["ProviderType"] = (int) SqlDbType.SmallInt;
599 row ["DataType"] = typeof (short);
600 row ["IsLong"] = false;
603 dataTypeNames.Add ("int");
604 row ["ProviderType"] = (int) SqlDbType.Int;
605 row ["DataType"] = typeof (int);
606 row ["IsLong"] = false;
609 dataTypeNames.Add ("bigint");
610 row ["ProviderType"] = (int) SqlDbType.BigInt;
611 row ["DataType"] = typeof (long);
612 row ["IsLong"] = false;
616 case TdsColumnType.Real:
617 case TdsColumnType.Float8:
618 case TdsColumnType.FloatN:
619 switch ((int) schema ["ColumnSize"]) {
621 dataTypeNames.Add ("real");
622 row ["ProviderType"] = (int) SqlDbType.Real;
623 row ["DataType"] = typeof (float);
624 row ["IsLong"] = false;
627 dataTypeNames.Add ("float");
628 row ["ProviderType"] = (int) SqlDbType.Float;
629 row ["DataType"] = typeof (double);
630 row ["IsLong"] = false;
634 case TdsColumnType.Image :
635 dataTypeNames.Add ("image");
636 row ["ProviderType"] = (int) SqlDbType.Image;
637 row ["DataType"] = typeof (byte[]);
638 row ["IsLong"] = true;
640 case TdsColumnType.Text :
641 dataTypeNames.Add ("text");
642 row ["ProviderType"] = (int) SqlDbType.Text;
643 row ["DataType"] = typeof (string);
644 row ["IsLong"] = true;
646 case TdsColumnType.UniqueIdentifier :
647 dataTypeNames.Add ("uniqueidentifier");
648 row ["ProviderType"] = (int) SqlDbType.UniqueIdentifier;
649 row ["DataType"] = typeof (Guid);
650 row ["IsLong"] = false;
652 case TdsColumnType.VarBinary :
653 case TdsColumnType.BigVarBinary :
654 dataTypeNames.Add ("varbinary");
655 row ["ProviderType"] = (int) SqlDbType.VarBinary;
656 row ["DataType"] = typeof (byte[]);
657 row ["IsLong"] = true;
659 case TdsColumnType.VarChar :
660 case TdsColumnType.BigVarChar :
661 dataTypeNames.Add ("varchar");
662 row ["ProviderType"] = (int) SqlDbType.VarChar;
663 row ["DataType"] = typeof (string);
664 row ["IsLong"] = false;
666 case TdsColumnType.Binary :
667 case TdsColumnType.BigBinary :
668 dataTypeNames.Add ("binary");
669 row ["ProviderType"] = (int) SqlDbType.Binary;
670 row ["DataType"] = typeof (byte[]);
671 row ["IsLong"] = true;
673 case TdsColumnType.Char :
674 case TdsColumnType.BigChar :
675 dataTypeNames.Add ("char");
676 row ["ProviderType"] = (int) SqlDbType.Char;
677 row ["DataType"] = typeof (string);
678 row ["IsLong"] = false;
680 case TdsColumnType.Bit :
681 case TdsColumnType.BitN :
682 dataTypeNames.Add ("bit");
683 row ["ProviderType"] = (int) SqlDbType.Bit;
684 row ["DataType"] = typeof (bool);
685 row ["IsLong"] = false;
687 case TdsColumnType.DateTime4 :
688 case TdsColumnType.DateTime :
689 case TdsColumnType.DateTimeN :
690 dataTypeNames.Add ("datetime");
691 row ["ProviderType"] = (int) SqlDbType.DateTime;
692 row ["DataType"] = typeof (DateTime);
693 row ["IsLong"] = false;
695 case TdsColumnType.Money :
696 case TdsColumnType.MoneyN :
697 case TdsColumnType.Money4 :
698 dataTypeNames.Add ("money");
699 row ["ProviderType"] = (int) SqlDbType.Money;
700 row ["DataType"] = typeof (decimal);
701 row ["IsLong"] = false;
703 case TdsColumnType.NText :
704 dataTypeNames.Add ("ntext");
705 row ["ProviderType"] = (int) SqlDbType.NText;
706 row ["DataType"] = typeof (string);
707 row ["IsLong"] = true;
709 case TdsColumnType.NVarChar :
710 dataTypeNames.Add ("nvarchar");
711 row ["ProviderType"] = (int) SqlDbType.NVarChar;
712 row ["DataType"] = typeof (string);
713 row ["IsLong"] = false;
715 case TdsColumnType.Decimal :
716 case TdsColumnType.Numeric :
717 dataTypeNames.Add ("decimal");
718 row ["ProviderType"] = (int) SqlDbType.Decimal;
719 row ["DataType"] = typeof (decimal);
720 row ["IsLong"] = false;
722 case TdsColumnType.NChar :
723 dataTypeNames.Add ("nchar");
724 row ["ProviderType"] = (int) SqlDbType.NChar;
725 row ["DataType"] = typeof (string);
726 row ["IsLong"] = false;
728 case TdsColumnType.SmallMoney :
729 dataTypeNames.Add ("smallmoney");
730 row ["ProviderType"] = (int) SqlDbType.SmallMoney;
731 row ["DataType"] = typeof (decimal);
732 row ["IsLong"] = false;
735 dataTypeNames.Add ("variant");
736 row ["ProviderType"] = (int) SqlDbType.Variant;
737 row ["DataType"] = typeof (object);
738 row ["IsLong"] = false;
742 schemaTable.Rows.Add (row);
749 private static object GetSchemaValue (TdsDataColumn schema, object key)
751 if (schema.ContainsKey (key) && schema [key] != null)
760 SqlBinary GetSqlBinary (int i)
762 object value = GetSqlValue (i);
763 if (!(value is SqlBinary))
764 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
765 return (SqlBinary) value;
772 SqlBoolean GetSqlBoolean (int i)
774 object value = GetSqlValue (i);
775 if (!(value is SqlBoolean))
776 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
777 return (SqlBoolean) value;
784 SqlByte GetSqlByte (int i)
786 object value = GetSqlValue (i);
787 if (!(value is SqlByte))
788 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
789 return (SqlByte) value;
796 SqlDateTime GetSqlDateTime (int i)
798 object value = GetSqlValue (i);
799 if (!(value is SqlDateTime))
800 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
801 return (SqlDateTime) value;
808 SqlDecimal GetSqlDecimal (int i)
810 object value = GetSqlValue (i);
811 if (!(value is SqlDecimal))
812 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
813 return (SqlDecimal) value;
820 SqlDouble GetSqlDouble (int i)
822 object value = GetSqlValue (i);
823 if (!(value is SqlDouble))
824 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
825 return (SqlDouble) value;
832 SqlGuid GetSqlGuid (int i)
834 object value = GetSqlValue (i);
835 if (!(value is SqlGuid))
836 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
837 return (SqlGuid) value;
844 SqlInt16 GetSqlInt16 (int i)
846 object value = GetSqlValue (i);
847 if (!(value is SqlInt16))
848 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
849 return (SqlInt16) value;
856 SqlInt32 GetSqlInt32 (int i)
858 object value = GetSqlValue (i);
859 if (!(value is SqlInt32))
860 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
861 return (SqlInt32) value;
868 SqlInt64 GetSqlInt64 (int i)
870 object value = GetSqlValue (i);
871 // TDS 7.0 returns bigint as decimal(19,0)
872 if (value is SqlDecimal) {
873 TdsDataColumn schema = command.Tds.Columns[i];
874 if ((byte)schema["NumericPrecision"] == 19 && (byte)schema["NumericScale"] == 0)
875 value = (SqlInt64) (SqlDecimal) value;
877 if (!(value is SqlInt64))
878 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
879 return (SqlInt64) value;
886 SqlMoney GetSqlMoney (int i)
888 object value = GetSqlValue (i);
889 if (!(value is SqlMoney))
890 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
891 return (SqlMoney) value;
898 SqlSingle GetSqlSingle (int i)
900 object value = GetSqlValue (i);
901 if (!(value is SqlSingle))
902 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
903 return (SqlSingle) value;
910 SqlString GetSqlString (int i)
912 object value = GetSqlValue (i);
913 if (!(value is SqlString))
914 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
915 return (SqlString) value;
922 object GetSqlValue (int i)
924 SqlDbType type = (SqlDbType) (schemaTable.Rows [i]["ProviderType"]);
925 object value = GetValue (i);
928 case SqlDbType.BigInt:
929 if (value == DBNull.Value)
930 return SqlInt64.Null;
931 return (SqlInt64) ((long) value);
932 case SqlDbType.Binary:
933 case SqlDbType.Image:
934 case SqlDbType.VarBinary:
935 case SqlDbType.Timestamp:
936 if (value == DBNull.Value)
937 return SqlBinary.Null;
938 return (SqlBinary) ((byte[]) value);
940 if (value == DBNull.Value)
941 return SqlBoolean.Null;
942 return (SqlBoolean) ((bool) value);
944 case SqlDbType.NChar:
945 case SqlDbType.NText:
946 case SqlDbType.NVarChar:
948 case SqlDbType.VarChar:
949 if (value == DBNull.Value)
950 return SqlString.Null;
951 return (SqlString) ((string) value);
952 case SqlDbType.DateTime:
953 case SqlDbType.SmallDateTime:
954 if (value == DBNull.Value)
955 return SqlDateTime.Null;
956 return (SqlDateTime) ((DateTime) value);
957 case SqlDbType.Decimal:
958 if (value == DBNull.Value)
959 return SqlDecimal.Null;
960 if (value is TdsBigDecimal)
961 return SqlDecimal.FromTdsBigDecimal ((TdsBigDecimal) value);
962 return (SqlDecimal) ((decimal) value);
963 case SqlDbType.Float:
964 if (value == DBNull.Value)
965 return SqlDouble.Null;
966 return (SqlDouble) ((double) value);
968 if (value == DBNull.Value)
969 return SqlInt32.Null;
970 return (SqlInt32) ((int) value);
971 case SqlDbType.Money:
972 case SqlDbType.SmallMoney:
973 if (value == DBNull.Value)
974 return SqlMoney.Null;
975 return (SqlMoney) ((decimal) value);
977 if (value == DBNull.Value)
978 return SqlSingle.Null;
979 return (SqlSingle) ((float) value);
980 case SqlDbType.UniqueIdentifier:
981 if (value == DBNull.Value)
983 return (SqlGuid) ((Guid) value);
984 case SqlDbType.SmallInt:
985 if (value == DBNull.Value)
986 return SqlInt16.Null;
987 return (SqlInt16) ((short) value);
988 case SqlDbType.TinyInt:
989 if (value == DBNull.Value)
991 return (SqlByte) ((byte) value);
994 throw new InvalidOperationException ("The type of this column is unknown.");
1001 int GetSqlValues (object[] values)
1004 int columnCount = schemaTable.Rows.Count;
1005 int arrayCount = values.Length;
1007 if (arrayCount > columnCount)
1008 count = columnCount;
1012 for (int i = 0; i < count; i += 1)
1013 values [i] = GetSqlValue (i);
1022 string GetString (int i)
1024 object value = GetValue (i);
1025 if (!(value is string)) {
1026 if (value is DBNull) throw new SqlNullValueException ();
1027 throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
1029 return (string) value;
1036 object GetValue (int i)
1038 if (i < 0 || i >= command.Tds.Columns.Count)
1039 throw new IndexOutOfRangeException ();
1041 if ((command.CommandBehavior & CommandBehavior.SequentialAccess) != 0) {
1042 return ((Tds)command.Tds).GetSequentialColumnValue (i);
1045 return command.Tds.ColumnValues [i];
1052 int GetValues (object[] values)
1054 int len = values.Length;
1055 int bigDecimalIndex = command.Tds.ColumnValues.BigDecimalIndex;
1057 // If a four-byte decimal is stored, then we can't convert to
1058 // a native type. Throw an OverflowException.
1059 if (bigDecimalIndex >= 0 && bigDecimalIndex < len)
1060 throw new OverflowException ();
1062 command.Tds.ColumnValues.CopyTo (0, values, 0,
1063 len > command.Tds.ColumnValues.Count ? command.Tds.ColumnValues.Count : len);
1064 return (len < FieldCount ? len : FieldCount);
1067 void IDisposable.Dispose ()
1070 GC.SuppressFinalize (this);
1077 IEnumerator GetEnumerator ()
1079 return new DbEnumerator (this);
1086 bool IsDBNull (int i)
1088 return GetValue (i) == DBNull.Value;
1099 if ((command.CommandBehavior & CommandBehavior.SingleResult) != 0 && resultsRead > 0)
1102 moreResults = command.Tds.NextResult ();
1104 command.GetOutputParameters ();
1107 schemaTable = ConstructSchemaTable ();
1124 if ((command.CommandBehavior & CommandBehavior.SingleRow) != 0 && rowsRead > 0)
1126 if ((command.CommandBehavior & CommandBehavior.SchemaOnly) != 0)
1131 if ((haveRead) && (!readResultUsed))
1133 readResultUsed = true;
1138 return (ReadRecord ());
1142 internal bool ReadRecord ()
1145 bool result = command.Tds.NextRow ();
1152 void ValidateState ()
1155 throw new InvalidOperationException ("Invalid attempt to read data when reader is closed");
1160 public override Type GetProviderSpecificFieldType (int position)
1162 throw new NotImplementedException ();
1166 public override object GetProviderSpecificValue (int position)
1168 throw new NotImplementedException ();
1172 public override int GetProviderSpecificValues (object [] values)
1174 throw new NotImplementedException ();
1179 #endregion // Methods