2007-07-31 Nagappan A <anagappan@novell.com>
[mono.git] / mcs / class / System.Data / System.Data.SqlClient / SqlParameter.cs
1 //
2 // System.Data.SqlClient.SqlParameter.cs
3 //
4 // Author:
5 //   Rodrigo Moya (rodrigo@ximian.com)
6 //   Daniel Morgan (danmorg@sc.rr.com)
7 //   Tim Coleman (tim@timcoleman.com)
8 //   Diego Caravana (diego@toth.it)
9 //   Umadevi S (sumadevi@novell.com)
10 //   Amit Biswas (amit@amitbiswas.com)
11 //
12 // (C) Ximian, Inc. 2002
13 // Copyright (C) Tim Coleman, 2002
14 //
15
16 //
17 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
18 //
19 // Permission is hereby granted, free of charge, to any person obtaining
20 // a copy of this software and associated documentation files (the
21 // "Software"), to deal in the Software without restriction, including
22 // without limitation the rights to use, copy, modify, merge, publish,
23 // distribute, sublicense, and/or sell copies of the Software, and to
24 // permit persons to whom the Software is furnished to do so, subject to
25 // the following conditions:
26 // 
27 // The above copyright notice and this permission notice shall be
28 // included in all copies or substantial portions of the Software.
29 // 
30 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
34 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 //
38
39 using Mono.Data.Tds;
40 using Mono.Data.Tds.Protocol;
41 using System;
42 using System.ComponentModel;
43 using System.Data;
44 using System.Data.Common;
45 using System.Data.SqlTypes;
46 using System.Runtime.InteropServices;
47 using System.Text;
48
49 namespace System.Data.SqlClient {
50         [TypeConverterAttribute (typeof (SqlParameterConverter))]
51 #if NET_2_0
52         public sealed class SqlParameter : DbParameter, IDbDataParameter, IDataParameter, ICloneable
53 #else
54         public sealed class SqlParameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
55 #endif // NET_2_0
56         {
57                 #region Fields
58
59                 TdsMetaParameter metaParameter;
60
61                 SqlParameterCollection container = null;
62                 DbType dbType;
63                 ParameterDirection direction = ParameterDirection.Input;
64                 bool isNullable;
65                 bool isTypeSet = false;
66                 int offset;
67                 SqlDbType sqlDbType;
68                 string sourceColumn;
69                 DataRowVersion sourceVersion;
70                 SqlCompareOptions compareInfo;
71                 int localeId;
72                 Object sqlValue;
73                 string udtTypeName;
74 #if NET_2_0
75                 bool sourceColumnNullMapping;
76                 string xmlSchemaCollectionDatabase = String.Empty;
77                 string xmlSchemaCollectionOwningSchema = String.Empty;
78                 string xmlSchemaCollectionName = String.Empty;
79 #endif
80
81                 #endregion // Fields
82
83                 #region Constructors
84
85                 public SqlParameter () 
86                         : this (String.Empty, SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
87                 {
88                         isTypeSet = false;
89                 }
90
91                 public SqlParameter (string parameterName, object value) 
92                 {
93                         metaParameter = new TdsMetaParameter (parameterName, value);
94                         InferSqlType (value);
95                         metaParameter.Value =  SqlTypeToFrameworkType (value);
96                         sourceVersion = DataRowVersion.Current;
97                 }
98                 
99                 public SqlParameter (string parameterName, SqlDbType dbType) 
100                         : this (parameterName, dbType, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
101                 {
102                 }
103
104                 public SqlParameter (string parameterName, SqlDbType dbType, int size) 
105                         : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
106                 {
107                 }
108                 
109                 public SqlParameter (string parameterName, SqlDbType dbType, int size, string sourceColumn) 
110                         : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, sourceColumn, DataRowVersion.Current, null)
111                 {
112                 }
113                 
114                 [EditorBrowsable (EditorBrowsableState.Advanced)]        
115                 public SqlParameter (string parameterName, SqlDbType dbType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value) 
116                 {
117                         metaParameter = new TdsMetaParameter (parameterName, size, 
118                                                               isNullable, precision, 
119                                                               scale, 
120                                                               value);
121                         if (dbType != SqlDbType.Variant) 
122                                 SqlDbType = dbType;
123                         metaParameter.Value = SqlTypeToFrameworkType (value);
124                         Direction = direction;
125                         SourceColumn = sourceColumn;
126                         SourceVersion = sourceVersion;
127                 }
128
129 #if NET_2_0
130                 public SqlParameter (string parameterName, SqlDbType dbType, int size, ParameterDirection direction, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, bool sourceColumnNullMapping, Object value, string xmlSchemaCollectionDatabase, string xmlSchemaCollectionOwningSchema, string xmlSchemaCollectionName)
131                         : this (parameterName, dbType, size, direction, false, precision, scale, sourceColumn, sourceVersion, value)
132                 {
133                         XmlSchemaCollectionDatabase = xmlSchemaCollectionDatabase;
134                         XmlSchemaCollectionOwningSchema = xmlSchemaCollectionOwningSchema;
135                         XmlSchemaCollectionName = xmlSchemaCollectionName;
136                         SourceColumnNullMapping = sourceColumnNullMapping;
137                 }
138 #endif
139
140                 // This constructor is used internally to construct a
141                 // SqlParameter.  The value array comes from sp_procedure_params_rowset.
142                 // This is in SqlCommand.DeriveParameters.
143                 internal SqlParameter (object[] dbValues) 
144                         : this (dbValues [3].ToString (), String.Empty)
145                 {
146                         Precision = 0;
147                         Scale = 0;
148                         Direction = ParameterDirection.Input;
149
150                         ParameterName = (string) dbValues[3];
151
152                         switch ((short) dbValues[5]) {
153                         case 1:
154                                 Direction = ParameterDirection.Input;
155                                 break;
156                         case 2:
157                                 Direction = ParameterDirection.Output;
158                                 break;
159                         case 3:
160                                 Direction = ParameterDirection.InputOutput;
161                                 break;
162                         case 4:
163                                 Direction = ParameterDirection.ReturnValue;
164                                 break;
165                         default:
166                                 Direction = ParameterDirection.Input;
167                                 break;
168                         }
169                         IsNullable = (dbValues [8] != null && 
170                                 dbValues [8] != DBNull.Value) ? (bool) dbValues [8] : false;
171
172                         if (dbValues [12] != null && dbValues [12] != DBNull.Value)
173                                 Precision = (byte) ((short) dbValues [12]);
174
175                         if (dbValues [13] != null && dbValues [13] != DBNull.Value)
176                                 Scale = (byte) ( (short) dbValues [13]);
177
178                         SetDbTypeName ((string) dbValues [16]);
179                 }
180
181                 #endregion // Constructors
182
183                 #region Properties
184
185                 // Used to ensure that only one collection can contain this
186                 // parameter
187                 internal SqlParameterCollection Container {
188                         get { return container; }
189                         set { container = value; }
190                 }
191
192                 internal void CheckIfInitialized ()
193                 {
194                         if (!isTypeSet)
195                                 throw new Exception ("all parameters to have an explicity set type");
196
197                         if (MetaParameter.IsVariableSizeType) {
198                                 if (SqlDbType == SqlDbType.Decimal && Precision == 0)
199                                         throw new Exception ("Parameter of type 'Decimal' have an explicitly set Precision and Scale");
200                                 else if (Size == 0)
201                                         throw new Exception ("all variable length parameters to have an explicitly set non-zero Size");
202                         }
203                 }
204         
205 #if ONLY_1_0 || ONLY_1_1
206                 [Browsable (false)]
207                 [DataSysDescription ("The parameter generic type.")]
208                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
209                 [RefreshProperties (RefreshProperties.All)]
210                 [DataCategory ("Data")]
211 #endif
212                 public 
213 #if NET_2_0
214                 override
215 #endif // NET_2_0
216                 DbType DbType {
217                         get { return dbType; }
218                         set { 
219                                 SetDbType (value); 
220                                 isTypeSet = true;
221                         }
222                 }
223
224 #if ONLY_1_0 || ONLY_1_1
225                 [DataCategory ("Data")]
226                 [DataSysDescription ("Input, output, or bidirectional parameter.")]
227                 [DefaultValue (ParameterDirection.Input)]
228 #endif
229 #if NET_2_0
230                 [RefreshProperties (RefreshProperties.All)]
231 #endif
232                 public 
233 #if NET_2_0
234                 override
235 #endif // NET_2_0
236          ParameterDirection Direction {
237                         get { return direction; }
238                         set { 
239                                 direction = value; 
240                                 switch( direction ) {
241                                         case ParameterDirection.Output:
242                                         MetaParameter.Direction = TdsParameterDirection.Output;
243                                                 break;
244                                         case ParameterDirection.InputOutput:
245                                                 MetaParameter.Direction = TdsParameterDirection.InputOutput;
246                                                 break;
247                                         case ParameterDirection.ReturnValue:
248                                                 MetaParameter.Direction = TdsParameterDirection.ReturnValue;
249                                                 break;
250                                 }
251                         }
252                 }
253
254                 internal TdsMetaParameter MetaParameter {
255                         get { return metaParameter; }
256                 }
257
258 #if ONLY_1_0 || ONLY_1_1
259                 [Browsable (false)]
260                 [DataSysDescription ("a design-time property used for strongly typed code-generation.")]
261                 [DefaultValue (false)]
262                 [DesignOnly (true)]
263                 [EditorBrowsable (EditorBrowsableState.Advanced)]        
264 #endif
265                 public 
266 #if NET_2_0
267                 override
268 #endif // NET_2_0
269                 bool IsNullable {
270                         get { return metaParameter.IsNullable; }
271                         set { metaParameter.IsNullable = value; }
272                 }
273
274                 [Browsable (false)]
275 #if ONLY_1_0 || ONLY_1_1
276                 [DataCategory ("Data")]
277                 [DataSysDescription ("Offset in variable length data types.")]
278                 [DefaultValue (0)]
279 #endif
280 #if NET_2_0
281                 [EditorBrowsable (EditorBrowsableState.Advanced)]
282 #endif
283                 public int Offset {
284                         get { return offset; }
285                         set { offset = value; }
286                 }
287         
288 #if ONLY_1_0 || ONLY_1_1
289                 [DataSysDescription ("Name of the parameter, like '@p1'")]
290                 [DefaultValue ("")]
291 #endif
292                 public 
293 #if NET_2_0
294                 override
295 #endif // NET_2_0
296                 string ParameterName {
297                         get { return metaParameter.ParameterName; }
298                         set { metaParameter.ParameterName = value; }
299                 }
300
301                 [DefaultValue (0)]
302 #if ONLY_1_0 || ONLY_1_1
303                 [DataCategory ("Data")]
304                 [DataSysDescription ("For decimal, numeric, varnumeric DBTypes.")]
305 #endif
306                 public byte Precision {
307                         get { return metaParameter.Precision; }
308                         set { metaParameter.Precision = value; }
309                 }
310
311                 [DefaultValue (0)]
312 #if ONLY_1_0 || ONLY_1_1
313                 [DataCategory ("Data")]
314                 [DataSysDescription ("For decimal, numeric, varnumeric DBTypes.")]
315 #endif
316                 public byte Scale {
317                         get { return metaParameter.Scale; }
318                         set { metaParameter.Scale = value; }
319                 }
320
321 #if ONLY_1_0 || ONLY_1_1
322                 [DataCategory ("Data")]
323                 [DataSysDescription ("Size of variable length data types (string & arrays).")]
324                 [DefaultValue (0)]
325 #endif
326                 public 
327 #if NET_2_0
328                 override
329 #endif // NET_2_0
330                 int Size {
331                         get { return metaParameter.Size; }
332                         set { metaParameter.Size = value; }
333                 }
334
335 #if ONLY_1_0 || ONLY_1_1
336                 [DataCategory ("Data")]
337                 [DataSysDescription ("When used by a DataAdapter.Update, the source column name that is used to find the DataSetColumn name in the ColumnMappings. This is to copy a value between the parameter and a datarow.")]
338                 [DefaultValue ("")]
339 #endif
340                 public 
341 #if NET_2_0
342                 override
343 #endif // NET_2_0
344                 string SourceColumn {
345                         get { return sourceColumn; }
346                         set { sourceColumn = value; }
347                 }
348
349 #if ONLY_1_0 || ONLY_1_1
350                 [DataCategory ("Data")]
351                 [DataSysDescription ("When used by a DataAdapter.Update (UpdateCommand only), the version of the DataRow value that is used to update the data source.")]
352                 [DefaultValue (DataRowVersion.Current)]
353 #endif
354                 public 
355 #if NET_2_0
356                 override
357 #endif // NET_2_0
358                 DataRowVersion SourceVersion {
359                         get { return sourceVersion; }
360                         set { sourceVersion = value; }
361                 }
362                 
363 #if ONLY_1_0 || ONLY_1_1
364                 [DataCategory ("Data")]
365                 [DataSysDescription ("The parameter native type.")]
366                 [DefaultValue (SqlDbType.NVarChar)]
367 #endif
368                 [RefreshProperties (RefreshProperties.All)]
369 #if NET_2_0
370                 [DbProviderSpecificTypeProperty(true)]
371 #endif
372                 public SqlDbType SqlDbType {
373                         get { return sqlDbType; }
374                         set { 
375                                 SetSqlDbType (value); 
376                                 isTypeSet = true;
377                         }
378                 }
379
380                 [TypeConverterAttribute (typeof (StringConverter))]
381 #if ONLY_1_0 || ONLY_1_1
382                 [DataCategory ("Data")]
383                 [DataSysDescription ("Value of the parameter.")]
384                 [DefaultValue (null)]
385 #else
386                 [RefreshProperties (RefreshProperties.All)]
387 #endif
388                 public 
389 #if NET_2_0
390                 override
391 #endif // NET_2_0
392                 object Value {
393                         get { return metaParameter.Value; }
394                         set {
395                                 if (!isTypeSet)
396                                         InferSqlType (value);
397                                 metaParameter.Value = SqlTypeToFrameworkType (value);
398                         }
399                 }
400
401 #if NET_2_0
402                 [Browsable (false)]
403                 public SqlCompareOptions CompareInfo{
404                         get{ return compareInfo; }
405                         set{ compareInfo = value; }
406                 }
407
408                 [Browsable (false)]
409                 public int LocaleId { 
410                         get { return localeId; }
411                         set { localeId = value; }
412                 }
413
414                 [Browsable (false)]
415                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
416                 public Object SqlValue { 
417                         get { return sqlValue; }
418                         set { sqlValue = value; }
419                 }
420         
421                 public override bool SourceColumnNullMapping {
422                         get { return sourceColumnNullMapping; }
423                         set { sourceColumnNullMapping = value; }
424                 }
425
426                 public string XmlSchemaCollectionDatabase {
427                         get { return xmlSchemaCollectionDatabase; }
428                         set { xmlSchemaCollectionDatabase = (value == null ? String.Empty : value); }
429                 }
430
431                 public string XmlSchemaCollectionName {
432                         get { return xmlSchemaCollectionName; }
433                         set {
434                                 xmlSchemaCollectionName = (value == null ? String.Empty : value);
435                         }
436                 }
437
438                 public string XmlSchemaCollectionOwningSchema {
439                         get { return xmlSchemaCollectionOwningSchema; } 
440                         set {
441                                 xmlSchemaCollectionOwningSchema = (value == null ? String.Empty : value);
442                         }
443                 }
444 #endif
445                 #endregion // Properties
446
447                 #region Methods
448
449                 object ICloneable.Clone ()
450                 {
451                         return new SqlParameter (ParameterName, SqlDbType, Size, Direction, IsNullable, Precision, Scale, SourceColumn, SourceVersion, Value);
452                 }
453
454                 // If the value is set without the DbType/SqlDbType being set, then we
455                 // infer type information.
456                 private void InferSqlType (object value)
457                 {
458                         if (value == null || value == DBNull.Value) {
459                                 SetSqlDbType (SqlDbType.NVarChar);
460                                 return;
461                         }
462
463                         Type type = value.GetType ();
464                         string exception = String.Format ("The parameter data type of {0} is invalid.", type.Name);
465
466                         switch (type.FullName) {
467                         case "System.Int64":
468                         case "System.Data.SqlTypes.SqlInt64":
469                                 SetSqlDbType (SqlDbType.BigInt);
470                                 break;
471                         case "System.Boolean":
472                         case "System.Data.SqlTypes.SqlBoolean":
473                                 SetSqlDbType (SqlDbType.Bit);
474                                 break;
475                         case "System.String":
476                         case "System.Data.SqlTypes.SqlString":
477                                 SetSqlDbType (SqlDbType.NVarChar);
478                                 break;
479                         case "System.DateTime":
480                         case "System.Data.SqlTypes.SqlDateTime":
481                                 SetSqlDbType (SqlDbType.DateTime);
482                                 break;
483                         case "System.Decimal":
484                         case "System.Data.SqlTypes.SqlDecimal":
485                                 SetSqlDbType (SqlDbType.Decimal);
486                                 break;
487                         case "System.Double":
488                         case "System.Data.SqlTypes.SqlDouble":
489                                 SetSqlDbType (SqlDbType.Float);
490                                 break;
491                         case "System.Byte[]":
492                         case "System.Data.SqlTypes.SqlBinary":
493                                 SetSqlDbType (SqlDbType.VarBinary);
494                                 break;
495                         case "System.Byte":
496                         case "System.Data.SqlTypes.SqlByte":
497                                 SetSqlDbType (SqlDbType.TinyInt);
498                                 break;
499                         case "System.Int32":
500                         case "System.Data.SqlTypes.SqlInt32":
501                                 SetSqlDbType (SqlDbType.Int);
502                                 break;
503                         case "System.Single":
504                         case "System.Data.SqlTypes.Single":
505                                 SetSqlDbType (SqlDbType.Real);
506                                 break;
507                         case "System.Int16":
508                         case "System.Data.SqlTypes.SqlInt16":
509                                 SetSqlDbType (SqlDbType.SmallInt);
510                                 break;
511                         case "System.Guid":
512                         case "System.Data.SqlTypes.SqlGuid":
513                                 SetSqlDbType (SqlDbType.UniqueIdentifier);
514                                 break;
515                         case "System.Money":
516                         case "System.SmallMoney":
517                         case "System.Data.SqlTypes.SqlMoney":
518                                 SetSqlDbType (SqlDbType.Money);
519                                 break;
520                         case "System.Object":
521                                 SetSqlDbType (SqlDbType.Variant); 
522                                 break;
523                         default:
524                                 throw new ArgumentException (exception);
525                         }
526                 }
527
528                 // When the DbType is set, we also set the SqlDbType, as well as the SQL Server
529                 // string representation of the type name.  If the DbType is not convertible
530                 // to an SqlDbType, throw an exception.
531                 private void SetDbType (DbType type)
532                 {
533                         string exception = String.Format ("No mapping exists from DbType {0} to a known SqlDbType.", type);
534
535                         switch (type) {
536                         case DbType.AnsiString:
537                                 MetaParameter.TypeName = "varchar";
538                                 sqlDbType = SqlDbType.VarChar;
539                                 MetaParameter.IsVariableSizeType = true;
540                                 break;
541                         case DbType.AnsiStringFixedLength:
542                                 MetaParameter.TypeName = "char";
543                                 sqlDbType = SqlDbType.Char;
544                                 MetaParameter.IsVariableSizeType = true;
545                                 break;
546                         case DbType.Binary:
547                                 MetaParameter.TypeName = "varbinary";
548                                 sqlDbType = SqlDbType.VarBinary;
549                                 MetaParameter.IsVariableSizeType = true;
550                                 break;
551                         case DbType.Boolean:
552                                 MetaParameter.TypeName = "bit";
553                                 sqlDbType = SqlDbType.Bit;
554                                 break;
555                         case DbType.Byte:
556                                 MetaParameter.TypeName = "tinyint";
557                                 sqlDbType = SqlDbType.TinyInt;
558                                 break;
559                         case DbType.Currency:
560                                 sqlDbType = SqlDbType.Money;
561                                 MetaParameter.TypeName = "money";
562                                 break;
563                         case DbType.Date:
564                         case DbType.DateTime:
565                                 MetaParameter.TypeName = "datetime";
566                                 sqlDbType = SqlDbType.DateTime;
567                                 break;
568                         case DbType.Decimal:
569                                 MetaParameter.TypeName = "decimal";
570                                 sqlDbType = SqlDbType.Decimal;
571                                 break;
572                         case DbType.Double:
573                                 MetaParameter.TypeName = "float";
574                                 sqlDbType = SqlDbType.Float;
575                                 break;
576                         case DbType.Guid:
577                                 MetaParameter.TypeName = "uniqueidentifier";
578                                 sqlDbType = SqlDbType.UniqueIdentifier;
579                                 break;
580                         case DbType.Int16:
581                                 MetaParameter.TypeName = "smallint";
582                                 sqlDbType = SqlDbType.SmallInt;
583                                 break;
584                         case DbType.Int32:
585                                 MetaParameter.TypeName = "int";
586                                 sqlDbType = SqlDbType.Int;
587                                 break;
588                         case DbType.Int64:
589                                 MetaParameter.TypeName = "bigint";
590                                 sqlDbType = SqlDbType.BigInt;
591                                 break;
592                         case DbType.Object:
593                                 MetaParameter.TypeName = "sql_variant";
594                                 sqlDbType = SqlDbType.Variant;
595                                 break;
596                         case DbType.Single:
597                                 MetaParameter.TypeName = "real";
598                                 sqlDbType = SqlDbType.Real;
599                                 break;
600                         case DbType.String:
601                                 MetaParameter.TypeName = "nvarchar";
602                                 sqlDbType = SqlDbType.NVarChar;
603                                 MetaParameter.IsVariableSizeType = true;
604                                 break;
605                         case DbType.StringFixedLength:
606                                 MetaParameter.TypeName = "nchar";
607                                 sqlDbType = SqlDbType.NChar;
608                                 MetaParameter.IsVariableSizeType = true;
609                                 break;
610                         case DbType.Time:
611                                 MetaParameter.TypeName = "datetime";
612                                 sqlDbType = SqlDbType.DateTime;
613                                 break;
614                         default:
615                                 throw new ArgumentException (exception);
616                         }
617                         dbType = type;
618                 }
619
620                 // Used by internal constructor which has a SQL Server typename
621                 private void SetDbTypeName (string dbTypeName)
622                 {
623                         switch (dbTypeName.ToLower ()) {        
624                         case "bigint":
625                                 SqlDbType = SqlDbType.BigInt;
626                                 break;
627                         case "binary":
628                                 SqlDbType = SqlDbType.Binary;
629                                 break;
630                         case "bit":
631                                 SqlDbType = SqlDbType.Bit;
632                                 break;
633                         case "char":
634                                 SqlDbType = SqlDbType.Char;
635                                 break;
636                         case "datetime":
637                                 SqlDbType = SqlDbType.DateTime;
638                                 break;
639                         case "decimal":
640                                 SqlDbType = SqlDbType.Decimal;
641                                 break;
642                         case "float":
643                                 SqlDbType = SqlDbType.Float;
644                                 break;
645                         case "image":
646                                 SqlDbType = SqlDbType.Image;
647                                 break;
648                         case "int":
649                                 SqlDbType = SqlDbType.Int;
650                                 break;
651                         case "money":
652                                 SqlDbType = SqlDbType.Money;
653                                 break;
654                         case "nchar":
655                                 SqlDbType = SqlDbType.NChar;
656                                 break;
657                         case "ntext":
658                                 SqlDbType = SqlDbType.NText;
659                                 break;
660                         case "nvarchar":
661                                 SqlDbType = SqlDbType.NVarChar;
662                                 break;
663                         case "real":
664                                 SqlDbType = SqlDbType.Real;
665                                 break;
666                         case "smalldatetime":
667                                 SqlDbType = SqlDbType.SmallDateTime;
668                                 break;
669                         case "smallint":
670                                 SqlDbType = SqlDbType.SmallInt;
671                                 break;
672                         case "smallmoney":
673                                 SqlDbType = SqlDbType.SmallMoney;
674                                 break;
675                         case "text":
676                                 SqlDbType = SqlDbType.Text;
677                                 break;
678                         case "timestamp":
679                                 SqlDbType = SqlDbType.Timestamp;
680                                 break;
681                         case "tinyint":
682                                 SqlDbType = SqlDbType.TinyInt;
683                                 break;
684                         case "uniqueidentifier":
685                                 SqlDbType = SqlDbType.UniqueIdentifier;
686                                 break;
687                         case "varbinary":
688                                 SqlDbType = SqlDbType.VarBinary;
689                                 break;
690                         case "varchar":
691                                 SqlDbType = SqlDbType.VarChar;
692                                 break;
693                         case "sql_variant":
694                                 SqlDbType = SqlDbType.Variant;
695                                 break;
696                         default:
697                                 SqlDbType = SqlDbType.Variant;
698                                 break;
699                         }
700                 }
701
702                 // When the SqlDbType is set, we also set the DbType, as well as the SQL Server
703                 // string representation of the type name.  If the SqlDbType is not convertible
704                 // to a DbType, throw an exception.
705                 internal void SetSqlDbType (SqlDbType type)
706                 {
707                         string exception = String.Format ("No mapping exists from SqlDbType {0} to a known DbType.", type);
708
709                         switch (type) {
710                         case SqlDbType.BigInt:
711                                 MetaParameter.TypeName = "bigint";
712                                 dbType = DbType.Int64;
713                                 break;
714                         case SqlDbType.Binary:
715                                 MetaParameter.TypeName = "binary";
716                                 dbType = DbType.Binary;
717                                 MetaParameter.IsVariableSizeType = true;
718                                 break;
719                         case SqlDbType.Timestamp:
720                                 MetaParameter.TypeName = "timestamp";
721                                 dbType = DbType.Binary;
722                                 break;
723                         case SqlDbType.VarBinary:
724                                 MetaParameter.TypeName = "varbinary";
725                                 dbType = DbType.Binary;
726                                 MetaParameter.IsVariableSizeType = true;
727                                 break;
728                         case SqlDbType.Bit:
729                                 MetaParameter.TypeName = "bit";
730                                 dbType = DbType.Boolean;
731                                 break;
732                         case SqlDbType.Char:
733                                 MetaParameter.TypeName = "char";
734                                 dbType = DbType.AnsiStringFixedLength;
735                                 MetaParameter.IsVariableSizeType = true;
736                                 break;
737                         case SqlDbType.DateTime:
738                                 MetaParameter.TypeName = "datetime";
739                                 dbType = DbType.DateTime;
740                                 break;
741                         case SqlDbType.SmallDateTime:
742                                 MetaParameter.TypeName = "smalldatetime";
743                                 dbType = DbType.DateTime;
744                                 break;
745                         case SqlDbType.Decimal:
746                                 MetaParameter.TypeName = "decimal";
747                                 dbType = DbType.Decimal;
748                                 break;
749                         case SqlDbType.Float:
750                                 MetaParameter.TypeName = "float";
751                                 dbType = DbType.Double;
752                                 break;
753                         case SqlDbType.Image:
754                                 MetaParameter.TypeName = "image";
755                                 dbType = DbType.Binary;
756                                 MetaParameter.IsVariableSizeType = true;
757                                 break;
758                         case SqlDbType.Int:
759                                 MetaParameter.TypeName = "int";
760                                 dbType = DbType.Int32;
761                                 break;
762                         case SqlDbType.Money:
763                                 MetaParameter.TypeName = "money";
764                                 dbType = DbType.Currency;
765                                 break;
766                         case SqlDbType.SmallMoney:
767                                 MetaParameter.TypeName = "smallmoney";
768                                 dbType = DbType.Currency;
769                                 break;
770                         case SqlDbType.NChar:
771                                 MetaParameter.TypeName = "nchar";
772                                 dbType = DbType.StringFixedLength;
773                                 MetaParameter.IsVariableSizeType = true;
774                                 break;
775                         case SqlDbType.NText:
776                                 MetaParameter.TypeName = "ntext";
777                                 dbType = DbType.String;
778                                 MetaParameter.IsVariableSizeType = true;
779                                 break;
780                         case SqlDbType.NVarChar:
781                                 MetaParameter.TypeName = "nvarchar";
782                                 dbType = DbType.String;
783                                 MetaParameter.IsVariableSizeType = true;
784                                 break;
785                         case SqlDbType.Real:
786                                 MetaParameter.TypeName = "real";
787                                 dbType = DbType.Single;
788                                 break;
789                         case SqlDbType.SmallInt:
790                                 MetaParameter.TypeName = "smallint";
791                                 dbType = DbType.Int16;
792                                 break;
793                         case SqlDbType.Text:
794                                 MetaParameter.TypeName = "text";
795                                 dbType = DbType.AnsiString;
796                                 MetaParameter.IsVariableSizeType = true;
797                                 break;
798                         case SqlDbType.VarChar:
799                                 MetaParameter.TypeName = "varchar";
800                                 dbType = DbType.AnsiString;
801                                 MetaParameter.IsVariableSizeType = true;
802                                 break;
803                         case SqlDbType.TinyInt:
804                                 MetaParameter.TypeName = "tinyint";
805                                 dbType = DbType.Byte;
806                                 break;
807                         case SqlDbType.UniqueIdentifier:
808                                 MetaParameter.TypeName = "uniqueidentifier";
809                                 dbType = DbType.Guid;
810                                 break;
811                         case SqlDbType.Variant:
812                                 MetaParameter.TypeName = "sql_variant";
813                                 dbType = DbType.Object;
814                                 break;
815                         default:
816                                 throw new ArgumentException (exception);
817                         }
818                         sqlDbType = type;
819                 }
820
821                 public override string ToString() 
822                 {
823                         return ParameterName;
824                 }
825
826                 private object SqlTypeToFrameworkType (object value)
827                 {
828                         if (! (value is INullable)) // if the value is not SqlType
829                                 return ConvertToFrameworkType (value);
830
831                         // Map to .net type, as Mono TDS respects only types from .net
832                         switch (value.GetType ().FullName) {
833                         case "System.Data.SqlTypes.SqlBinary":
834                                 return ( (SqlBinary) value).Value;
835                         case "System.Data.SqlTypes.SqlBoolean":
836                                 return ( (SqlBoolean) value).Value;
837                         case "System.Data.SqlTypes.SqlByte":
838                                 return ( (SqlByte) value).Value;
839                         case "System.Data.SqlTypes.SqlDateTime":
840                                 return ( (SqlDateTime) value).Value;
841                         case "System.Data.SqlTypes.SqlDecimal":
842                                 return ( (SqlDecimal) value).Value;
843                         case "System.Data.SqlTypes.SqlDouble":
844                                 return ( (SqlDouble) value).Value;
845                         case "System.Data.SqlTypes.SqlGuid":
846                                 return ( (SqlGuid) value).Value;
847                         case "System.Data.SqlTypes.SqlInt16":
848                                 return ( (SqlInt16) value).Value;
849                         case "System.Data.SqlTypes.SqlInt32 ":
850                                 return ( (SqlInt32 ) value).Value;
851                         case "System.Data.SqlTypes.SqlInt64":
852                                 return ( (SqlInt64) value).Value;
853                         case "System.Data.SqlTypes.SqlMoney":
854                                 return ( (SqlMoney) value).Value;
855                         case "System.Data.SqlTypes.SqlSingle":
856                                 return ( (SqlSingle) value).Value;
857                         case "System.Data.SqlTypes.SqlString":
858                                 return ( (SqlString) value).Value;
859                         }
860                         return value;
861                 }
862
863                 internal object ConvertToFrameworkType (object value)
864                 {
865                         if (value == null || value == DBNull.Value)
866                                 return value;
867                         switch (sqlDbType)  {
868                         case SqlDbType.BigInt :
869                                 return Convert.ChangeType (value, typeof (Int64));
870                         case SqlDbType.Binary:
871                         case SqlDbType.VarBinary:
872                                 if (value is byte[])
873                                         return value;
874                                 break;
875                         case SqlDbType.Bit:
876                                 return Convert.ChangeType (value, typeof (bool));
877                         case SqlDbType.Int:
878                                 return Convert.ChangeType (value, typeof (Int32));
879                         case SqlDbType.SmallInt :
880                                 return Convert.ChangeType (value, typeof (Int16));
881                         case SqlDbType.TinyInt :
882                                 return Convert.ChangeType (value, typeof (byte));
883                         case SqlDbType.Float:
884                                 return Convert.ChangeType (value, typeof (Double));
885                         case SqlDbType.Real:
886                                 return Convert.ChangeType (value, typeof (Single));
887                         case SqlDbType.Decimal:
888                                 return Convert.ChangeType (value, typeof (Decimal));
889                         case SqlDbType.Money:
890                         case SqlDbType.SmallMoney:
891                                 {
892                                         Decimal val = (Decimal)Convert.ChangeType (value, typeof (Decimal));
893                                         return Decimal.Round(val, 4);
894                                 }
895                         case SqlDbType.DateTime:
896                         case SqlDbType.SmallDateTime:
897                                 return Convert.ChangeType (value, typeof (DateTime));
898                         case SqlDbType.VarChar:
899                         case SqlDbType.NVarChar:
900                         case SqlDbType.Char:
901                         case SqlDbType.NChar:
902                         case SqlDbType.Text:
903                         case SqlDbType.NText:
904                                 return Convert.ChangeType (value,  typeof (string));
905                         case SqlDbType.UniqueIdentifier:
906                                 return Convert.ChangeType (value,  typeof (Guid));
907                         case SqlDbType.Variant:
908                                 return metaParameter.Value;
909                         }
910                         throw new  NotImplementedException ("Type Not Supported : " + sqlDbType.ToString());
911                 }
912
913 #if NET_2_0
914                 public override void ResetDbType ()
915                 {
916                         InferSqlType (metaParameter.Value);
917                 }
918
919                 public void ResetSqlDbType ()
920                 {
921                         InferSqlType (metaParameter.Value);
922                 }
923 #endif // NET_2_0
924
925                 #endregion // Methods
926         }
927 }