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