2003-12-12 Francisco Figueiredo Jr. (fxjrlists@yahoo.com.br)
[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 Npgsql.Design;
35
36 namespace Npgsql
37 {
38     /// <summary>
39     /// Represents a collection of parameters relevant to a <see cref="Npgsql.NpgsqlCommand">NpgsqlCommand</see>
40     /// as well as their respective mappings to columns in a <see cref="System.Data.DataSet">DataSet</see>.
41     /// This class cannot be inherited.
42     /// </summary>
43     [ListBindable(false)]
44     //  [Editor(typeof(NpgsqlParametersEditor), typeof(System.ComponentModel.Design.CollectionEditor))]
45     [Editor(typeof(NpgsqlParametersEditor), typeof(System.Drawing.Design.UITypeEditor))]
46     public sealed class NpgsqlParameterCollection : MarshalByRefObject, IDataParameterCollection
47     {
48         private ArrayList InternalList = new ArrayList();
49
50         // Logging related value
51         private static readonly String CLASSNAME = "NpgsqlParameterCollection";
52
53         // Our resource manager
54         private System.Resources.ResourceManager resman;
55
56         /// <summary>
57         /// Initializes a new instance of the NpgsqlParameterCollection class.
58         /// </summary>
59         internal NpgsqlParameterCollection()
60         {
61             this.resman = new System.Resources.ResourceManager(this.GetType());
62             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME);
63         }
64
65 #region NpgsqlParameterCollection Member
66
67         /// <summary>
68         /// Gets the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> with the specified name.
69         /// </summary>
70         /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to retrieve.</param>
71         /// <value>The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> with the specified name, or a null reference if the parameter is not found.</value>
72         [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
73         public NpgsqlParameter this[string parameterName] {
74             get
75             {
76                 NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, parameterName);
77                 return (NpgsqlParameter)this.InternalList[IndexOf(parameterName)];
78             }
79             set
80             {
81                 NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, parameterName, value);
82                 this.InternalList[IndexOf(parameterName)] = value;
83             }
84         }
85
86         /// <summary>
87         /// Gets the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> at the specified index.
88         /// </summary>
89         /// <param name="index">The zero-based index of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to retrieve.</param>
90         /// <value>The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> at the specified index.</value>
91         [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
92         public NpgsqlParameter this[int index] {
93             get
94             {
95                 NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, index);
96                 return (NpgsqlParameter)this.InternalList[index];
97             }
98             set
99             {
100                 NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, index, value);
101                 this.InternalList[index] = value;
102             }
103         }
104
105         /// <summary>
106         /// Adds the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see>.
107         /// </summary>
108         /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
109         /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
110         public NpgsqlParameter Add(NpgsqlParameter value)
111         {
112             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", value);
113
114             // Do not allow parameters without name.
115             if ((value.ParameterName == null) ||
116                     (value.ParameterName.Trim() == String.Empty) ||
117                     (value.ParameterName.Length == 1 && value.ParameterName[0] == ':'))
118                 throw new NpgsqlException(String.Format(this.resman.GetString("Exception_InvalidParameterName"), value.ParameterName));
119
120             this.InternalList.Add(value);
121             return value;
122         }
123
124         /// <summary>
125         /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> given the specified parameter name and value.
126         /// </summary>
127         /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>.</param>
128         /// <param name="value">The Value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
129         /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
130         /// <remarks>
131         /// Use caution when using this overload of the
132         /// <b>Add</b> method to specify integer parameter values.
133         /// Because this overload takes a <i>value</i> of type Object,
134         /// you must convert the integral value to an <b>Object</b>
135         /// type when the value is zero, as the following C# example demonstrates.
136         /// <code>parameters.Add(":pname", Convert.ToInt32(0));</code>
137         /// If you do not perform this conversion, the compiler will assume you
138         /// are attempting to call the NpgsqlParameterCollection.Add(string, DbType) overload.
139         /// </remarks>
140         public NpgsqlParameter Add(string parameterName, object value)
141         {
142             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, value);
143             return this.Add(new NpgsqlParameter(parameterName, value));
144         }
145
146         /// <summary>
147         /// Adds a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> given the parameter name and the data type.
148         /// </summary>
149         /// <param name="parameterName">The name of the parameter.</param>
150         /// <param name="parameterType">One of the DbType values.</param>
151         /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
152         public NpgsqlParameter Add(string parameterName, DbType parameterType)
153         {
154             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, parameterType);
155             return this.Add(new NpgsqlParameter(parameterName, parameterType));
156         }
157
158         /// <summary>
159         /// 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.
160         /// </summary>
161         /// <param name="parameterName">The name of the parameter.</param>
162         /// <param name="parameterType">One of the DbType values.</param>
163         /// <param name="size">The length of the column.</param>
164         /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
165         public NpgsqlParameter Add(string parameterName, DbType parameterType, int size)
166         {
167             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, parameterType, size);
168             return this.Add(new NpgsqlParameter(parameterName, parameterType, size));
169         }
170
171         /// <summary>
172         /// 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.
173         /// </summary>
174         /// <param name="parameterName">The name of the parameter.</param>
175         /// <param name="parameterType">One of the DbType values.</param>
176         /// <param name="size">The length of the column.</param>
177         /// <param name="sourceColumn">The name of the source column.</param>
178         /// <returns>The index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
179         public NpgsqlParameter Add(string parameterName, DbType parameterType, int size, string sourceColumn)
180         {
181             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", parameterName, parameterType, size, sourceColumn);
182             return this.Add(new NpgsqlParameter(parameterName, parameterType, size, sourceColumn));
183         }
184
185 #endregion
186
187 #region IDataParameterCollection Member
188
189         object System.Data.IDataParameterCollection.this[string parameterName] {
190             get
191             {
192                 NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, parameterName);
193                 return this.InternalList[IndexOf(parameterName)];
194             }
195             set
196             {
197                 NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, parameterName, value);
198                 CheckType(value);
199                 this.InternalList[IndexOf(parameterName)] = value;
200             }
201         }
202
203         /// <summary>
204         /// Removes the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> from the collection using the parameter name.
205         /// </summary>
206         /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to retrieve.</param>
207         public void RemoveAt(string parameterName)
208         {
209             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "RemoveAt", parameterName);
210             this.InternalList.RemoveAt(IndexOf(parameterName));
211         }
212
213         /// <summary>
214         /// Gets a value indicating whether a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> with the specified parameter name exists in the collection.
215         /// </summary>
216         /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
217         /// <returns><b>true</b> if the collection contains the parameter; otherwise, <b>false</b>.</returns>
218         public bool Contains(string parameterName)
219         {
220             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Contains", parameterName);
221             return (IndexOf(parameterName) != -1);
222         }
223
224         /// <summary>
225         /// Gets the location of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> in the collection with a specific parameter name.
226         /// </summary>
227         /// <param name="parameterName">The name of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
228         /// <returns>The zero-based location of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> in the collection.</returns>
229         public int IndexOf(string parameterName)
230         {
231             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IndexOf", parameterName);
232
233             // Iterate values to see what is the index of parameter.
234             Int32 index = 0;
235             if (parameterName[0] != ':')
236                 parameterName = ':' + parameterName;
237
238             foreach(NpgsqlParameter parameter in this)
239             {
240                 if (parameter.ParameterName == parameterName)
241                     return index;
242                 index++;
243             }
244             return -1;
245         }
246
247 #endregion
248
249 #region IList Member
250
251         bool IList.IsReadOnly {
252             get
253             {
254                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsReadOnly");
255                 return this.InternalList.IsReadOnly;
256             }
257         }
258
259         object System.Collections.IList.this[int index] {
260             get
261             {
262                 NpgsqlEventLog.LogIndexerGet(LogLevel.Debug, CLASSNAME, index);
263                 return (NpgsqlParameter)this.InternalList[index];
264             }
265             set
266             {
267                 NpgsqlEventLog.LogIndexerSet(LogLevel.Debug, CLASSNAME, index, value);
268                 CheckType(value);
269                 this.InternalList[index] = value;
270             }
271         }
272
273         /// <summary>
274         /// Removes the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> from the collection using a specific index.
275         /// </summary>
276         /// <param name="index">The zero-based index of the parameter.</param>
277         public void RemoveAt(int index)
278         {
279             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "RemoveAt", index);
280             this.InternalList.RemoveAt(index);
281         }
282
283         /// <summary>
284         /// Inserts a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> into the collection at the specified index.
285         /// </summary>
286         /// <param name="index">The zero-based index where the parameter is to be inserted within the collection.</param>
287         /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
288         public void Insert(int index, object value)
289         {
290             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Insert", index, value);
291             CheckType(value);
292             this.InternalList.Insert(index, value);
293         }
294
295         /// <summary>
296         /// Removes the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> from the collection.
297         /// </summary>
298         /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to remove from the collection.</param>
299         public void Remove(object value)
300         {
301             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Remove", value);
302             CheckType(value);
303             this.InternalList.Remove(value);
304         }
305
306         /// <summary>
307         /// Gets a value indicating whether a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> exists in the collection.
308         /// </summary>
309         /// <param name="value">The value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
310         /// <returns>true if the collection contains the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object; otherwise, false.</returns>
311         public bool Contains(object value)
312         {
313             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Contains", value);
314             CheckType(value);
315             return this.InternalList.Contains(value);
316         }
317
318         /// <summary>
319         /// Removes all items from the collection.
320         /// </summary>
321         public void Clear()
322         {
323             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Clear");
324             this.InternalList.Clear();
325         }
326
327         /// <summary>
328         /// Gets the location of a <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> in the collection.
329         /// </summary>
330         /// <param name="value">The value of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to find.</param>
331         /// <returns>The zero-based index of the <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object in the collection.</returns>
332         public int IndexOf(object value)
333         {
334             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IndexOf", value);
335             CheckType(value);
336             return this.InternalList.IndexOf(value);
337         }
338
339         /// <summary>
340         /// Adds the specified <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object to the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see>.
341         /// </summary>
342         /// <param name="value">The <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> to add to the collection.</param>
343         /// <returns>The zero-based index of the new <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> object.</returns>
344         public int Add(object value)
345         {
346             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Add", value);
347             CheckType(value);
348             return this.InternalList.Add(value);
349         }
350
351         bool IList.IsFixedSize {
352             get
353             {
354                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsFixedSize");
355                 return this.InternalList.IsFixedSize;
356             }
357         }
358
359 #endregion
360
361 #region ICollection Member
362
363         bool ICollection.IsSynchronized {
364             get
365             {
366                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "IsSynchronized");
367                 return this.InternalList.IsSynchronized;
368             }
369         }
370
371         /// <summary>
372         /// Gets the number of <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects in the collection.
373         /// </summary>
374         /// <value>The number of <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects in the collection.</value>
375         [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
376         public int Count {
377             get
378             {
379                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "Count");
380                 return this.InternalList.Count;
381             }
382         }
383
384         /// <summary>
385         /// Copies <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see> objects from the <see cref="Npgsql.NpgsqlParameterCollection">NpgsqlParameterCollection</see> to the specified array.
386         /// </summary>
387         /// <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>
388         /// <param name="index">The starting index of the array.</param>
389         public void CopyTo(Array array, int index)
390         {
391             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CopyTo", array, index);
392             this.InternalList.CopyTo(array, index);
393         }
394
395         object ICollection.SyncRoot {
396             get
397             {
398                 NpgsqlEventLog.LogPropertyGet(LogLevel.Debug, CLASSNAME, "SyncRoot");
399                 return this.InternalList.SyncRoot;
400             }
401         }
402
403 #endregion
404
405 #region IEnumerable Member
406
407         /// <summary>
408         /// Returns an enumerator that can iterate through the collection.
409         /// </summary>
410         /// <returns>An <see cref="System.Collections.IEnumerator">IEnumerator</see> that can be used to iterate through the collection.</returns>
411         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
412         {
413             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "GetEnumerator");
414             return this.InternalList.GetEnumerator();
415         }
416
417 #endregion
418
419         /// <summary>
420         /// In methods taking an object as argument this method is used to verify
421         /// that the argument has the type <see cref="Npgsql.NpgsqlParameter">NpgsqlParameter</see>
422         /// </summary>
423         /// <param name="Object">The object to verify</param>
424         private void CheckType(object Object)
425         {
426             NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CheckType", Object);
427             if(Object.GetType() != typeof(NpgsqlParameter))
428                 throw new InvalidCastException(String.Format(this.resman.GetString("Exception_WrongType"), Object.GetType().ToString()));
429         }
430
431     }
432 }