* SqlDataReader.cs: Added GetSchemaRowDbType overload for
authorGert Driesen <drieseng@users.sourceforge.net>
Sun, 4 Jan 2009 21:38:09 +0000 (21:38 -0000)
committerGert Driesen <drieseng@users.sourceforge.net>
Sun, 4 Jan 2009 21:38:09 +0000 (21:38 -0000)
getting sql type of a given column (identified using its
ordinal). Modified GetBytes to throw SqlNullValueException
(2.0 profile) or return 0 (1.0 profile) when reading bytes
sequentially. Added support for non-sequentially reading
text and ntext columns using GetBytes. Modified GetChar
to throw a NotSupportedException to match MS.

svn path=/trunk/mcs/; revision=122396

mcs/class/System.Data/System.Data.SqlClient/ChangeLog
mcs/class/System.Data/System.Data.SqlClient/SqlDataReader.cs

index 4d69c3b1b86c6751c13ba4ce1f3682df32664315..f610e0baaed4522c16a4a1dfd43221e1ecebf27a 100644 (file)
@@ -1,3 +1,13 @@
+2009-01-04  Gert Driesen  <drieseng@users.sourceforge.net>
+
+       * SqlDataReader.cs: Added GetSchemaRowDbType overload for
+       getting sql type of a given column (identified using its
+       ordinal). Modified GetBytes to throw SqlNullValueException
+       (2.0 profile) or return 0 (1.0 profile) when reading bytes
+       sequentially. Added support for non-sequentially reading
+       text and ntext columns using GetBytes. Modified GetChar
+       to throw a NotSupportedException to match MS.
+
 2009-01-04  Gert Driesen  <drieseng@users.sourceforge.net>
 
        * SqlCommandBuilder.cs (RefreshSchema): Clear commands.
index 359fe9345308a0ad772fd7e790ad31ba42e4e342..238c170053c02f113d449a979cae3c1022c073a6 100644 (file)
@@ -43,6 +43,7 @@ using System.ComponentModel;
 using System.Data;
 using System.Data.Common;
 using System.Data.SqlTypes;
+using System.Globalization;
 using System.Xml;
 
 namespace System.Data.SqlClient
@@ -277,6 +278,31 @@ namespace System.Data.SqlClient
                        return fieldType;
                }
 
+               SqlDbType GetSchemaRowDbType (int ordinal)
+               {
+                       int csize;
+                       short precision, scale;
+                       TdsColumnType ctype;
+                       TdsDataColumn column;
+
+                       if (ordinal < 0 || ordinal >= command.Tds.Columns.Count)
+                               throw new IndexOutOfRangeException ();
+
+                       column = command.Tds.Columns [ordinal];
+#if NET_2_0
+                       ctype = (TdsColumnType) column.ColumnType;
+                       csize = (int) column.ColumnSize;
+                       precision = (short) (column.NumericPrecision ?? 0);
+                       scale = (short) (column.NumericScale ?? 0);
+#else
+                       ctype = (TdsColumnType) column ["ColumnType"];
+                       csize = (int) column ["ColumnSize"];
+                       precision = (short) ((byte) column ["NumericPrecision"]);
+                       scale = (short) ((byte) column ["NumericScale"]);
+#endif
+                       return GetSchemaRowDbType (ctype, csize, precision, scale);
+               }
+
                private SqlDbType GetSchemaRowDbType (TdsColumnType ctype, int csize, short precision, short scale)
                {
                        Type fieldType;
@@ -543,10 +569,13 @@ namespace System.Data.SqlClient
                                try {
                                        long len = ((Tds)command.Tds).GetSequentialColumnValue (i, dataIndex, buffer, bufferIndex, length);
                                        if (len == -1)
-                                               throw new InvalidCastException ("Invalid attempt to GetBytes on column "
-                                                                               + "'" + command.Tds.Columns[i]["ColumnName"] +
-                                                                               "'." + "The GetBytes function"
-                                                                               + " can only be used on columns of type Text, NText, or Image");
+                                               throw CreateGetBytesOnInvalidColumnTypeException (i);
+                                       if (len == -2)
+#if NET_2_0
+                                               throw new SqlNullValueException ();
+#else
+                                               return 0;
+#endif
                                        return len;
                                } catch (TdsInternalException ex) {
                                        command.Connection.Close ();
@@ -556,10 +585,39 @@ namespace System.Data.SqlClient
 
                        object value = GetValue (i);
                        if (!(value is byte [])) {
-                               if (value is DBNull) throw new SqlNullValueException ();
-                               throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
+                               SqlDbType type = GetSchemaRowDbType (i);
+                               switch (type) {
+                               case SqlDbType.Image:
+                                       if (value is DBNull)
+                                               throw new SqlNullValueException ();
+                                       break;
+                               case SqlDbType.Text:
+#if NET_2_0
+                                       string text = value as string;
+                                       if (text != null)
+                                               value = Encoding.Default.GetBytes (text);
+                                       else
+                                               value = null;
+                                       break;
+#else
+                                       throw new InvalidCastException ();
+#endif
+                               case SqlDbType.NText:
+#if NET_2_0
+                                       string ntext = value as string;
+                                       if (ntext != null)
+                                               value = Encoding.Unicode.GetBytes (ntext);
+                                       else
+                                               value = null;
+                                       break;
+#else
+                                       throw new InvalidCastException ();
+#endif
+                               default:
+                                       throw CreateGetBytesOnInvalidColumnTypeException (i);
+                               }
                        }
-                       
+
                        if (buffer == null)
                                return ((byte []) value).Length; // Return length of data
 
@@ -581,12 +639,7 @@ namespace System.Data.SqlClient
 #endif // NET_2_0
                char GetChar (int i)
                {
-                       object value = GetValue (i);
-                       if (!(value is char)) {
-                               if (value is DBNull) throw new SqlNullValueException ();
-                               throw new InvalidCastException ("Type is " + value.GetType ().ToString ());
-                       }
-                       return (char) value;
+                       throw new NotSupportedException ();
                }
 
                public
@@ -1204,22 +1257,7 @@ namespace System.Data.SqlClient
 
                        object value = GetValue (i);
 
-                       column = command.Tds.Columns [i];
-#if NET_2_0
-                       ctype = (TdsColumnType) column.ColumnType;
-                       csize = (int) column.ColumnSize;
-                       precision = (short) (column.NumericPrecision ?? 0);
-                       scale = (short) (column.NumericScale ?? 0);
-#else
-                       ctype = (TdsColumnType) column ["ColumnType"];
-                       csize = (int) column ["ColumnSize"];
-                       precision = (short) ((byte) column ["NumericPrecision"]);
-                       scale = (short) ((byte) column ["NumericScale"]);
-#endif
-
-                       SqlDbType type = GetSchemaRowDbType (ctype, csize,
-                               precision, scale);
-
+                       SqlDbType type = GetSchemaRowDbType (i);
                        switch (type) {
                        case SqlDbType.BigInt:
                                if (value == DBNull.Value)
@@ -1499,6 +1537,16 @@ namespace System.Data.SqlClient
                                throw new InvalidOperationException ("No data available.");
                }
 
+               InvalidCastException CreateGetBytesOnInvalidColumnTypeException (int ordinal)
+               {
+                       string message = string.Format (CultureInfo.InvariantCulture,
+                               "Invalid attempt to GetBytes on column '{0}'." +
+                               "The GetBytes function can only be used on " +
+                               "columns of type Text, NText, or Image.",
+                               GetName (ordinal));
+                       return new InvalidCastException (message);
+               }
+
 #if NET_2_0
                public override Type GetProviderSpecificFieldType (int i)
                {