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