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