* SqlParameter.cs: Modified ConvertToFrameworkType to only perform
[mono.git] / mcs / class / System.Data / System.Data.SqlClient / SqlParameter.cs
index 7278d92412626b85832db1f51b8ca277eebaf8db..6774c0ddbebf84410b7ba1ea4ddf6cc9b257b2bb 100644 (file)
@@ -8,13 +8,14 @@
 //   Diego Caravana (diego@toth.it)
 //   Umadevi S (sumadevi@novell.com)
 //   Amit Biswas (amit@amitbiswas.com)
+//   Veerapuram Varadhan (vvaradhan@novell.com)
 //
 // (C) Ximian, Inc. 2002
 // Copyright (C) Tim Coleman, 2002
 //
 
 //
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004, 2008, 2009 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -44,6 +45,7 @@ using System.ComponentModel;
 using System.Data;
 using System.Data.Common;
 using System.Data.SqlTypes;
+using System.Globalization;
 using System.Runtime.InteropServices;
 using System.Text;
 using System.Xml;
@@ -78,6 +80,8 @@ namespace System.Data.SqlClient {
                string xmlSchemaCollectionDatabase = String.Empty;
                string xmlSchemaCollectionOwningSchema = String.Empty;
                string xmlSchemaCollectionName = String.Empty;
+#else
+               static Hashtable DbTypeMapping;
 #endif
 
                static Hashtable type_mapping;
@@ -89,17 +93,25 @@ namespace System.Data.SqlClient {
                
                static SqlParameter ()
                {
-
-#if NET_2_0
                        if (DbTypeMapping == null)
                                DbTypeMapping = new Hashtable ();
                        
                        DbTypeMapping.Add (SqlDbType.BigInt, typeof (long));
                        DbTypeMapping.Add (SqlDbType.Bit, typeof (bool));
+                       DbTypeMapping.Add (SqlDbType.Char, typeof (string));
+                       DbTypeMapping.Add (SqlDbType.NChar, typeof (string));
+                       DbTypeMapping.Add (SqlDbType.Text, typeof (string));
+                       DbTypeMapping.Add (SqlDbType.NText, typeof (string));
+                       DbTypeMapping.Add (SqlDbType.VarChar, typeof (string));
                        DbTypeMapping.Add (SqlDbType.NVarChar, typeof (string));
+                       DbTypeMapping.Add (SqlDbType.SmallDateTime, typeof (DateTime));
                        DbTypeMapping.Add (SqlDbType.DateTime, typeof (DateTime));
                        DbTypeMapping.Add (SqlDbType.Decimal, typeof (decimal));
                        DbTypeMapping.Add (SqlDbType.Float, typeof (double));
+                       DbTypeMapping.Add (SqlDbType.Binary, typeof (byte []));
+                       DbTypeMapping.Add (SqlDbType.Image, typeof (byte []));
+                       DbTypeMapping.Add (SqlDbType.Money, typeof (decimal));
+                       DbTypeMapping.Add (SqlDbType.SmallMoney, typeof (decimal));
                        DbTypeMapping.Add (SqlDbType.VarBinary, typeof (byte []));
                        DbTypeMapping.Add (SqlDbType.TinyInt, typeof (byte));
                        DbTypeMapping.Add (SqlDbType.Int, typeof (int));
@@ -107,7 +119,10 @@ namespace System.Data.SqlClient {
                        DbTypeMapping.Add (SqlDbType.SmallInt, typeof (short));
                        DbTypeMapping.Add (SqlDbType.UniqueIdentifier, typeof (Guid));
                        DbTypeMapping.Add (SqlDbType.Variant, typeof (object));
+#if NET_2_0
+                       DbTypeMapping.Add (SqlDbType.Xml, typeof (string));
 #endif
+
                        type_mapping = new Hashtable ();
 
                        type_mapping.Add (typeof (long), SqlDbType.BigInt);
@@ -491,7 +506,7 @@ namespace System.Data.SqlClient {
                object Value {
                        get {
                                if (sqlType != null)
-                                       return FrameworkTypeToSqlType (metaParameter.RawValue);
+                                       return GetSqlValue (metaParameter.RawValue);
                                return metaParameter.RawValue;
                        }
                        set {
@@ -529,10 +544,7 @@ namespace System.Data.SqlClient {
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public Object SqlValue {
                        get {
-                               object value = metaParameter.RawValue;
-                               if (value != null)
-                                       return FrameworkTypeToSqlType (value);
-                               return null;
+                               return GetSqlValue (metaParameter.RawValue);
                        }
                        set {
                                Value = value;
@@ -590,14 +602,17 @@ namespace System.Data.SqlClient {
                        SetSqlDbType ((SqlDbType) t);
                }
 
-#if NET_2_0
                // Returns System.Type corresponding to the underlying SqlDbType
-               internal override Type SystemType {
+#if NET_2_0
+               internal override
+#endif
+               Type SystemType {
                        get {
                                return (Type) DbTypeMapping [sqlDbType];
                        }
                }
-               
+
+#if NET_2_0
                internal override object FrameworkDbType {
                        get {
                                return sqlDbType;
@@ -973,7 +988,6 @@ namespace System.Data.SqlClient {
                {               
                        if (value == null)
                                return value;
-                       
                        switch (sqlDbType) {
                        case SqlDbType.BigInt:
                                if (value == DBNull.Value)
@@ -985,7 +999,7 @@ namespace System.Data.SqlClient {
                        case SqlDbType.Timestamp:
                                if (value == DBNull.Value)
                                        return SqlBinary.Null;
-                               return (SqlBinary) ((byte[]) value);
+                               return (SqlBinary) (byte[]) value;
                        case SqlDbType.Bit:
                                if (value == DBNull.Value)
                                        return SqlBoolean.Null;
@@ -998,7 +1012,16 @@ namespace System.Data.SqlClient {
                        case SqlDbType.VarChar:
                                if (value == DBNull.Value)
                                        return SqlString.Null;
-                               return (SqlString) ((string) value);
+
+                               string str;
+                               Type type = value.GetType ();
+                               if (type == typeof (char))
+                                       str = value.ToString ();
+                               else if (type == typeof (char[]))
+                                       str = new String ((char[])value);
+                               else
+                                       str = ((string)value);
+                                       return (SqlString) str;
                        case SqlDbType.DateTime:
                        case SqlDbType.SmallDateTime:
                                if (value == DBNull.Value)
@@ -1042,13 +1065,12 @@ namespace System.Data.SqlClient {
 #if NET_2_0
                        case SqlDbType.Xml:
                                if (value == DBNull.Value)
-                                       return SqlByte.Null;
+                                       return SqlXml.Null;
                                return (SqlXml) value;
 #endif
+                       default:
+                               throw new NotImplementedException ("Type '" + sqlDbType + "' not implemented.");
                        }
-                       
-                       // FIXME: Do the right thing
-                       return null;
                }
                
                object SqlTypeToFrameworkType (object value)
@@ -1086,7 +1108,16 @@ namespace System.Data.SqlClient {
                        if (typeof (SqlBinary) == type) {
                                return ((SqlBinary) value).Value;
                        }
+                       
+#if NET_2_0
+                       if (typeof (SqlBytes) == type) {
+                               return ((SqlBytes) value).Value;
+                       }
 
+                       if (typeof (SqlChars) == type) {
+                               return ((SqlChars) value).Value;
+                       }
+#endif
                        if (typeof (SqlBoolean) == type) {
                                return ((SqlBoolean) value).Value;
                        }
@@ -1118,214 +1149,38 @@ namespace System.Data.SqlClient {
                        return value;
                }
 
-               static object GetSqlNullValue (Type sqlType)
-               {
-                       if (sqlType == typeof (SqlBinary))
-                               return SqlBinary.Null;
-                       if (sqlType == typeof (SqlBoolean))
-                               return SqlBoolean.Null;
-                       if (sqlType == typeof (SqlByte))
-                               return SqlByte.Null;
-#if NET_2_0
-                       if (sqlType == typeof (SqlBytes))
-                               return SqlBytes.Null;
-                       if (sqlType == typeof (SqlChars))
-                               return SqlChars.Null;
-#endif
-                       if (sqlType == typeof (SqlDateTime))
-                               return SqlDateTime.Null;
-                       if (sqlType == typeof (SqlDecimal))
-                               return SqlDecimal.Null;
-                       if (sqlType == typeof (SqlDouble))
-                               return SqlDouble.Null;
-                       if (sqlType == typeof (SqlInt16))
-                               return SqlInt16.Null;
-                       if (sqlType == typeof (SqlInt32))
-                               return SqlInt32.Null;
-                       if (sqlType == typeof (SqlInt64))
-                               return SqlInt64.Null;
-                       if (sqlType == typeof (SqlMoney))
-                               return SqlMoney.Null;
-                       if (sqlType == typeof (SqlSingle))
-                               return SqlSingle.Null;
-                       if (sqlType == typeof (SqlString))
-                               return SqlString.Null;
-#if NET_2_0
-                       if (sqlType == typeof (SqlXml))
-                               return SqlXml.Null;
-#endif
-                       if (sqlType == typeof (SqlGuid))
-                               return SqlGuid.Null;
-
-                       throw new NotImplementedException ("Type '" + sqlType.FullName + "' not implemented.");
-               }
-
-               static object GetSqlNullValue (SqlDbType sqlDbType)
-               {
-                       switch (sqlDbType) {
-                       case SqlDbType.BigInt:
-                               return SqlInt64.Null;
-                       case SqlDbType.Binary:
-                       case SqlDbType.Image:
-                       case SqlDbType.VarBinary:
-                               return SqlBinary.Null;
-                       case SqlDbType.Bit:
-                               return SqlBoolean.Null;
-                       case SqlDbType.Int:
-                               return SqlInt32.Null;
-                       case SqlDbType.SmallInt:
-                               return SqlInt16.Null;
-                       case SqlDbType.TinyInt:
-                               return SqlByte.Null;
-                       case SqlDbType.Float:
-                       case SqlDbType.Real:
-                               return SqlSingle.Null;
-                       case SqlDbType.Decimal:
-                               return SqlDecimal.Null;
-                       case SqlDbType.Money:
-                       case SqlDbType.SmallMoney:
-                               return SqlMoney.Null;
-                       case SqlDbType.DateTime:
-                       case SqlDbType.SmallDateTime:
-                               return SqlDateTime.Null;
-                       case SqlDbType.VarChar:
-                       case SqlDbType.NVarChar:
-                       case SqlDbType.Char:
-                       case SqlDbType.NChar:
-                       case SqlDbType.Text:
-                       case SqlDbType.NText:
-                               return SqlString.Null;
-#if NET_2_0
-                       case SqlDbType.Xml:
-                               return SqlXml.Null;
-#endif
-                       case SqlDbType.UniqueIdentifier:
-                               return SqlGuid.Null;
-                       default:
-                               throw new NotImplementedException ("Type '" + sqlDbType + "' not implemented.");
-                       }
-               }
-
-               object FrameworkTypeToSqlType (object value)
+               internal object ConvertToFrameworkType (object value)
                {
-                       if (value == null || value == DBNull.Value) {
-                               if (sqlType != null)
-                                       return GetSqlNullValue (sqlType);
-                               else
-                                       return GetSqlNullValue (SqlDbType);
-                       }
-
-                       Type type = value.GetType ();
-
-                       if (type == typeof (string))
-                               return new SqlString ((string) value);
-
-                       if (type == typeof (short))
-                               return new SqlInt16 ((short) value);
-
-                       if (type == typeof (int))
-                               return new SqlInt32 ((int) value);
-
-                       if (type == typeof (DateTime))
-                               return new SqlDateTime ((DateTime) value);
-
-                       if (type == typeof (long))
-                               return new SqlInt64 ((long) value);
-
-#if NET_2_0
-                       if (type == typeof (char))
-                               return new SqlString (((char) value).ToString ());
-
-                       if (type == typeof (char []))
-                               return new SqlString (new string ((char []) value));
-#endif
-
-                       if (type == typeof (byte))
-                               return new SqlByte ((byte) value);
-
-                       if (type == typeof (byte []))
-                               return new SqlBinary ((byte []) value);
-
-                       if (type == typeof (bool))
-                               return new SqlBoolean ((bool) value);
-
-                       if (type == typeof (byte))
-                               return new SqlByte ((byte) value);
-
-                       if (type == typeof (decimal)) {
-                               if (sqlType != null && sqlType == typeof (SqlMoney))
-                                       return new SqlMoney ((decimal) value);
-                               return new SqlDecimal ((decimal) value);
-                       }
-
-                       if (type == typeof (double))
-                               return new SqlDouble ((double) value);
+                       if (value == null || value == DBNull.Value)
+                               return value;
+                       if (sqlDbType == SqlDbType.Variant)
+                               return metaParameter.Value;
 
-                       if (type == typeof (Guid))
-                               return new SqlGuid ((Guid) value);
+                       Type frameworkType = SystemType;
+                       if (frameworkType == null)
+                               throw new NotImplementedException ("Type Not Supported : " + sqlDbType.ToString());
 
-                       if (type == typeof (float))
-                               return new SqlSingle ((float) value);
+                       Type valueType = value.GetType ();
+                       if (valueType == frameworkType)
+                               return value;
 
-                       return value;
-               }
+                       object sqlvalue = null;
 
-               internal object ConvertToFrameworkType (object value)
-               {
-                       if (value == null || value == DBNull.Value)
-                               return value;
-                       
-                       if (value is string && ((string)value).Length == 0)
-                               return DBNull.Value;
-                       
-                       switch (sqlDbType)  {
-                       case SqlDbType.BigInt :
-                               return Convert.ChangeType (value, typeof (Int64));
-                       case SqlDbType.Binary:
-                       case SqlDbType.Image:
-                       case SqlDbType.VarBinary:
-                               if (value is byte[])
-                                       return value;
-                               break;
-                       case SqlDbType.Bit:
-                               return Convert.ChangeType (value, typeof (bool));
-                       case SqlDbType.Int:
-                               return Convert.ChangeType (value, typeof (Int32));
-                       case SqlDbType.SmallInt :
-                               return Convert.ChangeType (value, typeof (Int16));
-                       case SqlDbType.TinyInt :
-                               return Convert.ChangeType (value, typeof (byte));
-                       case SqlDbType.Float:
-                               return Convert.ChangeType (value, typeof (Double));
-                       case SqlDbType.Real:
-                               return Convert.ChangeType (value, typeof (Single));
-                       case SqlDbType.Decimal:
-                               return Convert.ChangeType (value, typeof (Decimal));
-                       case SqlDbType.Money:
-                       case SqlDbType.SmallMoney:
-                               {
-                                       Decimal val = (Decimal)Convert.ChangeType (value, typeof (Decimal));
-                                       return Decimal.Round(val, 4);
+                       try {
+                               sqlvalue = Convert.ChangeType (value, frameworkType);
+                               switch (sqlDbType) {
+                               case SqlDbType.Money:
+                               case SqlDbType.SmallMoney:
+                                       sqlvalue = Decimal.Round ((decimal) sqlvalue, 4);
+                                       break;
                                }
-                       case SqlDbType.DateTime:
-                       case SqlDbType.SmallDateTime:
-                               return Convert.ChangeType (value, typeof (DateTime));
-                       case SqlDbType.VarChar:
-                       case SqlDbType.NVarChar:
-                       case SqlDbType.Char:
-                       case SqlDbType.NChar:
-                       case SqlDbType.Text:
-                       case SqlDbType.NText:
-#if NET_2_0
-                       case SqlDbType.Xml:
-#endif
-                               return Convert.ChangeType (value,  typeof (string));
-                       case SqlDbType.UniqueIdentifier:
-                               return Convert.ChangeType (value,  typeof (Guid));
-                       case SqlDbType.Variant:
-                               return metaParameter.Value;
+                       } catch (FormatException ex) {
+                               throw new FormatException (string.Format (CultureInfo.InvariantCulture,
+                                       "Parameter value could not be converted from {0} to {1}.",
+                                       valueType.Name, frameworkType.Name), ex);
                        }
-                       throw new  NotImplementedException ("Type Not Supported : " + sqlDbType.ToString());
+
+                       return sqlvalue;
                }
 
 #if NET_2_0