copying the latest Sys.Web.Services from trunk.
[mono.git] / mcs / class / Npgsql / Npgsql / NpgsqlParameter.cs
1 // created on 18/5/2002 at 01:25
2
3 // Npgsql.NpgsqlParameter.cs
4 //
5 // Author:
6 //      Francisco Jr. (fxjrlists@yahoo.com.br)
7 //
8 //      Copyright (C) 2002 The Npgsql Development Team
9 //      npgsql-general@gborg.postgresql.org
10 //      http://gborg.postgresql.org/project/npgsql/projdisplay.php
11 //
12 // This library is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU Lesser General Public
14 // License as published by the Free Software Foundation; either
15 // version 2.1 of the License, or (at your option) any later version.
16 //
17 // This library is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 // Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License along with this library; if not, write to the Free Software
24 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
26
27 using System;
28 using System.Data;
29 using System.ComponentModel;
30 using NpgsqlTypes;
31
32 #if WITHDESIGN
33 using Npgsql.Design;
34 #endif
35
36
37 namespace Npgsql
38 {
39     ///<summary>
40     /// This class represents a parameter to a command that will be sent to server
41     ///</summary>
42     #if WITHDESIGN
43     [TypeConverter(typeof(NpgsqlParameterConverter))]
44     #endif
45     
46     public sealed class NpgsqlParameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
47     {
48
49         // Logging related values
50         private static readonly String CLASSNAME = "NpgsqlParameter";
51
52         // Fields to implement IDbDataParameter interface.
53         private byte                                precision = 0;
54         private byte                                scale = 0;
55         private Int32                               size = 0;
56
57         // Fields to implement IDataParameter
58         //private NpgsqlDbType                              npgsqldb_type = NpgsqlDbType.Text;
59         //private DbType                    db_type = DbType.String;
60         private NpgsqlNativeTypeInfo    type_info;
61         private ParameterDirection          direction = ParameterDirection.Input;
62         private Boolean                             is_nullable = false;
63         private String                              name;
64         private String                              source_column = String.Empty;
65         private DataRowVersion              source_version = DataRowVersion.Current;
66         private Object                              value = DBNull.Value;
67         private System.Resources.ResourceManager resman;
68
69         /// <summary>
70
71         /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> class.
72         /// </summary>
73         public NpgsqlParameter()
74         {
75             resman = new System.Resources.ResourceManager(this.GetType());
76             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
77         }
78
79         /// <summary>
80         /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
81         /// class with the parameter name and a value of the new <b>NpgsqlParameter</b>.
82         /// </summary>
83         /// <param name="parameterName">The name of the parameter to map.</param>
84         /// <param name="value">An <see cref="System.Object">Object</see> that is the value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.</param>
85         /// <remarks>
86         /// <p>When you specify an <see cref="System.Object">Object</see>
87         /// in the value parameter, the <see cref="System.Data.DbType">DbType</see> is
88         /// inferred from the .NET Framework type of the <b>Object</b>.</p>
89         /// <p>When using this constructor, you must be aware of a possible misuse of the constructor which takes a DbType parameter.
90         /// This happens when calling this constructor passing an int 0 and the compiler thinks you are passing a value of DbType.
91         /// Use <code> Convert.ToInt32(value) </code> for example to have compiler calling the correct constructor.</p>
92         /// </remarks>
93         public NpgsqlParameter(String parameterName, object value)
94         {
95             resman = new System.Resources.ResourceManager(this.GetType());
96             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME, parameterName, value);
97
98             this.ParameterName = parameterName;
99             this.value = value;
100
101             if ((this.value == null) || (this.value == DBNull.Value) )
102             {
103                 // don't really know what to do - leave default and do further exploration
104                 // Default type for null values is String.
105                 this.value = DBNull.Value;
106                 type_info = NpgsqlTypesHelper.GetNativeTypeInfo(typeof(String));
107                 return;
108             }
109             else
110             {
111                 type_info = NpgsqlTypesHelper.GetNativeTypeInfo(value.GetType());
112                 if (type_info == null)
113                 {
114                     throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), value.GetType()));
115                 }
116
117             }
118         }
119
120         /// <summary>
121         /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
122         /// class with the parameter name and the data type.
123         /// </summary>
124         /// <param name="parameterName">The name of the parameter to map.</param>
125         /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
126         public NpgsqlParameter(String parameterName, NpgsqlDbType parameterType) : this(parameterName, parameterType, 0, String.Empty)
127         {}
128
129
130         public NpgsqlParameter(String parameterName, DbType parameterType) : this(parameterName, NpgsqlTypesHelper.GetNativeTypeInfo(parameterType).NpgsqlDbType, 0, String.Empty)
131         {}
132
133         /// <summary>
134         /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
135         /// class with the parameter name, the <see cref="System.Data.DbType">DbType</see>, and the size.
136         /// </summary>
137         /// <param name="parameterName">The name of the parameter to map.</param>
138         /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
139         /// <param name="size">The length of the parameter.</param>
140         public NpgsqlParameter(String parameterName, NpgsqlDbType parameterType, Int32 size) : this(parameterName, parameterType, size, String.Empty)
141         {}
142
143         public NpgsqlParameter(String parameterName, DbType parameterType, Int32 size) : this(parameterName, NpgsqlTypesHelper.GetNativeTypeInfo(parameterType).NpgsqlDbType, size, String.Empty)
144         {}
145
146
147         /// <summary>
148         /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
149         /// class with the parameter name, the <see cref="System.Data.DbType">DbType</see>, the size,
150         /// and the source column name.
151         /// </summary>
152         /// <param name="parameterName">The name of the parameter to map.</param>
153         /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
154         /// <param name="size">The length of the parameter.</param>
155         /// <param name="sourceColumn">The name of the source column.</param>
156         public NpgsqlParameter(String parameterName, NpgsqlDbType parameterType, Int32 size, String sourceColumn)
157         {
158
159             resman = new System.Resources.ResourceManager(this.GetType());
160
161             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME, parameterName, parameterType, size, source_column);
162
163             this.ParameterName = parameterName;
164
165             type_info = NpgsqlTypesHelper.GetNativeTypeInfo(parameterType);
166             if (type_info == null)
167                 throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), parameterType));
168
169             this.size = size;
170             source_column = sourceColumn;
171
172
173         }
174
175         public NpgsqlParameter(String parameterName, DbType parameterType, Int32 size, String sourceColumn) : this(parameterName, NpgsqlTypesHelper.GetNativeTypeInfo(parameterType).NpgsqlDbType, size, sourceColumn)
176     {}
177
178
179
180         /// <summary>
181         /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
182         /// class with the parameter name, the <see cref="System.Data.DbType">DbType</see>, the size,
183         /// the source column name, a <see cref="System.Data.ParameterDirection">ParameterDirection</see>,
184         /// the precision of the parameter, the scale of the parameter, a
185         /// <see cref="System.Data.DataRowVersion">DataRowVersion</see> to use, and the
186         /// value of the parameter.
187         /// </summary>
188         /// <param name="parameterName">The name of the parameter to map.</param>
189         /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
190         /// <param name="size">The length of the parameter.</param>
191         /// <param name="sourceColumn">The name of the source column.</param>
192         /// <param name="direction">One of the <see cref="System.Data.ParameterDirection">ParameterDirection</see> values.</param>
193         /// <param name="isNullable"><b>true</b> if the value of the field can be null, otherwise <b>false</b>.</param>
194         /// <param name="precision">The total number of digits to the left and right of the decimal point to which
195         /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved.</param>
196         /// <param name="scale">The total number of decimal places to which
197         /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved.</param>
198         /// <param name="sourceVersion">One of the <see cref="System.Data.DataRowVersion">DataRowVersion</see> values.</param>
199         /// <param name="value">An <see cref="System.Object">Object</see> that is the value
200         /// of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.</param>
201         public NpgsqlParameter (String parameterName, NpgsqlDbType parameterType, Int32 size, String sourceColumn, ParameterDirection direction, bool isNullable, byte precision, byte scale, DataRowVersion sourceVersion, object value)
202         {
203
204             resman = new System.Resources.ResourceManager(this.GetType());
205
206             this.ParameterName = parameterName;
207             this.Size = size;
208             this.SourceColumn = sourceColumn;
209             this.Direction = direction;
210             this.IsNullable = isNullable;
211             this.Precision = precision;
212             this.Scale = scale;
213             this.SourceVersion = sourceVersion;
214             this.Value = value;
215
216             if (this.value == null)
217             {
218                 this.value = DBNull.Value;
219                 type_info = NpgsqlTypesHelper.GetNativeTypeInfo(typeof(String));
220             }
221             else
222             {
223                 type_info = NpgsqlTypesHelper.GetNativeTypeInfo(parameterType);
224                 if (type_info == null)
225                     throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), parameterType));
226             }
227
228         }
229
230         public NpgsqlParameter (String parameterName, DbType parameterType, Int32 size, String sourceColumn, ParameterDirection direction, bool isNullable, byte precision, byte scale, DataRowVersion sourceVersion, object value) : this(parameterName, NpgsqlTypesHelper.GetNativeTypeInfo(parameterType).NpgsqlDbType, size, sourceColumn, direction, isNullable, precision, scale, sourceVersion, value)
231     {}
232
233         // Implementation of IDbDataParameter
234         /// <summary>
235         /// Gets or sets the maximum number of digits used to represent the
236         /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> property.
237         /// </summary>
238         /// <value>The maximum number of digits used to represent the
239         /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> property.
240         /// The default value is 0, which indicates that the data provider
241         /// sets the precision for <b>Value</b>.</value>
242         [Category("Data"), DefaultValue((Byte)0)]
243         public Byte Precision
244         {
245             get
246             {
247                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Precision");
248                 return precision;
249             }
250
251             set
252             {
253                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Precision", value);
254                 precision = value;
255             }
256         }
257
258         /// <summary>
259         /// Gets or sets the number of decimal places to which
260         /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved.
261         /// </summary>
262         /// <value>The number of decimal places to which
263         /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved. The default is 0.</value>
264         [Category("Data"), DefaultValue((Byte)0)]
265         public Byte Scale
266         {
267             get
268             {
269                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Scale");
270                 return scale;
271             }
272
273             set
274             {
275                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Scale", value);
276                 scale = value;
277             }
278         }
279
280         /// <summary>
281         /// Gets or sets the maximum size, in bytes, of the data within the column.
282         /// </summary>
283         /// <value>The maximum size, in bytes, of the data within the column.
284         /// The default value is inferred from the parameter value.</value>
285         [Category("Data"), DefaultValue(0)]
286         public Int32 Size
287         {
288             get
289             {
290                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Size");
291                 return size;
292             }
293
294             set
295             {
296                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Size", value);
297                 size = value;
298             }
299         }
300
301         /// <summary>
302         /// Gets or sets the <see cref="System.Data.DbType">DbType</see> of the parameter.
303         /// </summary>
304         /// <value>One of the <see cref="System.Data.DbType">DbType</see> values. The default is <b>String</b>.</value>
305         [Category("Data"), RefreshProperties(RefreshProperties.All), DefaultValue(DbType.String)]
306         public DbType DbType
307         {
308             get
309             {
310                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "DbType");
311                 return TypeInfo.DbType;
312             }
313
314             // [TODO] Validate data type.
315             set
316             {
317                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "DbType", value);
318                 type_info = NpgsqlTypesHelper.GetNativeTypeInfo(value);
319                 if (type_info == null)
320                     throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), value));
321
322             }
323         }
324
325         /// <summary>
326         /// Gets or sets the <see cref="System.Data.DbType">DbType</see> of the parameter.
327         /// </summary>
328         /// <value>One of the <see cref="System.Data.DbType">DbType</see> values. The default is <b>String</b>.</value>
329         [Category("Data"), RefreshProperties(RefreshProperties.All), DefaultValue(NpgsqlDbType.Text)]
330         public NpgsqlDbType NpgsqlDbType
331         {
332             get
333             {
334                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "DbType");
335
336                 return TypeInfo.NpgsqlDbType;
337             }
338
339             // [TODO] Validate data type.
340             set
341             {
342                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "DbType", value);
343                 type_info = NpgsqlTypesHelper.GetNativeTypeInfo(value);
344                 if (type_info == null)
345                     throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), value));
346
347             }
348         }
349
350
351
352         internal NpgsqlNativeTypeInfo TypeInfo
353         {
354             get
355             {
356                 return type_info;
357             }
358         }
359
360         /// <summary>
361         /// Gets or sets a value indicating whether the parameter is input-only,
362         /// output-only, bidirectional, or a stored procedure return value parameter.
363         /// </summary>
364         /// <value>One of the <see cref="System.Data.ParameterDirection">ParameterDirection</see>
365         /// values. The default is <b>Input</b>.</value>
366         [Category("Data"), DefaultValue(ParameterDirection.Input)]
367         public ParameterDirection Direction
368         {
369             get
370             {
371                 NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "Direction");
372                 return direction;
373             }
374
375             set
376             {
377                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Direction", value);
378                 direction = value;
379             }
380         }
381
382         /// <summary>
383         /// Gets or sets a value indicating whether the parameter accepts null values.
384         /// </summary>
385         /// <value><b>true</b> if null values are accepted; otherwise, <b>false</b>. The default is <b>false</b>.</value>
386         
387         #if WITHDESIGN
388         [EditorBrowsable(EditorBrowsableState.Advanced), Browsable(false), DefaultValue(false), DesignOnly(true)]
389         #endif
390         
391         public Boolean IsNullable
392         {
393             get
394             {
395                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsNullable");
396                 return is_nullable;
397             }
398
399             set
400             {
401                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "IsNullable", value);
402                 is_nullable = value;
403             }
404         }
405
406         /// <summary>
407         /// Gets or sets the name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.
408         /// </summary>
409         /// <value>The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.
410         /// The default is an empty string.</value>
411         [DefaultValue("")]
412         public String ParameterName
413         {
414             get
415             {
416                 NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "ParameterName");
417                 return name;
418             }
419
420             set
421             {
422                 name = value;
423                 if ( (name.Equals(String.Empty)) || ((name[0] != ':') && (name[0] != '@')) )
424                     name = ':' + name;
425
426                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "ParameterName", value);
427             }
428         }
429
430         /// <summary>
431         /// Gets or sets the name of the source column that is mapped to the
432         /// <see cref="System.Data.DataSet">DataSet</see> and used for loading or
433         /// returning the <see cref="Npgsql.NpgsqlParameter.Value">Value</see>.
434         /// </summary>
435         /// <value>The name of the source column that is mapped to the
436         /// <see cref="System.Data.DataSet">DataSet</see>. The default is an empty string.</value>
437         [Category("Data"), DefaultValue("")]
438         public String SourceColumn
439         {
440             get
441             {
442                 NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "SourceColumn");
443                 return source_column;
444             }
445
446             set
447             {
448                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "SourceColumn", value);
449                 source_column = value;
450             }
451         }
452
453         /// <summary>
454         /// Gets or sets the <see cref="System.Data.DataRowVersion">DataRowVersion</see>
455         /// to use when loading <see cref="Npgsql.NpgsqlParameter.Value">Value</see>.
456         /// </summary>
457         /// <value>One of the <see cref="System.Data.DataRowVersion">DataRowVersion</see> values.
458         /// The default is <b>Current</b>.</value>
459         [Category("Data"), DefaultValue(DataRowVersion.Current)]
460         public DataRowVersion SourceVersion
461         {
462             get
463             {
464                 NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "SourceVersion");
465                 return source_version;
466             }
467
468             set
469             {
470                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "SourceVersion", value);
471                 source_version = value;
472             }
473         }
474
475         /// <summary>
476         /// Gets or sets the value of the parameter.
477         /// </summary>
478         /// <value>An <see cref="System.Object">Object</see> that is the value of the parameter.
479         /// The default value is null.</value>
480         [TypeConverter(typeof(StringConverter)), Category("Data")]
481         public Object Value
482         {
483             get
484             {
485                 NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "Value");
486                 return value;
487             }
488
489             // [TODO] Check and validate data type.
490             set
491             {
492                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Value", value);
493
494                 this.value = value;
495                 if ((this.value == null) || (this.value == DBNull.Value) )
496                 {
497                     // don't really know what to do - leave default and do further exploration
498                     // Default type for null values is String.
499                     this.value = DBNull.Value;
500                     if (type_info == null)
501                         type_info = NpgsqlTypesHelper.GetNativeTypeInfo(typeof(String));
502
503                 }
504                 else
505                 {
506                     if (type_info == null)
507                     {
508                         type_info = NpgsqlTypesHelper.GetNativeTypeInfo(value.GetType());
509                         if (type_info == null)
510                                 throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), value.GetType()));
511                         
512                     }
513
514                 }
515             }
516         }
517
518         /// <summary>
519         /// Creates a new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> that
520         /// is a copy of the current instance.
521         /// </summary>
522         /// <returns>A new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> that is a copy of this instance.</returns>
523         object System.ICloneable.Clone()
524         {
525             return new NpgsqlParameter(this.ParameterName, this.NpgsqlDbType,   this.Size, this.SourceColumn, this.Direction, this.IsNullable, this.Precision, this.Scale, this.SourceVersion, this.Value);
526         }
527
528
529     }
530 }