merge -r 53370:58178
[mono.git] / mcs / class / Mono.Data.SqliteClient / Mono.Data.SqliteClient / SqliteParameterCollection.cs
1 //
2 // Mono.Data.SqliteClient.SqliteParameterCollection.cs
3 //
4 // Represents a collection of parameters relevant to a SqliteCommand as well as 
5 // their respective mappings to columns in a DataSet.
6 //
7 //Author(s):            Vladimir Vukicevic  <vladimir@pobox.com>
8 //                      Everaldo Canuto  <everaldo_canuto@yahoo.com.br>
9 //                      Chris Turchin <chris@turchin.net>
10 //                      Jeroen Zwartepoorte <jeroen@xs4all.nl>
11 //                      Thomas Zoechling <thomas.zoechling@gmx.at>
12 //
13 // Copyright (C) 2002  Vladimir Vukicevic
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 using System;
36 using System.Data;
37 using System.Collections;
38
39 namespace Mono.Data.SqliteClient
40 {
41         public class SqliteParameterCollection : IDataParameterCollection, IList
42         {
43         
44                 #region Fields
45                 
46                 ArrayList numeric_param_list = new ArrayList();
47                 Hashtable named_param_hash = new Hashtable();
48                 
49                 #endregion
50
51                 #region Private Methods
52
53                 private void CheckSqliteParam (object value)
54                 {
55                         if (!(value is SqliteParameter))
56                                 throw new InvalidCastException ("Can only use SqliteParameter objects");
57                         SqliteParameter sqlp = value as SqliteParameter;
58                         if (sqlp.ParameterName == null || sqlp.ParameterName.Length == 0)
59                                 sqlp.ParameterName = this.GenerateParameterName();
60                  }
61
62                 private void RecreateNamedHash ()
63                 {
64                         for (int i = 0; i < numeric_param_list.Count; i++) 
65                         {
66                                 named_param_hash[((SqliteParameter) numeric_param_list[i]).ParameterName] = i;
67                         }
68                 }
69
70                 //FIXME: if the user is calling Insert at various locations with unnamed parameters, this is not going to work....
71                 private string GenerateParameterName()
72                 {
73                         int             index   = this.Count + 1;
74                         string  name    = String.Empty;
75
76                         while (index > 0)
77                         {
78                                 name = ":" + index.ToString();
79                                         if (this.IndexOf(name) == -1)
80                                         index = -1;
81                                 else
82                                 index++;
83                         }
84                         return name;
85                 }
86
87                 #endregion
88
89                 #region Properties
90                 
91                 object IList.this[int index] {
92                         get 
93                         {
94                                 return this[index];
95                         }
96                         set 
97                         {
98                                 CheckSqliteParam (value);
99                                 this[index] = (SqliteParameter) value;
100                         }
101                 }
102                 
103                 object IDataParameterCollection.this[string parameterName] {
104                         get 
105                         {
106                                 return this[parameterName];
107                         }
108                         set 
109                         {
110                                 CheckSqliteParam (value);
111                                 this[parameterName] = (SqliteParameter) value;
112                         }
113                 }
114                 
115                 public SqliteParameter this[string parameterName] 
116                 {
117                         get 
118                         {
119                                 if (this.Contains(parameterName))
120                                         return this[(int) named_param_hash[parameterName]];
121                                 else
122                                         throw new IndexOutOfRangeException("The specified name does not exist: " + parameterName);
123                         }
124                         set
125                         {
126                                 if (this.Contains(parameterName))
127                                         numeric_param_list[(int) named_param_hash[parameterName]] = value;
128                                 else
129                                         throw new IndexOutOfRangeException("The specified name does not exist: " + parameterName);
130                         }
131                 }
132
133                 public SqliteParameter this[int parameterIndex]
134                 {
135                         get
136                         {
137                                 if (this.Count >= parameterIndex+1)
138                                         return (SqliteParameter) numeric_param_list[parameterIndex];
139                                 else          
140                                         throw new IndexOutOfRangeException("The specified parameter index does not exist: " + parameterIndex.ToString());
141                         }
142                         set
143                         {
144                                 if (this.Count >= parameterIndex+1)
145                                         numeric_param_list[parameterIndex] = value;
146                                 else          
147                                         throw new IndexOutOfRangeException("The specified parameter index does not exist: " + parameterIndex.ToString());
148                         }
149                 }
150
151
152                 public int Count 
153                 {
154                         get
155                         {
156                                 return this.numeric_param_list.Count;
157                         }
158                 }
159
160                 bool IList.IsFixedSize
161                 {
162                         get
163                         {
164                                 return this.numeric_param_list.IsFixedSize;
165                         }
166                 }
167
168                 bool IList.IsReadOnly
169                 {
170                         get
171                         {
172                                 return this.numeric_param_list.IsReadOnly;
173                         }
174                 }
175
176
177                 bool ICollection.IsSynchronized 
178                 {
179                         get
180                         {
181                                 return this.numeric_param_list.IsSynchronized;
182                         }
183                 }
184                 
185
186                 object ICollection.SyncRoot 
187                 {
188                         get
189                         {
190                                 return this.numeric_param_list.SyncRoot;
191                         }
192                 }
193
194                 #endregion
195
196                 #region Public Methods
197                 
198                 public int Add (object value)
199                 {
200                         CheckSqliteParam (value);
201                         SqliteParameter sqlp = value as SqliteParameter;
202                         if (named_param_hash.Contains (sqlp.ParameterName))
203                                 throw new DuplicateNameException ("Parameter collection already contains the a SqliteParameter with the given ParameterName.");
204                         named_param_hash[sqlp.ParameterName] = numeric_param_list.Add(value);
205                                 return (int) named_param_hash[sqlp.ParameterName];
206                 }
207
208                 public SqliteParameter Add (SqliteParameter param)
209                 {
210                         Add ((object)param);
211                         return param;
212                 }
213                 
214                 public SqliteParameter Add (string name, object value)
215                 {
216                         return Add (new SqliteParameter (name, value));
217                 }
218                 
219                 public SqliteParameter Add (string name, DbType type)
220                 {
221                         return Add (new SqliteParameter (name, type));
222                 }
223                 
224                 public void Clear ()
225                 {
226                         numeric_param_list.Clear ();
227                         named_param_hash.Clear ();
228                 }
229                 
230                 public void CopyTo (Array array, int index)
231                 {
232                         this.numeric_param_list.CopyTo(array, index);
233                 }
234                 
235                 bool IList.Contains (object value)
236                 {
237                         return Contains ((SqliteParameter) value);
238                 }
239                 
240                 public bool Contains (string parameterName)
241                 {
242                         return named_param_hash.Contains (parameterName);
243                 }
244                 
245                 public bool Contains (SqliteParameter param)
246                 {
247                         return Contains (param.ParameterName);
248                 }
249                 
250                 public IEnumerator GetEnumerator ()
251                 {
252                         return this.numeric_param_list.GetEnumerator();
253                 }
254                 
255                 int IList.IndexOf (object param)
256                 {
257                         return IndexOf ((SqliteParameter) param);
258                 }
259                 
260                 public int IndexOf (string parameterName)
261                 {
262                         if (named_param_hash.Contains(parameterName))
263                                 return (int) named_param_hash[parameterName];
264                         else
265                                 return -1;
266                 }
267                 
268                 public int IndexOf (SqliteParameter param)
269                 {
270                         return IndexOf (param.ParameterName);
271                 }
272                 
273                 public void Insert (int index, object value)
274                 {
275                         CheckSqliteParam (value);
276                         if (numeric_param_list.Count == index) 
277                         {
278                                 Add (value);
279                                 return;
280                         }
281                         
282                         numeric_param_list.Insert (index, value);
283                         RecreateNamedHash ();
284                 }
285                 
286                 public void Remove (object value)
287                 {
288                         CheckSqliteParam (value);
289                         RemoveAt ((SqliteParameter) value);
290                 }
291                 
292                 public void RemoveAt (int index)
293                 {
294                         RemoveAt (((SqliteParameter) numeric_param_list[index]).ParameterName);
295                 }
296                 
297                 public void RemoveAt (string parameterName)
298                 {
299                         if (!named_param_hash.Contains (parameterName))
300                                 throw new ApplicationException ("Parameter " + parameterName + " not found");
301                         
302                         numeric_param_list.RemoveAt ((int) named_param_hash[parameterName]);
303                         named_param_hash.Remove (parameterName);
304                         
305                         RecreateNamedHash ();
306                 }
307                 
308                 public void RemoveAt (SqliteParameter param)
309                 {
310                         RemoveAt (param.ParameterName);
311                 }
312                 
313                 #endregion
314         }
315 }