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