* roottypes.cs: Rename from tree.cs.
[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 = String.Empty;
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         
70         /// <summary>
71
72         /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> class.
73         /// </summary>
74         public NpgsqlParameter()
75         {
76             resman = new System.Resources.ResourceManager(this.GetType());
77             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
78             //type_info = NpgsqlTypesHelper.GetNativeTypeInfo(typeof(String));
79         }
80
81         /// <summary>
82         /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
83         /// class with the parameter name and a value of the new <b>NpgsqlParameter</b>.
84         /// </summary>
85         /// <param name="parameterName">The name of the parameter to map.</param>
86         /// <param name="value">An <see cref="System.Object">Object</see> that is the value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.</param>
87         /// <remarks>
88         /// <p>When you specify an <see cref="System.Object">Object</see>
89         /// in the value parameter, the <see cref="System.Data.DbType">DbType</see> is
90         /// inferred from the .NET Framework type of the <b>Object</b>.</p>
91         /// <p>When using this constructor, you must be aware of a possible misuse of the constructor which takes a DbType parameter.
92         /// This happens when calling this constructor passing an int 0 and the compiler thinks you are passing a value of DbType.
93         /// Use <code> Convert.ToInt32(value) </code> for example to have compiler calling the correct constructor.</p>
94         /// </remarks>
95         public NpgsqlParameter(String parameterName, object value)
96         {
97             resman = new System.Resources.ResourceManager(this.GetType());
98             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME, parameterName, value);
99
100             this.ParameterName = parameterName;
101             this.value = value;
102
103             if ((this.value == null) || (this.value == DBNull.Value) )
104             {
105                 // don't really know what to do - leave default and do further exploration
106                 // Default type for null values is String.
107                 this.value = DBNull.Value;
108                 type_info = NpgsqlTypesHelper.GetNativeTypeInfo(typeof(String));
109                 return;
110             }
111             else
112             {
113                 type_info = NpgsqlTypesHelper.GetNativeTypeInfo(value.GetType());
114                 if (type_info == null)
115                 {
116                     throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), value.GetType()));
117                 }
118                 
119                 
120
121             }
122         }
123                 
124                 /// <summary>
125                 /// Internal constructor to handle parameter creation from CommandBuilder passing a NpgsqlNativeTypeInfo directly.
126                 /// </summary>
127                 internal NpgsqlParameter(String parameterName, object value, NpgsqlNativeTypeInfo type_info)
128                 {
129                         resman = new System.Resources.ResourceManager(this.GetType());
130                         NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME, parameterName, value, type_info);
131                         
132                         this.ParameterName = parameterName;
133                         this.value = (value == null) ? DBNull.Value : value;
134                         
135                         this.type_info = (type_info == null) ? NpgsqlTypesHelper.GetNativeTypeInfo(typeof(String)) : type_info;
136                 }
137                 
138         /// <summary>
139         /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
140         /// class with the parameter name and the data type.
141         /// </summary>
142         /// <param name="parameterName">The name of the parameter to map.</param>
143         /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
144         public NpgsqlParameter(String parameterName, NpgsqlDbType parameterType) : this(parameterName, parameterType, 0, String.Empty)
145         {}
146
147
148         public NpgsqlParameter(String parameterName, DbType parameterType) : this(parameterName, NpgsqlTypesHelper.GetNativeTypeInfo(parameterType).NpgsqlDbType, 0, String.Empty)
149         {}
150
151         /// <summary>
152         /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
153         /// class with the parameter name, the <see cref="System.Data.DbType">DbType</see>, and the size.
154         /// </summary>
155         /// <param name="parameterName">The name of the parameter to map.</param>
156         /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
157         /// <param name="size">The length of the parameter.</param>
158         public NpgsqlParameter(String parameterName, NpgsqlDbType parameterType, Int32 size) : this(parameterName, parameterType, size, String.Empty)
159         {}
160
161         public NpgsqlParameter(String parameterName, DbType parameterType, Int32 size) : this(parameterName, NpgsqlTypesHelper.GetNativeTypeInfo(parameterType).NpgsqlDbType, size, String.Empty)
162         {}
163
164
165         /// <summary>
166         /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
167         /// class with the parameter name, the <see cref="System.Data.DbType">DbType</see>, the size,
168         /// and the source column name.
169         /// </summary>
170         /// <param name="parameterName">The name of the parameter to map.</param>
171         /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
172         /// <param name="size">The length of the parameter.</param>
173         /// <param name="sourceColumn">The name of the source column.</param>
174         public NpgsqlParameter(String parameterName, NpgsqlDbType parameterType, Int32 size, String sourceColumn)
175         {
176
177             resman = new System.Resources.ResourceManager(this.GetType());
178
179             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME, parameterName, parameterType, size, source_column);
180
181             this.ParameterName = parameterName;
182             
183             type_info = NpgsqlTypesHelper.GetNativeTypeInfo(parameterType);
184             if (type_info == null)
185                 throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), parameterType));
186
187             this.size = size;
188             source_column = sourceColumn;
189
190
191         }
192
193         public NpgsqlParameter(String parameterName, DbType parameterType, Int32 size, String sourceColumn) : this(parameterName, NpgsqlTypesHelper.GetNativeTypeInfo(parameterType).NpgsqlDbType, size, sourceColumn)
194     {}
195
196
197
198         /// <summary>
199         /// Initializes a new instance of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
200         /// class with the parameter name, the <see cref="System.Data.DbType">DbType</see>, the size,
201         /// the source column name, a <see cref="System.Data.ParameterDirection">ParameterDirection</see>,
202         /// the precision of the parameter, the scale of the parameter, a
203         /// <see cref="System.Data.DataRowVersion">DataRowVersion</see> to use, and the
204         /// value of the parameter.
205         /// </summary>
206         /// <param name="parameterName">The name of the parameter to map.</param>
207         /// <param name="parameterType">One of the <see cref="System.Data.DbType">DbType</see> values.</param>
208         /// <param name="size">The length of the parameter.</param>
209         /// <param name="sourceColumn">The name of the source column.</param>
210         /// <param name="direction">One of the <see cref="System.Data.ParameterDirection">ParameterDirection</see> values.</param>
211         /// <param name="isNullable"><b>true</b> if the value of the field can be null, otherwise <b>false</b>.</param>
212         /// <param name="precision">The total number of digits to the left and right of the decimal point to which
213         /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved.</param>
214         /// <param name="scale">The total number of decimal places to which
215         /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved.</param>
216         /// <param name="sourceVersion">One of the <see cref="System.Data.DataRowVersion">DataRowVersion</see> values.</param>
217         /// <param name="value">An <see cref="System.Object">Object</see> that is the value
218         /// of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.</param>
219         public NpgsqlParameter (String parameterName, NpgsqlDbType parameterType, Int32 size, String sourceColumn, ParameterDirection direction, bool isNullable, byte precision, byte scale, DataRowVersion sourceVersion, object value)
220         {
221
222             resman = new System.Resources.ResourceManager(this.GetType());
223
224             this.ParameterName = parameterName;
225             this.Size = size;
226             this.SourceColumn = sourceColumn;
227             this.Direction = direction;
228             this.IsNullable = isNullable;
229             this.Precision = precision;
230             this.Scale = scale;
231             this.SourceVersion = sourceVersion;
232             this.Value = value;
233
234             if (this.value == null)
235             {
236                 this.value = DBNull.Value;
237                 type_info = NpgsqlTypesHelper.GetNativeTypeInfo(typeof(String));
238             }
239             else
240             {
241                 type_info = NpgsqlTypesHelper.GetNativeTypeInfo(parameterType);
242                 if (type_info == null)
243                     throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), parameterType));
244             }
245
246         }
247
248         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)
249     {}
250
251         // Implementation of IDbDataParameter
252         /// <summary>
253         /// Gets or sets the maximum number of digits used to represent the
254         /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> property.
255         /// </summary>
256         /// <value>The maximum number of digits used to represent the
257         /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> property.
258         /// The default value is 0, which indicates that the data provider
259         /// sets the precision for <b>Value</b>.</value>
260         [Category("Data"), DefaultValue((Byte)0)]
261         public Byte Precision
262         {
263             get
264             {
265                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Precision");
266                 return precision;
267             }
268
269             set
270             {
271                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Precision", value);
272                 precision = value;
273             }
274         }
275
276         /// <summary>
277         /// Gets or sets the number of decimal places to which
278         /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved.
279         /// </summary>
280         /// <value>The number of decimal places to which
281         /// <see cref="Npgsql.NpgsqlParameter.Value">Value</see> is resolved. The default is 0.</value>
282         [Category("Data"), DefaultValue((Byte)0)]
283         public Byte Scale
284         {
285             get
286             {
287                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Scale");
288                 return scale;
289             }
290
291             set
292             {
293                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Scale", value);
294                 scale = value;
295             }
296         }
297
298         /// <summary>
299         /// Gets or sets the maximum size, in bytes, of the data within the column.
300         /// </summary>
301         /// <value>The maximum size, in bytes, of the data within the column.
302         /// The default value is inferred from the parameter value.</value>
303         [Category("Data"), DefaultValue(0)]
304         public Int32 Size
305         {
306             get
307             {
308                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Size");
309                 return size;
310             }
311
312             set
313             {
314                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Size", value);
315                 size = value;
316             }
317         }
318
319         /// <summary>
320         /// Gets or sets the <see cref="System.Data.DbType">DbType</see> of the parameter.
321         /// </summary>
322         /// <value>One of the <see cref="System.Data.DbType">DbType</see> values. The default is <b>String</b>.</value>
323         [Category("Data"), RefreshProperties(RefreshProperties.All), DefaultValue(DbType.String)]
324         public DbType DbType
325         {
326             get
327             {
328                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "DbType");
329                 return TypeInfo.DbType;
330             }
331
332             // [TODO] Validate data type.
333             set
334             {
335                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "DbType", value);
336                 type_info = NpgsqlTypesHelper.GetNativeTypeInfo(value);
337                 if (type_info == null)
338                     throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), value));
339
340             }
341         }
342
343         /// <summary>
344         /// Gets or sets the <see cref="System.Data.DbType">DbType</see> of the parameter.
345         /// </summary>
346         /// <value>One of the <see cref="System.Data.DbType">DbType</see> values. The default is <b>String</b>.</value>
347         [Category("Data"), RefreshProperties(RefreshProperties.All), DefaultValue(NpgsqlDbType.Text)]
348         public NpgsqlDbType NpgsqlDbType
349         {
350             get
351             {
352                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "DbType");
353
354                 return TypeInfo.NpgsqlDbType;
355             }
356
357             // [TODO] Validate data type.
358             set
359             {
360                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "DbType", value);
361                 type_info = NpgsqlTypesHelper.GetNativeTypeInfo(value);
362                 if (type_info == null)
363                     throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), value));
364
365             }
366         }
367
368
369
370         internal NpgsqlNativeTypeInfo TypeInfo
371         {
372             get
373             {
374                 if (type_info == null)
375                         type_info = NpgsqlTypesHelper.GetNativeTypeInfo(typeof(String));
376                 return type_info;
377             }
378         }
379
380         /// <summary>
381         /// Gets or sets a value indicating whether the parameter is input-only,
382         /// output-only, bidirectional, or a stored procedure return value parameter.
383         /// </summary>
384         /// <value>One of the <see cref="System.Data.ParameterDirection">ParameterDirection</see>
385         /// values. The default is <b>Input</b>.</value>
386         [Category("Data"), DefaultValue(ParameterDirection.Input)]
387         public ParameterDirection Direction
388         {
389             get
390             {
391                 NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "Direction");
392                 return direction;
393             }
394
395             set
396             {
397                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Direction", value);
398                 direction = value;
399             }
400         }
401
402         /// <summary>
403         /// Gets or sets a value indicating whether the parameter accepts null values.
404         /// </summary>
405         /// <value><b>true</b> if null values are accepted; otherwise, <b>false</b>. The default is <b>false</b>.</value>
406         
407         #if WITHDESIGN
408         [EditorBrowsable(EditorBrowsableState.Advanced), Browsable(false), DefaultValue(false), DesignOnly(true)]
409         #endif
410         
411         public Boolean IsNullable
412         {
413             get
414             {
415                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsNullable");
416                 return is_nullable;
417             }
418
419             set
420             {
421                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "IsNullable", value);
422                 is_nullable = value;
423             }
424         }
425
426         /// <summary>
427         /// Gets or sets the name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.
428         /// </summary>
429         /// <value>The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.
430         /// The default is an empty string.</value>
431         [DefaultValue("")]
432         public String ParameterName
433         {
434             get
435             {
436                 NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "ParameterName");
437                 return name;
438             }
439
440             set
441             {
442                 name = value;
443                 if (value == null)
444                     name = String.Empty;
445                 if ( (name.Equals(String.Empty)) || ((name[0] != ':') && (name[0] != '@')) )
446                     name = ':' + name;
447
448                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "ParameterName", value);
449             }
450         }
451
452         /// <summary>
453         /// Gets or sets the name of the source column that is mapped to the
454         /// <see cref="System.Data.DataSet">DataSet</see> and used for loading or
455         /// returning the <see cref="Npgsql.NpgsqlParameter.Value">Value</see>.
456         /// </summary>
457         /// <value>The name of the source column that is mapped to the
458         /// <see cref="System.Data.DataSet">DataSet</see>. The default is an empty string.</value>
459         [Category("Data"), DefaultValue("")]
460         public String SourceColumn
461         {
462             get
463             {
464                 NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "SourceColumn");
465                 return source_column;
466             }
467
468             set
469             {
470                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "SourceColumn", value);
471                 source_column = value;
472             }
473         }
474
475         /// <summary>
476         /// Gets or sets the <see cref="System.Data.DataRowVersion">DataRowVersion</see>
477         /// to use when loading <see cref="Npgsql.NpgsqlParameter.Value">Value</see>.
478         /// </summary>
479         /// <value>One of the <see cref="System.Data.DataRowVersion">DataRowVersion</see> values.
480         /// The default is <b>Current</b>.</value>
481         [Category("Data"), DefaultValue(DataRowVersion.Current)]
482         public DataRowVersion SourceVersion
483         {
484             get
485             {
486                 NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "SourceVersion");
487                 return source_version;
488             }
489
490             set
491             {
492                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "SourceVersion", value);
493                 source_version = value;
494             }
495         }
496
497         /// <summary>
498         /// Gets or sets the value of the parameter.
499         /// </summary>
500         /// <value>An <see cref="System.Object">Object</see> that is the value of the parameter.
501         /// The default value is null.</value>
502         [TypeConverter(typeof(StringConverter)), Category("Data")]
503         public Object Value
504         {
505             get
506             {
507                 NpgsqlEventLog.LogPropertyGet(LogLevel.Normal, CLASSNAME, "Value");
508                 return value;
509             }
510
511             // [TODO] Check and validate data type.
512             set
513             {
514                 NpgsqlEventLog.LogPropertySet(LogLevel.Normal, CLASSNAME, "Value", value);
515
516                 this.value = value;
517                 if ((this.value == null) || (this.value == DBNull.Value) )
518                 {
519                     // don't really know what to do - leave default and do further exploration
520                     // Default type for null values is String.
521                     this.value = DBNull.Value;
522                     if (type_info == null)
523                         type_info = NpgsqlTypesHelper.GetNativeTypeInfo(typeof(String));
524
525                 }
526                 else
527                 {
528                     if (type_info == null)
529                     {
530                         type_info = NpgsqlTypesHelper.GetNativeTypeInfo(value.GetType());
531                         if (type_info == null)
532                                 throw new InvalidCastException(String.Format(resman.GetString("Exception_ImpossibleToCast"), value.GetType()));
533                         
534                     }
535
536                 }
537             }
538         }
539
540         /// <summary>
541         /// Creates a new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> that
542         /// is a copy of the current instance.
543         /// </summary>
544         /// <returns>A new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> that is a copy of this instance.</returns>
545         object System.ICloneable.Clone()
546         {
547             return new NpgsqlParameter(this.ParameterName, this.NpgsqlDbType,   this.Size, this.SourceColumn, this.Direction, this.IsNullable, this.Precision, this.Scale, this.SourceVersion, this.Value);
548         }
549
550
551     }
552 }