2010-07-25 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[mono.git] / mcs / class / Npgsql / Npgsql / NpgsqlParameterCollection.cs
1 // created on 09/07/2003 at 20:20
2 // Npgsql.NpgsqlParameterCollection.cs
3 //
4 // Author:
5 // Brar Piening (brar@gmx.de)
6 //
7 // Rewritten from the scratch to derive from MarshalByRefObject instead of ArrayList.
8 // Recycled some parts of the original NpgsqlParameterCollection.cs
9 // by Francisco Jr. (fxjrlists@yahoo.com.br)
10 //
11 // Copyright (C) 2002 The Npgsql Development Team
12 // npgsql-general@gborg.postgresql.org
13 // http://gborg.postgresql.org/project/npgsql/projdisplay.php
14 //
15 // This library is free software; you can redistribute it and/or
16 // modify it under the terms of the GNU Lesser General Public
17 // License as published by the Free Software Foundation; either
18 // version 2.1 of the License, or (at your option) any later version.
19 //
20 // This library is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23 // Lesser General Public License for more details.
24 //
25 // You should have received a copy of the GNU Lesser General Public
26 // License along with this library; if not, write to the Free Software
27 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28
29 using System;
30 using System.Reflection;
31 using System.Data;
32 using System.Collections;
33 using System.ComponentModel;
34 using NpgsqlTypes;
35
36 #if WITHDESIGN
37 using Npgsql.Design;
38 #endif
39
40 namespace Npgsql
41 {
42     /// <summary>
43     /// Represents a collection of parameters relevant to a <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>
44     /// as well as their respective mappings to columns in a <see cref="System.Data.DataSet">DataSet</see>.
45     /// This class cannot be inherited.
46     /// </summary>
47     
48     #if WITHDESIGN
49     [ListBindable(false)]
50     [Editor(typeof(NpgsqlParametersEditor), typeof(System.Drawing.Design.UITypeEditor))]
51     #endif
52     
53     public sealed class NpgsqlParameterCollection : MarshalByRefObject, IDataParameterCollection
54     {
55         private ArrayList InternalList = new ArrayList();
56
57         // Logging related value
58         private static readonly String CLASSNAME = "NpgsqlParameterCollection";
59
60         // Our resource manager
61         private System.Resources.ResourceManager resman;
62
63         /// <summary>
64         /// Initializes a new instance of the NpgsqlParameterCollection class.
65         /// </summary>
66         internal NpgsqlParameterCollection()
67         {
68             this.resman = new System.Resources.ResourceManager(this.GetType());
69             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
70         }
71
72 #region NpgsqlParameterCollection Member
73
74         /// <summary>
75         /// Gets the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> with the specified name.
76         /// </summary>
77         /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to retrieve.</param>
78         /// <value>The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> with the specified name, or a null reference if the parameter is not found.</value>
79         
80         #if WITHDESIGN
81         [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
82         #endif
83         
84         public NpgsqlParameter this[string parameterName] {
85             get
86             {
87                 NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, parameterName);
88                 return (NpgsqlParameter)this.InternalList[IndexOf(parameterName)];
89             }
90             set
91             {
92                 NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, parameterName, value);
93                 this.InternalList[IndexOf(parameterName)] = value;
94             }
95         }
96
97         /// <summary>
98         /// Gets the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> at the specified index.
99         /// </summary>
100         /// <param name="index">The zero-based index of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to retrieve.</param>
101         /// <value>The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> at the specified index.</value>
102         
103         #if WITHDESIGN
104         [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
105         #endif
106         
107         public NpgsqlParameter this[int index] {
108             get
109             {
110                 NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, index);
111                 return (NpgsqlParameter)this.InternalList[index];
112             }
113             set
114             {
115                 NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, index, value);
116                 this.InternalList[index] = value;
117             }
118         }
119
120         /// <summary>
121         /// Adds the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see>.
122         /// </summary>
123         /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
124         /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
125         public NpgsqlParameter Add(NpgsqlParameter value)
126         {
127             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", value);
128
129             // Do not allow parameters without name.
130             
131             this.InternalList.Add(value);
132             
133             // Check if there is a name. If not, add a name based in the index of parameter.
134             if (value.ParameterName.Trim() == String.Empty ||
135             (value.ParameterName.Length == 1 && value.ParameterName[0] == ':'))
136                 value.ParameterName = ":" + "Parameter" + (IndexOf(value) + 1);
137         
138             
139             return value;
140         }
141
142         /// <summary>
143         /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> given the specified parameter name and value.
144         /// </summary>
145         /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.</param>
146         /// <param name="value">The Value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
147         /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
148         /// <remarks>
149         /// Use caution when using this overload of the
150         /// <b>Add</b> method to specify integer parameter values.
151         /// Because this overload takes a <i>value</i> of type Object,
152         /// you must convert the integral value to an <b>Object</b>
153         /// type when the value is zero, as the following C# example demonstrates.
154         /// <code>parameters.Add(":pname", Convert.ToInt32(0));</code>
155         /// If you do not perform this conversion, the compiler will assume you
156         /// are attempting to call the NpgsqlParameterCollection.Add(string, DbType) overload.
157         /// </remarks>
158         public NpgsqlParameter Add(string parameterName, object value)
159         {
160             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, value);
161             return this.Add(new NpgsqlParameter(parameterName, value));
162         }
163
164         /// <summary>
165         /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> given the parameter name and the data type.
166         /// </summary>
167         /// <param name="parameterName">The name of the parameter.</param>
168         /// <param name="parameterType">One of the DbType values.</param>
169         /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
170         public NpgsqlParameter Add(string parameterName, NpgsqlDbType parameterType)
171         {
172             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, parameterType);
173             return this.Add(new NpgsqlParameter(parameterName, parameterType));
174         }
175
176         /// <summary>
177         /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> with the parameter name, the data type, and the column length.
178         /// </summary>
179         /// <param name="parameterName">The name of the parameter.</param>
180         /// <param name="parameterType">One of the DbType values.</param>
181         /// <param name="size">The length of the column.</param>
182         /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
183         public NpgsqlParameter Add(string parameterName, NpgsqlDbType parameterType, int size)
184         {
185             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, parameterType, size);
186             return this.Add(new NpgsqlParameter(parameterName, parameterType, size));
187         }
188
189         /// <summary>
190         /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> with the parameter name, the data type, the column length, and the source column name.
191         /// </summary>
192         /// <param name="parameterName">The name of the parameter.</param>
193         /// <param name="parameterType">One of the DbType values.</param>
194         /// <param name="size">The length of the column.</param>
195         /// <param name="sourceColumn">The name of the source column.</param>
196         /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
197         public NpgsqlParameter Add(string parameterName, NpgsqlDbType parameterType, int size, string sourceColumn)
198         {
199             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, parameterType, size, sourceColumn);
200             return this.Add(new NpgsqlParameter(parameterName, parameterType, size, sourceColumn));
201         }
202
203 #endregion
204
205 #region IDataParameterCollection Member
206
207         object System.Data.IDataParameterCollection.this[string parameterName] {
208             get
209             {
210                 NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, parameterName);
211                 return this.InternalList[IndexOf(parameterName)];
212             }
213             set
214             {
215                 NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, parameterName, value);
216                 CheckType(value);
217                 this.InternalList[IndexOf(parameterName)] = value;
218             }
219         }
220
221         /// <summary>
222         /// Removes the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> from the collection using the parameter name.
223         /// </summary>
224         /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to retrieve.</param>
225         public void RemoveAt(string parameterName)
226         {
227             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "RemoveAt", parameterName);
228             this.InternalList.RemoveAt(IndexOf(parameterName));
229         }
230
231         /// <summary>
232         /// Gets a value indicating whether a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> with the specified parameter name exists in the collection.
233         /// </summary>
234         /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
235         /// <returns><b>true</b> if the collection contains the parameter; otherwise, <b>false</b>.</returns>
236         public bool Contains(string parameterName)
237         {
238             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Contains", parameterName);
239             return (IndexOf(parameterName) != -1);
240         }
241
242         /// <summary>
243         /// Gets the location of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> in the collection with a specific parameter name.
244         /// </summary>
245         /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
246         /// <returns>The zero-based location of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> in the collection.</returns>
247         public int IndexOf(string parameterName)
248         {
249             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IndexOf", parameterName);
250
251             // Iterate values to see what is the index of parameter.
252             Int32 index = 0;\r
253             if ((parameterName[0] == ':') || (parameterName[0] == '@'))\r
254                 parameterName = parameterName.Remove(0, 1);\r
255 \r
256             foreach (NpgsqlParameter parameter in this)\r
257             {\r
258                 if (parameter.ParameterName.Remove(0, 1) == parameterName)\r
259                     return index;\r
260                 index++;
261             }
262             return -1;
263         }
264
265 #endregion
266
267 #region IList Member
268
269         bool IList.IsReadOnly {
270             get
271             {
272                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsReadOnly");
273                 return this.InternalList.IsReadOnly;
274             }
275         }
276
277         object System.Collections.IList.this[int index] {
278             get
279             {
280                 NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, index);
281                 return (NpgsqlParameter)this.InternalList[index];
282             }
283             set
284             {
285                 NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, index, value);
286                 CheckType(value);
287                 this.InternalList[index] = value;
288             }
289         }
290
291         /// <summary>
292         /// Removes the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> from the collection using a specific index.
293         /// </summary>
294         /// <param name="index">The zero-based index of the parameter.</param>
295         public void RemoveAt(int index)
296         {
297             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "RemoveAt", index);
298             this.InternalList.RemoveAt(index);
299         }
300
301         /// <summary>
302         /// Inserts a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> into the collection at the specified index.
303         /// </summary>
304         /// <param name="index">The zero-based index where the parameter is to be inserted within the collection.</param>
305         /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
306         public void Insert(int index, object value)
307         {
308             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Insert", index, value);
309             CheckType(value);
310             this.InternalList.Insert(index, value);
311         }
312
313         /// <summary>
314         /// Removes the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> from the collection.
315         /// </summary>
316         /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to remove from the collection.</param>
317         public void Remove(object value)
318         {
319             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Remove", value);
320             CheckType(value);
321             this.InternalList.Remove(value);
322         }
323
324         /// <summary>
325         /// Gets a value indicating whether a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> exists in the collection.
326         /// </summary>
327         /// <param name="value">The value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
328         /// <returns>true if the collection contains the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object; otherwise, false.</returns>
329         public bool Contains(object value)
330         {
331             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Contains", value);
332             CheckType(value);
333             return this.InternalList.Contains(value);
334         }\r
335 \r
336         /// <summary>\r
337         /// Gets a value indicating whether a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> with the specified parameter name exists in the collection.\r
338         /// </summary>\r
339         /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>\r
340         /// <param name="parameter">A reference to the requested parameter is returned in this out param if it is found in the list.  This value is null if the parameter is not found.</param>\r
341         /// <returns><b>true</b> if the collection contains the parameter and param will contain the parameter; otherwise, <b>false</b>.</returns>\r
342         public bool TryGetValue(string parameterName, out NpgsqlParameter parameter)\r
343         {\r
344             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "TryGetValue", parameterName);\r
345             int index = IndexOf(parameterName);\r
346             if (index != -1)\r
347             {\r
348                 parameter = this[index];\r
349                 return true;\r
350             }\r
351             else\r
352             {\r
353                 parameter = null;\r
354                 return false;\r
355             }\r
356         }\r
357
358         /// <summary>
359         /// Removes all items from the collection.
360         /// </summary>
361         public void Clear()
362         {
363             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Clear");
364             this.InternalList.Clear();
365         }
366
367         /// <summary>
368         /// Gets the location of a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> in the collection.
369         /// </summary>
370         /// <param name="value">The value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
371         /// <returns>The zero-based index of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object in the collection.</returns>
372         public int IndexOf(object value)
373         {
374             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IndexOf", value);
375             CheckType(value);
376             return this.InternalList.IndexOf(value);
377         }
378
379         /// <summary>
380         /// Adds the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see>.
381         /// </summary>
382         /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
383         /// <returns>The zero-based index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
384         public int Add(object value)
385         {
386             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", value);
387             CheckType(value);
388             this.Add((NpgsqlParameter)value);
389             return IndexOf(value);
390         }
391
392         bool IList.IsFixedSize {
393             get
394             {
395                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsFixedSize");
396                 return this.InternalList.IsFixedSize;
397             }
398         }
399
400 #endregion
401
402 #region ICollection Member
403
404         bool ICollection.IsSynchronized {
405             get
406             {
407                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsSynchronized");
408                 return this.InternalList.IsSynchronized;
409             }
410         }
411
412         /// <summary>
413         /// Gets the number of <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects in the collection.
414         /// </summary>
415         /// <value>The number of <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects in the collection.</value>
416         
417         #if WITHDESIGN
418         [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
419         #endif
420         
421         public int Count {
422             get
423             {
424                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Count");
425                 return this.InternalList.Count;
426             }
427         }
428
429         /// <summary>
430         /// Copies <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects from the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> to the specified array.
431         /// </summary>
432         /// <param name="array">An <see cref="System.Array">Array</see> to which to copy the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects in the collection.</param>
433         /// <param name="index">The starting index of the array.</param>
434         public void CopyTo(Array array, int index)
435         {
436             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CopyTo", array, index);
437             this.InternalList.CopyTo(array, index);
438         }
439
440         object ICollection.SyncRoot {
441             get
442             {
443                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "SyncRoot");
444                 return this.InternalList.SyncRoot;
445             }
446         }
447
448 #endregion
449
450 #region IEnumerable Member
451
452         /// <summary>
453         /// Returns an enumerator that can iterate through the collection.
454         /// </summary>
455         /// <returns>An <see cref="System.Collections.IEnumerator">IEnumerator</see> that can be used to iterate through the collection.</returns>
456         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
457         {
458             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetEnumerator");
459             return this.InternalList.GetEnumerator();
460         }
461
462 #endregion
463
464         /// <summary>
465         /// In methods taking an object as argument this method is used to verify
466         /// that the argument has the type <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
467         /// </summary>
468         /// <param name="Object">The object to verify</param>
469         private void CheckType(object Object)
470         {
471             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CheckType", Object);
472             if(Object.GetType() != typeof(NpgsqlParameter))
473                 throw new InvalidCastException(String.Format(this.resman.GetString("Exception_WrongType"), Object.GetType().ToString()));
474         }
475
476     }
477 }